2015-03-22 2 views
0

Я пытаюсь загрузить данные в формате JSON с моего сервера в приложение IOS.борется с разбором JSON в swift

Вот мой JSON:

[ 
    { 
    "BankName": "bank1", 
    "CurrencyName": "cur1", 
    "SellRate": "0.65", 
    "BuyRate": "0.55", 
    "OfficialRate": "0.6" 
    }, 
    { 
    "BankName": "bank1", 
    "CurrencyName": "cur2", 
    "SellRate": "1.65", 
    "BuyRate": "1.55", 
    "OfficialRate": "1.6" 
    } 
] 

Есть 2 файла в моем проекте:

1:

import Foundation 
class Shot { 
    var bankName: String! 
    var currencyName: String! 
    var sellRate: String! 
    var buyRate: String! 
    var offRate: String! 

    init (data: NSDictionary) {   
     self.bankName = getStringFromJSON(data, key:"BankName") 
     self.currencyName = getStringFromJSON(data, key:"CurrencyName") 
     self.sellRate = getStringFromJSON(data, key:"SellRate") 
     self.buyRate = getStringFromJSON(data, key:"BuyRate") 
     self.offRate = getStringFromJSON(data, key: "OfficialRate") 
    } 

    func getStringFromJSON(data: NSDictionary, key: String) -> String {      
     if let info = data[key] as? String{ 
      return info 
     } 
     return "" 
    } 
} 

2:

import Foundation 
class JsonTest {  
    func loadJson(completion: ((AnyObject) -> Void)!) {  
     var urlString = "http://a.com/g.php"   
     let session = NSURLSession.sharedSession() 
     let sourceUrl = NSURL(string: urlString) 

     var task = session.dataTaskWithURL(sourceUrl!){ 
      (data, response, error) -> Void in 

      if error != nil { 
       println(error.localizedDescription) 
      } else { 

       var error: NSError? 
       var jsonData = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &error) as NSArray 

       var shots = [Shot]() 

       println(jsonData) 

       for shot in jsonData{ 
        let shot = Shot(data: shot as NSDictionary) 
        shots.append(shot)      
       }     
       println(shots) //[jsontest.Shot, jsontest.Shot]     
      } 
     }   
     task.resume() 
    } 
} 

Я пытаюсь автоматически заполнять массив, когда мой pp начинается. Для этого у меня есть код в моем классе mainViewController.

override func viewDidLoad() { 
    super.viewDidLoad() 

    let api = JsonTest() 
    api.loadJson(nil) 

} 

Проблема возникает, когда я пытаюсь напечатать переменную кадров во втором файле. возвращает [jsontest.Shot, jsontest.Shot], когда ожидал массив словарей.

println(jsonData) отлично работает и показывает данные JSON по URL.

Может кто-нибудь сообщить, что не так в моей программе?

+0

Кажется, что есть две проблемы: 1) вы пытаетесь использовать 'println' для отладки вместо установки точки останова и проверки значений ваших объектов, а 2) вы не создали описание' '' '' '' '' '' debugDescription 'для вашего объекта, поэтому' println' на вашем объекте просто использует некоторую реализацию по умолчанию. – nhgrif

ответ

2

"кадры" представляет собой массив экземпляров выстрел, а не словарю:

class Shot { 
    var bankName: String! 
    var currencyName: String! 
    var sellRate: String! 
    var buyRate: String! 
    var offRate: String! 

    init (data: NSDictionary) { 
     self.bankName = getStringFromJSON(data, key:"BankName") 
     self.currencyName = getStringFromJSON(data, key:"CurrencyName") 
     self.sellRate = getStringFromJSON(data, key:"SellRate") 
     self.buyRate = getStringFromJSON(data, key:"BuyRate") 
     self.offRate = getStringFromJSON(data, key: "OfficialRate") 
    } 

    func getStringFromJSON(data: NSDictionary, key: String) -> String { 
     if let info = data[key] as? String{ 
      return info 
     } 
     return "" 
    } 
} 

var shots = [Shot]() 
let urlString = "http://almazini.lt/getrates.php" 
let sourceUrl = NSURL(string: urlString) 
// Using NSData instead of NSURLSession for experimenting in Playground 
let data = NSData(contentsOfURL: sourceUrl!) 
var error: NSError? 
// As I'm using Swift 1.2 I had to change "as" with "as!" 
let jsonData = NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers, error: &error) as! NSArray 
for shot in jsonData{ 
    let shot = Shot(data: shot as! NSDictionary) 
    shots.append(shot) 
} 
println(shots[0].bankName) 

screenshot

обновления для Swift 2

var shots = [Shot]() 
let urlString = "http://almazini.lt/getrates.php" 
// Using NSData instead of NSURLSession for experimenting in Playground 
if let sourceUrl = NSURL(string: urlString) { 
    NSURLSession.sharedSession().dataTaskWithURL(sourceUrl, completionHandler: { (data, response, error) in 
     if error == nil { 
      if let data = data, jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []), jsonArray = jsonData as? [NSDictionary] { 
       for item in jsonArray { 
        let shot = Shot(data: item) 
        shots.append(shot) 
       } 
       print(shots[0].bankName) 
      } else { 
       print("no JSON data") 
      } 
     } else { 
      print(error!.localizedDescription) 
     } 
    }).resume() 
} 
+0

можете ли вы добавить в свой ответ полный текст кода, который используется на детской площадке, пожалуйста? – Almazini

+0

Несомненно, я обновил свой ответ с помощью кода, который я использовал на игровой площадке. – Moritz

+0

спасибо! можете ли вы рассказать мне, что является лучшим способом создания массива словарей с данными из JSON. В нашем примере это массив с двумя словарями внутри него. Можем ли мы создать пустой словарь и вытащить данные из экземпляра класса Shot? или, может быть, есть лучший способ. – Almazini

0

Похоже, есть две проблемы :

  1. Вы пытаетесь использовать println для отладки вместо установки точки останова и проверки значений ваших объектов.
  2. Вы не создали объект description или debugDescription для своего объекта, поэтому println на вашем объекте используется только по умолчанию.

shots является массивом пользовательского объекта, поэтому при вызове println, это с помощью description для Array, которая выводит объекты в массиве, разделенные запятыми, и в квадратных скобках.

По умолчанию свойство description для классов в Swift просто печатает имя класса.

В идеале, вы должны использовать только точку останова, чтобы проверить значения вашего объекта, чтобы быть уверенным, что правильно инициализирован, но если это на самом деле важно, чтобы заставить их печатать правильно, это лишь вопрос реализации description собственности:

override var description: String { 
    get { 
     // build and return some string that represents your Shot object 
    } 
} 
+0

привет, я использовал точку останова ot узнать значения моих переменных. Но решил, что println поможет быстрее понять проблему, если кто-то попробует мой код. – Almazini

+0

моей ошибкой было то, что я не знал, что это пример класса. \t Можете ли вы рассказать мне, что является лучшим способом создания переменной с массивом словарей с данными из JSON. В нашем примере это массив с двумя словарями внутри него. Можем ли мы создать пустой словарь и вытащить данные из экземпляра класса Shot? или, может быть, есть лучший способ? – Almazini

Смежные вопросы