当前位置: 首页 > 面试题库 >

NSUserDefaultsDidChangeNotification和Today扩展

公羊安怡
2023-03-14
问题内容

我正在开发带有 Today Extension 的iPhone应用 程序
。该应用程序具有一个Model模块,可从加载/保存到NSUserDefaults。由于我希望主应用程序和扩展程序都可以使用此信息,因此我使用了一个应用程序组:

let storage = NSUserDefaults(suiteName: "group.etc.etc.etc...")

应用程序和扩展程序都可以毫无问题地访问信息。

主应用有时可能会创建本地通知以呈现给用户。该通知有两个与之关联的动作(UIUserNotificationAction)。这些操作之一触发一些代码在主应用程序的后台运行。该代码将更改NSUserDefaults信息并触发同步。我的代码是这样的:

func application(application: UIApplication, handleActionWithIdentifier id: String?, forLocalNotification not: UILocalNotification, completionHandler: () -> ()) {
    // Interact with model here
    // New information gets saved to NSUserDefaults
    userDefaultsStorage.synchronize()
    completionHandler()
}

现在,在Today Ext。我自然会观察到对信息所做的任何更改,NSUserDefaults以便可以在小部件上重新加载界面:

override func viewDidLoad() {
    super.viewDidLoad()

    // ...

    NSNotificationCenter.defaultCenter().addObserverForName(NSUserDefaultsDidChangeNotification, object: nil, queue: NSOperationQueue.mainQueue()) { _ in
        self.reload()
    }
}

现在,这是我的问题:

  1. 主应用程序安排UILocalNotification。我打开今天视图,并查看我的今天小部件。

  2. 触发通知时,屏幕顶部会显示一条横幅。

  3. 我在该横幅上滑行以显示这两个动作,然后选择了我前面提到的一个动作(今天的小部件仍处于活动状态并显示在屏幕上)。

我知道事实是该操作在后台正确运行,并且正在对上的信息进行更改NSUserDefaults

但是,即使 Today窗口小部件
一直处于活动状态并一直显示在屏幕上,也不会触发任何重装操作。经过进一步调查,我可以证实,NSUserDefaultsDidChangeNotification
没有 被解雇(我把一个断点,并没有触发,并做了一些其他检查以及)。

我知道通知操作正在进行更改,因为如果我强制重新加载小部件(通过关闭和打开Today视图),则小部件会正确更新。

我在线上看过各种教程,他们说的第一件事就是听此通知并更新小部件,以使“小部件与NSUserDefaults
保持同步。但事实是,AFAICT的此通知绝对没有用!怎么会??

注1:当我改变的NSUserDefaults的信息 的今天正确插件的通知火灾。

注意2:调试今天的小部件绝对是可怕的,顺便说一句。始终有必要告诉Xcode“按名称附加处理…”,然后它才能对断点和崩溃作出反应。而且iOS一直在为该小部件创建新流程,因此我不得不不断告诉Xcode再次附加。


问题答案:

从这里的文档:

Cocoa包括两种类型的通知中心:NSNotificationCenter类在单个流程中管理通知。NSDistributedNotificationCenter类可在一台计算机上跨多个进程管理通知。

显然,包含应用程序和Today扩展是不同的进程,因为当您调试Today扩展时,您想附加包含应用程序的进程,但是NSNotificationCenter仅在单个进程中工作。

为了在包含应用程序和扩展程序之间进行通信,您可以使用 Darwin Notify Center
,其功能CFNotificationCenter类似于NSDistributedNotificationCenter,仅适用于osx。

想法是使用他们共享的组文件夹中的文件。在包含应用程序中,您可以将要发送的数据写入文件中,然后发布CFNotification,今天扩展名将接收到。

在今天的扩展中,用于CFNotificationCenterAddObserver观察者CFNotification,在接收到它后,将调用回调,其中由于回调是C样式函数而必须发布NSNotification,并且在收到此NSNotification后不能在CFNotification中传递“
userInfo”对象,它将开始从文件中读取数据,该文件用于更新Notification Center中的今日扩展视图。

您可以使用此github代码实现强制加载今天的扩展视图。这个对我有用。
这是一篇很棒的文章。http://www.atomicbird.com/blog/sharing-with-app-
extensions

另一种选择是使用setHasContent函数。计划本地标识符时,将content设置为false以隐藏视图,handleActionWithIdentifier将其设置为true以显示视图。这样,当您留在通知中心时,暂时不会看到该视图,但是当它看到时,它将是更新的数据。

let widgetController = NCWidgetController.widgetController()
widgetController.setHasContent(false, forWidgetWithBundleIdentifier: "YourTodayWidgetBundleIdentifier")

但是我认为整个问题很少见,不需要解决,因为您可以将更新的数据重新加载到通知中心,也可以切换到“通知”选项卡,再切换回“今天”选项卡。



 类似资料:
  • TODAY WEB 是一个轻量级 Web 框架 安装 <dependency> <groupId>cn.taketoday</groupId> <artifactId>today-web</artifactId> <version>2.3.6.RELEASE</version></dependency> Maven Central 案例 DEMO 文档 Wiki 使用说明 通过 

  • TODAY Context 是一个轻量级依赖注入框架。 使用说明 标识一个Bean 使用@Component 任意注解只要注解上有@Component注解就会标识为一个Bean不论多少层 @Target({ ElementType.TYPE, ElementType.METHOD })public @interface Component { /** @return bean name */

  • TODAY AOP 是一个轻量级 Aop 框架 安装 <dependency> <groupId>cn.taketoday</groupId> <artifactId>today-aop</artifactId> <version>1.0.5.RELEASE</version></dependency> Maven Central 案例 DEMO 使用说明 使用@Aspect标注

  • Today 学习指南 NG-ZORRO 是由阿里巴巴阿里云和计算平台事业部的小伙伴为 Ant Design 开发的 Angular 版本,是一个适用于构建中后台应用的组件库。本项目是 NG-ZORRO 的配套教程。如果你想要了解一下 NG-ZORRO 的使用姿势,或者你是 Angular 初学者,想要通过一个项目来锻炼自己的开发能力,欢迎你来学习一下我们的教程! 项目介绍 我们的教程项目要带大家编

  • TODAY Method Invoker 是一个 Java 字节码级别方法调用。 使用说明 public class TestHandlerInvoker { public static void main(String[] args) throws Exception { System.setProperty("cglib.debugLocation", "D:/debug");

  • 问题内容: 今天,扩展程序未在Swift应用程序中显示,但在Objective C应用程序中显示。 我要做的就是在故事板上添加一个UILabel,其中包含一些内容,用于快速,客观的c应用程序。 它是在我运行Objective C应用程序时显示的,而在我执行Swift应用程序时却没有显示。 我在这里想念什么吗? 问题答案: 您可以注释掉提供的init方法。 这将使您的扩展程序正常运行。这个问题似乎是