Save Images Locally with Swift 5
Depending on what you are building, it could be useful to save images locally. In this tutorial I will show you the basics of how to save an image to
UserDefaults as well as to the
file system. You will be able to use the same technique to save an image to
Core Data, but I will not be showing you how to do that.
Why save images locally?
There are many reasons for wanting to save images locally on a users device. You might want to save the images so that you do not need to download them again, or, you might be building an app that edits images. These are only a few of the reasons that you may want to save images locally.
Like I mentioned before, we are going to build an app that allows us to save an image locally. We will be using
file system in order to save locally. To get started we will start by writing the foundational code and then later on we will add the implementation code for each method of saving the images.
Lets start by creating the
StorageType enum. This enum will have two cases,
fileSystem. This will be used in the
retrieveImage functions that we will be creating later on.
Now that we have the storage types we can start creating the foundations of the
store function will take three parameters.
image, this will be of type
key, this will be of type
String and will be a unique name for the image we want to save/retrieve, and finally we will pass through the
We now have our function. We should be able to add some of the base logic to it now. In this function we want to take a
UIImage and convert it to
Data. This will make it much easier for use to store the image. We also want to use the correct file storage. Update your
store function with the following
We have now created the foundations of our
store function. Later on we will implement each of the saving methods, but for now we are going to move on to getting the foundational code written for our
retrieveImage function is going to take two arguments. The first argument will be,
key, which will be the same as the
key in the
store function. The second argument will be
storageType, again, this will be used in the same way as it is used in the
And that is all that is needed for the foundation code. We can now start implementing the
UserDefaults save and retrieve functionality.
Saving and retrieving image with UserDefaults
UserDefaults is the easier way to save the images. In our code that we have written so far we have already converted our
Data. All we need to do now is to save and retrieve it.
Lets do the saving first. To save the data to
UserDefaults update your
store method to look like the below code.
That was quite easy, a nice one liner to save the image when using
UserDefaults. Ok, now lets implement the
retrieveImage functionality for
So that was almost as simple as storing the image. Because
Any type, we need to cast it back to
Data when we retrieve it. Once we do that, we instantiate a new
UIImage with the
imageData and then we return that
UIImage that we initialised.
Save and retrieve image with File System
file system is quite a bit more complicated than using
UserDefaults. We are going to start off by writing a small helper method called
filePath will only take one argument called
key argument is the same
key that we use in other places in our code.
filePath method doesn’t do too much, but it will help out later on. Basically all this method will do is get the url for the home directory on the device. It will then append the
key.png to the url and return that value. I have used the png extension in this example as we are only working with png data in this example.
Ok, now that we have our helper function we can implement the
.fileSystem functionality in the
store function. Update your
store function to look like the below function.
filePath function returns an
optional URL we need to unwrap it before we can use it. Once we have unwrapped it we need to write the data to that filePath. Luckily for us
Data has a
write method which we can use to write the data to a file. This is where we will use the filePath that our helper method has returned. The
write method can throw an error so we need to make sure do wrap it in a
do catch. You should now be able to write the image data to disk.
This was a little bit more complicated but not too much more complicated, so lets move straight into the
retrieveImage function to look like the below:
Once again we start off by using our
filePath helper method to return the
URL to the file that we have stored. Once we have that
URL we ask the
FileManager to get the contents of that
URL. Now that we have the file data we can use that data to instantiate a new
UIImage. If none of the above produces a
nil value we can return our image that we retrieved from disk.
That is it when it comes to the basics. You should now be able to read and write an image to the
file system as well as to
Creating test UI
Now that we have all the functional stuff done we can test that everything is working as expected. To do this I have updated my
Main.storyboard to look like the following:
Once you have done that, created outlets for the two UIImageView’s and the two UIButton’s. My outlets look like this:
If you add this code you will not be able to build your project. So to fix that problem we need to implement those two functions,
save function will call the
store function that we created earlier and the
display function will call the
retrieveImage function and then display the image that was returned, either from the
fileSystem or from
UserDefaults. These two functions look like this:
I have wrapped calling the
store and the
DispatchQueue’s because if you don’t then it will block the main thread.
Awesome, now that everything is hooked up you should be able to build and run the app. You will need to update the
display method depending on where you want to save an image. Oh, you will also need to change the image name. I used an image called
buildingImage, but this will not work for you. To get an image into your project you can drag any image into your
Assets.xcassets and then you will need to replace
buildingImage with whatever the name of your image is.