Persisting Image Data Locally (swift 3)
In this post I’ll go over how to persist image data locally on your phone. My previous post covers getting the camera up and running in your app — check it out here. We will pick up where that post left off and get the pictures we are taking in the app to stick around.
We wont be using core data to store the image data directly but rather the file path to where the image data is stored on your phone. Core data is not a good tool for storing large amounts of data — but it’s very good for storing things like Strings which can represent a file path.
Lets set up an entity that will be used to store the file path and write a method that fetches that string. In the .xcdatamodeld file I added a new entity called “Image” and gave it two attributes called “filePath” and “placement” both of type string.
Before we get to using the CoreData lets setup the filePath and imageData we actually want to save!
File Manager lets you work with the iPhone’s file directory directly. Using the FileManager we can specify where we want to save files and also remove them if needed.
We will want to set up the file path and save the imageData when we click “Use Photo” when we are in the camera view controller. In the didFinishPickingMediaWithInfo method we can add the following code.
Using the FileManager class we can access the home directory of the iPhone, create a unique name for our photo, and get the URL to save the photo data. I added some print statements to show what each variable is doing. Also notice that the file path has a code for the application, so the documents file path is unique between different apps.
The filePath we create on the last line uses the selectedImageTag to create a unique .png component to append to the end of the file path. In this case we are just giving it a number 1, 2, or 3.
Note that if we try to save the “1.png” file twice we will get a crash because the filePath already exists. We will need to add some logic to clear the old data when saving a new “1.png” image.
Next we can write the code that actually converts our image into data and writes it to the created filePath.
Back To Core Data
Now that we have a filePath leading to our imageData we can save the filePath using coreData. We will need to set up logic that both save and fetch the filePaths for all three of our images.
Since the CoreData boilerplate code exists in the AppDelegate we will need to gain access to to its shared instance in our view controller class. Lets set up a variable we can use to reference it.
Now we can access the CoreData stack with the persistentContainer variable and saveContext function. This will allow us to add some logic to the didFinishPickingMediaWithOptions function that works with core data.
Notice that the imageTag determines the placement of the image.
Last thing we need to do is write a function that will fetch the coreData Image entity convert the image data into an image and display the images in the appropriate view (if they exist).
We can call this in the viewDidLoad and the app should be working!
One thing to note is that when you save imageData to the documentDirectory the user can’t easily delete it. I’ll add a button to the bottom of the app “clear cache” that will remove any files from the directory.
Thanks for reading :)