gpt4 book ai didi

ios - NSUserDefaultsDidChangeNotification 和今天的扩展

转载 作者:IT王子 更新时间:2023-10-29 05:19:22 25 4
gpt4 key购买 nike

我正在开发一个带有 Today Extension 的 iPhone 应用程序。该应用程序有一个模型模块,可从 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()
}

现在,在今天的分机上。我很自然地观察到对 NSUserDefaults 上的信息所做的任何更改,以便我可以重新加载小部件上的界面:

override func viewDidLoad() {
super.viewDidLoad()

// ...

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

现在,这是我的问题:

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

  2. 当通知触发时,屏幕顶部会出现一个横幅。

  3. 我在该横幅上向下滑动以显示这两个操作,然后选择我之前提到的一个(今日小部件仍在屏幕上)。

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

但是,即使 today widget 一直处于事件状态并一直显示在屏幕上,也不会触发重新加载操作。经过进一步调查,我可以确认 NSUserDefaultsDidChangeNotification 没有被触发(我放置了一个断点但它没有触发,并且还做了一些其他检查)。

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

我在网上看过各种教程,他们说的第一件事就是收听此通知并更新小部件,以便“小部件与 NSUserDefaults 同步”。但问题是 AFAICT 这个通知绝对没用!怎么会??


注意 1:当我从 的今天小部件更改 NSUserDefaults 的信息时,通知会正确触发。

注意 2:顺便说一句,调试今天的小部件绝对是可怕的。在它可以对断点和崩溃使用react之前,总是需要告诉 Xcode“按名称附加到进程...”。 iOS 不断地为小部件创建一个新进程,所以我必须不断地告诉 Xcode 再次附加。

最佳答案

来自 doc这里:

Cocoa includes two types of notification centers: The NSNotificationCenter class manages notifications within a single process. The NSDistributedNotificationCenter class manages notifications across multiple processes on a single computer.

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

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

想法是使用他们共享的组文件夹中的文件。在包含应用程序中,您将要发送的数据写入文件,然后发布一个 CFNotification,今天的分机将收到该通知。

在今天的扩展中,使用CFNotificationCenterAddObserver 观察CFNotification,收到它后,回调将被调用,其中一个NSNotification 必须被发布,因为回调是一个C 风格的函数和“userInfo”不能传入CFNotification,收到这个NSNotification对象后,开始从文件中读取数据,用于更新通知中心的今天扩展 View 。

您可以使用这个 github code实现强制加载今天的扩展 View 。它对我有用。
这是一篇关于此的好文章。 http://www.atomicbird.com/blog/sharing-with-app-extensions

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

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

但我认为整个问题是极少数情况,不需要修复,因为您可以通过重新加载通知中心或切换到通知标签并切换回今天标签来获取更新数据。

关于ios - NSUserDefaultsDidChangeNotification 和今天的扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28284989/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com