Code related: Projects/UserDefaults
- How to save data using UserDefaults
- How to retrieve data from UserDefaults
- Generic approach for user defaults
You must use the UserDefaults Starter for this module. Inside the starter project you should have the project structure used on the LoginForm project
In order to save a string, just add the next line:
UserDefaults.standard.set("Are you ready?", forKey: "LoadingMessage")
Note: You need to be aware that you have access to multiple methods for store data:
integer(forKey:)
returns an integer if the key existed, or 0 if not.bool(forKey:)
returns a boolean if the key existed, or false if not.float(forKey:)
returns a float if the key existed, or 0.0 if not.double(forKey:)
returns a double if the key existed, or 0.0 if not.
After saving a custom welcome message, we need to retrieve it from user defaults:
let loadingMessage = UserDefaults.standard.string(forKey: "LoadingMessage")
Now we can use the stored value to display the the message on our message label.
messageLabel.text = loadingMessage
At the end your code should look like this:
import UIKit
class DispatchViewController: UIViewController {
private let mainFlow: Flow = .login
@IBOutlet weak var messageLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
UserDefaults.standard.set("Are you ready?", forKey: "LoadingMessage")
let loadingMessage = UserDefaults.standard.string(forKey: "LoadingMessage")
messageLabel.text = loadingMessage
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.setMainFlow(to: self.mainFlow)
}
}
}
At this point we are ready to create an structured way for using user defaults. First we need to add the Local
folder to our project:
- Add a new
Local
folder inside theData
folder using Finder - Add new files to our UserDefaults project inside the Xcode
Inside our folder Data/Local
we need to create an enum to keep track of all our keys, named LocalKeys.swift
, use the following structure:
enum LocalKeys: String {
case loadingMessage = "loading-message"
}
Note: In the future you may end up using a structure like this:
enum LocalKeys: String {
enum User: String {
case current = "user-current"
}
enum Token: String {
case authToken = "token-auth"
}
//HERE: Add your custom keys
}
Now, also inside our folder Data/Local
the next file to create is a protocol to define our local data manager behavior. The file name should be DispatchManagerProtocol.swift
.
protocol DispatchManagerProtocol {
func save(message: String?)
func retrieve() -> String?
func clear()
}
We need to create a concrete data manager that uses our protocol. Inside our folder Data/Local
create a new swift file called DispatchManager.swift
which implements DispatchManagerProtocol
.
class DispatchManager: DispatchManagerProtocol {
func save(message: String?) {
}
func retrieve() -> String? {
return nil
}
func clear() {
}
}
Move the code inside the DispatchViewController
inside the methods of our new DispatchManager
. Finally we need update our DispatchViewController
in order to use the structured implementation.
Your DispatchViewController
code should look like this:
import UIKit
class DispatchViewController: UIViewController {
private let mainFlow: Flow = .login
var dataManager: DispatchManagerProtocol! = DispatchManager()
@IBOutlet weak var messageLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
messageLabel.text = dataManager.retrieve()
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.setMainFlow(to: self.mainFlow)
}
}
}
In the future the amount of local managers we are going to use migth increase, so before continue we need to crate some folders.
- Click the
Data/Local
group inside Xcode to display the options menu, select "New group" - Rename the created folder to
Protocols
- Move the
DispatchManagerProtocol
file inside theProtocols
group - Click the
Data/Local
group inside Xcode to display the options menu, select "New group" - Rename the created folder to
Managers
- Move the
DispatchManager
file inside theManagers
folder
Use UserDefaults
to store:
- Session flag after user logs in
- Username entered by the user
Use the values stored to:
- Decide the main application flow (User should be redirected to pokemons list if has logged in)
- Display the user name as title for the pokemons screen. Use the template:
Pokédex - <Username>
Use the YellowPod - Local definition to combine the library DefaultsKit with our structured way to save values.