简体   繁体   English

解析 JSON 数据 Swift “线程 4:致命错误:在展开可选值时意外发现 nil”

[英]Parsing JSON Data Swift “Thread 4: Fatal error: Unexpectedly found nil while unwrapping an Optional value”

I am trying to parse some JSON data returned from an API call.我正在尝试解析从 API 调用返回的一些 JSON 数据。 The path I want to navigate is media > faces > points.我要导航的路径是媒体 > 面孔 > 点。 I can navigate to faces but getting points is the issue.我可以导航到面孔,但获得积分是问题所在。

here is code这是代码


let dictionary = try JSONSerialization.jsonObject(with: data!, options:.mutableContainers) as? [String:Any]

let media = dictionary!["media"] as? [String: Any]
print(media!["faces"]) // Works see the returned data below
let faces = media!["faces"] as? [String: Any]
print(faces!["points"]) // Thread 4: Fatal error: Unexpectedly found nil while unwrapping an Optional value

API returned data for print(media!["faces"]) API 返回打印数据(media!["faces"])

{
    angle = "1.2222";
    "appearance_id" = 0;
    "detection_score" = 1;
    duration = "00:00:00";
    "face_uuid" = "78338d20-9ced-11ea-b153-0cc47a6c4dbd";
    height = "74.31999999999999";
    "media_uuid" = "fec83ac3-de00-44f0-ad5b-e1e990a29a8c";
    "person_id" = "";
    points =     (
                {
            name = "basic eye left";
            type = 512;
            x = "85.16";
            y = "86.62";
        },
                {
            name = "basic eye right";
            type = 768;
            x = "110.92";
            y = "86.66";
        }

Since you are a beginner I'm helping you out.由于您是初学者,我正在帮助您。 These questions have been asked many times (There is a high chance you get duplicate flag).这些问题已经被问过很多次(你很有可能得到重复的标志)。 Here is how you avoid these kinds of errors, try not to use force-unwraps (this symbol ! ) anywhere without any exception to avoid these errors.以下是避免此类错误的方法,请尽量不要在任何地方使用强制展开(此符号! )以避免这些错误。 Instead of if let you can use guard let , it's a personal choice.而不是if let你可以使用guard let ,这是个人选择。

if let data = data,
    let dictionary = try JSONSerialization.jsonObject(with: data, options:.mutableContainers) as? [String: Any],
    let media = dictionary["media"] as? [String: Any],
    let faces = media["faces"] as? [[String: Any]],
    let points = faces[0]["points"] {
    print(points)
}

Edit: Since "faces" parameter is an array you need to parse them as an Array and not as Dictionary .编辑:由于"faces"参数是一个数组,您需要将它们解析为Array而不是Dictionary The above example shows how to get to the first set of "points" .上面的例子展示了如何到达第一组"points"

Update: Better approach would be to use JSONDecoder .更新:更好的方法是使用JSONDecoder Here's how: Create this struct outside the class:方法如下:在 class 之外创建此结构:

struct Response: Codable { var media: Media }
struct Media: Codable { var faces: [Face] }
struct Face: Codable { var points: [Point] }
struct Point: Codable { }

And then decode like this:然后像这样解码:

if let data = data,
    let response = try JSONDecoder().decode(Response.self, from: data) {
    print(response.media.faces[0].points)
}

The main problem here is that you are force unwrapping optionals that you can't guarantee have a value - and when they don't have one that's causing a fatal error.这里的主要问题是你强制解包你不能保证有一个值的选项 - 当它们没有一个导致致命错误的时候。

A better approach is to unwrap the variables safely and throw an error if you need to handle it.更好的方法是安全地解包变量并在需要处理时抛出错误。 I've tried to show a few different ways to do that below.我试图在下面展示几种不同的方法来做到这一点。

guard let data = data else { return }
do {
    let dictionary = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any]
    guard let media = dictionary?["media"] as? [String: Any] else { throw MyError.mediaNotFoundError }

    if let faces = media["faces"] as? [String: Any] {
        print(faces)

        guard let points = faces["points"] else { throw MyError.pointsNotFound}
        print(points)
    } else {
        throw MyError.facesNotFound
    }
} catch {
    // Handle error here
}

Note, I have used a custom error enum.请注意,我使用了自定义错误枚举。 I would also advise adding a localised description to it in order to add more details for debugging.我还建议为其添加本地化描述,以便为调试添加更多详细信息。

enum MyError: Error {
    case mediaNotFoundError
    case facesNotFound
    case pointsNotFound
}

I would also recommend reading this answer here for a more in-depth explanation on optionals.我还建议在此处阅读此答案,以更深入地解释选项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 致命错误:在展开可选值Swift时意外发现nil - fatal error: unexpectedly found nil while unwrapping an Optional value, Swift JSON致命错误:展开可选值时意外发现nil - JSON fatal error: unexpectedly found nil while unwrapping an Optional value JSON解析并接收到:致命错误:在展开可选值时意外发现nil - JSON Parsing and recieved : fatal error: unexpectedly found nil while unwrapping an Optional value 解析JSON时出现“致命错误:在展开可选值时意外发现nil” - “fatal error: unexpectedly found nil while unwrapping an Optional value” when parsing JSON 致命错误:在展开Optional值时意外发现nil,获取json错误swift - fatal error: unexpectedly found nil while unwrapping an Optional value, Get json error swift 使用JSON的Swift上的“致命错误:在展开可选值时意外发现nil” - “Fatal error: Unexpectedly found nil while unwrapping an Optional value” on Swift with JSON 致命错误:解开Optional值时意外发现nil - fatal error: unexpectedly found nil while unwrapping an Optional value 使用Alamofire的Swift JSON-在展开可选值时意外发现nil - Swift JSON with Alamofire - Unexpectedly found nil while unwrapping an Optional value 展开Optional值JSON swift时意外发现nil - Unexpectedly found nil while unwrapping an Optional value JSON swift 致命错误:使用字典为有效JSON展开可选值时意外发现nil - fatal error: unexpectedly found nil while unwrapping an Optional value using Dictionary for valid JSON
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM