【问题标题】:JSON Streaming in chunks using Alamofire Swift使用 Alamofire Swift 分块的 JSON 流式传输
【发布时间】:2020-06-02 02:15:49
【问题描述】:

如何使用 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}

如果块数为 3 且每个块的项目数为 3,我从 API 得到的响应

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 中它工作正常。

【问题讨论】:

    标签: json swift swift3 alamofire


    【解决方案1】:

    要接收流数据,可以尝试添加

    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
        }
    
    

    【讨论】:

      【解决方案2】:

      您的请求失败的原因可能是您使用responseJSON 来解析响应,而响应似乎不是有效的json。

      返回的数据由三个名为data 的单独数组组成,它们都位于顶层。这应该如何转换为字典或数组?

      是否可以更改服务器格式化响应的方式,例如 - 让它返回一个顶级数组,其中包含多个 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
              }
          ]
      ]
      

      如果无法做到这一点,请将响应解析为字符串,然后使用正则表达式查找字符串中的每个“数据”数组,然后将其解析为 JSON。

      【讨论】:

        【解决方案3】:

        详细阐述 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;
                    }
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2023-04-01
          • 2012-06-30
          • 2010-09-24
          • 2014-07-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-08
          • 1970-01-01
          相关资源
          最近更新 更多