Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Loading/Downloading an image from a URL in Swift
In this article, you will learn how you can download an image from a URL in the Swift language.
In the iOS application, image downloading from the image URL is the most common task. Apple provides us with a native library to download any data from any URL. There are many third-party libraries available on GitHub to download the images.
But in this tutorial, we are not going to use any third-party library. We will use the URLSession class provided by Apple itself.
What is the URLSession Class?
URLSession is a class in the Foundation framework that provides an API for downloading data from and uploading data to a server over a network connection. It uses a URL to identify the location of the resource and can be used to perform a variety of network requests, including GET, POST, PUT, and DELETE.
Example
Here's an example of how you can use URLSession to make a GET request in Swift.
<div class="code-mirror language-swift" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;"><span class="token keyword">import</span> <span class="token class-name">UIKit</span>
<span class="token keyword">let</span> url <span class="token operator">=</span> <span class="token function">URL</span><span class="token punctuation">(</span>string<span class="token punctuation">:</span> <span class="token string-literal"><span class="token string">"url_string"</span></span><span class="token punctuation">)</span><span class="token operator">!</span>
<span class="token keyword">let</span> task <span class="token operator">=</span> <span class="token class-name">URLSession</span><span class="token punctuation">.</span>shared<span class="token punctuation">.</span><span class="token function">dataTask</span><span class="token punctuation">(</span>with<span class="token punctuation">:</span> url<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span>data<span class="token punctuation">,</span> response<span class="token punctuation">,</span> error<span class="token punctuation">)</span> <span class="token keyword">in</span>
<span class="token keyword"><font color="#000000"> </font>if</span> <span class="token keyword">let</span> error <span class="token operator">=</span> error <span class="token punctuation">{</span>
<span class="token comment">// handle error</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token keyword">guard</span> <span class="token keyword">let</span> httpResponse <span class="token operator">=</span> response <span class="token keyword">as</span><span class="token operator">?</span> <span class="token class-name">HTTPURLResponse</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">200</span><span class="token operator">...</span><span class="token number">299</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span>httpResponse<span class="token punctuation">.</span>statusCode<span class="token punctuation">)</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token comment">// handle error</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token keyword">let</span> data <span class="token operator">=</span> data <span class="token punctuation">{</span>
<span class="token comment">// process data</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
task<span class="token punctuation">.</span><span class="token function">resume</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</div>
This code creates a URL object representing the API endpoint and then creates a dataTask using the dataTask(with:) method of URLSession. The dataTask sends a GET request to the server and retrieves the data in the response. The completion handler is called when the request is complete, and it receives the data, response, and error as arguments.
You can use the response and data objects to handle the server's response and process the data as needed.
To load an image from a URL in Swift, you are going to use the same URLSession class to send a request to the server where the image is hosted. You will then use the data from the response to create an image with the UIImage class.
Here's an example of how you can do this
Algorithm
Step 1 ? Create a class ImageDownloader and a method downloadImage().
Step 2 ? Check for a valid URL object otherwise return.
Step 3 ? Call the dataTask() method of the URLSession class.
Step 4 ? Implement the completion callback in the dataTask() method.
Step 5 ? Check for the error before moving on to the next step.
Step 6 ? Convert the received data into UIImage object with if-let.
Example
<div class="code-mirror language-swift" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;"><span class="token keyword">import</span> <span class="token class-name">UIKit</span>
<span class="token keyword">class</span> <span class="token class-name">ImageDownloader</span> <span class="token punctuation">{</span>
<span class="token keyword"><font color="#000000"> </font>static</span> <span class="token keyword">func</span> <span class="token function-definition function">downloadImage</span><span class="token punctuation">(</span><span class="token omit keyword">_</span> urlString<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span> completion<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>_image<span class="token punctuation">:</span> <span class="token class-name">UIImage</span><span class="token operator">?</span><span class="token punctuation">,</span> <span class="token omit keyword">_</span> urlString<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token operator">?</span><span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">?</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">guard</span> <span class="token keyword">let</span> url <span class="token operator">=</span> <span class="token function">URL</span><span class="token punctuation">(</span>string<span class="token punctuation">:</span> urlString<span class="token punctuation">)</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
completion<span class="token operator">?</span><span class="token punctuation">(</span><span class="token nil constant">nil</span><span class="token punctuation">,</span> urlString<span class="token punctuation">)</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token class-name">URLSession</span><span class="token punctuation">.</span>shared<span class="token punctuation">.</span><span class="token function">dataTask</span><span class="token punctuation">(</span>with<span class="token punctuation">:</span> url<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span>data<span class="token punctuation">,</span> response<span class="token punctuation">,</span>error<span class="token punctuation">)</span> <span class="token keyword">in</span>
<span class="token keyword">if</span> <span class="token keyword">let</span> error <span class="token operator">=</span> error <span class="token punctuation">{</span>
<span class="token function">print</span><span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"error in downloading image: </span><span class="token interpolation-punctuation punctuation">\(</span><span class="token interpolation">error</span><span class="token interpolation-punctuation punctuation">)</span><span class="token string">"</span></span><span class="token punctuation">)</span>
completion<span class="token operator">?</span><span class="token punctuation">(</span><span class="token nil constant">nil</span><span class="token punctuation">,</span> urlString<span class="token punctuation">)</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token keyword">guard</span> <span class="token keyword">let</span> httpResponse <span class="token operator">=</span> response <span class="token keyword">as</span><span class="token operator">?</span> <span class="token class-name">HTTPURLResponse</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token operator">...</span><span class="token number">299</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span>httpResponse<span class="token punctuation">.</span>statusCode<span class="token punctuation">)</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
completion<span class="token operator">?</span><span class="token punctuation">(</span><span class="token nil constant">nil</span><span class="token punctuation">,</span> urlString<span class="token punctuation">)</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token keyword">let</span> data <span class="token operator">=</span> data<span class="token punctuation">,</span> <span class="token keyword">let</span> image <span class="token operator">=</span> <span class="token class-name">UIImage</span><span class="token punctuation">(</span>data<span class="token punctuation">:</span> data<span class="token punctuation">)</span> <span class="token punctuation">{</span>
completion<span class="token operator">?</span><span class="token punctuation">(</span>image<span class="token punctuation">,</span> urlString<span class="token punctuation">)</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
completion<span class="token operator">?</span><span class="token punctuation">(</span><span class="token nil constant">nil</span><span class="token punctuation">,</span> urlString<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">resume</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</div>
Explanation
In the above example, you can see that validating the URL object before proceeding further is always a viable option. Once the request is completed, the completion
handler gives you data, response, and error. Verify whether an error was received or not before getting a valid image from the data.
Example
<div class="code-mirror language-swift" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;"><span class="token keyword">import</span> <span class="token class-name">UIKit</span>
<span class="token keyword">class</span> <span class="token class-name">TestViewController</span><span class="token punctuation">:</span> <span class="token class-name">UIViewController</span> <span class="token punctuation">{</span>
<span class="token keyword">override</span> <span class="token keyword">func</span> <span class="token function-definition function">viewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">viewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
view<span class="token punctuation">.</span>backgroundColor <span class="token operator">=</span> <span class="token punctuation">.</span>white
<span class="token keyword">let</span> imageView <span class="token operator">=</span> <span class="token class-name">UIImageView</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
imageView<span class="token punctuation">.</span>contentMode <span class="token operator">=</span> <span class="token punctuation">.</span>scaleAspectFill
imageView<span class="token punctuation">.</span>layer<span class="token punctuation">.</span>cornerRadius <span class="token operator">=</span> <span class="token number">16</span>
imageView<span class="token punctuation">.</span>layer<span class="token punctuation">.</span>masksToBounds <span class="token operator">=</span> <span class="token boolean">true</span>
imageView<span class="token punctuation">.</span>backgroundColor <span class="token operator">=</span> <span class="token class-name">UIColor</span><span class="token punctuation">(</span>white<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> alpha<span class="token punctuation">:</span> <span class="token number">0.1</span><span class="token punctuation">)</span>view<span class="token punctuation">.</span><span class="token function">addSubview</span><span class="token punctuation">(</span>imageView<span class="token punctuation">)</span>
imageView<span class="token punctuation">.</span>translatesAutoresizingMaskIntoConstraints <span class="token operator">=</span> <span class="token boolean">false</span>
imageView<span class="token punctuation">.</span>widthAnchor<span class="token punctuation">.</span><span class="token function">constraint</span><span class="token punctuation">(</span>equalToConstant<span class="token punctuation">:<font color="#000000"> </font></span><span class="token number">250</span><span class="token punctuation">)</span><span class="token punctuation">.</span>isActive <span class="token operator">=</span> <span class="token boolean">true</span>
imageView<span class="token punctuation">.</span>heightAnchor<span class="token punctuation">.</span><span class="token function">constraint</span><span class="token punctuation">(</span>equalToConstant<span class="token punctuation">:</span><span class="token number">250</span><span class="token punctuation">)</span><span class="token punctuation">.</span>isActive <span class="token operator">=</span> <span class="token boolean">true</span>
imageView<span class="token punctuation">.</span>centerXAnchor<span class="token punctuation">.</span><span class="token function">constraint</span><span class="token punctuation">(</span>equalTo<span class="token punctuation">:</span>view<span class="token punctuation">.</span>centerXAnchor<span class="token punctuation">)</span><span class="token punctuation">.</span>isActive <span class="token operator">=</span> <span class="token boolean">true</span>
imageView<span class="token punctuation">.</span>centerYAnchor<span class="token punctuation">.</span><span class="token function">constraint</span><span class="token punctuation">(</span>equalTo<span class="token punctuation">:</span>
view<span class="token punctuation">.</span>centerYAnchor<span class="token punctuation">)</span><span class="token punctuation">.</span>isActive <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token class-name">ImageDownloader</span><span class="token punctuation">.</span><span class="token function">downloadImage</span><span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"https://picsum.photos/300"</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
image<span class="token punctuation">,</span> urlString <span class="token keyword">in</span>
<span class="token keyword">if</span> <span class="token keyword">let</span> imageObject <span class="token operator">=</span> image <span class="token punctuation">{</span>
<span class="token comment">// performing UI operation on main thread</span>
<span class="token class-name">DispatchQueue</span><span class="token punctuation">.</span>main<span class="token punctuation">.</span><span class="token keyword">async</span> <span class="token punctuation">{</span>
imageView<span class="token punctuation">.</span>image <span class="token operator">=</span> imageObject
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</div>
Note that this code uses the dataTask method of URLSession to perform the request asynchronously. This means that the image will be loaded in the background, and the main thread will not be blocked. This is important to ensure that your app remains responsive while the image is being loaded.
Output

Conclusion
Note that URLSession also provides other methods for performing network requests, such as uploadTask for uploading data to a server, and downloadTask for downloading data from a server. You can use these methods depending on your needs.
