How to get data to return from NSURLSessionDataTas

2019-05-30 19:18发布

问题:

I have this same question as was asked and answered here: How to get data to return from NSURLSessionDataTask

The difference: How can I do this in Swift? I do not know Objective C at all so trying to interpret that answer is proving a bit futile for me..

So given the code below I have a FirstViewController which will call my HomeModel class to go and get the data using a NSURLSession call. Once the call is complete I want return the data to the FirstViewController so that I may go and set it in the view.

FirstViewController class looks like:

import UIKit
class FirstViewController: UIViewController
{
    let homeModel = HomeModel()

    override func viewDidLoad()
    {
       super.viewDidLoad()

       // Go load the home page content
       SetHomeContent()
    }

  override func didReceiveMemoryWarning()
  {
      super.didReceiveMemoryWarning()
  }

  /*Call to go get home page content*/
  func SetHomeContent()
  {
      homeModel.GetHomeData();

      //TODO find a way to get result here... and set it to the textView
  }
}

HomeModel class looks like:

 import Foundation
 class HomeModel
 {

    private let siteContent:String = "http://www.imoc.co.nz/MobileApp/HomeContent"

   func GetHomeData()
   {
      var url : NSURL! = NSURL(string:siteContent)
      var request: NSURLRequest = NSURLRequest(URL:url)
      let config = NSURLSessionConfiguration.defaultSessionConfiguration()
      let session = NSURLSession(configuration: config)

      let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler:      {(data, response, error) in

        var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil

        let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: error) as? NSDictionary!

      // At this stage I want the jsonResult to be returned to the FirstViewController
    });

    // do whatever you need with the task
    task.resume()
}

I guess I want either a way to pass in a completion handler from the original all or something similar to C# 5 using async tasks to await the result..

Any help appreciated..

回答1:

With the help and suggestion taken from Abizern I finally managed how to write up this block or closure if you want.

So what worked for me in the end:

The GetHomeData function I changed as follows:

private let siteContent:String = "http://www.imoc.co.nz/MobileApp/HomeContent"
// I changed the signiture from my original question
func GetHomeData(completionHandler: ((NSDictionary!) -> Void)?)
{
    var url : NSURL! = NSURL(string:siteContent)
    var request: NSURLRequest = NSURLRequest(URL:url)
    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    let session = NSURLSession(configuration: config)

    let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
        var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil

        let jsonResult: NSDictionary! =  NSJSONSerialization.JSONObjectWithData(data, options: nil, error: error) as? NSDictionary!

        // then on complete I call the completionHandler...
        completionHandler?(jsonResult?);
    });
    task.resume()
}

Then I call the function like this:

/*Call to go get home page content*/
func SetHomeContent()
{
    homeModel.GetHomeData(self.resultHandler)
}

func resultHandler(jsonResult:NSDictionary!)
{
    let siteContent = jsonResult.objectForKey("SiteContent") as NSDictionary
    let paraOne = siteContent.objectForKey("HomePageParagraphOne") as String
}


回答2:

Change your GetHomeData() method so that it takes a block. When you call the method pass it the block that does what you want to with the data. In the completion block of the data task, call this passed in block.