Today Extensionを使用して iPhone アプリを開発しています。アプリには、から読み込み/に保存する Model モジュールがありますNSUserDefaults
。この情報をメイン アプリと拡張機能の両方で利用できるようにするため、アプリ グループを使用します。
let storage = NSUserDefaults(suiteName: "group.etc.etc.etc...")
アプリと拡張機能の両方が問題なく情報にアクセスできます。
メイン アプリは、ユーザーに提示するローカル通知を作成する場合があります。その通知には 2 つのアクションが関連付けられています ( UIUserNotificationAction
)。これらのアクションの 1 つが、メイン アプリのバックグラウンドで実行されるコードをトリガーします。そのコードは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()
}
}
さて、ここに私の問題があります:
メイン アプリは UILocalNotification をスケジュールします。今日のビューを開いて、今日のウィジェットを確認します。
通知が発生すると、画面上部にバナーが表示されます。
そのバナーを下にスライドして 2 つのアクションを表示し、前述の 1 つを選択します (今日のウィジェットはまだライブで画面に表示されています)。
アクションがバックグラウンドで正しく実行されていること、および の情報が変更されていることはわかっていますNSUserDefaults
。
ただし、today ウィジェットが常にアクティブで画面に表示されていても、リロード アクションはトリガーされません。さらに調査した結果、 が起動されていないことを確認できましNSUserDefaultsDidChangeNotification
た(ブレークポイントを配置しましたが、トリガーされず、他のチェックも行いました)。
通知アクションによって変更が行われていることがわかります。これは、(今日のビューを閉じてから開くことによって) ウィジェットを強制的にリロードすると、ウィジェットが正しく更新されるためです。
オンラインでさまざまなチュートリアルを見てきましたが、彼らが最初に言うことは、この通知を聞いて、「ウィジェットが同期するNSUserDefaults
」ようにウィジェットを更新することです。しかし、問題は、この通知は絶対に役に立たないということです! どうして??
注 1:今日のウィジェット内から NSUserDefaults の情報を変更すると、通知が正しく発生します。
注 2: 今日のウィジェットをデバッグするのはまったくひどいことです。ブレークポイントやクラッシュに反応する前に、Xcode に「名前でプロセスにアタッチ...」するように指示する必要があります。また、iOS は常にウィジェット用の新しいプロセスを作成しているため、Xcode に再度アタッチするように常に指示する必要があります。