【问题标题】:NSUserDefaultsDidChangeNotification not sentNSUserDefaultsDidChangeNotification 未发送
【发布时间】:2017-08-31 09:16:38
【问题描述】:

在 iOS 应用程序和 Today Extension 之间进行数据共享时,我遇到了一个问题,即当我更改 UserDefaults 时,主应用程序或扩展程序都不会发送 NSUserDefaultsDidChangeNotification。问题是我可以为我创建的 App Group 成功读取和写入数据到 UserDefaults。所以数据实际上是由应用程序和扩展程序共享的。但是永远不会触发(或检测到) UserDefaults 更改的通知。谁能告诉我可能是什么问题?

UserDefaults 中数据的写入

NSUserDefaults defaults = new NSUserDefaults("group.com.name1.name2",NSUserDefaultsType.SuiteName);
defaults.SetString("UPDATE " + DateTime.Now.Minute, "data");
defaults.Synchronize();

通知处理程序

NSNotificationCenter.DefaultCenter.AddObserver(
                NSValueTransformer.UserDefaultsDidChangeNotification, (notification) => {
    NSUserDefaults defaults = new NSUserDefaults("group.com.name1.name2",NSUserDefaultsType.SuiteName);
    string str = defaults.StringForKey("data");  
});

【问题讨论】:

标签: ios xamarin xamarin.ios nsuserdefaults today-extension


【解决方案1】:

您可以使用容器应用中的CFNotificationCenter 向您的扩展应用发布跨进程通知。

共享常量:

const string id = "group.sushihangover";
const string key = "LastUpdateTime";

容器应用/在你的 NSUserDefaults 对象上设置一个观察者:

var todayWidgetUserDefaults = new NSUserDefaults(id, NSUserDefaultsType.SuiteName);

NSValueTransformer.Notifications.ObserveUserDefaultsDidChange(todayWidgetUserDefaults,(sender, e) => 
{
     CFNotificationCenter.Darwin.PostNotification(id, todayWidgetUserDefaults, null, true, true);
});

今日扩展应用:

var todayWidgetUserDefaults = new NSUserDefaults(id, NSUserDefaultsType.SuiteName);

void ObserverAction(string notificationId, NSDictionary userInfo)
{
    if (notificationId == id)
    {
        Console.WriteLine(todayWidgetUserDefaults.StringForKey(key));
    }
}
var observerToken = CFNotificationCenter.Darwin.AddObserver(id, todayWidgetUserDefaults, ObserverAction, CFNotificationSuspensionBehavior.DeliverImmediately);

注意:App Group 权利必须在您的容器应用和 Today Extension 应用中设置。

【讨论】:

  • 我尝试了您的解决方案,但不幸的是它仍然无法正常工作。这可能是由于我使用模拟器测试的事实造成的吗?
  • @tomkou 在模拟器上运行良好。当然,你只能调试一个进程,当你离开今天屏幕时,iOS 会停止你的扩展,所以在你的 Today 扩展上启动一个调试会话,在 ObserverAction 中放置一个断点,然后转到你的容器应用程序,修改一个 NSUserDefault 键/值(即通过内部按钮触摸),现在返回手机的“今日”屏幕,以便您的扩展程序再次运行,您应该会收到更改通知。
  • @SushiHangover 非常感谢。这对我帮助很大。在新的推送消息到达后,使用它从我的通知服务扩展通知我的视图。
【解决方案2】:

所以,SushiHangover 提供了完美的工作代码。 但是,问题出在Info.plist 文件中。为了能够交换通知,应为具有Remote Notification 功能的应用启用Background Mode。这听起来像是一件很明显的事情,但是我阅读的使用User Defaults 在扩展程序和应用程序之间交换数据的教程都没有提到这一点。也许,这是一件显而易见的事情。但我写这篇文章是为了以防万一有人也错过了这件事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-01
    • 2013-05-28
    • 2013-03-31
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多