当用户更改联系人访问权限时,iOS 6中的应用程序崩溃了。

46

我有一个应用程序使用地址簿。在iOS 6上运行时,当用户执行需要访问地址簿的操作时,它会运行此代码。

if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
{
    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);

    ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error)
    {
        if (granted)
        {
            showContactChooser();
        }
    });

    CFRelease(addressBookRef);
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
{
    showContactChooser();
}
else
{
    showAccessDeniedAlert();
}

这段代码完美运行:我可以读取联系人信息,当用户拒绝访问时,应用程序做出了相应的反应。

然而,如果用户:

  1. 在应用中允许访问联系人,
  2. 退出应用,
  3. 转到“设置”-> “隐私”-> “联系人”,并禁用应用程序的联系人访问权限,
  4. 运行应用程序,
  5. 在应用程序在后台运行时进入设置并启用应用程序的联系人访问权限,

应用程序会立即在main()内崩溃,没有任何异常或有意义的堆栈跟踪。我尝试打开“所有异常”和[NSException raise]断点,但这并没有给我更多信息。

即使应用程序在启动期间没有运行上述代码,也可以重现崩溃。

这里发生了什么?我应该订阅哪个回调函数?


根据rmaddy的下面的回答,这不是崩溃,而是iOS终止了应用程序。 - Alexey Blinov
我也遇到了同样的问题,但是是关于我的应用程序的位置权限 :( - user1832451
2个回答

78

我在自己的应用程序中也看到了这种情况,而且我也看到其他人报告了这个问题。我相信这是有意的行为。操作系统会关闭任何对隐私权限变化做出反应的后台应用程序。苹果似乎采用了粗暴的方法。这不是崩溃(虽然在调试器中运行时可能会出现这种情况)。应用程序会因各种其他原因而终止。把它添加到原因列表中。这使我们有更多理由在应用程序完全重新启动时恢复应用程序状态。

请注意,此行为适用于所有不同的隐私设置,如联系人、照片、麦克风、日历和相机。


2
已验证在iOS 7.0.3上的照片安全设置也会出现此问题。这似乎是苹果的合理之举,我没有任何抱怨!有人知道在应用程序由于安全更新而崩溃之前运行后台代码以保存一些数据的方法吗? - Albert Renshaw
2
已验证,这在iOS 7.0.3中的麦克风安全设置中也会发生。 - Pavan
1
在 iOS 7 中与日历相关的应用程序中工作方式相同。如果您在设备上运行应用程序,而不是通过 Xcode 调试或模拟器,则会看到应用程序重新启动,对用户不可见。因此,正如 rmaddy 所说,只需确保您的应用程序在完全重新启动时“恢复应用程序状态的工作良好...” - leanne
这是故意的行为。如果您在应用程序运行时更改应用程序权限,它将被终止。 - russbishop

-2
通常情况下,当应用程序从挂起状态恢复时,它应该从您的AppDelegate调用application:didEnterForeground。在我看来,那将是一个很好的地方让您重新调整您的通讯录权限。

在我看来,最佳实践是在应用程序需要使用这些数据时(例如进入某个屏幕时)立即请求权限。 - Kacper Cz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接