Crashing on passwordObject #26
Comments
I managed to get more details. It apparently does not like the archive. I will have to figure out how to determine if the NSData value will cause a crash or not before trying to use it. It would probably a good idea to ensure this method does a check as well. [NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive (0x61, 0x62, 0x63, 0x31, 0x32, 0x33, 0x0, 0x0)' |
Is the item you are trying to fetch through |
Basically, in order for |
I am working on figuring it out. |
The tests in the |
I cleared my keychain and now I can save and fetch the passwordObject property without the exception. It may have been caused by the data being saved with different formats, though I do not understand it since if it was stored as NSData, NSString or NSDictionary it should not fail with an exception. I wonder if there is a safer way to unarchive data from the keychain. Since there were items stored prior to moving back to SSKeyChain those may have been the cause. |
Again, |
Do you know of a way to determine what the blob is so if it is not something NSKeyedUnarchiver can handle it simply does not try? Crashing seems like a harsh penalty. I'd prefer it to provide a method which can set an error reference. |
@brennanMKE, have you tried wrapping the call in a |
It uses |
The way I would see NSKeyedUnarchiver being a real problem is initially storing the password as an NSString in version 1.0 of the application and then in 2.0 it is stored as an NSDictionary using NSCoding. Unarchiving the NSString would cause it to crash, so being able to detect what format it would help. I've seen apps which have failed and even crashed with new versions possibly because of a keychain issue like this. To prevent this problem what I may do is use a Service name of AppName-1.0 for version 1.0 and when version 2.0 comes out I would migrate all accounts in the AppName-1.0 Service over to AppName-2.0 and serialize the passwordObject appropriate for that version, then delete all accounts under AppName-1.0. This could even make sense if both versions are serializing an NSDictionary but the new version has a different value or a modified structure. It seems like a lot of work though. Do you think this is the only way to go? |
Right. I think about it the same as I would any database schema. I first try loading current data. If none is found you fallback, migrate to the newest form, then delete them once you successfully save. Going forward you could include a version number in the password object (if you are using a dictionary) that can indicate what the contents look like. |
I think I will do that and always use an NSDictionary and use one of the values as the version as you suggest. Thanks for the sanity check. |
I am using the code currently on the branch but when unarchiveObjectWithData: is called it causes an exception. I cannot explain it and I do not know how to get around it. The exception provides no information in the latest version of Xcode.
Any ideas?
if ([self.passwordData length]) {
return [NSKeyedUnarchiver unarchiveObjectWithData:self.passwordData];
}
return nil;
}
The text was updated successfully, but these errors were encountered: