上下文
我一直在使用这个例子项目来玩今天的扩展。
这个应用程序非常简单:
我的目标是:每当在容器应用程序或小部件中发生数据更改时,我都希望两者都能反映这些更改:
实施
我理解,容器应用程序和扩展在各自的进程中运行,这意味着两个约束:
NSUserDefaultsDidChangeNotification没用。我还知道,为了访问共享容器,两个目标都必须选择进入同一组Id下的App。
数据访问由嵌入式框架TodoKit管理。它没有将属性保存在内存中,而是直接向NSUserDefaults获取适当的值:
public struct ShoppingItemStore: ShoppingStoreType {
private let defaultItems = [
ShoppingItem(name: "Coffee"),
ShoppingItem(name: "Banana"),
]
private let defaults = NSUserDefaults(suiteName: appGroupId)
public init() {}
public func items() -> [ShoppingItem] {
if let loaded = loadItems() {
return loaded
} else {
return defaultItems
}
}
public func toggleItem(item: ShoppingItem) {
let initial = items()
let updated = initial.map { original -> ShoppingItem in
return original == item ?
ShoppingItem(name: original.name, status: !original.status) : original
}
saveItems(updated)
}
private func saveItems(items: [ShoppingItem]) {
let boxedItems = items.map { item -> [String : Bool] in
return [item.name : item.status]
}
defaults?.setValue(boxedItems, forKey: savedDataKey)
defaults?.synchronize()
}
private func loadItems() -> [ShoppingItem]? {
if let loaded = defaults?.valueForKey(savedDataKey) as? [[String : Bool]] {
let unboxed = loaded.map { dict -> ShoppingItem in
return ShoppingItem(name: dict.keys.first!, status: dict.values.first!)
}
return unboxed
}
return nil
}
}问题所在
以下是起作用的原因:
这就验证了,我的应用程序组的设置是否正确。
然而,当我在主应用程序中改变一些东西,然后拉下Notification,它是完全不同步的。这就是我不明白的部分。
我的视图直接从共享容器中获取数据。每当发生更改时,我都会立即更新共享容器中的数据。
我遗漏了什么?我如何正确地同步这两者?我的数据访问类没有对任何状态进行管理,但我不明白为什么它的行为不正确。
更多信息
NSFilePresenter,尽管它看起来很麻烦,而且我还没有完全理解这个机制。我真的希望有一个比这个更简单的解决方案。发布于 2015-06-13 21:20:09
我在这里学到了两件事:
首先,总是重复检查您的权限,我的不知怎么搞砸了,这就是共享容器行为如此笨拙的原因。
第二:虽然没有调用viewWillAppear(_:),但当您关闭通知中心时,仍然可以从应用程序委托触发更新:
func applicationDidBecomeActive(application: UIApplication) {
NSNotificationCenter.defaultCenter().postNotificationName(updateDataNotification, object: nil)
}然后在您的视图控制器中:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
NSNotificationCenter.defaultCenter().addObserverForName(updateDataNotification, object: nil, queue: NSOperationQueue.mainQueue()) { (_) -> Void in
self.tableView.reloadData()
}
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}更新您的“今日”小部件很简单:每次拉下通知中心时,都会调用viewWillAppear(:_),以便您可以查询那里的新数据。
我将很快更新GitHub上的示例项目。
https://stackoverflow.com/questions/30822988
复制相似问题