Abdulrahman Alattas
Abdulrahman Alattas

Reputation: 75

Using data inside AnyObject Swift 2.0

i have i code that takes JSON data from web php file, the data goes to data var using contentOfUrl then converted to jsonarray var typed AnyObject using NSJSONSerialization.JSONObjectWithData.

but the problem is when i want to use it from the jsonarray var i searched for tow days and i found one but didn't work because his AnyObject var structure is different.

so how can i use it?

Code:

    import Foundation

class DBConnectController{

    func ViewControllerConnect(DeviceID : Int) -> String{

        let data : NSData = NSData(contentsOfURL : NSURL(string: "http://xx.com/xc.php")!)!

        var jsonarray : AnyObject
        do {
            jsonarray = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments)

            print(jsonarray["2"]) // tried this but didn't work
            print(jsonarray["2"].value) // tried this but didn't work
            // and tried other

        } catch {
            print("Error decoding json using NSJSONSerialization.JSONObjectWithData")
        }

        return "f"
    }
}

jsonarray structure (showed when make a break point before the return:

Upvotes: 2

Views: 714

Answers (2)

Rob
Rob

Reputation: 437592

The Swift 2 rendition of the answer is as follows:

let task = NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in
    guard data != nil else {
        print("dataTaskWithURL error: \(error)")
        return
    }

    do {
        if let jsonarray = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[String: AnyObject]],
            let status = jsonarray.first?["status"] as? String {
                // use `status` here
                print(status)
        }
    } catch {
        print("Error decoding json using NSJSONSerialization.JSONObjectWithData: \(error)")
    }
}
task.resume()

This:

  • Uses asynchronous request rather than synchronous NSData(contentsOfURL:) ... never use synchronous network calls from the main thread of the app;

  • Guards against network errors (rather than forced unwrapping with ! which would crash if there was some unpreventable network error);

  • Gracefully unwrap jsonarray and status rather than forced unwrapping;

  • Log the JSON parsing error if any; and

  • Use .first with optional chaining rather than [0], because the latter can crash if you get empty array and you end up exceeding the bounds of the array.

Upvotes: 0

BaseZen
BaseZen

Reputation: 8718

What you have there is an array of dictionary objects. (BTW I'm on Xcode 6 / Swift 1.2 so you may not need the 'err' parameter there.)

(By the way, your array appears to have only one element, so check: myStructuredData.count before overrunning it.)

func viewControllerConnect(deviceID: Int) -> String? {
    var err: NSError?
    var retVal: String?
    if let url = NSURL(string: "http://xx.com/xc.php"),
        data = NSData(contentsOfURL: url), // BAD You're doing long-running network task in UI thread, address this soon
        jsonData: AnyObject = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: &err) {
            if let myStructuredData = jsonData as? [[String: AnyObject]] { // You have an array of dictionaries there
                retVal = myStructuredData[0]["status"] as? String // For example, not sure of your exact needs & conventions
            }
            else {
                println("JSON data had unexpected structure: \(err?.localizedDescription)")
            }
        }
        else {
            println("Could not load JSON data")
        }
    return retVal
}

Upvotes: 2

Related Questions