解析 JSON Swift 3 CTA 火车跟踪器
Posted
技术标签:
【中文标题】解析 JSON Swift 3 CTA 火车跟踪器【英文标题】:Parsing JSON Swift 3 CTA Train Tracker 【发布时间】:2017-05-16 04:26:09 【问题描述】:我正在尝试解析 CTA 火车到达的 JSON。
ctatt =
errCd = 0;
errNm = "<null>";
eta = (
arrT = "2017-05-15T23:22:32";
destNm = Howard;
destSt = 30173;
flags = "<null>";
heading = 305;
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 0;
lat = "41.91065";
lon = "-87.64918";
prdt = "2017-05-15T23:18:32";
rn = 843;
rt = Red;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward Howard";
stpId = 30255;
trDr = 1;
,
arrT = "2017-05-15T23:21:45";
destNm = "95th/Dan Ryan";
destSt = 30089;
flags = "<null>";
heading = 91;
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 0;
lat = "41.95377";
lon = "-87.65493";
prdt = "2017-05-15T23:17:45";
rn = 836;
rt = Red;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward 95th/Dan Ryan";
stpId = 30256;
trDr = 5;
,
arrT = "2017-05-15T23:27:28";
destNm = Kimball;
destSt = 30249;
flags = "<null>";
heading = 357;
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 0;
lat = "41.90563";
lon = "-87.63712";
prdt = "2017-05-15T23:18:28";
rn = 426;
rt = Brn;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward Kimball or Linden";
stpId = 30257;
trDr = 1;
,
arrT = "2017-05-15T23:27:16";
destNm = Loop;
destSt = 30249;
flags = "<null>";
heading = 89;
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 0;
lat = "41.96641";
lon = "-87.67864";
prdt = "2017-05-15T23:18:16";
rn = 427;
rt = Brn;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward Loop";
stpId = 30258;
trDr = 5;
,
arrT = "2017-05-15T23:28:25";
destNm = "95th/Dan Ryan";
destSt = 30089;
flags = "<null>";
heading = 178;
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 0;
lat = "41.97345";
lon = "-87.65853";
prdt = "2017-05-15T23:18:25";
rn = 939;
rt = Red;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward 95th/Dan Ryan";
stpId = 30256;
trDr = 5;
,
arrT = "2017-05-15T23:32:01";
destNm = Howard;
destSt = 30173;
flags = "<null>";
heading = 357;
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 0;
lat = "41.87815";
lon = "-87.6276";
prdt = "2017-05-15T23:18:01";
rn = 928;
rt = Red;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward Howard";
stpId = 30255;
trDr = 1;
,
arrT = "2017-05-15T23:37:32";
destNm = "95th/Dan Ryan";
destSt = 30089;
flags = "<null>";
heading = 162;
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 0;
lat = "42.00566";
lon = "-87.66565";
prdt = "2017-05-15T23:18:32";
rn = 926;
rt = Red;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward 95th/Dan Ryan";
stpId = 30256;
trDr = 5;
,
arrT = "2017-05-15T23:40:41";
destNm = Kimball;
destSt = 0;
flags = "<null>";
heading = "<null>";
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 1;
lat = "<null>";
lon = "<null>";
prdt = "2017-05-15T23:18:41";
rn = 431;
rt = Brn;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward Kimball or Linden";
stpId = 30257;
trDr = 1;
,
arrT = "2017-05-15T23:40:41";
destNm = "See train";
destSt = 0;
flags = "<null>";
heading = "<null>";
isApp = 0;
isDly = 0;
isFlt = 0;
isSch = 1;
lat = "<null>";
lon = "<null>";
prdt = "2017-05-15T23:18:41";
rn = 434;
rt = Brn;
staId = 41320;
staNm = Belmont;
stpDe = "Service toward Loop";
stpId = 30258;
trDr = 5;
);
tmst = "2017-05-15T23:18:54";
;
在我的ViewController.swift
import UIKit
class ViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
let url = URL(string: "http://lapi.transitchicago.com/api/1.0/ttarrivals.aspx?key=individualkeygoeshere&mapid=41320&outputType=JSON")
let task = URLSession.shared.dataTask(with: url!) (data, response, error) in
if error != nil
print("Error")
else
if let content = data
do
let myJSON = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if let ctattimetable = myJSON["ctatt"] as? [String:Any]
if let estArrivalTime = ctattimetable["eta"] as? [Any]
print(estArrivalTime)
if let stationName = estArrivalTime["staNm"]
print(stationName)
catch
task.resume()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
我还没有一个特定的目标,只是想在Swift 3
中解析JSON
。因此,在这种情况下,我要做的是获取每个 eta 的站名(JSON 中的 staNm),所以基本上我希望得到 Belmont 作为响应。我收到 swift 编译器错误,无法使用“String”类型的索引来下标“[Any]”类型的值。我被困在如何从 eta 获取每个键的值。有人知道我会怎么做吗? CTA 火车跟踪器 API 的文档在这里:http://www.transitchicago.com/developers/ttdocs/default.aspx
【问题讨论】:
谢谢大家!所有这些答案都有帮助,希望我能全部选择 【参考方案1】:eta
是Dictionary
的数组,数组不能是subscript
和String
类型,你可以用Int
为数组下标,如果你想从中访问特定的键,你需要简单地遍历数组您还需要将其指定为字典数组,而不是将 eta 指定为 Any
的数组。
do
let myJSON = try JSONSerialization.jsonObject(with: content, options: []) as? [String:Any] ?? [:]
if let ctattimetable = myJSON["ctatt"] as? [String:Any]
if let estArrivalTime = ctattimetable["eta"] as? [[String:Any]]
for item in estArrivalTime
if let stationName = item["staNm"] as? String
print(stationName)
//You can access other keys here on item dictionary same way like staNm
catch
【讨论】:
【参考方案2】:if let ctattimetable = myJSON["ctatt"] as? [String : Any]
if let estArrivalTime = ctattimetable["eta"] as? [[String : Any]]
for eta in estArrivalTime
if let stationName = eta["staNm"]
print(stationName)
【讨论】:
【参考方案3】:你在这句话中做错了
if let stationName = estArrivalTime["staNm"]
因为你从这个 if let 语句中得到了一个对象数组
if let estArrivalTime = ctattimetable["eta"] as? [Any]
因此,您必须使用此循环迭代此数组中的每个项目以获取 staNm
for item in estArrivalTime
if let _staNm = item["staNm"] as? String
print("staNm : \(_staNm)")
【讨论】:
【参考方案4】:JSON 是字典而不是 任何东西
let myJSON = try JSONSerialization.jsonObject(with: content) as! [String:Any]
键 eta
的值是一个字典数组,而不是 Anything
if let estArrivalTime = ctattimetable["eta"] as? [[String:Any]]
如果您想要的不仅仅是打印键 staNm
的值,您需要将其转换为 String
。
更具体的类型,编译器不会抱怨。
一如既往,不要在 Swift 中使用 .mutableContainers
。完全没有效果。
请阅读 Swift 博客中全面的 Apple 文章:Working with JSON in Swift
【讨论】:
以上是关于解析 JSON Swift 3 CTA 火车跟踪器的主要内容,如果未能解决你的问题,请参考以下文章
涉及 JSON 解析以及静态和动态 UITableView 单元格的 Swift3 项目 - 使其更加面向对象
使用 javascript 事件跟踪创建短代码以插入 CTA 按钮