How to get data to return from NSURLSessionDataTask in Swift
Asked Answered
K

3

1

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..

Kissable answered 7/11, 2014 at 5:29 Comment(0)
K
3

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
}
Kissable answered 7/11, 2014 at 9:48 Comment(0)
C
1

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.

Cinchonism answered 7/11, 2014 at 7:20 Comment(1)
Hi, I have changed my GetHome fun to :func GetHomeData(completionHandler: ((NSDictionary!) -> Void)?) -> NSDictionary then calling the function to: let result : NSDictionary = homeModel.GetHomeData({(jsonResult) in // use result }); ...but I get an exception in the GetHomeData function when returning the result. Can you please provide me with an example?Kissable
N
0

You can use this framework for Swift coroutines - https://github.com/belozierov/SwiftCoroutine

DispatchQueue.main.startCoroutine {
    let dataFuture = URLSession.shared.dataTaskFuture(for: url)
    let data = try dataFuture.await().data
    . . . parse data ...
}
Nose answered 27/5, 2020 at 15:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.