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:行已运行,并且note不为零。是什么赋予了?

4

2 回答 2

1

您尝试删除的通知必须在deliveredNotifications数组中。引用文档-removeDeliveredNotification:

如果用户通知不在 DeliverNotifications 中,则不会发生任何事情。

当您调用时,您的通知可能会被复制-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

谢谢你的好问题。

似乎 Apple 已解决问题,因为它可以通过使用单行代码为我工作。

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

我在模拟器中尝试了 5-6 个小时来清除本地通知,但没有运气。当我在实际设备中运行代码时,它会喜欢这种魅力。

快乐编码。

于 2018-09-26T11:47:48.403 回答