简体   繁体   中英

JSON parsing in swift different ways. Which one to use?

I have been following a tutorial for JSON parsing in swift. It has the following mentioned codes for parsing and retrievig the data.

func jsonParsingFromURL () {
        let url = NSURL(string: "http://theappguruz.in//Apps/iOS/Temp/json.php")
        let request = NSURLRequest(URL: url!)

        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
            self.startParsing(data!)
        }
    }

    func jsonParsingFromFile()
    {
        let path: NSString = NSBundle.mainBundle().pathForResource("days", ofType: "json")!
        let data : NSData = try! NSData(contentsOfFile: path as String, options: NSDataReadingOptions.DataReadingMapped)

        self.startParsing(data)
    }

    func startParsing(data :NSData)
    {
        let dict: NSDictionary!=(try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary

        for var i = 0 ; i < (dict.valueForKey("MONDAY") as! NSArray).count ; i++
        {
            arrDict.addObject((dict.valueForKey("MONDAY") as! NSArray) .objectAtIndex(i))
        }
        for var i = 0 ; i < (dict.valueForKey("TUESDAY") as! NSArray).count ; i++
        {
            arrDict.addObject((dict.valueForKey("TUESDAY") as! NSArray) .objectAtIndex(i))
        }
        for var i = 0 ; i < (dict.valueForKey("WEDNESDAY") as! NSArray).count ; i++
        {
            arrDict.addObject((dict.valueForKey("WEDNESDAY") as! NSArray) .objectAtIndex(i))
        }
        tvJSON .reloadData()
    }

This is fine but I am unable to understand what is going on at the line -

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
                self.startParsing(data!)

I saw another tutorial which was using functions like the following to parse JSON-

//Making the API Request

var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
//Preparing for the response

// Declare an array as below

var data: NSMutableData = NSMutableData()

// Receiving the response

1.

func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
   // Received a new request, clear out the data object
   self.data = NSMutableData()
}
2.

func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
   // Append the received chunk of data to our data object
   self.data.appendData(data)
}
3.

func connectionDidFinishLoading(connection: NSURLConnection!) {
   // Request complete, self.data should now hold the resulting info
   // Convert the retrieved data in to an object through JSON deserialization
   var err: NSError
   var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

   if jsonResult.count>0 && jsonResult["results"].count>0 {
      var results: NSArray = jsonResult["results"] as NSArray
      self.tableData = results
      self.appsTableView.reloadData()

   }
} 

So what is the difference between the above 2 coding and which one is advisable to use. Please also say something about

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
                    self.startParsing(data!)

Thanks!

First, and most importantly, NSURLConnection is deprecated in iOS 9. You should be using NSURLSession instead.

As to your questions, they are about async network reads more than JSON parsing.

NSURLConnection:

NSURLConnection has at least 2 different ways you can use it.

  1. You can set up a delegate, start the connection, and wait for your delegate methods (like connection:didReceiveData: ) to be called.
  2. You can use the class method sendAsynchronousRequest , which takes a completion block.

The sendAsynchronousRequest method is simpler to implement, but not as powerful. You don't get called until all the data has been received, so you can't do things like display a progress indicator, or save the data to disk as it comes in to avoid holding everything in memory.

If you don't need those things, I would suggest going with the block-based sendAsynchronousRequest method.

NSURLSession:

NSURLSession , the replacement for NSURLConnection , also offers both a delegate-based and a block-based approach, with pros and cons similar to those for NSURLConnection .

With NSURLSession , if you don't need fine-grained control it's easier to use the system's shared session ( NSURLSession.sharedSession() ). Then you create an NSURLSessionTask using the NSURLSession method dataTaskWithRequest:completionHandler: and start the task running with the resume() method. Just like NSURLConnection, it invokes your completion block (closure) when the download is complete.

NSURLSession also allows you to download your data directly to disk, set up secure connections, get your data in chunks as it is downloaded, and lots of other options (that you may or may not need.)

EDIT:

Here is an excerpt from the NSURLSession class reference about sharedSession :

  • (NSURLSession *)sharedSession Discussion For basic requests, the URL session class provides a shared singleton session object that gives you a reasonable default behavior. By using the shared session, you can fetch the contents of a URL to memory with just a few lines of code.

Unlike the other session types, you do not create the shared session; you merely request it by calling [NSURLSession sharedSession]. As a result, you don't provide a delegate or a configuration object. Therefore, with the shared session:

You cannot obtain data incrementally as it arrives from the server.

You cannot significantly customize the default connection behavior.

Your ability to perform authentication is limited.

You cannot perform background downloads or uploads while your app is not running.

The shared session uses the shared NSURLCache, NSHTTPCookieStorage, and NSURLCredentialStorage objects, uses a shared custom networking protocol list (configured with registerClass: and unregisterClass:), and is based on a default configuration.

When working with a shared session, you should generally avoid customizing the cache, cookie storage, or credential storage (unless you are already doing so with NSURLConnection), because there's a very good chance that you'll eventually outgrow the capabilities of the default session, at which point you'll have to rewrite all of those customizations in a manner that works with your custom URL sessions.

In other words, if you're doing anything with caches, cookies, authentication, or custom networking protocols, you should probably be using a [custom] session instead of the [shared] session.

(I fixed a couple of typos in Apple's docs in my quote. My changes are in square brackets in the last sentence.)

Do a search online for NSURLSession Swift or NSURLSessionDataTask Swift and you should be able to find tutorials on using NSURLSession. It's actually quite easy.

AlamoFire

You might also do a search on "AlamoFire". It's a lightweight Swift framework that offers easy async downloading including built-in JSON handling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM