Swift - чтение файла JSON

Я новичок в Swift - пытаюсь прочитать файл JSON из URL. Моя попытка ниже.

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 ответа

Решение

Обновите свой код с этим:

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]()
}

Это работает нормально для меня.

Мне потребовалась секунда, чтобы понять, поэтому я не виню вас за то, что вы пропустили это.

JSON, с которым вы связаны, минимизирован, поэтому трудно увидеть структуру. Давайте посмотрим (фрагмент) на него после прохождения через преттификатор:

[
   {
      "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, но мы делаем полные нативные типы здесь, поэтому давайте использовать нативный словарь Swift.

Чтобы сделать это, мы должны знать типы словаря (синтаксис для собственного типа словаря [KeyType: ValueType]). Изучение JSON показывает, что все ключи Strings, но значения бывают разных типов, поэтому мы можем использовать AnyObject,

Это дает нам тип словаря [String: AnyObject]и весь наш JSON является массивом этого, поэтому последний тип [[String: AnyObject]] (Вот это да).


Теперь, когда у нас есть правильный тип, мы можем изменить функцию, которую вы используете, чтобы немного проанализировать JSON.

Прежде всего, давайте использовать наш новый тип для возвращаемых и приведенных значений. Затем давайте сделаем тип возвращаемого значения необязательным на случай, если что-то пойдет не так, и добавим 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
}
Другие вопросы по тегам