使用 Alamofire 解析 json 的问题

Posted

技术标签:

【中文标题】使用 Alamofire 解析 json 的问题【英文标题】:Issue with parsing json using Alamofire 【发布时间】:2017-09-13 05:51:21 【问题描述】:

我在邮递员中的 JSON 响应如下所示...


    "success": 1,
    "Details": 
        "seller_id": "165",
        "mobile_no": "9653265987",
        "seller_name": "User A",
        "seller_email_id": "user@gmail.com",
        "company_name": "myCompany",
        "category": "Cosmetics",
        "otp": "1111"
    ,
    "message": "Seller Already Registered!!!"

现在我想根据成功是 0 还是 1 给出一个条件,因此我想提取成功。我也想提取手机号码。但我无法弄清楚如何做到这一点。

这就是我提出 Alamofire 发布请求的方式...

Alamofire.request(url, method: .post, parameters: Parameters, encoding: URLEncoding.httpBody, headers: headers)
            .responseString  (response) in

                if let httpResponse = response.response 
                    print("error \(httpResponse.statusCode)")

                    if httpResponse.statusCode == 200 
                        //Do something

                    
                
        

我确实遇到过其他用户提出的类似问题...但无法从他们那里找到针对我的问题的确切解决方案...

【问题讨论】:

您是否使用任何第三方序列化数据,如 swiftyjson 或 Gloss..? 不..只是 Alamofire.. 【参考方案1】:

试试这个

Alamofire.request(url, method: .post, parameters: Parameters, encoding: URLEncoding.httpBody, headers: headers)
            .responseJSON  (response) in

                switch response.result
                case .success(_):
                    print("Success: \(response)")
                    let JsonResponse = response.result.value as? [String: Any]

                    if JsonResponse?["success"] as! Int == 1
                        let dict = JsonResponse?["Details"] as! [String : Any]
                        let mobileNo = dict["mobile_no"] as! String
                    
                    else
                        print("Failed")
                    

                case .failure(let error):
                    print("Failed: \(error)")
                
        

【讨论】:

在这一行让 JsonResponse = response.result.value as? [String: Any] ,我收到来自 String 的警告 ''cast?到不相关的类型 [String:Any] 总是失败''.. 可能正因为如此,在下一行,它崩溃了...... @User.bw 不要只复制我的一小部分代码,只需用您的代码替换整个代码即可。 这个解决方案也有效......但接受了下面的答案,因为它给出了更详细的答案......但是谢谢......已经给予了支持......:)【参考方案2】:

有几个问题:

    request 的参数看起来不太正确。

    parameters 参数看起来不正确:充其量,有一个 Parameters 变量很奇怪(变量应该使用小写;这与 Alamofire 类型冲突);

    编码应该是URLEncoding.default。或者,因为URLEncoding.default 默认值,你可以完全省略它。

    如果你想检查状态码,让validate为你做。

    如果您期望 JSON 作为响应,请使用 reponseJSON 而不是 responseString

    if letguard letas? 一起使用,以安全地展开选项。不要使用as!(除非你 100% 确定它永远不会失败......并且在处理来自远程服务器的响应时,你永远不能 100% 有信心)。

因此:

func performRequest(url: String, parameters: [String: String]?, headers: [String: String]?) 
    Alamofire.request(url, method: .post, parameters: parameters, headers: headers)
        .validate(statusCode: 200 ..< 300)
        .responseJSON  response in
            switch response.result 
            case .success(let value):
                guard let dictionary = value as? [String: Any],
                    let success = dictionary["success"] as? Int else 
                        print("success not found")
                        return
                

                guard success == 1 else 
                    print("web service reported failure")
                    return
                

                guard let details = dictionary["Details"] as? [String: Any] else 
                    print("Did not find details")
                    return
                

                guard let mobile = details["mobile_no"] as? String else 
                    print("mobile not found")
                    return
                

                print(mobile)

            case .failure(let error):
                print("Failed: \(error)")
            
    


或者,在您下面的评论中,如果您想goToSignUpScreen() 如果success0,那么:

Alamofire.request(url, method: .post, parameters: parameters, headers: headers)
    .validate(statusCode: 200 ..< 300)
    .responseJSON  response in
        switch response.result 
        case .success(let value):
            guard let dictionary = value as? [String: Any],
                let success = dictionary["success"] as? Int else 
                    print("success not found")
                    return
            

            if success == 0 
                self.goToSignUpScreen()
            
        case .failure(let error):
            print("Failed: \(error)")
        

【讨论】:

解决方案很恰当,@Rob。但我有一个疑问..这肯定很简单......:)但请把它当作初学者的东西。问题是......你提到这一行 let success = dictionary["success"] as? Int else ...现在在这里,如果我想给出这个...if let result = response.result.value as? [字符串:任何] 如果结果[“成功”]为! Int == 0 self.gotToSignUpScreen() 那我怎么在保护声明中提到呢? 首先,为什么要转到response.result.value 而不是使用.success(let value) 提供的value?二、为什么要用as!而不是as??仅在转换失败时您的应用程序崩溃(即您知道它永远可能发生)时,才使用!。但是如果你想goToSignUpScreen 如果success 为零,你当然可以这样做,如上所示。 我们如何发送参数作为get方法?它会显示无效的网址 是的。这样做很常见。但是如果你得到无效的 URL,也许你忘记了这个方案(https:// 部分,或者其他什么)。根据您在此处提供的内容,我无法诊断此问题。发布您自己的问题,向我们展示您的尝试以及您得到的确切响应/错误。

以上是关于使用 Alamofire 解析 json 的问题的主要内容,如果未能解决你的问题,请参考以下文章

无法使用闭包使用 alamofire 解析 json

使用 Alamofire/Codable 解析 JSON 行

JSON数据未在swift3中使用Alamofire进行解析

使用 Alamofire 解析 json 的问题

我需要使用 Alamofire 解析 Json 的帮助

使用未解析的标识符 'json' (Swift 3) (Alamofire)