
Persistence: Saving data to a place where it can be re-accessed and retrieved upon restart of the device or app. Necessary for any app that wants to store data long term and keep it available to the user.
Types of Persistence
- NSUserDefaults
- iOS File System
- Core Data
NSUserDefaults
The easiest way to persist data to a device.
A Dictionary that stores the data in plist file
Can hold Data, String, Number, Date, Array or Dictionary
Should be used for small amounts of data less than 1MB, because it reads and writes all in one shot.
Example: User Preferences for the app
How To Use it:
1. To check and see if the app has ran before:
2. In the AppDelegate.swift file write a new function. This function will check to see if the app has launched before and if it hasn’t it will set the default value of the item we are trying to save. In this case it will if the user has selected Dark Mode.
3. It can be for anything, a value on a slider, text on a screen, a switch button.
func checkIfFirstLaunch() { if UserDefaults.standard.bool(forKey: "HasLaunchedBefore") { print("App has launched before") } else { print("This is the first launch ever!") UserDefaults.standard.set(true, forKey: "HasLaunchedBefore") UserDefaults.standard.set(false, forKey: "DarkThemeOn") UserDefaults.standard.synchronize() }
4. We need to call the function we can do this is one of the existing methods.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { print("App Delegate: will finish launching") checkIfFirstLaunch() return true }
5. We need to save the changes when the user flips the switch. We need to set the UserDefaults and tell it that we are going to be using a bool that has a key of “DarkThemeOn”
override fun viewDidLoad() {
super.viewDidLoad()
let DarkThemeOn = UserDefaults.standard.bool(forKey: "DarkThemeOn")
if DarkThemeOne {
switchToDark()
}
}
@IBAction func switchFlipped(sender: Any) {
if themeSwitch.isOn {
switchToDark()
UserDefaults.standard.set(true, forKey: "DarkThemeOn")
} else {
switchToLight()
UserDefaults.standard.set(false, forKey: "DarkThemeOn")
}
}
iOS File System
Where are the User Defaults being saved? Where is anything for the app being saved?
The way that the iPhone file system is organized and divided up to store files. The iPhone and iPad system is called iOS and is made up of a hierarchy of folders/directories (Unix based).
iOS was conceived with the notion that each is independent of each other. Each app once it’s installed in placed in what’s called a “sandbox”, its own storage container.
All apps and items stored on the app can expand to fit more items but they can only expand as long as there is storage in the phone. Once the whole phone storage is full then nothing else can be added until room is cleared up.
The Sandbox
When an app is installed it’s made with several pre-made containers.
The Bundle Container:
Contains the application itself . It is a directory that holds the executable code and its resources (like images, audio files and so on).
The Data Container:
Holds all the user and app data. There are usually three directories.
Temp – Is used for storing temporary data that doesn’t have to persist across launches. This will never get backed up.
Documents – This is where user data should go. Backups will be made and iOS will never delete its contents.
Library – This is for non-user data, or files that we don’t want to expose to the user.
Both Documents and Library have a few standard subdirectories. i.e. Documents -> Inbox, Library -> Applications Support, Library-> Caches and many others.
We can create subdirectories of our own to better organize our files.
NSUserData lives inside the Data Container -> Library
To save items in the sandbox we need to do two things.
1. Find where the sandbox is within the phone.
2. Write to a file within that folder.
This is to be accomplished by using
1. FileManager to get the path to the directory in the sandbox
2. String to write or read text files.
3. Data to write or read binary files.
How To Use it:
func sandboxPlayground() { // This instance of file manager will allow us to find folders, copy files, remove files. // Use this to get the path to the folder within our sandbox. // It returns an array of URL's instead of just one. This is because there is a documents folder for each app that is installed. let fileManager = FileManager.default // this will give us an array or just the one folder we need. let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask) // with the above we can now get the url for the file we are going to create. let url = urls.last?.appendingPathComponent("file.txt") // now we can save a string or data into it, they both work similarly. do { try "Hello World!".write(to: url!, atomically: true, encoding: .utf8) } catch { print("Error while writing") } // to read it we can do this do { let content = try String(contentsOf: url!, encoding: String.Encoding.utf8) if content == "Hello World!" { print("Yes, it works") } else { print("Nope, it didn't work") } } catch { print("Something went wrong") } }
Core Data section coming up next.