从“今天”扩展中调度本地通知

我正在制作一个包含Today Extension的应用程序。 今天的扩展显示了一个定时器的列表,如果用户select一个定时器,我想为该定时器创build和安排本地通知。

我的问题是通知的安排是用这行代码完成的:

UIApplication.sharedApplication().scheduleLocalNotification(notification) 

这非常不幸地依赖于UIApplication.sharedApplication() ,它不能从扩展中访问。

所以我的问题是: 我怎样才能从一个今天延长安排一个本地通知?

有趣的是,我可以用我的应用程序和我的扩展之间的代码共享一个框架,在这个框架中,我可以调用:

 func schedule() { // ... let settings = UIUserNotificationSettings(forTypes: .Sound | .Alert, categories: nil) UIApplication.sharedApplication().registerUserNotificationSettings(settings) // ... UIApplication.sharedApplication().scheduleLocalNotification(notification) // ... } 

如果我然后从我的扩展中导入该框架,并调用schedule()我得到这个输出:

 Failed to inherit CoreMedia permissions from 13636: (null) Attempting to schedule a local notification <UIConcreteLocalNotification: 0x7feaf3657a00>{fire date = Saturday, November 1, 2014 at 1:01:48 PM Western European Standard Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, November 1, 2014 at 1:01:48 PM Western European Standard Time, user info = (null)} with an alert but haven't received permission from the user to display alerts Attempting to schedule a local notification <UIConcreteLocalNotification: 0x7feaf3657a00>{fire date = Saturday, November 1, 2014 at 1:01:48 PM Western European Standard Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, November 1, 2014 at 1:01:48 PM Western European Standard Time, user info = (null)} with a sound but haven't received permission from the user to play sounds 

因此,在扩展模块中运行的模块可以访问UIApplication.sharedApplication()因为这段代码实际上是试图安排一个通知,但是系统没有准备好请求显示警报的权限的扩展,所以它失败了(这就是它似乎无论如何)。

我该如何解决这个问题?

此外,我知道我可以启动我的应用程序使用一个url,并安排通常从应用程序的通知,但这不是用户firendly。 有了今天的扩展的全部目的是使用户不必打开应用程序安排通知。 交互必须是快速,简单和透明的,将用户从他们所在的应用程序中拖出来,只需要运行几行代码,然后完成它就不是我想要做的事情。

我认为这可能成为可能,如果你这样做:

  1. 每当你想安排一个本地的通知,让你今天的扩展创build通知,并将其信息写入共享容器中的文件。

  2. (你需要一个服务器)联系你的服务器forms你今天的扩展,请求你的服务器发送一个简单的推送通知(content-available:1),然后将唤醒你的主应用程序。

  3. 当您的应用程序被远程通知唤醒时,从共享容器中读取从第1步创build的文件,安排本地通知,然后返回到睡眠状态。

这是不太可能的工作。 应用程序扩展名不允许访问sharedApplication 。 事实上,可以防止编译器注意到你正在这样做并不会改变这一点。 如果你在debugging器中试试这个,我猜这个sharedApplication实际上是返回零,这就是代码失败的原因。

如果你find一些方法来使其工作,不要依靠它。 苹果几乎可以肯定地认为这是一个错误,并在未来的版本中修复它,不加警告地打破你的扩展

如果有人来这个问题,这是现在可以在iOS 10中实现,它是新的UserNotifications框架。 要从您的应用扩展程序安排本地通知,您可以从您的扩展中调用以下代码行:

 UNUserNotificationCenter.current().add(<#UNNotificationRequest#>)