I thought I would be careful and try Swift in an existing Obj-C project by translating one class. And small, simple at that. Oh dear.
Transliterating the original obj-c into Swift should be easy, and it seemed so. Unfortunately, although the encoder in persistent storage works, it crashes with an EXC_BREAKPOINT error in the first line of the initializer.
IF (and caps intentionally) NSCoding / Swift gives the same persistent content as NSCoding / ObjC, then my entire version of obj-c should be able to read what is encoded by Swift and vice versa. This is not the case, and my perfectly working version of obj-c crashes when trying to read persistent storage from the Swift version. Of course, if NSCoding is done correctly, should it generate something in one that reads in the other? Otherwise, should there be separate protocols NSCodingSwift and NSCodingObjC?
So, to summarize, I can read / write in obj-c. I cannot write / obj -c and read / fast, and I can write / quickly read / obj -c, and I cannot read / write in swift.
Here are two versions:
let keyBeaconItemNameKey = "name" let keyBeaconItemUUIDKey = "uuid" let keyBeaconItemMajorValueKey = "major" let keyBeaconItemMinorValueKey = "minor" import UIKit import CoreLocation class SMBeaconItem : NSObject, NSCoding { var name : String! var uuid : NSUUID! var major : NSNumber! var minor : NSNumber! init(newName : String, newUUID : NSUUID, newMajor : NSNumber, newMinor : NSNumber ) { name = newName uuid = newUUID major = newMajor minor = newMinor } init( coder decoder : NSCoder!) { name = decoder.decodeObjectForKey(keyBeaconItemNameKey) as String uuid = decoder.decodeObjectForKey(keyBeaconItemUUIDKey) as NSUUID major = decoder.decodeObjectForKey(keyBeaconItemMajorValueKey) as NSNumber minor = decoder.decodeObjectForKey(keyBeaconItemMinorValueKey) as NSNumber } func encodeWithCoder( encoder: NSCoder!) { encoder.encodeObject(name, forKey:keyBeaconItemNameKey) encoder.encodeObject(uuid, forKey:keyBeaconItemUUIDKey) encoder.encodeObject(major, forKey:keyBeaconItemMajorValueKey) encoder.encodeObject(minor, forKey:keyBeaconItemMinorValueKey) } }
And the working original:
@implementation SMBeaconItem - (instancetype)initWithName:(NSString *)name uuid:(NSUUID *)uuid major:(CLBeaconMajorValue)major minor:(CLBeaconMinorValue)minor { self = [super init]; if (!self) { return nil; } _name = name; _uuid = uuid; _majorValue = major; _minorValue = minor; return self; } #pragma mark - Persistence - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (!self) { return nil; } _name = [aDecoder decodeObjectForKey:keyBeaconItemNameKey]; _uuid = [aDecoder decodeObjectForKey:keyBeaconItemUUIDKey]; _majorValue = [[aDecoder decodeObjectForKey:keyBeaconItemMajorValueKey] unsignedIntegerValue]; _minorValue = [[aDecoder decodeObjectForKey:keyBeaconItemMinorValueKey] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.name forKey:keyBeaconItemNameKey]; [aCoder encodeObject:self.uuid forKey:keyBeaconItemUUIDKey]; [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:self.majorValue] forKey:keyBeaconItemMajorValueKey]; [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:self.minorValue] forKey:keyBeaconItemMinorValueKey]; } @end
Thanks for any help you can give.