【问题标题】:Getting error when parsing JSON in Swift 3在 Swift 3 中解析 JSON 时出错
【发布时间】:2018-01-09 11:42:49
【问题描述】:

1.这是响应字符串

{"error_msg": null,"applicationStateJson": {"notifications_size": "0","dfilterlogin": 1,"loginstype": null,"email_status": "0","address_status": "0","defaultfiltername": "hyderabad","login_status": "1","defaultfilterid": 145,"profile_id": null,"freelancer": "Y","otp_status": "1","notifications": []},"status": null}

2。下面一个是完美的 JSONObject,我使用 JSONLint

{
"error_msg": null,
"applicationStateJson": {
    "notifications_size": "0",
    "dfilterlogin": 1,
    "loginstype": null,
    "email_status": "0",
    "address_status": "0",
    "defaultfiltername": "hyderabad",
    "login_status": "1",
    "defaultfilterid": 145,
    "profile_id": null,
    "freelancer": "Y",
    "otp_status": "1",
    "notifications": []
},
"status": null
}

3.当我在 Swift 3 中尝试以下代码时

let json1 = try? JSONSerialization.jsonObject(with: data, options: [])

                    if let object = json1 as? [String: Any]{

                        if let applicationState = object["applicationStateJson"] as? [String: Any]{
                            print("applicationState   \(applicationState)")
                        }
                    }

4.我得到了 JSONObject,但它不是正确的 JSONObject

(因为逗号变成了分号,所以null值变成了“”然后空数组[]变成了())

Optional({
applicationStateJson =     {
    "address_status" = 0;
    defaultfilterid = 145;
    defaultfiltername = hyderabad;
    dfilterlogin = 1;
    "email_status" = 0;
    freelancer = Y;
    "login_status" = 1;
    loginstype = "<null>";
    notifications =         (
    );
    "notifications_size" = 0;
    "otp_status" = 1;
    "profile_id" = "<null>";
};
"error_msg" = "<null>";
status = "<null>";
})

我想要第 2 步那样的 JSONObject,有什么帮助吗?

【问题讨论】:

  • 一样,只是从JSON字符串转换为Swift Dictionary对象
  • 如何再次更改 JSON 字符串?
  • 最后,我找到了方法,{if let theJSONData = try? JSONSerialization.data(withJSONObject: applicationState, options: .prettyPrinted), let theJSONText = String(data: theJSONData, encoding: String.Encoding.ascii) { print("JSON string = \n(theJSONText)") }}
  • 我能问一下为什么要将 JSON 字符串转换为 Swift 对象,然后再次部分创建 JSON 字符串吗?听起来你正在做你不需要做的事情
  • 为什么因为我想从 JSON 对象中解析 JSON 对象,也就是我想要响应中的 applicationStateJson

标签: json swift xcode swift3


【解决方案1】:

在 Swift 中读取和使用 JSON 响应不需要您将 JSON 对象转换回 JSON 来获取特定部分。将数据加载到 Swift 类型后,您可以直接使用它来获取所需的部分。

这么长的路要更好地解释我的观点......

let jsonData = jsonString.data(using: .utf8)!
let json1 = try? JSONSerialization.jsonObject(with: jsonData, options: [])

if let object = json1 as? [String: Any]{

    if let applicationState = object["applicationStateJson"] as? [String: Any]{
        print("applicationState   \(applicationState)")

        if let addressStatus = applicationState["address_status"] as? String {
            print(addressStatus)
        }
    }
}

使用 Codable 协议的 Swift 4 方式

let jsonString = "{\"error_msg\": null,\"applicationStateJson\": {\"notifications_size\": \"0\",\"dfilterlogin\": 1,\"loginstype\": null,\"email_status\": \"0\",\"address_status\": \"0\",\"defaultfiltername\": \"hyderabad\",\"login_status\": \"1\",\"defaultfilterid\": 145,\"profile_id\": null,\"freelancer\": \"Y\",\"otp_status\": \"1\",\"notifications\": []},\"status\": null}"

struct ApplicationState: Codable {
    let notificationsSize: String
    let dFilterLogin: Int
    let loginsType: String?
    let emailStatus: String
    let addressStatus: String

    enum CodingKeys : String, CodingKey {
        case notificationsSize = "notifications_size"
        case dFilterLogin = "dfilterlogin"
        case addressStatus = "address_status"
        case loginsType = "loginstype"
        case emailStatus = "email_status"
    }
}

struct ApplicationStateResponse: Codable {
    let errorMsg: String?
    let applicationState: ApplicationState

    enum CodingKeys : String, CodingKey {
        case errorMsg = "error_msg"
        case applicationState = "applicationStateJson"
    }
}

let jsonData = jsonString.data(using: .utf8)!
let decoder = JSONDecoder()
let response = try! decoder.decode(ApplicationStateResponse.self, from: jsonData)
let appState = response.applicationState

print(appState.addressStatus)

这两个都按预期打印地址状态的 0。一个比另一个更容易使用。

这个article 更详细地解释了可编码协议将是一本不错的读物。

【讨论】:

    【解决方案2】:

    将 Swift Dictionary 对象转换为 JSON 字符串,

    if let theJSONData = try?  JSONSerialization.data(withJSONObject: applicationState, options: .prettyPrinted),
                                    let theJSONText = String(data: theJSONData, encoding: String.Encoding.ascii) {
                                    print("JSON string = \n\(theJSONText)")
                                }
    

    【讨论】:

    • 如何使用您的代码从 jsonString 获取 applicationStateJson?
    • 您没有在问题中提到您只想要 JSON 字符串的一部分。
    猜你喜欢
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多