Reputation: 820
How to request using Alamofire to get stream JSON. I am using the below function to get the response
self.sessionManager?.request(url, method: methodType!, parameters: params, encoding: JSONEncoding.default, headers: headers)
.validate()
.responseJSON { (response) in
if (response.result.error == nil) {
completion(response.result.value as AnyObject?, nil , response.response?.statusCode )
} else {
// debugPrint("HTTP Request failed: \(String(describing: response.result.error))")
completion(nil, response.result.error, response.response?.statusCode)
}
}
And my API Url something like
http://{server Url}/services/data/{number of chunks}/{items in per chunk}
and the response I get from API if the number of chunks is 3 and items per chunk is 3
data: [
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026419,
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417,
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417,
}
]
data: [
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417,
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417,
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417,
}
]
data: [
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417,
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417,
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417,
}
]
data:done
I did not get any response from the server but in Postman it works fine.
Upvotes: 6
Views: 3240
Reputation: 39
Elaborating a little on Alex's most helpful answer:
fileprivate lazy var alamoSession: Session = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 20
configuration.urlCache?.removeAllCachedResponses()
return Alamofire.Session(configuration: configuration /*, interceptor: interceptor*/)
}()
fileprivate func alamofireChunked () {
guard let url = URL(string: "http://A_Steaming_Source.com") // Put your datasource here
else {
return
}
let urlRequest = URLRequest(url: url)
alamoSession.streamRequest(urlRequest).validate().responseStream { response in
if let data = response.value {
print("received \(data.count) bytes")
if data.count > 0 {
// process received data here
}
} else {
switch response.event {
case .complete( _):
// perform any post processing here
print("stream is finished")
break;
default:
break;
}
}
}
}
Upvotes: 0
Reputation: 89
To receive streaming data, you can try adding
request.stream(closure: { data in ... })
Inside closure you should collect data chunks from server and parse them lately, after response is called. In that case response will be nil.
So it would be something like:
let mData = NSMutableData()
self.sessionManager?
.request(url, method: methodType!, parameters: params, encoding: JSONEncoding.default, headers: headers)
.validate()
.stream(closure: { data in mData.append(data) })
.response { response in
//parse mData
}
Upvotes: 3
Reputation: 3927
The reason your request fails might be that you are using responseJSON
to parse the response, and the response does not seem to be valid json.
The returned data consists of three individual arrays named data
, all located at the top level. How should this be converted to a dictionary or array?
Is it possible to change the way the server formats the response, to - for example - have it return one toplevel array, with several data
child arrays (one for each chunk)? Sort of like this:
[
[
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026419
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417
}
],
[
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417
}
],
[
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417
},
{
"invalidDraft": false,
"bulkReserve": false,
"srNo": 0,
"returned": false,
"status": "ACTIVE",
"timestamp": 1580186026417
}
]
]
If this is not possible, parse the response as a string instead, and then use regular expression to find every "data" array in the string, which can then be parsed as JSON.
Upvotes: 0