Search code examples
iosversioninginfo.plistnsbundle

No "kCFBundleVersionKey" sometimes: all possible scenarios?


I have a code like this in my app:

NSString* version = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];

In most cases it works, and returns the Bundle version, but sometimes (let's say in 2% of cases) it returns nil.

The code is called within the function [AppDelegate application:didFinishLaunchingWithOptions:], in Main thread, an app is in foreground.

I could imagine this being an Apple's bug with some file reading error, but the percentage is quite high as for a rare Apple bug. Also I know a one could mess with versions/bundles/Info.plist - but the percentage is too small for such case.

So, the first question: what can be the reason of [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey] returning nil in this case?

The second question: do you know if these hypotheses make sense / are easy to check:

  1. The user launches an app the first time after update, and [NSBundle mainBundle] becomes fully configured after application:didFinishLaunchingWithOptions ?
  2. The app is in the process of an auto-update (from AppStore), the user opens it, and the system is currently writing a new data to Info.plist.
  3. Some background thread in my app is also reading the [NSBundle mainBundle], the system uses some weird lock, so the read from a Main thread fails.

UPD: I've seen this question, but it's not related.


Solution

  • By default all files of the application, on a device that uses content protection, are encrypted. If you try to read them before they are decrypted(by the OS) you will get nil. The files are decrypted and they are available shortly after the user unlocks her phone, this might change and be more strict if you set a different value for the data protection entitlement. So the data might not be available when the application launches because they are not yet decrypted. This might be one reason that you get nil some times, the solution would be to wait to be notified in the app delegate that they data are ready before you read them.

    The answers to all parts of the second questions are NO. There is no documented configuration that the app needs to do after an update that might affect the main Bundle. The user can not open an application if it is in the process of updating. The access to the main Bundle is thread-safe.