EKEventStore.authorizationStatus(for:) 显示的对话框显然隐藏在覆盖层后面

Dialog box displayed by EKEventStore.authorizationStatus(for:) apparently hidden behind overlay

我的应用 application(_:didFinishLaunchingWithOptions:launchOptions:) 正在创建这样的 overlay

window.makeKeyAndVisible()
let launchStoryboard = UIStoryboard(name: "LaunchScreen", bundle: nil)
let overlayView = launchStoryboard.instantiateInitialViewController()!.view!
window.addSubview(overlayView)

Main.storyboard 中定义的应用程序初始视图控制器是 UITabBarController,其第一个选项卡包含 UINavigationControllerviewDidLoad() 的根视图控制器调用 EKEventStore.authorizationStatus(for:)

此时,应用程序似乎停止了,只有叠加层可见。当我停止该应用程序时,会出现询问是否应允许该应用程序访问日历的对话框。它显然隐藏在覆盖层下方。

如何确保对话框出现在屏幕的最前面,以便用户有机会回答其实际问题?

UPDATE 以下是有关回答问题的一般上下文的更多信息:应用程序委托中代码的原因是——除非它发生在之前的启动中-- 我需要提示用户输入服务器凭据,从服务器获取数据并将其中一些数据存储在 EKEvents 中。叠加层支持呈现视图控制器以获取用户的凭据(请参阅 here)。当从服务器接收到数据时,覆盖将被删除。尽管处于应用程序生命周期的早期阶段,但为了 UIApplication.shared.keyWindow 接收值,必须调用 makeKeyAndVisible。呈现所述视图控制器以获取凭据需要该值。

问题不在于对话框隐藏在叠加层后面,而是我同步调用了 EKEventStorerequestAccess(to:completion:)(通过在调用完成后等待信号量处理程序)在 application(_:didFinishLaunchingWithOptions:launchOptions:) 内。因此整个应用程序停止了,甚至没有显示对话框。

解决方案包括异步请求访问。以下方案目前已经足够好了:

  • 实例变量 calendarEventnil 如果对 EKCalendar 的访问尚未(尚未)授予
  • requestAccess(to:completion:)application(_:didFinishLaunchingWithOptions:launchOptions:)
  • 内部调用
  • calendarEventrequestAccess(to:completion:)
  • 的完成处理程序中设置为此 EKCalendar
  • 在读取或写入日历应用程序之前检查是否 calendarEvent != nil
  • 在 运行 循环的循环中调用 application(_:didFinishLaunchingWithOptions:launchOptions:) calendarEvent 仍然是 nil;应用程序的行为就好像日历是空的
  • 在 运行 的后续循环中设置了循环 calendarEvent;应用程序实际上只在后来的周期中写入日历