Where to store user data persistently across app updates (iOS)?
Simplest method of persisting data across app restarts is by using UserDefaults. In your case you can store custom data types in a UserDefaults key as follows:
- Init defaults object
let defaults = UserDefaults.standard
- Create a custom data type for your data (needs to be Codable)
struct Bookmark: Codable {
let name: String
let url: String
}
struct Bookmarks: Codable {
let bookmarks: [Bookmark]
}
- Save data as follows
// data is of type Bookmarks here
if let encodedData = try? JSONEncoder().encode(data) {
defaults.set(encodedData, forKey: "bookmarks")
}
- Retrieve data later
if let savedData = defaults.object(forKey: "bookmarks") as? Data {
if let savedBookmarks = try? JSONDecoder().decode(Bookmarks.self, from: savedData) {
print("Saved user: \(savedBookmarks)")
}
}
More info here and here
What is correct way to store/retrieve user data (read/write files) in iPhone (iOS) dev via Swift?
See iOS Storage Best Practices video and the File System Basics document. That should get you going.
In short, app data is generally stored in “application support directory”, documents exposed to the user (e.g. the Files app) are stored in “documents” folder, downloads that can be easily re-retrieved are stored in “caches” folder. Technically you could use UserDefaults
for storing of this sort of application data, but it really is not intended for this purpose.
Re opening a file for “read/write”, when dealing with JSON, you don’t generally do that. You read the file into a Data
and deserialize the JSON into your model objects.
do {
let fileURL = try FileManager.default
.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("appdata.json")
let data = try Data(contentsOf: fileURL)
let appData = try JSONDecoder().decode(AppData.self, from: data)
// do something with appData
} catch {
print(error)
}
When you want to update, you serialize the model objects into a Data
containing your JSON and then write it to the file, replacing the file.
do {
let fileURL = try FileManager.default
.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("appdata.json")
let data = try JSONEncoder().encode(appData)
try data.write(to: fileURL)
} catch {
print(error)
}
Obviously, this assumes that the AppData
type (or whatever you call it) conforms to Codable
, but you said you were familiar with serialization of JSON. See Encoding and Decoding Custom Types for more information.
How do I store user data once logged in to be used throughout the app?
You can use UserDefaults to store data for use across the app.
How can I use UserDefaults in Swift?
Keep in mind it is not recommended for large chunks of data as the data gets loaded into memory everytime the app loads, for large data you're better off using some local database like Realm, Core Data etc.
Best method to store data for an iOS app?
If the data you want to store is very little and not sensitive, you can use UserDefaults
For example, user's name, their age etc.
For Large amounts of data you should use Core Data, its a good and an easy way to manage your objects. For example, you have 1000 items, each with a property, you can basically use core data for that. It is pretty straightforward as how to create Managed Objects, store them and how to later retrieve them using queries.
Basically when you configure your project with core data, project creates an sqlite file attached to your project.
There are many tutorials on how to get started with Core Data, if you have an average experience with iOS, it will be a piece of cake for ya.
Here's a nice tutorial that will help you setup core data in your project:
https://www.raywenderlich.com/173972/getting-started-with-core-data-tutorial-2
How to save local data in a Swift app?
The simplest solution for storing a few strings or common types is UserDefaults.
The UserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Boolean values, and URLs.
UserDefaults
lets us store objects against a key of our choice, It's a good idea to store these keys somewhere accessible so we can reuse them.
Keys
struct DefaultsKeys {
static let keyOne = "firstStringKey"
static let keyTwo = "secondStringKey"
}
Setting
let defaults = UserDefaults.standard
defaults.set("Some String Value", forKey: DefaultsKeys.keyOne)
defaults.set("Another String Value", forKey: DefaultsKeys.keyTwo)
Getting
let defaults = UserDefaults.standard
if let stringOne = defaults.string(forKey: DefaultsKeys.keyOne) {
print(stringOne) // Some String Value
}
if let stringTwo = defaults.string(forKey: DefaultsKeys.keyTwo) {
print(stringTwo) // Another String Value
}
Swift 2.0
In Swift 2.0 UserDefaults
was called NSUserDefaults
and the setters and getters were named slightly differently:
Setting
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Some String Value", forKey: DefaultsKeys.keyOne)
defaults.setObject("Another String Value", forKey: DefaultsKeys.keyTwo)
Getting
let defaults = NSUserDefaults.standardUserDefaults()
if let stringOne = defaults.stringForKey(DefaultsKeys.keyOne) {
print(stringOne) // Some String Value
}
if let stringTwo = defaults.stringForKey(DefaultsKeys.keyTwo) {
print(stringTwo) // Another String Value
}
For anything more serious than minor config you should consider using a more robust persistent store:
- CoreData
- Realm
- SQLite
How and When to Store Settings & User Data in an iOS App?
As mentioned in comments, use NSUserDefaults
for settings. For "large files" it's more likely you mean "user data". In that case, you can use Core Data or store your own NSCoding
-compliant data model via NSKeyedArchiver
(and unarchived via NSKeyedUnarchiver
) or their ...Secure...
alternatives to write to your app's documents.
Rather than save only when the application's state changes, you should probably persist small changes as they're made (this is basically what NSUserDefaults
does) or as some logical group of changes are made (what constitutes a "logical group" depends entirely on the nature of the data and your app and is therefore up to you).
So: Identify the "settings" and store them the right way (in NSUserDefaults
). Then identify your user's game data and store that the right way (in some sort of data file).
Best way to store user information in iOS app
The keychain would not be overkill, that kind of thing is what it's for.
Really though it sounds like a bad security problem in your API. If the user can login and can then access the data of every other user via the API and then if they fiddle with some values, that's no good.
Best way to store user information for my iOS app
The user information needs to be stored in the keychain to keep it secure.
Any other information could be stored in any one of:
- User defaults
NSUserDefaults
- File on disk (maybe a plist)
- Database
Core Data
(technically just a file on disk)
Which you choose depends on what the data is, how much there is and what kind of access you need to it.
If your data is small and chosen by the user as some kind of setting then user defaults makes sense and is the lowest cost for you to implement.
To use a database, check out Core Data intro
.
Related Topics
How to Change a Swiftui Color to Uicolor
Finding Distance Between Cllocationcoordinate2D Points
How to Add Custom Text in Nsdateformatter's Format String
Com.Facebook.Sdk Error 2 on iOS
Xcode 5/iOS 7 - Localization Not Working in Simulator
Using Sysctlbyname() from Swift
Apple MACh-O Linker (Id) Warning:Building for MACosx, But Linking Against Dylib Built for iOS
Uitableviewcellaccessorycheckmark and Autolayout Constraints
Programmatically Highlight Uibarbuttonitem
Simple Uitableview in Swift - Unexpectedly Found Nil
Enable Uialertaction of Uialertcontroller Only After Input Is Validated
iOS 7 When Rotating View in Tab Bar, Right Side of View Is Not Clickable
Static VS Class as Class Variable/Method (Swift)
Disable iOS Simulator 'Connect Hardware Keyboard' Programmatically
"Could Not Inspect Application Package" Xcode