[英]if let can not assign value to a Variable
我正在开发一个应用程序,它可以从 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 数据格式不正确,还是我的代码有问题? 请帮助我,我是 swift 的新手,所以这可能是基本错误,但任何帮助将不胜感激。
未解析的数据是这样的
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\"}]}")
您的打印输出看起来几乎像 JSON,但事实并非如此。 我猜你会打印出一个从构思JSONSerialization
派生的对象,它会自行决定它从字符串中解析的内容。 通过应用Codable
协议,可以更轻松地以更通用的方式进行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
的内容,而不是一些半解析的结构。
即使 StackOverflow 建议我编辑上一个答案,我也会添加另一个答案,但我不能不注意到添加您的“新”未解析数据基本上会将这个问题变成一个完全不同的问题。 通常你应该问另一个问题,也许发表评论,你想在另一个问题上继续。 足够的元,现在是答案。
虽然您的“未解析数据”在技术上是正确的,但在两个方面仍然非常不方便。 线性化选项最终会被转义,所以你所有的双引号都将被转义(并且在正确的 JSON 中有大量的双引号)并且不会有在 StackOverflow 上看起来很难阅读的换行符,你应该尽量保持你的行不要太远大于典型浏览器窗口的宽度。 可以通过简单地解开可选项(使用!
)来处理转义的双引号,但是添加漂亮的换行符有点困难。 但是,由于您的 JSON 现在基本上是正确的,我可以使用它来展示Codable
协议的其他一些优点。 如果你运行这个 Playground:
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
设法解析了它,但是作为人类,当您以漂亮的印刷形式看到它时,判断它应该是什么样子也容易JSONDecoder
。
像这样,您的activity
应该很容易处理并在TableView
使用它,所以我希望至少您的一些问题已经解决了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.