0

this is my php file from a server:

<?php

    $results = Array(
        Array(
            "name"      => "William",
            "location"  => "UK",
            "action"    => "Post Update"
        ),
        Array(
            "name"      => "Sammy",
            "location"  => "US",
            "action"    => "posted news"
        )
    );

    header("Content-Type: application/json");
    echo json_encode($results);
?>

And this is how I try to fetch the json array from within swift

let urlPath = "http://someurltophpserver"
        let url = NSURL(string: urlPath)
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
            if ((error) != nil) {
                println("Error")
            } else {
                let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
                // do something with the data
            }
        })
        task.resume()

The app crashes in this line let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary with error:

Could not cast value of type '__NSArrayM' (0x8c9b58) to 'NSDictionary' (0x8c9d74).

New to swift and http request, so not entirely sure what this means.

1 Answer 1

1

The reason your app is crashing is because of the as!. You’re trying to force unwrap an optional, so if this fails during run time, the app will crash.

Change the line to this:

if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary
{
    // Do stuff if jsonResult set with a value of type NSDictionary
}

This will stop the app crashing, but by the looks of it the top level object returned by the JSON serialiser is going to be an NSArray not an NSDictionary you seem to expecting, that’s probably why the app is actually crashing. You’re code says to the compiler “let jsonResult equal a value that is definitely going to be an NSDictionary”.

Also, as a side, I would recommend the easiest way to download some data is with NSData(contentsOfURL:url). Run this in a background queue using Grand Central Dispatch to avoid blocking the main thread (UI).

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

    let data = NSData(contentsOfURL: url)

    // Run any other code on the main queue. Especially any UIKit method.

    NSOperationQueue.mainQueue().addOperationWithBlock({

        // Do stuff with data
    })
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.