DEV Community

George Nyakundi
George Nyakundi

Posted on

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.

Top comments (0)