Fetching data with URLSession using HTTP (Swift XCode)

In this tutorial, we will be learning about Fetching data with URLSession. Every app worth building will need to send or receive information from the internet at some point and therefore, networking support is a critical part of any development platform. In Swift, this support for networking is provided by the Foundation framework.

When we need to retrieve information from the internet, we send out a request to a server on the internet, and that server sends a response that hopefully contains the information we requested.

In this recipe, we will learn how to send network requests and receive a response using the Foundation framework.

Getting ready

It is helpful to know of the different components that Foundation provides that deal with networking and what they do:

  • URL: The address of a resource on a remote server. It contains information about the server and where the resource can be found on the server.
  • URLRequest: Represents the request that will be made to the remote server. Defines the URL of the resource, how the request should be sent, metadata in the form of headers, and data that should be sent with it.
  • URLSession: Manages the communication with remote servers, holds the configuration for that communication, and creates and optimizes the underlying connections.
  • URLSessionDataTask: An object that manages the state of the request and delivers the response.
  • URLResponse: Holds the metadata of the response from the remote server.


Fetching data with URLSession : How to do it…


Let’s use these networking tools to retrieve an image from a remote server:

1. Import PlaygroundSupport and set up indefinite execution for this playground:

import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true


2. Import Foundation and create an instance of URLSession:

import Foundation
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)


3. Next, we will construct a request for a remote image:

let urlString = "https://imgs.xkcd.com/comics/api.png"
let url = URL(string: urlString)!
let request = URLRequest(url: url)


4. Now that we have our URLRequest, we can create a data task to retrieve the image from the remote server:

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

})


5. We will take the image data and put it in a UIImage object to display it. So, we need to import the UIKit framework, which provides UIImage. So, let’s import UIKit at the top of the playground:

import UIKit


6. Check for image data in the completion handler and create a UIImage object:

let task = session.dataTask(with: request) { (data, response, error)
  in
    guard let imageData = data else {
        return // No Image, handle error
    }
    _ = UIImage(data: imageData)
}

7. Call resume on the task to start it:

task.resume()


How it works…


Let’s walk through the previously mentioned steps to understand what we are doing:

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true


Playgrounds execute the code they contain from top to bottom. When the end of the playground page is reached, the playground stops executing. In our example, the task is created and started, but then the playground reaches the end of the page before the image has been fully retrieved, because this happens asynchronously. If the playground were to stop execution here, the completion handler would never be executed, and we wouldn’t see the image. This isn’t a problem in a normal app that is continually running while it is in use; it is just specific to how Swift playgrounds work.

To solve this, we need to tell the playground that we don’t want it to stop executing when it reaches the end of the page and instead, it should run indefinitely while we wait for the response to be received. This is done by importing the PlaygroundSupport framework in Step 1 and setting needsIndefiniteExecution to be true on the current PlaygroundPage.

import Foundation
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)


In Step 2, when creating URLSession, we pass in a URLSessionConfiguration object, which allows configuring the time it takes for a request to time out and cache responses, among other things. For our purposes, we will just use the default configuration.

let urlString = "https://imgs.xkcd.com/comics/api.png"
let url = URL(string: urlString)!
let request = URLRequest(url: url)


In  Step 3, we will be requesting the image from the excellent webcomic XKCD (http://xkcd.com). We can create the URL from a string, and then create a URLRequest request from the URL.

let task = session.dataTask(with: request, completionHandler: { (data,
response, error) in
})


In Step 4, we do not create a data task directly; instead, we ask our URLSession instance to create the data task, and we pass in URLRequest and a completion handler. The completion handler will be fired once a response has been received from the remote server or some error has occurred.

The completion handler has three inputs, all optional:

  • data: Data: The data returned in the body of the response; if our request was successful, this will contain our image data.
  • response: URLResponse: The response metadata, including response headers. If the request was over HTTP/HTTPS, then this will be HTTPURLResponse, which will contain the HTTP status code.
  • error: Error: If the request was unsuccessful, due to a network issue, for example, this value will have the error, and the data and response value will be nil. If the request was successful, this error value will be nil.
let task = session.dataTask(with: request) { (data, response, error) in
   guard let imageData = data else {
      return // No Image, handle error
   }
   _ = UIImage(data: imageData)
}


In Step 6, we check for response data and turn it into an image. To do this, we will need to construct a UIImage object from the data. UIImage is a class that represents an image on iOS and can be found in the UIKit framework. So, we also needed to import UIKit at the top of the playground, as we have done in Step 5.

NOTE

Since we don’t plan on doing anything with the image in this example, we are just going to view it in a playground preview; the compiler will complain if we assign it to a value that is never used. Therefore, we replace a normal value assignment with _, which allows the UIImage object to be generated without it being assigned to anything.

task.resume()


In Step 7, we have created the data task to retrieve the image, but we need to actually start the task to make the request. To do that, we call resume on the task.

When we run the playground, you will eventually see that the image value has been populated in the playground’s right sidebar, and you can click on the preview icon to see the image that has been downloaded:

Figure – Retrieved image displayed in the playground timeline 

Fetching data with URLSession using HTTP is useful when you want to fetch information from JSON or XML available on the server.

See also

Learn more about Swift iOS Development

BasicCodist Swift for Beginners

Written by

XR Developer responsible for end-to-end development of XR solutions spanning multiple domains, by using various XR and WebXR libraries.

Leave a Reply