iOS Equivalent For Android Shared Preferences

IosSharedpreferences

Ios Problem Overview


I am porting an Android app to iOS, one thing I used was the Shared Preferences in Android to save each time a level was complete.

That way when the user gets back into the app, they can see they are up to level 3 or whatever.

Is there a similar mechanism in iOS? or do I have to manually write out to an application specific file?

If so, how do I write out to files only visible to my application?

Thanks.

Ios Solutions


Solution 1 - Ios

Use NSUserDefaults: - note that this is for small bits of data, such as the current level like you mentioned. Don't abuse this and use it as a large database, because it is loaded into memory every time you open your app, whether you need something from it or not (other parts of your app will also use this).

Objective-C:

Reading:

NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];

NSString *currentLevelKey = @"currentlevel";

if ([preferences objectForKey:currentLevelKey] == nil)
{
	//	Doesn't exist.
}
else
{
	//	Get current level
	const NSInteger currentLevel = [preferences integerForKey:currentLevelKey];
}

Writing:

NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];

NSString *currentLevelKey = @"currentlevel";

const NSInteger currentLevel = ...;
[preferences setInteger:currentLevel forKey:currentLevelKey];

//	Save to disk
const BOOL didSave = [preferences synchronize];

if (!didSave)
{
	//	Couldn't save (I've never seen this happen in real world testing)
}

. Swift:

Reading:

let preferences = NSUserDefaults.standardUserDefaults()

let currentLevelKey = "currentLevel"

if preferences.objectForKey(currentLevelKey) == nil {
	//	Doesn't exist
} else {
	let currentLevel = preferences.integerForKey(currentLevelKey)
}

Writing:

let preferences = NSUserDefaults.standardUserDefaults()

let currentLevelKey = "currentLevel"

let currentLevel = ...
preferences.setInteger(currentLevel, forKey: currentLevelKey)

//  Save to disk
let didSave = preferences.synchronize()

if !didSave {
	//  Couldn't save (I've never seen this happen in real world testing)
}

Solution 2 - Ios

Here is an update for Swift 3

Reading

let preferences = UserDefaults.standard

let currentLevelKey = "currentLevel"
if preferences.object(forKey: currentLevelKey) == nil {
    //  Doesn't exist
} else {
    let currentLevel = preferences.integer(forKey: currentLevelKey)
}

Writing

let preferences = UserDefaults.standard

let currentLevel = ...
let currentLevelKey = "currentLevel"
preferences.set(currentLevel, forKey: currentLevelKey)

Update

From UserDefaults documentation > synchronize() waits for any pending asynchronous updates to the defaults database and returns; this method is now unnecessary and shouldn't be used.

Solution 3 - Ios

class Configuration {

    static func value<T>(defaultValue: T, forKey key: String) -> T{
    
        let preferences = UserDefaults.standard
        return preferences.object(forKey: key) == nil ? defaultValue : preferences.object(forKey: key) as! T
    }

    static func value(value: Any, forKey key: String){
    
        UserDefaults.standard.set(value, forKey: key)
    }

}

Example

//set
Configuration.value(value: "my_value", forKey: "key_1")

//get
let myValue = Configuration.value(defaultValue: "default_value", forKey: "key_1")

Solution 4 - Ios

As per the previous answer, you already know that UserDefaults is the equivalent to shared preferences in ios. You can create a common write function and for read create function based on data type. And call your required method from anywhere.

> ViewController.swift

 // write data
 writeAnyData(key: "MY_KEY", value: "MyData")
 // read string data 
 readStringData(key: "MY_KEY"), animated: true)

> Utils.swift

// read and write user default
let userDefault = UserDefaults.standard
// write
func writeAnyData(key: String, value: Any){
    userDefault.set(value, forKey: key)
    userDefault.synchronize()
}

// read int values
func readIntData(key: String) -> Int{
    if userDefault.object(forKey: key) == nil {
        return 0
    } else {
        return userDefault.integer(forKey: key)
    }
}

// read string values
func readStringData(key: String) -> String{
    if userDefault.object(forKey: key) == nil {
        return ""
    } else {
        return userDefault.string(forKey: key)!
    }
}
// read bool value
func readBoolData(key: String) -> Bool{
    if userDefault.object(forKey: key) == nil {
        return false
    } else {
        return userDefault.bool(forKey: key)
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionddoorView Question on Stackoverflow
Solution 1 - IosSomeGuyView Answer on Stackoverflow
Solution 2 - IosBenView Answer on Stackoverflow
Solution 3 - IosHasanagaView Answer on Stackoverflow
Solution 4 - IosMd Imran ChoudhuryView Answer on Stackoverflow