2015-03-02 5 views
3

Я новичок в Swift - пытаясь прочитать JSON-файл с URL-адреса. Моя попытка ниже.Swift - Чтение файла 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() 
} 
+1

Что такое сообщение об ошибке? –

+1

Тема 1: EXC_BAD_ACCESS (код = 2, адрес = 0x102475138) – Davemen

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

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

+0

Рад помочь вам .. :) –

+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 s, но значения имеют разные типы, поэтому мы можем использовать AnyObject.

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


Теперь, когда у нас есть правильный тип, мы можем изменить функцию, которую вы используете, для синтаксического анализа 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

Это должен быть правильный ответ. Красиво написано. – Schemetrical