JSON 使用 Alamofire 分块流式传输 Swift
JSON Streaming in chunks using Alamofire Swift
如何使用 Alamofire 请求获取流 JSON。我正在使用以下函数来获取响应
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)
}
}
还有我的 API Url 类似
http://{server Url}/services/data/{number of chunks}/{items in per chunk}
我从 API 得到的响应如果块的数量是 3 并且每个块的项目是 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
我没有从服务器收到任何响应,但在 Postman 中它工作正常。
您的请求失败的原因可能是您正在使用 responseJSON
解析响应,而响应似乎无效 json。
returned 数据由三个名为 data
的独立数组组成,都位于顶层。这应该如何转换为字典或数组?
是否可以更改服务器格式化响应的方式,例如 - 让它 return 一个顶层数组,有几个 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
}
],
[
{
"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
}
]
]
如果这不可能,将响应解析为字符串,然后使用正则表达式查找字符串中的每个 "data" 数组,然后可以将其解析为 JSON。
要接收流式数据,您可以尝试添加
request.stream(closure: { data in ... })
在调用响应后,您应该在闭包内部从服务器收集数据块并最近解析它们。
在这种情况下,响应将为零。
所以它会是这样的:
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
}
详细阐述 Alex 最有帮助的回答:
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;
}
}
}
}
如何使用 Alamofire 请求获取流 JSON。我正在使用以下函数来获取响应
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)
}
}
还有我的 API Url 类似
http://{server Url}/services/data/{number of chunks}/{items in per chunk}
我从 API 得到的响应如果块的数量是 3 并且每个块的项目是 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
我没有从服务器收到任何响应,但在 Postman 中它工作正常。
您的请求失败的原因可能是您正在使用 responseJSON
解析响应,而响应似乎无效 json。
returned 数据由三个名为 data
的独立数组组成,都位于顶层。这应该如何转换为字典或数组?
是否可以更改服务器格式化响应的方式,例如 - 让它 return 一个顶层数组,有几个 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
}
],
[
{
"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
}
]
]
如果这不可能,将响应解析为字符串,然后使用正则表达式查找字符串中的每个 "data" 数组,然后可以将其解析为 JSON。
要接收流式数据,您可以尝试添加
request.stream(closure: { data in ... })
在调用响应后,您应该在闭包内部从服务器收集数据块并最近解析它们。 在这种情况下,响应将为零。
所以它会是这样的:
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
}
详细阐述 Alex 最有帮助的回答:
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;
}
}
}
}