I have an ObjC iOS app in which I archive/unarchive data. The data in question comes from a companion server. Each user gets a different set of data.
While I've never had a user complaint, I see a very small number of crashes reported via Crashlytics on this line:
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
The crash detail:
Fatal Exception: NSInvalidArgumentException
*** -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive (0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30)
The crash occurs in somewhere around 0.002% of sessions, but is most common among a small number of unknown users.
I found this relevant question: Archiving / Unarchiving results in initForReadingWithData incomprehensible archive. The discussion provides two reasonable theories for the cause; one that the archive contains the characters "bplist" (sounds very reasonable), and the other involving size of the archive (unlikely given the typical data set size).
I'm looking for suggestions on how to detect this situation and act in some way short of a crash. NSKeyedArchiver does not seem to have a method returning an error - a failed archive is a crash.
Ideally I prefer some mechanism to detect the root cause of the issue before it occurs. The frequency of this issue doesn't justify me writing my own archive parser, nor does it justify the risk of adding anything crazy that would be executed by all users.
I avoid @try
blocks out of practice. Obviously that's a possibility. The app reads this archive far more frequently than writing, so my thinking is to attempt a read (inside a @try
) just after the write, and if the read fails do something to report state details back to me. I'll also need to find another way to cache data for these users, but that's the easy part.