Nazadus Nazadus - 1 year ago 51
JSON Question

Swifty Json getting unknown but long way works fine?

I'm attempting to use SwiftyJson to pull some JSON data.
What's unusual is the "println(json)" says "unknowon" while if I pull the JSON data the regular way it works just fine -- the "println(pop)" says medium, as expected.
Below is the code I'm using. I started cutting out parts until I got to "println(json)" and then decided to try and handle it manually to see if it's SwiftyJson or me.
Any suggestions? I'm fairly new to iOS programming so I'm assuming I'm being silly in some form or another.

var ghostlandsJsonUrl: NSURL = NSURL(string: "")!
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)
} 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{


Answer Source

Looking at SwiftyJSON source code I can see that JSON is a simple struct. It implements the Printable protocol. Which give support to the print methods.

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

Which means that for a reason or another the rawString method returns 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"
            return nil

As you are fairly new to iOS development, I will tell you that the constructor doesn't expect a NSData object.

Here is the source:

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
            _type = .Unknown
            _object = NSNull()
            _error = NSError(domain: ErrorDomain, code: ErrorUnsupportedType, userInfo: [NSLocalizedDescriptionKey: "It is a unsupported type"])

So you should pass it the unserialized NSData as it:

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)