Loading and saving data is essential for any iOS app. Plist files with SwiftyPlistManager are fun and easy. Learn how to read and write Plist file in Swift.
Update note: This epic blog post on how to read and write Plist Files and how to manage them was updated for iOS 11 and Swift 4.
Now you can watch my YouTube video series on how to use SwiftyPlistManager here.
Fortunately there are a lot of ways you can manage data in iOS. There is CoreData or UserDefaults. Recently JSON is quite popular. If you wanted to go the natively supported plist way than you would quickly realise that it can get cumbersome real fast. That is why I have created SwiftyPlistManager as a helper in my own projects. Now you can read and write data to your liking. And the best part is that today I am open-sourcing it. Take a look at it at https://github.com/rebeloper/SwiftyPlistManager
- read and write data with one call
- supports multiple plist files
- supports completion handlers
- error handling
- written in Swift 4
What you need to know about the Plist file
This tutorial assumes that you know the basics of the structure of the plist file, but to just to be on the safe side here’s the jargon you must know in order to proceed.
You can get started right away. Installation is through CocoaPods or Manual. Let’s take a look at the Manual installation first.
Go to the GitHub repo and “Clone or Download” green button than on “Download ZIP”
Once you unzip the downloaded file you will see the contents like so:
You will basically see an example project. You can certainly open it and take a look around. For the sake of this tutorial we will not do that. Instead we will create a new project. The main file that you are interested at the moment here is the “SwiftyPlaistManager.swift” file. “Data.plist” and “OtherData.plist” are two helper empty plist files that we will use through the tutorial. “ViewController.swift” is the example viewcontroller with a step by step walkthrough of the way you can use SwiftyPlistManager.
The manual setup’s last step is to add the “SwiftyPlistManager.swift” file into your project. Just simply drag and drop it into your project. I’ll create a new Single View Application in Xcode for this called: ManualExample.
One other way to add SwiftyPlistManager to your project is through CocoaPods. I highly recommend it. If you want to stick to the manual process feel free to skip over the next step and continue at the “Setup” section.
Installing via CocoaPods
If you haven’t already install CocoaPods by opening Terminal and running: sudo gem install cocoapod
For a detailed guide on how to install CocoaPod onto your computer visit the CocoaPods Getting Started Guide.Next
First thing’s first. Create a new Xcode project (Single View Application with the Language: Swift) and name it: SPMTutorial.
Great! Now instead of manually adding SfiftyPlistManager to it we will add it through CocoaPods.
Open Terminal if not already and type in “cd “. Note the “space” after “cd”!
Next navigate to the root folder of your project and drag and drop it into the Terminal.
Hit “Return” and you’ll be in your project root folder. Now type in: pod init and hit “Return” again. A Podfile will be immediately created for you.
Next we need to add the “SwiftyPlistManager” pod into it. Do the following:
- type in: vim Podfile
- press “A” to edit the file
- with the down-arrow key go down and under “# Pods for SPMTutorial” write: pod ‘SwiftyPlistManager’ (make sure that these are NOT smart quotes – you can copy and paste this line from the GitHub README page)
- press “esc”
- type in “” (that is : followed by an x)
- finally hit “Return” to exit from the vim editor
Finally, type: pod install to install the pod in your Podfile. Terminal will download and install “SwiftyPlistManager” into your project.
Terminal has created an .xcworkspace for you. Close your current project and from now on work only in the SPMTutorial.xcworkspace. Go ahead and double click it or open it with a Terminal command: open SPMTutorial.xcworkspace
When you expand some groups you will see that now your workspace incorporates the “SwiftyPlistManager” pod.
Nice job! You have successfully added “SwiftyPlistManager” to your app via CocoaPods.
Next you need to add some helper files.
SwiftyPlistManager needs template plist files to use them as the starting point of your data saving and loading. Basically on the first launch of the app it will copy it into it’s Document directory and after that you’ll be interacting with this copied version of the plist.
Just drag and drop (or create) your plist file(s) into your project. We’ll just add the “Data.plist” and “OtherData.plist” files.
Show me the code
Now let’s start coding! Open up ViewController.swift. It is always a good practice to make our keys typo-proof. Add the following constants (and one variable) to the viewDidLoad() function.
Xcode complains that we are not using these. Don’t worry we will soon. Disregard these warnings.
Now go to ‘Data.plist‘ and add a new item with this key: ‘newKey‘ and with a String value: ‘Hello SwiftyPlistManager‘
If you’re using CocoaPods you must first import SwiftyPlistManager into your ViewController.swift file.
IMPORTANT: You always have to “start” SwiftyPlistManager on every launch of your app. Add the next line of code to your ‘application(_:didFinishLaunchingWithOptions:)‘ function in AppDelegate.swift. For the sake of this tutorial let’s just add it in the ViewController.swift. This is fine too, as long as it is fired on every launch. Set ‘logging’ to ‘true’ if you want to log what’s going on under the hood. Optionally set it to ‘false’ before release or when you are fed up with too much text in the console.
Bulid & Run. Stop. Never comment back this line of code. What this did is copy your existing Data.plist file into the app’s Documents directory. From now on the app will interact with this newly created file and NOT with the plist file you see in Xcode. This is why if you change a value (or add a new item) to your plist now (after the first launch) than changes will not be reflected in the MyData.plist file you see in Xcode. Instead changes will be saved to the plist file created in the Documents directory. Consider this Data.plist file (that one you see in Xcode) as a ‘starting’ file in witch you set up all of your needed keys with some default values.
IMPORTANT: After you first launch your app and than add/remove items in the Data.plist file the changes will not be reflected in the file in the Documents directory. To add more key-value pairs to your Data.plist file or change the value of any key-value pair do the following steps:
- Add your desired new items to the Data.plist file
- Delete your app from the simulator/device
- Build & Run the app
You will always have to repeat these steps if you wish to add new key-value pairs through the Data.plist file. You can easily skip these steps if you add key-value pair through code. The downside of this is that you can’t actually see or edit the key-value pairs in the file you see in Xcode.
Multiple plist files
You can ‘start’ as many plist files as you’d like as long as you have them in your project bundle already. Of course if the plist does not exist SwiftyPlistManger will gently warn you in the log. Try starting SwiftyPlistManager with these 3 items: “Data“, “OtherData” and “NonExistent“. Of course, use the constants that you have set up above. Build and Run. Take a look at the console log.
Comment the line back again. In this tutorial we will work on the ‘Data.plist’ file only.
Let’s test if the item with the ‘newKey’ key exits and print it out in the Log. SwiftyPlistManager uses completion handlers. You’ll get back your ‘result’ as an Any? object. For now let’s just check if the error is nil. We’ll talk about in depth error handling later on. After adding the call Build and Run your app again.
Hurray! Comment back that call.
Now let’s change the value of this item. We want to avoid the cumbersome 3 step process detailed above, so we are going to do it in code. Build and Run.
You can notice a warning. We’ll talk about it later. It’s harmless for now, but it can get into a monster if you’re not careful. Details soon below.
Note that you don’t see any changes in the Data.plist file. This is how it should be, because the app saved the new value to the file in the Documents directory, remember? So now let’s get back the changed value. Comment back the save and add this new call (build and run):
Note that the value you get back is an optional. Retrieveng it with the ‘bang operator’ (!) is quite risky because you might get back nil and that would crash your app! My suggestion is to never ever use the ‘bang operator’. It’s risky, crash-prone and shouts that you are a lazy, clueless (or both) developer. There are better ways to write code. For a start let’s add a default value. Change the call to look like this.
As you can see nothing has changed in the log, we’re just a tad safer. At this point the optional value will default to the “No Value” Sting. I personally hate working with default values because they might pop up and would ruin the user experience of any app. To enhance your code let’s unwrap the ‘result’ with a guard-let statement. Change the call agin to look like this:
Again, no change in the log, but now we’re super safe. Another way is to unwrap it with an if-let statement if you do not wish to return from the completion handler right away.
Congratulations! You have learned how and when to use (or not to use) the ‘bang operator’, ‘guard-let statements’ and ‘if-let’ statements. You now have solid knowledge of how to deal with optionals.
Most of the times you want to cast your result into a constant right away and not wait for the completion handler to finish. You can use the following call to do just that. For this example we’ll unwrap it with a guard-let statement.
Of course if you try to fetch a value with a non-existent key, ‘SwiftyPlistManager’ has your back. It will show a WARNING in the log that the key does not exist AND it will not crash the app. Sweet!
Adding new key-value pairs
Now let’s take a look at some other awesome powers that come with SwiftyPlistManager. You can add a new key-value pair like so:
Build & Run your project… Congratulations! You have just created and saved your first key-value pair into your plist file. Stop the project from running.
Now add a next value with an Int and another one with a Bool:
Awesome! Take a look at your progress in the Log. Notice that ‘true’ is represented with a ‘1’ and ‘false’ is represented with a ‘0’. Stop your project from running. As in real life examples you just can’t comment out these 3 calls after the first launch of the app, but you don’t have to. ‘SwiftyPlistManager’ takes care of not creating a new item for the same key. Do not comment out this last calls and Build & Run again. Take a look at the Log.
Remember, you don’t have to add your items through code at all. You can add them into the Data.plist file; it’s much easier, but it has a downside: Once you run and test your code for the first time you cannot add or delete any entries using the plist file. Changes made will not be reflected. You will have to delete your app from the simulator, Clean your project (Product/Clean) and Build & Run again to see your changes. However adding/saving/deleting will work when done in code.
Great! So now you know that ‘adding’ a new key-value pair is not the same as ‘updating’/’saving a new value’ for a key. Let’s do that now. Change and at the same time Save the second key’s value to ’28’ (anotherIntValue).
Semi Type Safeness
Let’s talk about that warning now. ‘SwiftyPlistManager’ is Semi Type Safe. What this means is that for example if you try to save a String value for a non-String value, let’s say to save ‘Alex’ (stringValue) for the ‘thirdKey’ witch already has a Bool value, than ‘SwiftyPlistManager’ will give you a Warning but let you make the save anyway. It is your responsibility that you save the right types of values. Try it out.
Better change back the value to a Bool for the Item with key ‘thirdKey’ before you forget it.
The warning will come up this time too, but now you know that it is set back the way you need it.
Of course, you may add Dictionaries, Arrays, Dates and Data items too. Try it out by adding a new dictionary.
Now just to have some fun with it, change the age of John to 56.
Well done! Now comment back the calls.
Once in a while you might want to remove a key-value pair.
Edit: as of tag 1.0.2 “removeValueKeyPair” has been renamed “removeKeyValuePair”.
Of course, if this line is executed several times ‘SwiftyPlistManager’ realises that the item was already removed and does not exist. Try it out for yourself!
Sometimes you might want to delete all the data from your plist file.
Of course, if this line is executed several times ‘SwiftyPlistManager’ realises that the plist is empty and cancels the operation. Try it out for yourself.
Remember: Your plist file is saved and updated inside the application’s Documents folder. This is why you will not see any changes at all in the MyData.plist file that you see in the Xcode project. That file is there as a ‘starter’ file. Once you start the app and make the ‘startPlistManager()’ call a copy is created in the app’s Documents folder and from that new file is used for all your data till you delete your app from simulator/device and Clean (Product/Clean) your project.
Let’s talk about error-handling. When performing calls with ‘SwiftyPlistManager’ you get access to possible errors in the completion handlers. Let’s dive deep into learning all about them. For a start let’s write a function that interprets the error types you might get. We will simply log the error, but you can do whatever you want.
Now let’s take a look at the most common use cases and their errors.
Go ahead and investigate the log.
And that covers all the aspects that you need to know about ‘SwiftyPlistManager’. Now you are ready to read and write plist files in your own projects.
Let me know if you enjoyed this tutorial in the comments below. If you have any questions you can leave them there too.
If you liked this blog post share it with your friends or just sign up to our newsletter to get more awesomeness like this in your Inbox regularly.