Upload Photo Button Swift Xcode Lets Make That App

About applications need to fetch data from a remote server and downloading images is a very common chore applications need to perform. In this series, I prove y'all how to download images using Swift. Nosotros accept a look at several solutions. I prove you the pros and cons of each solution and, most chiefly, which pitfalls to avoid.

Downloading an Image From a URL

This postal service focuses on the basics, that is, How does an application download an image from a URL in Swift? Allow'south start with a blank Xcode project. Select New > Project... from Xcode's File menu and choose the Single View App template from the iOS > Application department.

Setting Up the Project in Xcode 11

Name the project Images and set User Interface to Storyboard. Leave the checkboxes at the bottom unchecked. Tell Xcode where you would similar to salve the project and click the Create button.

Setting Up the Project in Xcode 11

Nosotros keep the awarding simple. Open ViewController.swift and create an outlet with name imageView of blazon UIImageView!, an implicitly unwrapped optional. The thought is elementary. The view controller downloads an image from a URL and displays it in its image view.

          import UIKit  course ViewController: UIViewController {      // MARK: - Backdrop      @IBOutlet var imageView: UIImageView!      // MARK: - View Life Bike      override func viewDidLoad() {         super.viewDidLoad()     }  }                  

Open Primary.storyboard, click the Library button in the top correct, and add an image view to the View Controller scene. Pivot the image view to the edges of the view controller's view.

Creating the User Interface in Xcode 11

Select the view controller in the storyboard and open up the Connections Inspector on the right. Connect the imageView outlet to the image view in the View Controller scene.

Before nosotros move on, we need to configure the image view. Select the image view, open the Attributes Inspector on the right, and fix Content Manner to Attribute Fit.

Downloading Image Data

With the user interface in place, nosotros tin can focus on downloading an image and displaying it in the image view. Open up ViewController.swift and navigate to the viewDidLoad() method. When information technology'due south appropriate for an application to download remote resources, such as images, differs from application to awarding. Nosotros download an image in the view controller'southward viewDidLoad() method, but this is usually not what you desire.

Nosotros showtime past creating a URL object that points to the remote image. Your awarding normally obtains the URL of the remote image from an API of some sort. You should not hard code the URL of a remote resource in the project if you tin avoid it.

Notice that we forced unwrap the result of the initialization. This is an case and then we are not focused on safety.

          // MARK: - View Life Cycle  override func viewDidLoad() {     super.viewDidLoad()      // Create URL     let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")! }                  

Strategy 1: Using the Data Struct to Download Images

I want to evidence you two strategies to download an image from a remote server. The commencement strategy is every bit simple as it gets. We initialize a Data object by invoking the init(contentsOf:) initializer. Considering the initializer is throwing, we use the try? keyword and optional binding to safely access the result of the initialization.

          // Marker: - View Life Cycle  override func viewDidLoad() {     super.viewDidLoad()      // Create URL     let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")!      // Fetch Prototype Information     if let data = effort? Information(contentsOf: url) {         // Create Image and Update Image View         imageView.image = UIImage(data: data)     } }                  

In the body of the if statement, the view controller uses the Data object to create a UIImage instance. Information technology assigns the UIImage case to the image property of its prototype view. That's it. Build and run the application in the simulator to encounter the result.

Download an Image From a URL in Swift

This looks fine, but there is 1 important problem. The paradigm data is fetched synchronously and the operation blocks the principal thread. Wait. What? This simply means that the execution of the application is interrupted as long as the image data is being downloaded. This may non seem similar a big problem, but I can assure you that this is something you demand to avert at any price. If the device suffers from a slow network connection, so this subtle issue turns into a major problem. As long every bit the application is downloading the remote resource, the user isn't able to interact with the application. That'south a trouble. Right?

Strategy 2: Using the URLSession API to Download Images

Permit'due south have a look at the second strategy. We employ the URLSession API to fetch the epitome data. This is a bit more involved, only it isn't circuitous. We obtain a reference to the shared URLSession instance through the shared course method. Nosotros invoke the dataTask(with:completionHandler:) method on the URLSession case, passing in the URL object as the outset argument and a closure equally the second statement. We store the result of dataTask(with:completionHandler:) in a constant with name dataTask.

          // Marking: - View Life Cycle  override func viewDidLoad() {     super.viewDidLoad()      // Create URL     let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/in a higher place-the-clouds.jpg")!      // Create Data Task     let dataTask = URLSession.shared.dataTask(with: url) { (data, _, _) in      } }                  

The completion handler, a closure, is executed when the request to fetch the paradigm information completes, successfully or unsuccessfully. The closure accepts 3 arguments. We are interested in the first argument for now, the Information object that holds the image data. In the closure, we safely unwrap the Information object and use it to create a UIImage case. We use the UIImage instance to update the image property of the view controller's image view.

The closure keeps a strong reference to self, the view controller. That isn't what we desire, though. We utilize a capture list to weakly reference self in the closure.

          // MARK: - View Life Cycle  override func viewDidLoad() {     super.viewDidLoad()      // Create URL     let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/higher up-the-clouds.jpg")!      // Create Data Task     let dataTask = URLSession.shared.dataTask(with: url) { [weak self] (information, _, _) in         if let data = data {             // Create Image and Update Image View             self?.imageView.epitome = UIImage(data: data)         }     } }                  

To start the data chore, we invoke resume() on the URLSessionDataTask instance.

          // MARK: - View Life Cycle  override func viewDidLoad() {     super.viewDidLoad()      // Create URL     allow url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")!      // Create Data Job     let dataTask = URLSession.shared.dataTask(with: url) { [weak self] (information, _, _) in         if let data = data {             // Create Image and Update Epitome View             self?.imageView.image = UIImage(information: data)         }     }      // Start Data Task     dataTask.resume() }                  

There is i last trouble we need to resolve. The completion handler we pass to the dataTask(with:completionHandler:) method is executed on a background thread. You probably know that the user interface should e'er be updated from the main thread. Fortunately, the solution is simple. We use Grand Central Acceleration to update the prototype view on the primary thread.

          // MARK: - View Life Cycle  override func viewDidLoad() {     super.viewDidLoad()      // Create URL     permit url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")!      // Create Information Task     let dataTask = URLSession.shared.dataTask(with: url) { [weak self] (data, _, _) in         if permit data = information {             DispatchQueue.main.async {                 // Create Prototype and Update Prototype View                 self?.imageView.image = UIImage(data: data)             }         }     }      // Start Information Task     dataTask.resume() }                  

Similar I said, the second strategy is more involved, but it is more robust and doesn't cake the main thread. Nosotros can ready the result we encountered using the first strategy by creating the Data object on a background thread, using K Cardinal Dispatch. The solution looks something similar this.

          // Marker: - View Life Cycle  override func viewDidLoad() {     super.viewDidLoad()      // Create URL     let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")!      DispatchQueue.global().async {         // Fetch Prototype Data         if let data = try? Data(contentsOf: url) {             DispatchQueue.primary.async {                 // Create Image and Update Image View                 self.imageView.epitome = UIImage(information: data)             }         }     } }                  

Notice that we still update the image view from the main thread using Grand Cardinal Acceleration. It's a small-scale just important particular.

stonemanbrint1954.blogspot.com

Source: https://cocoacasts.com/fm-3-download-an-image-from-a-url-in-swift

0 Response to "Upload Photo Button Swift Xcode Lets Make That App"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel