How To Fetch and Parse JSON Using Swift 2 + XCode

2020-06-06 07:32发布

问题:

Was looking for useful tutorials for networking with Swift 2 and iOS 9, but it seems that topic has no content online. I have watched the WWDC session Networking with NSURLSession But I couldn't adapt the new API of iOS9 to have an asynchronous way to fetch and parse JSON data. What I have tried:

    do {
        if let url = NSURL(string: "site/api.php?option=fetchOps"),
            let data = NSData(contentsOfURL: url),
            let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [[String:AnyObject]] {

        }
    } catch let error as NSError {
        print(error.description)
    }

Please share your experience with networking on iOS9 and Swift2, any best practices maybe a Singleton class for networking and parsing maybe an ORM ?

回答1:

Easy way to make a request for you:

How to make an HTTP request in Swift?

Or If you want to send request by your own:

HTTP POST error Handling in Swift 2

Converting a String to JSON Object:

Just as an example, here I've converted a NSString

First of all convert the NSString to NSDictionary

static func convert(src: NSString) -> NSDictionary {
    // convert String to NSData
    let data = src.dataUsingEncoding(NSUTF8StringEncoding)
    var error: NSError?

    // convert NSData to 'AnyObject'
    let anyObj: AnyObject?
    do {
        anyObj = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(rawValue: 0))
    } catch let error1 as NSError {
        error = error1
        anyObj = nil
    }

    if(error != nil) {
        // If there is an error parsing JSON, print it to the console
        print("JSON Error \(error!.localizedDescription)")
        //self.showError()
        return NSDictionary()
    } else {

        return anyObj as! NSDictionary
    }

}

And then, use it like this

if  let name = dictionary["name"] as? String {
    self.name = name
}

You can use the converted JSON to make an object like this

import Foundation

class Student {
var name="";

init(dictionary: NSDictionary) {
    let _NAME = "name"
    if  let name = dictionary[_NAME] as? String {
        self.name = name
    }
}

}


回答2:

oha, well ... search for async network calls for swift. You will find many things.

But yea... Create an NSMutableRequest, init eith the URL, set the method to GET or POST.

Now make:

let task = NSURLSession.sharedSession().dataTaskWithRequest(yourMutableRequest) { 
data, response, error in 
// do your stuff here

}
task.resume()

This will run asynchron, so you need to think about a way to handle the data. At first your response data is in the variable data this is a type of NSData. You will need this to create your dictionary:

let dictionaryOrArray = NSJSONSerialization.JSONObjectWithData(data, options:.MutableContainers, error: nil)

Maybe you need to put this in a guard or if let statemant.

Now you need to pass the data to the function caller... you can do this in many ways, i prefer success and failure blocks You call your Request function and you provide a success and failure block. This blocks will do what should happen in the end:

    let successBlock:[AnyObject]->Void = { response in 
     // handle your dict
    }

    let failureBlock:NSError->Void = { error in 
    // error handling
    }

    YourClass.fetchSomething(someURL, parameters: params, requestMethod: method, success : successBlock, failure: failureBlock)

Something like that. In your request block with data, response, error you just do the following:

If error {
    failure(error)
    return
}

success(dictionaryOrArray)