3

私の Mac アプリには、実行時間の長いエクスポート操作を実行するコードがあります。エクスポートの最後に、ユーザー通知を作成して、エクスポートが完了したことをユーザーに知らせます。

- (NSUserNotification*)deliverNotificationWithSound:(NSString*)sound title:(NSString*)title messageFormat:(NSString*)message {
    NSUserNotification * note = [NSUserNotification new];

    note.soundName = sound;
    note.title = title;
    note.informativeText = [NSString stringWithFormat:message, NSRunningApplication.currentApplication.localizedName, self.document.displayName];
    note.userInfo = @{ @"documentFileURL": self.document.fileURL.absoluteString };

    [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:note];
    return note;
}

次に、エクスポートに関する詳細 (発生した警告、便利な「表示」ボタンなど) を記載したシートを作成します。彼らがシートを閉じると、次のように通知を削除したいと思います。

[NSUserNotificationCenter.defaultUserNotificationCenter removeDeliveredNotification:note];

ただし、これによって実際に通知センターから通知が削除されるわけではありません。ブレークポイントを設定しました。-removeDeliveredNotification:行は実行され、nilnoteではありません。何を与える?

4

2 に答える 2

1

削除しようとしている通知は、deliveredNotifications配列内にある必要があります。ドキュメントを引用する-removeDeliveredNotification:

ユーザー通知が deliveryNotifications に含まれていない場合、何も起こりません。

を呼び出すと通知がコピーされる可能性がある-deliverNotification:ため、そのインスタンスへの参照を保持して後で削除しようとすると失敗する可能性があります。代わりに、通知のuserInfoプロパティに何かを隠して識別できるようにし、deliveredNotifications配列をスキャンして削除する通知を見つけます。


ブレントによって追加されました

これが私の質問のメソッドの修正版です。コピーを識別するために、整数にキャストされた元の通知のポインター値を使用しています。これは絶対確実ではありませんが、おそらく十分です。

- (NSUserNotification*)deliverNotificationWithSound:(NSString*)sound title:(NSString*)title messageFormat:(NSString*)message {
    NSUserNotification * note = [NSUserNotification new];

    note.soundName = sound;
    note.title = title;
    note.informativeText = [NSString stringWithFormat:message, NSRunningApplication.currentApplication.localizedName, self.document.displayName];
    note.userInfo = @{ @"documentFileURL": self.document.fileURL.absoluteString, @"originalPointer": @((NSUInteger)note) };

    [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:note];

    // NSUserNotificationCenter actually delivers a copy of the notification, not the original.
    // If we want to remove the notification later, we'll need that copy.
    for(NSUserNotification * deliveredNote in NSUserNotificationCenter.defaultUserNotificationCenter.deliveredNotifications) {
        if([deliveredNote.userInfo[@"originalPointer"] isEqualToNumber:note.userInfo[@"originalPointer"]]) {
            return deliveredNote;
        }
    }

    return nil;
}
于 2013-02-27T22:18:52.813 に答える
0

素晴らしい質問をありがとう。

1行のコードを使用するだけで機能するため、Appleは問題を修正したようです。

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: aryIdentifier)

ローカル通知をクリアするためにシミュレーターで 5 ~ 6 時間試しましたが、うまくいきませんでした。実際のデバイスでコードを実行すると、その魅力が気に入るはずです。

ハッピーコーディング。

于 2018-09-26T11:47:48.403 に答える