The Main Thread

iOS devices can run multiple chunks of code simultaneously. These computations proceed in parallel, so this is referred to as parallel computing. A common way to express this is by representing each computation with a different thread of control.

So far in this book, all your code has been running on the main thread. The main thread is sometimes referred to as the UI thread, because any code that modifies the UI must run on the main thread.

When the web service completes, you want it to update the image view. To avoid blocking the main thread with long-running tasks, URLSessionDataTask runs on a background thread, and the completion handler is called on this thread. You need a way to force code to run on the main thread so that you can update the image view. You can do that easily using the OperationQueue class.

You will update the asynchronous PhotoStore methods to call their completion handlers on the main thread.

In PhotoStore.swift, update fetchInterestingPhotos(completion:) to call the completion closure on the main thread.

Listing 20.35  Executing the interesting photos completion handler on the main thread (PhotoStore.swift)

func fetchInterestingPhotos(completion: @escaping (Result<[Photo], Error>) -> Void) {

    let url = FlickrAPI.interestingPhotosURL
    let request = URLRequest(url: url)
    let task = session.dataTask(with: request) {
        (data, response, error) in

        let result = self.processPhotosRequest(data: data, error: error)
        OperationQueue.main.addOperation {
            completion(result)
        }
    }
    task.resume()
}

Do the same for fetchImage(for:completion:).

Listing 20.36  Executing the image fetching completion handler on the main thread (PhotoStore.swift)

func fetchImage(for photo: Photo,
                completion: @escaping (Result<UIImage, Error>) -> Void) {

    let photoURL = photo.remoteURL
    let request = URLRequest(url: photoURL)

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

        let result = self.processImageRequest(data: data, error: error)
        OperationQueue.main.addOperation {
            completion(result)
        }
    }
    task.resume()
}

Build and run the application. Now that the image view is being updated on the main thread, you will have something to show for all your hard work: An image will appear when the web service request finishes. (It might take a little time to show the image if the web service request takes a while to finish.)

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset