I have a class and inside the class is a (swift) array, based on a global struct. I want to save an array with this class to NSUserDefaults. This is my code:
struct mystruct {
var start : NSDate = NSDate()
var stop : NSDate = NSDate()
}
class MyClass : NSObject {
var mystructs : [mystruct]
init(mystructs : [mystruct]) {
self.mystructs = mystructs
super.init()
}
func encodeWithCoder(encoder: NSCoder) {
//let val = mystructs.map { $0 as NSObject } //this also doesn't work
let objctvtmrec = NSMutableArray(mystructs) //gives error
encoder.encodeObject(objctvtmrec)
//first approach:
encoder.encodeObject(mystructs) //error: [mystructs] doesn't conform to protocol 'anyobject'
}
}
var records : [MyClass] {
get {
var returnValue : [MyClass]? = NSUserDefaults.standardUserDefaults().objectForKey("records") as? [MyClass]
if returnValue == nil
{
returnValue = []
}
return returnValue!
}
set (newValue) {
let val = newValue.map { $0 as AnyObject }
NSUserDefaults.standardUserDefaults().setObject(val, forKey: "records")
NSUserDefaults.standardUserDefaults().synchronize()
}
}
I already subclassed to NSObject, and I know I need NSCoding. But I don't find any way to convert the struct array to an NSMuteableArray or something similar I can store. The only idea until now is to go through each entry and copy it directly to a new array or to use much or objective-c code all over the project, so i never need to convert from swift arrays to objective-c arrays. Both are things I don't want to do.
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.
Overview. The NSUserDefaults class provides a programmatic interface for interacting with the defaults system. The defaults system allows an app to customize its behavior to match a user's preferences. For example, you can allow users to specify their preferred units of measurement or media playback speed.
NSUserDefaults is ideal for storing small bits of information between app launches. Its API is very simple, and does its job well. It does show its Objective-C roots in Swift moreso than some other classes, but it still gets the job done.
In Swift, you define a structure or class in a single file, and the external interface to that class or structure is automatically made available for other code to use. An instance of a class is traditionally known as an object.
Just to make it clear, since they only differ by one letter, the first one listed as NSDat a, while the fourth one is an NSDat e. A property list, or NSUserDefaults can store any type of object that can be converted to an NSData object. It would require any custom class to implement that capability, but if it does, that can be stored as an NSData.
Structures and classes have a similar definition syntax. You introduce structures with the struct keyword and classes with the class keyword. Both place their entire definition within a pair of braces: Whenever you define a new structure or class, you define a new Swift type.
Swift structs are not classes, therefore they don't conform to AnyObject
protocol. You have to rethink your approach. Here are some suggestions:
Convert your struct
to final class
to enforce immutability
final class MyStruct {
let start : NSDate = NSDate()
let stop : NSDate = NSDate()
}
encoder.encodeObject(mystructs)
Map them as an array dictionaries of type [String: NSDate]
let structDicts = mystructs.map { ["start": $0.start, "stop": $0.stop] }
encoder.encodeObject(structDicts)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With