1

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.

Community
  • 1
  • 1
Mitch Cohen
  • 1,551
  • 3
  • 15
  • 29

1 Answers1

0

While the use of try/catch should be somewhat rare, this is a perfectly valid use case for its use. It's bad for your app to crash due to an unexpected file. It's something your app should handle and can easily recover from. Catch the exception from trying to unarchive a bad file and report an appropriate error to the user or handle it in some other appropriate fashion.

I do the same in one of my apps in code where I unzip a zip file a user can import into the app. The user could have imported something other than a zip file. So I wrap the unzip code with try/catch. The catch basically displays an error to the user letting them know the zip file wasn't valid.

rmaddy
  • 314,917
  • 42
  • 532
  • 579