DEV Community

George Nyakundi
George Nyakundi

Posted on

3 2

Asynchronous DataTask Request in Xcode Playground Tutorial

This can be achieved in three simple steps.

  • import PlaygroundSupport

  • call PlaygroundPage.current.needsIndefiniteExecution = true

  • Write out your network request

  • upon completion of the network request call PlaygroundPage.current.finishExecution()

To put this into context i'll be using the Github Jobs api to illustrate the steps above

  • Step 1: - Add this statement to your playground
import Foundation
import PlaygroundSupport
Enter fullscreen mode Exit fullscreen mode
  • Step 2:- Right below the import statements set the needs Indefinite Execution to true
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true
Enter fullscreen mode Exit fullscreen mode

Good progress so far. As per you needs create your network request, for our tutorial we'll create a Github Jobs API request as follows

  • First we'll define our Struct which implements the Codable protocol and it defines the shape of our response , then we'll make the Network call.

You file should look like this

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true
struct GithubJob: Codable {
    var company: String?
   var company_logo: String?
   var company_url: String?
   var description: String?
   var id: String?
   var location: String?
   var title: String?
   var url: String?
}

func fetchGithubJobs(completionHandler: @escaping(Result<[GithubJob],Error>) -> Void) {
    //create an instance of the jsonDecoder
    let jsonDecoder = JSONDecoder()
    //create a dataTask
    let session = URLSession(configuration: .default, delegate: nil, delegateQueue: .main)
    let endpoint = "https://jobs.github.com/positions.json?description=api"

    //create a url from the endpoint
    guard let endpointURL = URL(string: endpoint) else {
        return
    }
    //create a request
    var request = URLRequest(url: endpointURL)
    request.httpMethod = "GET"

    //create the dataTask
    let dataTask = session.dataTask(with: request) { (data, _, error) in
        //check if error is nil
        guard error == nil else {
            completionHandler(.failure(error!))
            return
        }
        //check if we already have data
        guard let jsonData = data else {
            return
        }
        //try to decode the response
        do {
            let githubJobs = try jsonDecoder.decode([GithubJob].self, from: jsonData)
            print("Jobs are \(githubJobs)")
            completionHandler(.success(githubJobs))


        } catch {
            print("Something Went wrong")
            completionHandler(.failure(error))
        }
    }

    dataTask.resume()

}

Enter fullscreen mode Exit fullscreen mode

The last step involves us calling our function and then once our function finishes executing calling PlaygroundPage.current.finishExecution()

Adding this last step your file should look like the code snippet below.

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true
struct GithubJob: Codable {
    var company: String?
   var company_logo: String?
   var company_url: String?
   var description: String?
   var id: String?
   var location: String?
   var title: String?
   var url: String?
}

func fetchGithubJobs(completionHandler: @escaping(Result<[GithubJob],Error>) -> Void) {
    //create an instance of the jsonDecoder
    let jsonDecoder = JSONDecoder()
    //create a dataTask
    let session = URLSession(configuration: .default, delegate: nil, delegateQueue: .main)
    let endpoint = "https://jobs.github.com/positions.json?description=api"

    //create a url from the endpoint
    guard let endpointURL = URL(string: endpoint) else {
        return
    }
    //create a request
    var request = URLRequest(url: endpointURL)
    request.httpMethod = "GET"

    //create the dataTask
    let dataTask = session.dataTask(with: request) { (data, _, error) in
        //check if error is nil
        guard error == nil else {
            completionHandler(.failure(error!))
            return
        }
        //check if we already have data
        guard let jsonData = data else {
            return
        }
        //try to decode the response
        do {
            let githubJobs = try jsonDecoder.decode([GithubJob].self, from: jsonData)
            print("Jobs are \(githubJobs)")
            completionHandler(.success(githubJobs))


        } catch {
            print("Something Went wrong")
            completionHandler(.failure(error))
        }
    }

    dataTask.resume()

}

fetchGithubJobs { result in
    switch result {
    case .success(let jobs):
        print("Jobs are \(jobs)")
    default:
        print("Something Went Wrong")
    }
    PlaygroundPage.current.finishExecution()
}

Enter fullscreen mode Exit fullscreen mode

Execute this and you should see the Job listing on the debug area.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

📊 A side-by-side product comparison between Sentry and Crashlytics

A free guide pointing out the differences between Sentry and Crashlytics, that’s it. See which is best for your mobile crash reporting needs.

See Comparison

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay