16

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()
    }
}

さて、ここに私の問題があります:

  1. メイン アプリは UILocalNotification をスケジュールします。今日のビューを開いて、今日のウィジェットを確認します。

  2. 通知が発生すると、画面上部にバナーが表示されます。

  3. そのバナーを下にスライドして 2 つのアクションを表示し、前述の 1 つを選択します (今日のウィジェットはまだライブで画面に表示されています)。

アクションがバックグラウンドで正しく実行されていること、および の情報が変更されていることはわかっていますNSUserDefaults

ただし、today ウィジェットが常にアクティブで画面に表示されていても、リロード アクションはトリガーされません。さらに調査した結果、 が起動されていないことを確認できましNSUserDefaultsDidChangeNotification(ブレークポイントを配置しましたが、トリガーされず、他のチェックも行いました)。

通知アクションによって変更が行われていることがわかります。これは、(今日のビューを閉じてから開くことによって) ウィジェットを強制的にリロードすると、ウィジェットが正しく更新されるためです。

オンラインでさまざまなチュートリアルを見てきましたが、彼らが最初に言うことは、この通知を聞いて、「ウィジェットが同期するNSUserDefaults」ようにウィジェットを更新することです。しかし、問題は、この通知は絶対に役に立たないということです! どうして??


注 1:今日のウィジェットから NSUserDefaults の情報を変更すると、通知が正しく発生します。

注 2: 今日のウィジェットをデバッグするのはまったくひどいことです。ブレークポイントやクラッシュに反応する前に、Xcode に「名前でプロセスにアタッチ...」するように指示する必要があります。また、iOS は常にウィジェット用の新しいプロセスを作成しているため、Xcode に再度アタッチするように常に指示する必要があります。

4

1 に答える 1