I am converting my app from Objective-C to Swift and I am having a problem unarchiving (in Swift) my persist objects that were previously archived in Objective-C. For example, I have an NSMutableDictionary file that was archived with the following Objective-C code:
NSString *indexFilename = "somefilename";
NSMutableDictionary *index = [NSMutableDictionary dictionary];
// Dictionary gets populated...
// Save it...
[NSKeyedArchiver archiveRootObject:index toFile:indexFilename];
These files are unarchived just fine in the Objective-C version of the app with:
NSMutableDictionary *index = nil;
if ([[NSFileManager defaultManager] fileExistsAtPath:indexFilename]) {
index = [NSKeyedUnarchiver unarchiveObjectWithFile:indexFilename];
}
But in the new Swift version, the following code sets index to nil:
let filename = "somefilename"
var index = NSKeyedUnarchiver.unarchiveObjectWithFile(filename)
Should this just work or is there something else I need to do to unarchive these files successfully in Swift?
Thanks.
I hacked together a test project to see if I could reproduce your problem. Here’s my Objective-C side.
+ (void)hackPath:(NSString *)indexFilename {
NSMutableDictionary *index = [NSMutableDictionary dictionary];
index[@"a"] = @"A";
index[@"b"] = @"B";
BOOL success = [NSKeyedArchiver archiveRootObject:index toFile:indexFilename];
assert(success);
}
And here’s the Swift side.
let docDir = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
let docName = "hack-\(NSUUID().UUIDString).dat"
let docFile = docDir.URLByAppendingPathComponent(docName)
print("docName = \(docName)")
Hack.hackPath(docFile.path)
let index = NSKeyedUnarchiver.unarchiveObjectWithFile(docFile.path!)
print(index)
This prints:
docName = hack-7531C650-90CC-4196-A957-796B4C8FE639.dat
Optional({
a = A;
b = B;
})
indicating that Swift was able to decode the archive.
IIRC NSKeyedUnarchiver lets you allocate an instance and set a delegate on it to learn about and potentially override various events in the archiving process. That’s the way I usually debug problems like this.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"