【问题标题】:How to get the result value of Alamofire.request().responseJSON in swift 2?如何在 swift 2 中获取 Alamofire.request().responseJSON 的结果值?
【发布时间】:2015-11-08 05:19:47
【问题描述】:

我对新版 Alamofire for Swift 2 有疑问

Alamofire.request(.POST, urlString, parameters: parameters as? [String : AnyObject])
        .responseJSON { (request, response, result) -> Void in
            let dico = result as? NSDictionary
            for (index, value) in dico! {
                print("index : \(index)     value : \(value)")
            }
    }

在本节中,我想将结果转换为 NSDictionary。但是当我编译并设置断点时,调试器说 dico 是 nil。如果我使用 debugDescription 打印结果,它不是 nil 并且包含我所期望的 如何转换 Result 变量?

【问题讨论】:

  • 试试if let dico = result as? [String: AnyObject] { ... }
  • 如果没有执行,那是因为结果为 nil(或者不能向下转换为字典)。您应该查看error 中的内容。
  • 另外,值得注意的是字典有键,而不是索引。
  • 感谢@mattt 的回答。我找到了怎么做。我用你说的,但没有用,当我这样做时: if let dico = result.value as? [String: AnyObject] {} 只需将结果“替换”为“result.value”即可找到

标签: ios json swift swift2 alamofire


【解决方案1】:

已接受的答案效果很好,但随着 Alamofire 3.0.0 的引入,一些重大更改会影响此实现。
migration guide 有进一步的解释,但我会强调与实际解决方案相关的那些。

  • Response
    所有响应序列化程序(除了响应)都返回一个通用的响应结构。

  • Response type
    Result 类型已重新设计为不存储 NSData 的双重泛型类型?在.Failure 的情况下。

还要考虑到 Alamofire 将任何已完成的请求视为成功,无论响应的内容如何。因此,您需要在.responseJSON() 之前链接.validate() 以达到.Failure 的情况。 阅读更多关于它的信息here

更新代码:

let url = "http://api.myawesomeapp.com"
Alamofire.request(.GET, url).validate().responseJSON { response in
    switch response.result {
    case .Success(let data):
        let json = JSON(data)
        let name = json["name"].stringValue
        print(name)
    case .Failure(let error):
        print("Request failed with error: \(error)")
    }
}

供参考:

  • Xcode 7.3 (Swift 2.2)
  • Alamofire 3.3.1
  • SwiftyJSON 2.3.3

【讨论】:

  • Alamofire 不会遇到 .Failure 情况,除非您在 .responseJSON{} 之前链接 .validate(),因此它会将所有已完成的请求视为 .Success,即使 HTTP 状态代码不是在 200 范围内:github.com/Alamofire/Alamofire#validation
  • 谢谢@ChrisTrevarthen,没有注意到这一点。已根据您的说明更新答案。
  • 在 Alamofire 4.0 中,数据现在是“任何”。你是怎么处理的?
  • 这对我有用,即使在 Alamofire 4.0 和 promisekit 中
  • @osrl 看来,使用 Alamofire 4.0,您可以改为访问 response.result.isSuccessresponse.result.isFailure
【解决方案2】:

如果您不介意使用 SwiftyJSON 库,这里是 Xcode 7 Beta 5 + Alamofire 2.0.0-beta.1 + SwiftyJSON(xcode7 分支)中的一个工作示例

Alamofire.request(.GET, url, parameters: params, encoding: ParameterEncoding.URL).responseJSON { (_, _, result) in
    switch result {
        case .Success(let data):
            let json = JSON(data)
            let name = json["name"].string
        case .Failure(_, let error):
            print("Request failed with error: \(error)")
    }
}

编辑:

更新SwiftyJSONgit 页面

【讨论】:

  • SwifyJSON 链接已损坏 :(
【解决方案3】:

您现在可以开箱即用地实现大部分所需的行为,而无需 SwiftyJSON。我的 OAuthTokenResponse 是一个可编码的简单结构。 Alamofire 库 5.2.2 允许您使用“responseDecodable”进行响应

如果你说的结构是这样的:

struct OAuthTokenResponse : Codable
{
    var access_token:String?
    var token_type:String?
    var expires_in:Int?
    var scope:String?
}

然后在你的网络调用中(使用 Alamofire)

let request = AF.request(identityUrl, method: .post, parameters: parameters, encoding: URLEncoding.httpBody)
    request
        .validate()
        .responseDecodable { (response:AFDataResponse<OAuthTokenResponse>) in
            
            switch response.result {
            case .success(let data):
                do {
                    let jwt = try decode(jwt: data.access_token!) // example
                    self.connected = true
                    print(jwt)
                } catch {
                    print(error.localizedDescription)
                    self.connected = false
                }
                
            case .failure(let error):
                    self.connected = false
                    print(error.localizedDescription)
            }
        
        }

在上面的代码中,成功案例使用可解码协议将您的 JSON 自动反序列化到您的结构中。任何错误都将导致错误案例被命中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2017-03-18
    • 2019-12-18
    • 1970-01-01
    相关资源
    最近更新 更多