Save an Object in Nsuserdefaults and Realm

Save an object in NSUserDefaults and Realm

Using Swift4's Codable protocol, you can save a custom class to UserDefaults without having to conform to the old NSCoding protocol.

class Team: Object, Codable {
@objc dynamic var id:Int = 0
@objc dynamic var name:String = ""
}

let team = Team()
team.id = 1
team.name = "Team"
let encodedTeam = try! JSONEncoder().encode(team)
UserDefaults.standard.set(encodedTeam, forKey: "team")
let decodedTeam = try! JSONDecoder().decode(Team.self, from: UserDefaults.standard.data(forKey: "team")!)

This solves the problem of multiple inheritance, since your type doesn't need to inherit from NSObject anymore.

How to save an array of objects to NSUserDefault with swift?

From the Property List Programming Guide:

If a property-list object is a container (that is, an array or dictionary), all objects contained within it must also be property-list objects. If an array or dictionary contains objects that are not property-list objects, then you cannot save and restore the hierarchy of data using the various property-list methods and functions.

You'll need to convert the object to and from an NSData instance using NSKeyedArchiver and NSKeyedUnarchiver.

For example:

func savePlaces(){
let placesArray = [Place(lat: 123, lng: 123, name: "hi")]
let placesData = NSKeyedArchiver.archivedDataWithRootObject(placesArray)
NSUserDefaults.standardUserDefaults().setObject(placesData, forKey: "places")
}

func loadPlaces(){
let placesData = NSUserDefaults.standardUserDefaults().objectForKey("places") as? NSData

if let placesData = placesData {
let placesArray = NSKeyedUnarchiver.unarchiveObjectWithData(placesData) as? [Place]

if let placesArray = placesArray {
// do something…
}

}
}

Is it possible to save an NSManagedObject in NSUserDefaults?

No, you should not store an NSManagedObject in NSUserDefaults. Core Data is an object persistence technology, so it doesn't make sense to try and persist an NSManagedObject in some other format.

There are few alternatives you can use:

  1. You could simply store the name of the lift in your user defaults and then query for this to get the object back from Core Data. This may not work for you if lift names aren't unique
  2. You can add an identifier attribute to your Lift entity and store something like a UUID string in that attribute; You can then store the same string in UserDefaults. This will ensure one object is selected uniquely.
  3. You can add a new boolean attribute to your Lift entity default and again use a query to retrieve it; You would need to ensure you only set the value to true on one lift at a time.
  4. You can use managedObject.objectId.uriRepresentation to get a URL that you can store as a string and then use to retrieve the object later. This is probably the most complex solution and I would suggest you try one of the other options.

iOS Swift Storing Realm Object to UserDefaults.standard

You'll need to supply conformance methods to NSCoding for your Realm models in order to be able to persist them to UserDefaults.

However, I'd encourage you to use Realm to persist Realm models given that you're already using Realm in your app.

Can I use Realm for all data storage, or should I use NSUserDefaults for storing username/password?

You should not store passwords or any sensitive information inside NSUserDefault, by using a simple file manager you can read all the data stored in it, it is really unsafe.
you don't even need a database or sort of. The right place to store sensitive info is the keychain of your device.

There are a lot of libs on github that can help you in using it.

Pay attention that what you save inside the keychain will persist even after you remove the application.

Trying to save custom object in UserDefaults using NSKeyedArchiver

Use JSONEncoder to save data to UserDefaults. Dummy code:

class YourClassName: Codable {
//Your properties here

func saveInPreference() {
do {
let jsonEncoder = JSONEncoder()
UserDefaults.standard.set(try jsonEncoder.encode(Your object here), forKey: "Write UserDefaultKey here")
UserDefaults.standard.synchronize()
}
catch {
print(error.localizedDescription)
}
}
}

Hope that helps!

@Faraz A. Khan comment if you have any questions in the above piece of code.

Save Dictionary into NSUserDefaults Swift

I managed to save my custom Dictionary using Realm!
Instead of a struct I use a different class like this:

import RealmSwift

class Sensors : Object {

dynamic var sensorName = ""
dynamic var sensorType = ""
dynamic var sensorSub = ""

}

and then I fill it like this:

    var useOfRealm = try! Realm() 
var allSensors = useOfRealm.objects(Sensors.self)
var saving = Sensors()
func fillThis() {
try! useOfRealm.write {

saving.sensorName = "something"
saving.sensorType = "something"
saving.sensorSub = "something"

useOfRealm.add(saving)
}
}

Use the function with parameters so you can fill the 'Dictionary' Dynamically.

Use allSensors so you can retrieve everything that you want.

Swift saving and retrieving custom object from UserDefaults

Swift 4 or later

You can once again save/test your values in a Playground


UserDefaults need to be tested in a real project. Note: No need to force synchronize. If you want to test the coding/decoding in a playground you can save the data to a plist file in the document directory using the keyed archiver. You need also to fix some issues in your class:



class Person: NSObject, NSCoding {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
required init(coder decoder: NSCoder) {
self.name = decoder.decodeObject(forKey: "name") as? String ?? ""
self.age = decoder.decodeInteger(forKey: "age")
}
func encode(with coder: NSCoder) {
coder.encode(name, forKey: "name")
coder.encode(age, forKey: "age")
}
}

Testing:

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

do {
// setting a value for a key
let newPerson = Person(name: "Joe", age: 10)
var people = [Person]()
people.append(newPerson)
let encodedData = try NSKeyedArchiver.archivedData(withRootObject: people, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "people")
// retrieving a value for a key
if let data = UserDefaults.standard.data(forKey: "people"),
let myPeopleList = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [Person] {
myPeopleList.forEach({print($0.name, $0.age)}) // Joe 10
}
} catch {
print(error)
}

}
}


Related Topics



Leave a reply



Submit