我在 iOS 9 中请求日历访问时遇到了一个奇怪的情况。该逻辑在所有 iOS 10 设备上都运行良好。
在我们的示例中,我们在工具栏上添加了一个按钮,用户点击该按钮即可将事件添加到其日历中。
因此,在用户第一次点击“添加到日历”按钮之前,我们不会检查访问日历的权限。像这样:
@IBAction func addToCalendarPressed(_ sender: UIBarButtonItem) {
eventStore.requestAccess(to: .event, completion: { (granted, error) in
if (granted) && (error == nil) {
// Present the EKEventEditViewController
} else {
// Do something else (show an alert)
}
})
}
在 iOS 10 中,应用程序会按照您的预期显示日历访问提示。 在 iOS 9.x 中,不显示提示,完成处理程序立即触发,并授予返回 false。
更糟糕的是,即使“日历权限”检查似乎已完成,您也无法进入“设置”并手动启用日历访问。就设备而言,该应用程序从未进行过权限检查,因此该应用程序永远不会出现在“设置”>“隐私”>“日历”下。
我尝试将检查移至 viewWillAppear 或 viewDidLoad 中,而不是等待用户点击按钮,但它仍然不起作用。我已经提取了一些带有事件检查的示例应用程序,它们可以在 iOS 9 中运行。我只是无法弄清楚为什么提示在这种情况下失败。
该应用程序还会检查位置(但不在该屏幕上),并且这些在 iOS 9 中可以正常工作。
我们发现了问题。不知何故,我们的项目在 info.plist 中没有 CFBundleDisplayName。在开发的后期,在 Xcode 8 中打开项目添加了该属性,但将名称留空。
iOS 9 的日历权限和照片权限提示在权限提示中显示应用程序名称时都使用该值。
解决方法是简单地在 info.plist 中为 CFBundleDisplayName 设置 $(PRODUCT_NAME)。
我在 ios17 上也遇到了类似的问题。提示未显示,完成处理程序立即触发,并授予返回 false。 我在 info.plist 中缺少 NSCalendarsFullAccessUsageDescription
eventStore.requestFullAccessToEvents { [weak self] (granted, error) in
if granted {
// Access granted
} else {
// Access denied
}
}