【问题标题】:Get Method JSON Response(String) Coding Complaint for key获取密钥的方法 JSON 响应(字符串)编码投诉
【发布时间】:2019-04-26 19:27:23
【问题描述】:

我的ResponseString如下,

SUCCESS: 
{"code":200,"shop_detail":{"name":"dad","address":"556666"},
"shop_types : [{"name":"IT\/SOFTWARE","merchant_type":"office"}]}

我的带头的Get请求代码如下,

func getProfileAPI() {
        let headers: HTTPHeaders = [
            "Authorisation": AuthService.instance.tokenId ?? "",
            "Content-Type": "application/json",
            "Accept": "application/json"
        ]
        print(headers)
        let scriptUrl = "http://haitch.igenuz.com/api/merchant/profile"

        if let url = URL(string: scriptUrl) {
            var urlRequest = URLRequest(url: url)
            urlRequest.httpMethod = HTTPMethod.get.rawValue

            urlRequest.addValue(AuthService.instance.tokenId ?? "", forHTTPHeaderField: "Authorization")
            urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
            urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")

            Alamofire.request(urlRequest)
                .responseString { response in
                    debugPrint(response)
                    print(response)
                    if let result = response.result.value //    getting the json value from the server
                    {
                        print(result)

                        let jsonData1 = result as NSString
                        print(jsonData1)
                        let name = jsonData1.object(forKey: "code") as! [AnyHashable: Any]
                        print(name)
                       // var data = jsonData1!["shop_detail"]?["name"] as? String

      } }
}

当我试图获取“名称”的值时,它得到了'[<__nscfstring> valueForUndefinedKey:]:此类不符合键值编码的键码。请指导我获取名称、地址的值..??????

【问题讨论】:

    标签: ios json string xcode swift4


    【解决方案1】:

    您可以使用 Response Handler 代替 Response String Handler

    响应处理程序

    响应处理程序不会评估任何响应数据。它 仅直接从 URL 会话转发所有信息 代表。它相当于使用 cURL 执行请求的 Alamofire。

    struct Root: Codable {
        let code: Int
        let shopDetail: ShopDetail
        let shopTypes: [ShopType]
    }
    
    struct ShopDetail: Codable {
        let name, address: String
    }
    
    struct ShopType: Codable {
        let name, merchantType: String
    }
    

    如果您将解码器keyDecodingStrategy(检查this)设置为.convertFromSnakeCase,您也可以从结构声明中省略编码键,正如@vadian 在 cmets 中已经提到的那样:


    Alamofire.request(urlRequest).response { response in
        guard 
           let data = response.data, 
           let json = String(data: data, encoding: .utf8) 
        else { return }
        print("json:", json)
        do {
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            let root = try decoder.decode(Root.self, from: data)
            print(root.shopDetail.name)
            print(root.shopDetail.address)
            for shop in root.shopTypes {
                print(shop.name)
                print(shop.merchantType)
            }
        } catch { 
            print(error) 
        }            
    }
    

    有关编码和解码自定义类型的更多信息,您可以阅读此post

    【讨论】:

    • 它正在打印 json,现在请帮助我获取为 name/address 和 shoptype 为 name/merchant_type 打印的商店详细信息的值
    • 太棒了,效果很好,非常感谢@Leo Dabus 的出色编码。这有助于我学习新事物。
    【解决方案2】:

    您可以尝试将json字符串转换为数据然后对其进行解码

    struct Root: Codable {
        let code: Int
        let shopDetail: ShopDetail
        let shopTypes: [ShopType] 
    }
    
    struct ShopDetail: Codable {
        let name, address: String
    }
    
    struct ShopType: Codable {
        let name, merchantType: String 
    }
    

    然后

    let jsonStr = result as! String
    let dec = JSONDecoder()
    dec.keyDecodingStrategy = .convertFromSnakeCase
    let res = try? dec.decode(Root.self,from:jsonStr.data(using:.utf8)!)
    

    请注意,您的 str json 可能无效,因为您在 shop_types 之后错过了 ",因此请确保它看起来像这样

    {"code":200,"shop_detail":{"name":"dad","address":"556666"}, "shop_types" : [{"name":"IT/SOFTWARE","merchant_type":"office"}]}

    【讨论】:

    • 您知道如果使用.convertFromSnakeCase 密钥解码策略可以省略所有 CodingKeys 吗?
    • @vadian 我同意,原因是我没有时间自己写 json
    猜你喜欢
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 2022-09-29
    • 2019-08-16
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    相关资源
    最近更新 更多