Swift - 阅读JSON文件

时间:2015-03-02 04:08:22

标签: json swift

我是Swift的新手 - 尝试从URL读取JSON文件。我的尝试如下。

JSON看起来有效 - 我用JSONLint测试它但它一直崩溃。

思想?

func getRemoteJsonFile() -> NSDictionary {
    //Create a new url

    let remoteUrl:NSURL? = NSURL(string: "http://nfl-api.azurewebsites.net/myplayers.json")

    //check if its nil
    if let actualRemoteUrl = remoteUrl {

        //try to get the data
        let filedata:NSData? = NSData(contentsOfURL: actualRemoteUrl)

            //check if its nil
        if let actualFileData = filedata {

            //parse out the dictionaries
            let jsonDict = NSJSONSerialization.JSONObjectWithData(actualFileData, options: NSJSONReadingOptions.AllowFragments, error: nil) as NSDictionary

            return jsonDict
        }
    }
        return NSDictionary()
}

2 个答案:

答案 0 :(得分:5)

我花了一秒钟才弄明白,所以我不会责怪你错过它。

您链接的JSON缩小了,因此很难看到结构。在通过a prettifier进行管道后,让我们看一下(片段):

[
   {
      "PlayerId":2501863,
      "PlayerName":"Peyton Manning",
      "PlayerTeam":"DEN",
      "PlayerPosition":"QB",
      "PlayerPassingYards":4727,
      "PlayerPassingTDs":39,
      "PlayerInterceptions":15,
      "PlayerRushingYards":-24,
      "PlayerRushingTDs":0,
      "PlayerReceivingYards":0,
      "PlayerReceivingTDs":0,
      "PlayerReturnYards":0,
      "PlayerReturnTDs":0,
      "PlayerFumbleTDs":0,
      "PlayerTwoPointConversions":2,
      "PlayerFumblesLost":2,
      "PlayerTeamLogo":"http://i.nflcdn.com/static/site/7.0/img/logos/teams-gloss-81x54/den.png"
   }
]

咦。它被括在括号中,这意味着它是一个数组

它是一个数组,因此您无法将其转换为NSDictionary 。相反,您可以将其转换为NSArray,但为什么不使用原生的Swift类型?

好吧,如果你不喜欢类型,你就要发现了,但我仍然认为这是一种更好的方法,因为它会迫使你思考你所依赖的数据。解析。

所以我们有这个函数的类型定义的第一部分;它是一个数组([])。我们的阵列由哪些组件组成?我们可以使用简单的NSDictionary,但我们在此处执行完整的原生类型,因此请使用a native Swift dictionary

为此,我们必须知道字典的类型(本地字典类型的语法是[KeyType: ValueType])。检查JSON显示所有键都是String个,但值的类型各不相同,因此我们可以使用AnyObject

这给了我们一个[String: AnyObject]的字典类型,我们的整个JSON是一个数组,所以最后的类型是[[String: AnyObject]](哇)。


现在我们有了正确的类型,我们可以修改你用来解析JSON的函数。

首先,让我们使用我们的新类型作为返回值和强制转换值。然后,让我们在出现问题时生成返回类型optional并添加error变量来记录该内容。

清理过的功能看起来像这样:

func getData() -> [[String: AnyObject]]? {
    let data: NSData? = NSData(contentsOfURL: NSURL(string: "http://nfl-api.azurewebsites.net/myplayers.json")!)
    if let req: NSData = data {
        var error: NSError?
        if let JSON: [[String: AnyObject]] = NSJSONSerialization.JSONObjectWithData(req, options: NSJSONReadingOptions.AllowFragments, error: &error) as? [[String: AnyObject]] {
            return JSON
        }
    }
    return nil
}

那就是它!

我们现在可以调用函数并从[[String: AnyObject]](再次,哇)中提取值,如下所示:

if let data: [[String: AnyObject]] = getData() {
    println(data[0]["PlayerName"]!) // Peyton Manning
}

答案 1 :(得分:0)

使用以下代码更新您的代码:

func getRemoteJsonFile() -> [NSDictionary] {

    // Create a new URL
    let remoteUrl:NSURL? = NSURL(string: "http://nfl-api.azurewebsites.net/myplayers.json")

    let urlString:String = "\(remoteUrl)"

    // Check if it's nil
    if let actualRemoteUrl = remoteUrl {

        // Try to get the data
        let fileData:NSData? = NSData(contentsOfURL: actualRemoteUrl)

        // Check if it's nil
        if let actualFileData = fileData {

            // Parse out the dictionaries
            let arrayOfDictionaries:[NSDictionary]? = NSJSONSerialization.JSONObjectWithData(actualFileData, options: NSJSONReadingOptions.MutableContainers, error: nil) as [NSDictionary]?

            if let actualArrayOfDictionaries = arrayOfDictionaries {

                // Successfully parsed out array of dictionaries
                return actualArrayOfDictionaries
            }
        }

    }
    return [NSDictionary]()
}

这对我来说很好。