【问题标题】:No "kCFBundleVersionKey" sometimes: all possible scenarios?有时没有“kCFBundleVersionKey”:所有可能的情况?
【发布时间】:2022-01-06 06:57:15
【问题描述】:

我的应用中有这样的代码:

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

在大多数情况下它有效,并返回 Bundle version,但有时(假设在 2% 的情况下)它返回 nil

代码在函数[AppDelegate application:didFinishLaunchingWithOptions:]中被调用,在主线程中,一个应用在前台。

我可以想象这是一个 Apple 的错误,带有一些文件读取错误,但与罕见的 Apple 错误相比,该百分比相当高。 我也知道一个人可能会弄乱版本/捆绑包/Info.plist - 但对于这种情况,百分比太小了。

那么,第一个问题:在这种情况下,[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey] 返回nil 的原因是什么?

第二个问题:你知道这些假设是否有意义/是否容易验证:

  1. 用户在更新后第一次启动应用,[NSBundle mainBundle] 变为完全配置之后 application:didFinishLaunchingWithOptions ?
  2. 应用正在自动更新(来自 AppStore),用户打开它,系统当前正在写入新数据到Info.plist
  3. 我的应用程序中的一些后台线程也在读取[NSBundle mainBundle],系统使用了一些奇怪的锁,因此从主线程读取失败。

UPD:我见过this question,但不相关。

【问题讨论】:

    标签: ios versioning info.plist nsbundle


    【解决方案1】:

    默认情况下,在使用内容保护的设备上,应用程序的所有文件都是加密的。如果您尝试在它们被解密(由操作系统)之前阅读它们,您将得到 nil。这些文件被解密,并且在用户解锁手机后很快可用,如果您为data protection entitlement 设置不同的值,这可能会改变并且更加严格。因此,当应用程序启动时,数据可能不可用,因为它们尚未解密。这可能是您有时会得到 nil 的一个原因,解决方案是等待app delegate 通知他们数据已准备好,然后再阅读它们。

    第二个问题所有部分的答案都是“否”。在可能影响主 Bundle 的更新之后,没有记录应用程序需要执行的配置。用户无法打开正在更新的应用程序。对主 Bundle 的访问是线程安全的。

    【讨论】:

    • 谢谢,您的回答看起来很棒。它极大地改善了我的头脑风暴结果。在我执行fix-AppStore release-crashlytics feedback 循环之前,我无法检查第一部分是否正确,但如果没有新想法出现,我肯定会在 2 天内奖励它。现在我刚刚投了赞成票,再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 2016-08-07
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    相关资源
    最近更新 更多