URLSession in Swift
In Swift, URLSession is a powerful framework for networking that allows developers to send and receive data from the web. URLSession provides a range of functionalities that enable developers to interact with web-based services and download data, including images, audio, and video files. In this way, it enables the development of robust and dynamic applications.
URLSession can be used to perform HTTP/HTTPS requests, download data from a URL, and upload data to a web service. It can be used for both background and foreground network requests, and it supports a range of authentication and security features.
URLSession has three types of tasks: data tasks, download tasks, and upload tasks.
- Data tasks: This type of task is used for sending and receiving data in the form of Data objects.
- Download tasks: This type of task is used to download files from the web. It supports resumable downloads, so if the download is interrupted, it can be resumed from where it left off.
- Upload tasks: This type of task is used to upload data to a web service. It supports uploading data in the form of files or streams.
URLSession also provides a range of options for configuring the behavior of network requests, including cache policy, timeout interval, and cookie policy.
To use URLSession, you need to create a URLSession object and then create a task to perform the desired operation. You can then start the task, and it will run asynchronously in the background.
URLSession provides a range of delegate methods that allow you to handle the response from the web service, track the progress of the task, and handle errors.
Overall, URLSession is a powerful framework for networking that provides a range of functionalities for sending and receiving data from the web. It enables developers to create robust and dynamic applications that interact with web-based services and download data, including images, audio, and video files.
enum DataError: Error {
case invalidData
case invalidResponse
case message(_ error: Error?)
}
class APIManager {
static let shared = APIManager()
private init() { }
let url = URL(fileURLWithPath: "anyURL")
// @escaping is used here, because this is a background task.
// If you write a print statemnet after the dataTask completes, i.e. after resume(), then it will execute beforehand.
// This happens because it is time consuming task and can not be implemented on main thread.
//@escaping captures data in memeory.
func fetchData(completion: @escaping (Result<[Product], Error>) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data else {
completion(.failure(.invalidData))
return
}
guard let response = response as? HTTPURLResponse, 200 ... 299 ~= response.statusCode else {
completion(.failure(.invalidResponse))
return
}
// JSONDecoder() converts data to model of type Array
do {
let products = try JSONDecoder().decode([Products].self, from: data)
completion(.success(products))
}
catch {
completion(.failure(.message(error)))
}
}.resume()
}
}
- First, an enumeration named
DataError
is defined, which conforms to theError
protocol. It contains three cases:invalidData
,invalidResponse
, andmessage
which takes an optionalError
parameter. - Next, a class named
APIManager
is defined with a private initializer and a static instance property namedshared
that returns an instance of the class. - An instance property named
url
is declared, which holds the URL that will be used to fetch data. - The
fetchData
function is defined with a completion handler that takes aResult
object that contains an array ofProduct
objects or an error. - The
fetchData
function calls thedataTask(with:completionHandler:)
method of the sharedURLSession
object, passing in theurl
property and a completion handler that will be executed when the task completes. - Inside the completion handler, the response is checked to ensure that the status code falls within the 200–299 range. If it does not, the completion handler is called with a
.invalidResponse
error. - Next, the response data is checked to ensure that it is not
nil
. If it isnil
, the completion handler is called with an.invalidData
error. - If the response data is not
nil
, theJSONDecoder
is used to decode the data into an array ofProduct
objects. If successful, the completion handler is called with aResult
object containing the array of products. - If an error is thrown during the decoding process, the completion handler is called with a
.message
error that contains the original error. - Finally, the task is started by calling the
resume()
method on it.
Overall, this code shows how to use URLSession
to fetch and decode JSON data from an API. The Result
type is used to return either a successful result or an error, and the DataError
enumeration is used to define the specific types of errors that can occur during the process.
final class ProductView {
var products: [Product] = []
func fetch() {
APIManager.shared.fetchProducts { response in
switch response {
case .success(let products):
self.products = products
case .failue(let error):
print(error)
}
}
}
}
Keywords used in this code:
enum
: Defines a custom error typeDataError
with casesinvalidData
,invalidResponse
, andmessage
.static
: Defines a class-level propertyshared
of typeAPIManager
, which is a singleton instance of theAPIManager
class.private
: Ensures that theinit()
method can only be called from within theAPIManager
class.escaping
: Indicates that the closure parametercompletion
may be called asynchronously after the functionfetchData
has returned.Result
: A Swift built-in enum that represents either a successful result with an associated value or a failure with an associated error.guard
: A control flow statement that executes a set of statements only when a condition is not met, and optionally returns from the current scope.return
: A keyword that exits the current scope and returns a value to the caller.URLSession
: A Foundation class that manages URLSessionTasks, which retrieve the contents of URLs, including text, XML, and binary data.dataTask(with:completionHandler:)
: A method ofURLSession
that creates a task that retrieves the contents of a URL based on the specified URL request object and calls a handler upon completion.resume()
: A method ofURLSessionDataTask
that starts the task, which calls the completion handler when the task completes or fails.HTTPURLResponse
: A Foundation class that represents an HTTP URL response.200 ... 299
: A range of HTTP status codes indicating a successful response.JSONDecoder()
: A Foundation class that decodes instances of a data type from JSON objects.decode(_:from:)
: A method ofJSONDecoder
that decodes an instance of the specified type from the given JSON representation.