2015-04-09 2 views
1

Я пытаюсь использовать SwiftyJson, чтобы вытащить некоторые данные JSON. Необычно, что «println (json)» говорит «unknowon», а если я вытаскиваю данные JSON обычным способом, это работает отлично - «println (pop)» означает среду, как и ожидалось. Ниже приведен код, который я использую. Я начал вырезать части до тех пор, пока не добрался до «println (json)», а затем решил попробовать и обработать его вручную, чтобы увидеть, является ли это SwiftyJson или мной. Любые предложения? Я довольно новичок в программировании на iOS, поэтому я предполагаю, что я глуп в той или иной форме.Swifty Json становится неизвестным, но долгий путь отлично работает?

var ghostlandsJsonUrl: NSURL = NSURL(string: "http://us.battle.net/api/wow/realm/status?realm=Ghostlands")! 
    var jsonData: NSData! 

    var request: NSURLRequest = NSURLRequest(URL: ghostlandsJsonUrl) 
    let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
    let session = NSURLSession(configuration: config) 

    let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in 
     jsonData = data 
     if(jsonData != nil) { 
      let json = JSON(jsonData) 
      println(json) 
     } else { 
      println("jsonData: nil value... net down again?") 
     } 

     let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) 
     if let statuses = jsonObject as? NSDictionary{ 
      if let realms = statuses["realms"] as? NSArray{ 
       if let realm = realms[0] as? NSDictionary{ 
        if let pop = realm["population"] as? NSString{ 
         println(pop) 
        } 
       } 
      } 
     } 

    }); 
    task.resume() 

ответ

2

Глядя на SwiftyJSONsource code я могу видеть, что JSON простой struct. Он реализует Printable protocol. Что дает поддержку методам print.

public var description: String { 
     if let string = self.rawString(options:.PrettyPrinted) { 
      return string 
     } else { 
      return "unknown" 
     } 
    } 

Это означает, что для или иной причине метод rawString возвращает nil.

public func rawString(encoding: UInt = NSUTF8StringEncoding, options opt: NSJSONWritingOptions = .PrettyPrinted) -> String? { 
     switch self.type { 
     case .Array, .Dictionary: 
      if let data = self.rawData(options: opt) { 
       return NSString(data: data, encoding: encoding) 
      } else { 
       return nil 
      } 
     case .String: 
      return (self.object as String) 
     case .Number: 
      return (self.object as NSNumber).stringValue 
     case .Bool: 
      return (self.object as Bool).description 
     case .Null: 
      return "null" 
     default: 
      return nil 
     } 
    } 

Как вы достаточно новое для развития IOS, я расскажу вам о том, что конструктор не ожидает NSData объекта.

Вот источник:

public var object: AnyObject { 
    get { 
     return _object 
    } 
    set { 
     _object = newValue 
     switch newValue { 
     case let number as NSNumber: 
      if number.isBool { 
       _type = .Bool 
      } else { 
       _type = .Number 
      } 
     case let string as NSString: 
      _type = .String 
     case let null as NSNull: 
      _type = .Null 
     case let array as [AnyObject]: 
      _type = .Array 
     case let dictionary as [String : AnyObject]: 
      _type = .Dictionary 
     default: 
      _type = .Unknown 
      _object = NSNull() 
      _error = NSError(domain: ErrorDomain, code: ErrorUnsupportedType, userInfo: [NSLocalizedDescriptionKey: "It is a unsupported type"]) 
     } 
    } 
} 

Таким образом, вы должны передать ему десериализуются NSData как это:

if let jsonData = data { 
    //jsonData can't be nil with this kind of if 

    let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) 
    let json = JSON(jsonObject) 
    println(json) 
    //... 
+0

Интересно. Это, безусловно, объясняет, почему * все, что я пытался сделать для доступа к данным внутри, всегда было бы нулевым. Предположим, мне придется не использовать SwiftyJSON в этом экземпляре, пока я не смогу понять, почему он не доволен тем, что использует Blizzard. Благодаря! –

+0

Я добавил объяснение, которое я нашел. Я никогда не использовал SwiftyJSON, так что это может быть не так, но вы получите эту идею. – Francescu

+0

Вы, действительно, правы. Я очень ценю вашу помощь в этом. Я бы не придумал это самостоятельно в любое разумное время. Вы, сэр, скала! –

2

Конструктор JSON делает сериализации. Ниже приведен код конструктора из SwiftyJSON git repo, где вы можете напрямую передать NSData.

public init(data:NSData, options opt: NSJSONReadingOptions = .AllowFragments, error: NSErrorPointer = nil) { 
    do { 
     let object: AnyObject = try NSJSONSerialization.JSONObjectWithData(data, options: opt) 
     self.init(object) 
    } catch let aError as NSError { 
     if error != nil { 
      error.memory = aError 
     } 
     self.init(NSNull()) 
    } 
} 

В простой, вы можете напрямую использовать данные, возвращаемые в обработчик завершения работы NSURLSession задачи данных, как показано ниже в коде.

let json = JSON(data: jsonData)