解析 JSON 数组中Swift

标签: json Swift
发布时间: 2017/3/5 16:12:46
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我有这工作,但它看起来像一个手动的过程,我不能解决如何循环在循环内部 (或应该)。现在我只测试这 3 个变量,但会有最终会约 100。这里是我的游乐场。有没有方法来简化这,所以我不需要手动添加每个数组名?

import Foundation

var json_data_url = "216.92.214.107/data_test.json"
var LRKSFOweekdayDep : [String] = [String]()
var LRKSFOweekendDep : [String] = [String]()
var SFOLRKweekdayDep : [String] = [String]()

let journeysURL:NSURL = NSURL(string: json_data_url)!
let data = NSData(contentsOfURL: journeysURL)!

do {
    let json = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
    print(json)

    if let dep_obj =  json as? NSDictionary {
        if let array_journey = dep_obj["journey"] as? NSArray{
            if let journies = array_journey[0] as? NSDictionary {
                if let array_dep = journies["LRKSFOweekdayDep"] as? NSDictionary{
                    if let dep = array_dep["dep"] as? NSArray {
                        for var i = 0; i < dep.count; ++i
                        {
                            let add = dep[i] as! String
                            LRKSFOweekdayDep.append(add)
                        }
                        print(LRKSFOweekdayDep)
                    }
                }
            }

            if let journies = array_journey[1] as? NSDictionary {
                if let array_dep = journies["LRKSFOweekendDep"] as? NSDictionary{
                    if let dep = array_dep["dep"] as? NSArray {
                        for var i = 0; i < dep.count; ++i
                        {
                            let add = dep[i] as! String
                            LRKSFOweekendDep.append(add)
                        }
                        print(LRKSFOweekendDep)
                    }
                }
            }

            if let journies = array_journey[2] as? NSDictionary {
                if let array_dep = journies["SFOLRKweekdayDep"] as? NSDictionary{
                    if let dep = array_dep["dep"] as? NSArray {
                        for var i = 0; i < dep.count; ++i
                        {
                            let add = dep[i] as! String
                            SFOLRKweekdayDep.append(add)
                        }
                        print(SFOLRKweekdayDep)
                    }
                }
            }
        }
    }
} catch {
    print("error serializing JSON: \(error)")
}

解决方法 1:

现在,你有喜欢的东西︰

if let dep = array_dep["dep"] as? NSArray {
    for var i = 0; i < dep.count; ++i {
        let add = dep[i] as! String
        LRKSFOweekendDep.append(add)
    }
}

这可以简化为︰

LRKSFOweekendDep = array_dep["dep"] as? [String]

那当然,假设您定义 LRKSFOweekendDep 为可选。如果它不是可选的你可以︰

LRKSFOweekendDep = array_dep["dep"] as? [String] ?? []

但是,它应该是可选的。


在注释中,你说将要 100 的这些。而不是为每个有一个变量,我认为,你宁愿保留对象的数组。例如,请考虑︰

struct Journey {
    let name: String
    let departures: [String]
}

然后,若要分析你的 JSON,您可以遍历结果︰

let json = try NSJSONSerialization.JSONObjectWithData(data!, options: [])

var journeys = [Journey]()

if let results = json as? [String: AnyObject], let array = results["journey"] as? [[String: AnyObject]] {
    for dictionary in array {
        for (name, departures) in dictionary {
            if let departureDictionary = departures as? [String: [AnyObject]], let departureList = departureDictionary["dep"] as? [String] {
                journeys.append(Journey(name: name, departures: departureList))
            }
        }
    }
}

最后,我劝你们不要 NSData(contentsOfURL:) ,因为这是同步。使用 NSURLSessiondataTaskWithURL ,这是异步。此外,如果您使用 data! 模式,首先检查以确保它不是 nil 。否则为如果 datanil 为任何原因是在您的控件 (例如 web 服务器已关闭,互联网暂时中断,等),应用程序会崩溃而不是优雅地处理它。

投入,都在一起,你就会得到类似︰

func retrieveJourneys(completionHandler: ([Journey]?, NSError?) -> ()) {
    let task = NSURLSession.sharedSession().dataTaskWithURL(journeysURL) { data, response, error in
        guard error == nil && data != nil else {
            completionHandler(nil, error)
            return
        }

        var json: [String: AnyObject]?

        do {
            json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String: AnyObject]
        } catch let parseError as NSError {
            completionHandler(nil, parseError)
        }

        var journeys = [Journey]()

        if let array = json!["journey"] as? [[String: AnyObject]] {
            for dictionary in array {
                for (name, departures) in dictionary {
                    if let departureDictionary = departures as? [String: [AnyObject]], let departureList = departureDictionary["dep"] as? [String] {
                        journeys.append(Journey(name: name, departures: departureList))
                    }
                }
            }
        }
        completionHandler(journeys, nil)
    }
    task.resume()
}

然后你将使用它就像这样︰

var journeys: [Journey]?

override func viewDidLoad() {
    super.viewDidLoad()

    retrieveJourneys { journeys, error in
        guard error == nil && journeys != nil else {   // make sure it didn't have network problem
            print(error)
            return
        }

        dispatch_async(dispatch_get_main_queue()) {    // now update model on main queue
            self.journeys = journeys

            // and, for giggles and grins, this is how you might grab the first one and examine it:

            let someJourney = self.journeys![0]
            print(someJourney.name)
            print(someJourney.departures)
        }
    }
}

现在,以上的假定你想要的旅程,由你收到他们的顺序排列的排序的列表。

另一方面,如果你不在乎顺序,但想要检索离职与给定的键相关联的有效途径,您可能会使用字典︰

func retrieveDepartures(completionHandler: ([String: [String]]?, NSError?) -> ()) {
    let task = NSURLSession.sharedSession().dataTaskWithURL(journeysURL) { data, response, error in
        guard error == nil && data != nil else {
            completionHandler(nil, error)
            return
        }

        var json: [String: AnyObject]?

        do {
            json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String: AnyObject]
        } catch let parseError as NSError {
            completionHandler(nil, parseError)
        }

        var departures = [String: [String]]()

        if let array = json!["journey"] as? [[String: AnyObject]] {
            for dictionary in array {
                for (name, departureObject) in dictionary {
                    if let departureDictionary = departureObject as? [String: [AnyObject]], let departureList = departureDictionary["dep"] as? [String] {
                        departures[name] = departureList
                    }
                }
            }
        }
        completionHandler(departures, nil)
    }
    task.resume()
}

然后:

var departures: [String: [String]]?

override func viewDidLoad() {
    super.viewDidLoad()

    retrieveDepartures { departures, error in
        guard error == nil && departures != nil else {
            print(error)
            return
        }

        dispatch_async(dispatch_get_main_queue()) {
            self.departures = departures

            // and, for giggles and grins, this is how you might grab a list of departures given a particular key

            let departureTimes = self.departures!["LRKSFOweekdayDep"]
            print(departureTimes)
        }
    }
}
官方微信
官方QQ群
31647020