如果让我们无法为变量赋值

时间:2018-05-15 16:43:21

标签: ios json swift

我正在开发一个应用程序而不是从fitbitapi中提取数据并在tableview中显示它,但是当我尝试将从Web API获取的数据附加到原始模型时,这是我的代码

for json in jsons.values {
        print("json is \(json)")
        if let Json = json as? [String : Any]{

            var healthData : StepStats? = nil
            if let date = Json["dateTime"] as? String,
                let value = Json["value"] as? Int{
                healthData = StepStats(dateTime : date, value : value as AnyObject)

            }
            if let HealthData = healthData {
                model.append(HealthData)
            }

        }
        else {
            print("Unexpected Error")

        }

每次运行此代码时,都会产生意外错误,而Json = nil,初始json就在这里

    {
    dateTime = "2018-04-15";
    value = 0;
},
    {
    dateTime = "2018-04-16";
    value = 6969;
},
}

我认为这是我收到的Json数据格式没有很好的格式化,或者我的代码有什么问题吗?请帮助我,我是新手,因为它可能是基本的错误,但任何帮助都会受到赞赏。

未解析的数据就像这样

Optional("{\"activities-steps\":[{\"dateTime\":\"2018-04-17\",\"value\":\"7170\"},{\"dateTime\":\"2018-04-18\",\"value\":\"6443\"},{\"dateTime\":\"2018-04-19\",\"value\":\"11254\"},{\"dateTime\":\"2018-04-20\",\"value\":\"5771\"},{\"dateTime\":\"2018-04-21\",\"value\":\"33\"},{\"dateTime\":\"2018-04-22\",\"value\":\"2697\"},{\"dateTime\":\"2018-04-23\",\"value\":\"11\"},{\"dateTime\":\"2018-04-24\",\"value\":\"8\"},{\"dateTime\":\"2018-04-25\",\"value\":\"0\"},{\"dateTime\":\"2018-04-26\",\"value\":\"0\"},{\"dateTime\":\"2018-04-27\",\"value\":\"0\"},{\"dateTime\":\"2018-04-28\",\"value\":\"389\"},{\"dateTime\":\"2018-04-29\",\"value\":\"4916\"},{\"dateTime\":\"2018-04-30\",\"value\":\"0\"},{\"dateTime\":\"2018-05-01\",\"value\":\"0\"},{\"dateTime\":\"2018-05-02\",\"value\":\"0\"},{\"dateTime\":\"2018-05-03\",\"value\":\"0\"},{\"dateTime\":\"2018-05-04\",\"value\":\"1929\"},{\"dateTime\":\"2018-05-05\",\"value\":\"0\"},{\"dateTime\":\"2018-05-06\",\"value\":\"0\"},{\"dateTime\":\"2018-05-07\",\"value\":\"0\"},{\"dateTime\":\"2018-05-08\",\"value\":\"2818\"},{\"dateTime\":\"2018-05-09\",\"value\":\"6990\"},{\"dateTime\":\"2018-05-10\",\"value\":\"6558\"},{\"dateTime\":\"2018-05-11\",\"value\":\"15434\"},{\"dateTime\":\"2018-05-12\",\"value\":\"0\"},{\"dateTime\":\"2018-05-13\",\"value\":\"0\"},{\"dateTime\":\"2018-05-14\",\"value\":\"0\"},{\"dateTime\":\"2018-05-15\",\"value\":\"0\"},{\"dateTime\":\"2018-05-16\",\"value\":\"0\"},{\"dateTime\":\"2018-05-17\",\"value\":\"0\"}]}")

2 个答案:

答案 0 :(得分:0)

您的打印输出看起来几乎像JSON,但事实并非如此。我猜你打印出一个从错误的JSONSerialization派生出来的对象,它将自己决定从字符串中解析它是什么。通过应用Codable协议,可以更加轻松地以更加通用的方式控制这一点。鉴于您可以运行以下Playground

import Cocoa

let jsonData = """
[
    {
        "dateTime":"2018-04-15",
        "value":0
    },
    {
        "dateTime":"2018-04-16",
        "value":6969
    }
]
""".data(using: .utf8)!

struct HealthData: Codable {
    let date: Date
    let value: Int

    private enum CodingKeys: String, CodingKey {
        case date = "dateTime"
        case value
    }
}

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)

do {
    let datas = try decoder.decode([HealthData].self, from: jsonData)
    print(datas)
} catch {
    print(error)
}

极大地简化了您的解析策略,因为大多数解析策略由JSONDecoder处理,您甚至可以指定日期格式化程序。如果我的猜测错误,请随时添加实际 JSON,但请发布您从服务中获得的String内容,而不是一半解析结构。

答案 1 :(得分:0)

即使StackOverflow建议我编辑上一个答案,我也会添加另一个答案,但我不能不注意到添加你的" new"未解析的数据基本上将这个问题变成了一个完全不同的问题。通常你应该问另一个问题,也许你想在另一个问题上继续发表评论。足够的元,现在为答案。

当你的"未解析的数据"在技​​术上是正确的,它在两个方面仍然非常不方便。线性化的选项最终被转义,所以你的所有双引号都将被转义(并且有大量的正确JSON)并且不会出现在StackOverflow上难以阅读的新行,你应该尝试保留你的行并不比典型浏览器窗口的宽度大得多。转义双引号可以通过简单地展开可选(使用!)来处理,但添加漂亮的换行有点困难。但是,由于您的JSON基本上是正确的,我现在可以使用它来展示Codable协议的其他一些精确性。如果你运行这个游乐场:

