How to Create an Upload Image to Button Swift
Most applications demand to fetch data from a remote server and downloading images is a very common job applications need to perform. In this series, I evidence you lot how to download images using Swift. We take a look at several solutions. I show you the pros and cons of each solution and, most chiefly, which pitfalls to avoid.
Downloading an Image From a URL
This mail focuses on the basics, that is, How does an application download an prototype from a URL in Swift? Permit'due south outset with a bare Xcode project. Select New > Project... from Xcode's File bill of fare and cull the Unmarried View App template from the iOS > Application section.
Name the project Images and set User Interface to Storyboard. Leave the checkboxes at the lesser unchecked. Tell Xcode where you would like to save the project and click the Create button.
We go on the application simple. Open ViewController.swift and create an outlet with proper noun imageView of type UIImageView!, an implicitly unwrapped optional. The idea is simple. The view controller downloads an image from a URL and displays it in its prototype view.
import UIKit grade ViewController: UIViewController { // MARK: - Properties @IBOutlet var imageView: UIImageView! // MARK: - View Life Bike override func viewDidLoad() { super.viewDidLoad() } } Open Main.storyboard, click the Library button in the summit right, and add an image view to the View Controller scene. Pin the epitome view to the edges of the view controller's view.
Select the view controller in the storyboard and open 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 correct, and prepare Content Mode to Attribute Fit.
Downloading Image Data
With the user interface in place, nosotros can focus on downloading an paradigm and displaying it in the image view. Open ViewController.swift and navigate to the viewDidLoad() method. When it's appropriate for an awarding to download remote resources, such equally images, differs from application to application. Nosotros download an prototype in the view controller's viewDidLoad() method, only this is commonly not what you desire.
Nosotros outset by creating a URL object that points to the remote epitome. Your awarding usually obtains the URL of the remote image from an API of some sort. You should not difficult code the URL of a remote resource in the projection if you can avoid it.
Notice that we forced unwrap the result of the initialization. This is an example so we are not focused on safety.
// Marker: - View Life Bike 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 prove you two strategies to download an paradigm from a remote server. The first strategy is every bit simple as it gets. We initialize a Data object past invoking the init(contentsOf:) initializer. Because the initializer is throwing, we apply the try? keyword and optional binding to safely admission the result of the initialization.
// Marker: - View Life Bike override func viewDidLoad() { super.viewDidLoad() // Create URL let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")! // Fetch Image Information if let information = effort? Information(contentsOf: url) { // Create Image and Update Image View imageView.image = UIImage(information: data) } } In the body of the if statement, the view controller uses the Data object to create a UIImage example. It assigns the UIImage instance to the image property of its image view. That's information technology. Build and run the application in the simulator to come across the result.
This looks fine, but there is one important problem. The image data is fetched synchronously and the functioning blocks the principal thread. Wait. What? This merely means that the execution of the application is interrupted as long as the paradigm data is beingness downloaded. This may not seem like a big problem, but I tin can clinch you that this is something you need to avoid at any cost. If the device suffers from a slow network connexion, and then this subtle result turns into a major problem. Equally long equally the application is downloading the remote resources, the user isn't able to collaborate with the application. That's a problem. Correct?
Strategy 2: Using the URLSession API to Download Images
Let'south take a look at the second strategy. Nosotros employ the URLSession API to fetch the image data. This is a chip more than involved, just it isn't complex. We obtain a reference to the shared URLSession instance through the shared grade method. Nosotros invoke the dataTask(with:completionHandler:) method on the URLSession instance, passing in the URL object equally the kickoff argument and a closure every bit the second statement. Nosotros store the effect of dataTask(with:completionHandler:) in a abiding with name dataTask.
// Marking: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() // Create URL let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")! // Create Information Task permit dataTask = URLSession.shared.dataTask(with: url) { (data, _, _) in } } The completion handler, a closure, is executed when the request to fetch the image data completes, successfully or unsuccessfully. The closure accepts iii arguments. We are interested in the first argument for now, the Data object that holds the prototype information. In the closure, nosotros safely unwrap the Data object and use information technology to create a UIImage example. We utilize the UIImage instance to update the image property of the view controller's prototype view.
The closure keeps a strong reference to self, the view controller. That isn't what we desire, though. Nosotros apply a capture list to weakly reference cocky in the closure.
// Mark: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() // Create URL let 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 let data = information { // Create Image and Update Paradigm View cocky?.imageView.epitome = UIImage(data: data) } } } To outset the data job, we invoke resume() on the URLSessionDataTask instance.
// Mark: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() // Create URL let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")! // Create Data Task let dataTask = URLSession.shared.dataTask(with: url) { [weak self] (information, _, _) in if permit data = data { // Create Epitome and Update Epitome View self?.imageView.image = UIImage(data: information) } } // Beginning Data Task dataTask.resume() } At that place is one last trouble we demand to resolve. The completion handler we pass to the dataTask(with:completionHandler:) method is executed on a groundwork thread. You probably know that the user interface should always be updated from the primary thread. Fortunately, the solution is elementary. We use Grand Central Dispatch to update the image view on the main thread.
// Marker: - 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 Job permit dataTask = URLSession.shared.dataTask(with: url) { [weak self] (data, _, _) in if let data = data { DispatchQueue.main.async { // Create Image and Update Prototype View cocky?.imageView.image = UIImage(data: information) } } } // Start Data Task dataTask.resume() } Similar I said, the 2nd strategy is more involved, only it is more robust and doesn't block the main thread. We can fix the upshot we encountered using the first strategy by creating the Data object on a background thread, using Grand Central Dispatch. The solution looks something like this.
// Marking: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() // Create URL permit url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/in a higher place-the-clouds.jpg")! DispatchQueue.global().async { // Fetch Image Data if let data = try? Data(contentsOf: url) { DispatchQueue.main.async { // Create Image and Update Image View self.imageView.epitome = UIImage(data: information) } } } } Notice that we still update the prototype view from the primary thread using Grand Cardinal Dispatch. It's a minor simply important detail.
Source: https://cocoacasts.com/fm-3-download-an-image-from-a-url-in-swift
0 Response to "How to Create an Upload Image to Button Swift"
Post a Comment