import Cocoa

let string = "{\"activities-steps\":[{\"dateTime\":\"2018-04-17\",\"value\":\"7170\"},{\"dateTime\":\"2018-04-18\",\"value\":\"6443\"},{\"dateTime\":\"2018-04-19\",\"value\":\"11254\"},{\"dateTime\":\"2018-04-20\",\"value\":\"5771\"},{\"dateTime\":\"2018-04-21\",\"value\":\"33\"},{\"dateTime\":\"2018-04-22\",\"value\":\"2697\"},{\"dateTime\":\"2018-04-23\",\"value\":\"11\"},{\"dateTime\":\"2018-04-24\",\"value\":\"8\"},{\"dateTime\":\"2018-04-25\",\"value\":\"0\"},{\"dateTime\":\"2018-04-26\",\"value\":\"0\"},{\"dateTime\":\"2018-04-27\",\"value\":\"0\"},{\"dateTime\":\"2018-04-28\",\"value\":\"389\"},{\"dateTime\":\"2018-04-29\",\"value\":\"4916\"},{\"dateTime\":\"2018-04-30\",\"value\":\"0\"},{\"dateTime\":\"2018-05-01\",\"value\":\"0\"},{\"dateTime\":\"2018-05-02\",\"value\":\"0\"},{\"dateTime\":\"2018-05-03\",\"value\":\"0\"},{\"dateTime\":\"2018-05-04\",\"value\":\"1929\"},{\"dateTime\":\"2018-05-05\",\"value\":\"0\"},{\"dateTime\":\"2018-05-06\",\"value\":\"0\"},{\"dateTime\":\"2018-05-07\",\"value\":\"0\"},{\"dateTime\":\"2018-05-08\",\"value\":\"2818\"},{\"dateTime\":\"2018-05-09\",\"value\":\"6990\"},{\"dateTime\":\"2018-05-10\",\"value\":\"6558\"},{\"dateTime\":\"2018-05-11\",\"value\":\"15434\"},{\"dateTime\":\"2018-05-12\",\"value\":\"0\"},{\"dateTime\":\"2018-05-13\",\"value\":\"0\"},{\"dateTime\":\"2018-05-14\",\"value\":\"0\"},{\"dateTime\":\"2018-05-15\",\"value\":\"0\"},{\"dateTime\":\"2018-05-16\",\"value\":\"0\"},{\"dateTime\":\"2018-05-17\",\"value\":\"0\"}]}"

let jsonData = string.data(using: .utf8)!

struct Step: Codable {
    let value: String
    let dateTime : Date
}

struct Activity: Codable {
    let steps: [Step]
    enum CodingKeys: String, CodingKey {
        case steps = "activities-steps"
    }
}

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-mm-dd"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)

do {
    let activity = try decoder.decode(Activity.self, from: jsonData)

    let encoder = JSONEncoder()
    encoder.dateEncodingStrategy = .formatted(formatter)
    encoder.outputFormatting = .prettyPrinted
    let data = try encoder.encode(activity)
    print(String(data: data, encoding: .utf8)!)
} catch {
    print(error)
}

这将打印出以下漂亮的JSON:

{
    "activities-steps" : [
        {
            "value" : "7170",
            "dateTime" : "2018-04-17"
        },
        {
            "value" : "6443",
            "dateTime" : "2018-04-18"
        },
        {
            "value" : "11254",
            "dateTime" : "2018-04-19"
        },
        {
            "value" : "5771",
            "dateTime" : "2018-04-20"
        },
        {
            "value" : "33",
            "dateTime" : "2018-04-21"
        },
        {
            "value" : "2697",
            "dateTime" : "2018-04-22"
        },
        {
            "value" : "11",
            "dateTime" : "2018-04-23"
        },
        {
            "value" : "8",
            "dateTime" : "2018-04-24"
        },
        {
            "value" : "0",
            "dateTime" : "2018-04-25"
        },
        {
            "value" : "0",
            "dateTime" : "2018-04-26"
        },
        {
            "value" : "0",
            "dateTime" : "2018-04-27"
        },
        {
            "value" : "389",
            "dateTime" : "2018-04-28"
        },
        {
            "value" : "4916",
            "dateTime" : "2018-04-29"
        },
        {
            "value" : "0",
            "dateTime" : "2018-04-30"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-01"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-02"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-03"
        },
        {
            "value" : "1929",
            "dateTime" : "2018-05-04"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-05"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-06"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-07"
        },
        {
            "value" : "2818",
            "dateTime" : "2018-05-08"
        },
        {
            "value" : "6990",
            "dateTime" : "2018-05-09"
        },
        {
            "value" : "6558",
            "dateTime" : "2018-05-10"
        },
        {
            "value" : "15434",
            "dateTime" : "2018-05-11"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-12"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-13"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-14"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-15"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-16"
        },
        {
            "value" : "0",
            "dateTime" : "2018-05-17"
        }
    ]
}

现在这仍然是一个笨拙的StackOverflow问题(通常你可能应该减少它,因为它只是无聊的重复,但这对于第一个问题是可以的),但它仍然更容易以这种形式消化。并且它有希望教会您如何构建Codable结构以真正的Swifty形式表示您的数据,以及如何将一些凌乱的JSON格式化为更易读的格式,更容易用您的眼睛消化。

很明显JSON是正确的,因为JSONDecoder设法解析它,但是当你以漂亮的印刷形式看到它时,它作为人类判断它应该是什么样子也更容易。

像这样,activity应该很容易处理并在TableView中使用,所以我希望至少有一些问题已经解决了。