iOS UserNotifications通知管理---本地通知篇

iOS UserNotifications通知管理---本地通知篇

iOS 10對以前混亂的和通知相關(guān)的API進(jìn)行了統(tǒng)一,使用獨(dú)立的UserNotifications.framework來集中管理和使用iOS系統(tǒng)中通知的功能,在之前的基礎(chǔ)上增加了撤回單條通知,更新已展示過的通知,中途更新通知的內(nèi)容,在通知中展現(xiàn)圖片資源,自定義通知UI等一系列新功能,非常強(qiáng)大。這篇文章我們主要先介紹一下通知相關(guān)的【本地通知】,可以先下載一下Demo,配合著代碼看一下。

向用戶展示申請通知權(quán)限

[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError *__nullable error){
        //如果granted為YES 則說明申請成功
        if (granted) {
            NSLog(@"開通成功");
            [[UIApplication sharedApplication] registerForRemoteNotifications];
        } else {
            NSLog(@"開通失敗");
        }
    }];

獲取當(dāng)前通知權(quán)限的詳細(xì)信息

[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings){
        self.settings = settings; //self的setting的成員類型為:UNNotificationSettings
    }];

具體細(xì)節(jié)可以參照Demo中的AuthorizationViewController

發(fā)送一個通知

發(fā)送一個通知的步驟大體可以分為以下幾步:
1、創(chuàng)建一個新的發(fā)送通知內(nèi)容 UNMutableNotificationContent
2、創(chuàng)建一個通知發(fā)送的觸發(fā)類型,UNTimeIntervalNotificationTrigger(在一定時間后觸發(fā))、UNCalendarNotificationTrigger(在某月末日某時觸發(fā))、UNLocationNotificationTrigger(在用戶進(jìn)入或是離開某個區(qū)域時觸發(fā))
3、設(shè)置一個發(fā)送請求標(biāo)識符 NSSting
4、創(chuàng)建一個發(fā)送請求 UNNotificationRequest
5、將發(fā)送請求添加到發(fā)送中心 addNotificationRequest

具體代碼如下:

//創(chuàng)建通知內(nèi)容
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"發(fā)送通知";
    content.body = @"發(fā)送通知的內(nèi)容";
    
    //創(chuàng)建發(fā)送觸發(fā) (在一定時間后觸發(fā) 5秒)
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO];
    
    //設(shè)置一個發(fā)送請求標(biāo)識符
    NSString *identifier = @"timeInterVal";
    
    //創(chuàng)建一個發(fā)送請求
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger ];
    
    //
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *error){
        if (error) {
            NSLog(@"發(fā)送失敗%@",error);
        } else {
            NSLog(@"發(fā)送成功%@",error);
        }
    }];

具體細(xì)節(jié)可以參照Demo中的TimeIntervalViewController

通知管理

取消還未展示的通知

當(dāng)我們添加一個通知后,在這個通知觸發(fā)之前,我們有機(jī)會取消這個通知的發(fā)送。使用- (void)removePendingNotificationRequestsWithIdentifiers:(NSArray<NSString *> *)identifiers移除通知即可。(注意和【移除已經(jīng)展示過通知】接口的區(qū)別)

- (IBAction)pendingRemovalAction:(id)sender {
    
    //創(chuàng)建通知內(nèi)容
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"pendingRemoval";
    content.body = @"ljt&ths";
    
    //創(chuàng)建發(fā)送觸發(fā) 5秒后通知
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO];
    
    //設(shè)置一個發(fā)送請求標(biāo)識符
    NSString *identifier = @"pendingRemoval";
    
    //創(chuàng)建一個發(fā)送請求
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger ];
    
    //將發(fā)送請求添加到發(fā)送中心
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *error){
        if (error) {
            NSLog(@"發(fā)送失敗%@",error);
        } else {
            NSLog(@"發(fā)送成功%@",error);
        }
    }];
    
    //通知添加到通知中心之后可以在通知未發(fā)出的時間內(nèi)取消
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"移除通知請求 %@",identifier);
        [[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[identifier]];  //標(biāo)識符要一致
    });
}
更新還未展示的通知

當(dāng)我們頻繁展示同一類通知的時候,用戶會受到多條類似的通知,事實上,用戶只用關(guān)心最新的一條通知即可,而最新的通知框架就給我提供了方便的接口來更新已經(jīng)還未展示的通知,只用將相同標(biāo)識的通知再次添加到通知中心即可。

- (IBAction)pendingUpdateAction:(id)sender {
    //創(chuàng)建通知
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"pendingUpdate";
    content.body = @"ljt&ths";
    
    //創(chuàng)建發(fā)送觸發(fā) 5秒
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO];
    
    //創(chuàng)建通知標(biāo)識
    NSString *identifier = @"pendingUpdate";
    
    //創(chuàng)建一個發(fā)送通知請求
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
    
    //將發(fā)送通知請求添加到通知中心
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *error){
        if (error) {
            NSLog(@"發(fā)送失敗%@",error);
        } else {
            NSLog(@"發(fā)送成功%@",error);
        }
    }];
    
    //發(fā)送之后可以在通知未發(fā)出的時間內(nèi)取消  通知的標(biāo)識符要一致
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"準(zhǔn)備更新請求");
        //創(chuàng)建新的通知
        UNMutableNotificationContent *contentNew = [[UNMutableNotificationContent alloc] init];
        contentNew.title = @"pendingUpdate";
        contentNew.body = @"ths&ljt";
        
        //創(chuàng)建發(fā)送觸發(fā) 1秒
        UNTimeIntervalNotificationTrigger *triggerNew = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1.0 repeats:NO];
        
        //創(chuàng)建一個新的發(fā)送通知請求
        UNNotificationRequest *requestNew = [UNNotificationRequest requestWithIdentifier:identifier content:contentNew trigger:triggerNew];
        
        //將新的發(fā)送通知請求添加到通知中心
        [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:requestNew withCompletionHandler:^(NSError *error){
            if (error) {
                NSLog(@"發(fā)送失敗%@",error);
            } else {
                NSLog(@"發(fā)送成功%@",error);
            }
        }];
    });
}
移除已經(jīng)展示過的通知

移除已經(jīng)展示過的通知和取消還未展示的通知類似,只不過使用的方法不一樣,這里使用的是- (void)removeDeliveredNotificationsWithIdentifiers:(NSArray<NSString *> *)identifiers,注意和【取消未展示的通知】的區(qū)別

- (IBAction)deliveredRemovalAction:(id)sender {
    //創(chuàng)建通知
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"deliveredRemoval";
    content.body = @"ljt&ths";
    
    //創(chuàng)建發(fā)送觸發(fā) 5秒
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO];
    
    //創(chuàng)建通知標(biāo)識
    NSString *identifier = @"deliveredRemoval";
    
    //創(chuàng)建一個發(fā)送通知請求
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
    
    //將發(fā)送通知請求添加到通知中心
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *error){
        if (error) {
            NSLog(@"發(fā)送失敗%@",error);
        } else {
            NSLog(@"發(fā)送成功%@",error);
        }
    }];
    
    //發(fā)送之后并且通知已經(jīng)展示過,移除通知
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"移除通知請求 %@",identifier);
        [[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[identifier]];
    });
    
}
更新已經(jīng)展示過的通知

已經(jīng)展示過的通知,我們同樣也可更新,與【更新還未展示過的通知】一樣,我們創(chuàng)建一個新的通知,并把通知標(biāo)識設(shè)置為一樣,即可。

- (IBAction)deliveredUpdateAction:(id)sender {
    //創(chuàng)建通知
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"deliveredUpdate";
    content.body = @"ljt&ths";
    
    //創(chuàng)建發(fā)送觸發(fā) 5秒
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO];
    
    //創(chuàng)建通知標(biāo)識
    NSString *identifier = @"deliveredUpdate";
    
    //創(chuàng)建一個發(fā)送通知請求
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
    
    //將發(fā)送通知請求添加到通知中心
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *error){
        if (error) {
            NSLog(@"發(fā)送失敗%@",error);
        } else {
            NSLog(@"發(fā)送成功%@",error);
        }
    }];
    
    //發(fā)送之后并且通知已經(jīng)展示過,移除通知  通知的標(biāo)識符要一致
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(7.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"準(zhǔn)備更新請求");
        //創(chuàng)建新的通知
        UNMutableNotificationContent *contentNew = [[UNMutableNotificationContent alloc] init];
        contentNew.title = @"deliveredUpdate";
        contentNew.body = @"ths&ljt";
        
        //創(chuàng)建發(fā)送觸發(fā) 1秒
        UNTimeIntervalNotificationTrigger *triggerNew = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1.0 repeats:NO];
        
        //創(chuàng)建一個新的發(fā)送通知請求
        UNNotificationRequest *requestNew = [UNNotificationRequest requestWithIdentifier:identifier content:contentNew trigger:triggerNew];
        
        //將新的發(fā)送通知請求添加到通知中心
        [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:requestNew withCompletionHandler:^(NSError *error){
            if (error) {
                NSLog(@"發(fā)送失敗%@",error);
            } else {
                NSLog(@"發(fā)送成功%@",error);
            }
        }];
    });
}

具體細(xì)節(jié)可以參照Demo中的ManagementViewController

展示一個多媒體的通知

我們可以在通知中嵌入圖片或視頻資源,為本地通知添加多媒體內(nèi)容十分簡單,只需要通過本地磁盤上的文件URL創(chuàng)建一個UNNotificationAttachment對象,然后將這個對象放到數(shù)組中賦值給通知內(nèi)容的attachments屬性即可。

我們這里展示一個圖片:

- (IBAction)mediaAction:(id)sender {
    //創(chuàng)建通知內(nèi)容
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"media";
    content.body = @"show me an image!";
    
    
    //添加附件圖片資源
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"onevcat" ofType:@"jpg"];
    UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"onevcat" URL:[NSURL fileURLWithPath:imagePath] options:nil error:nil];
    content.attachments = @[attachment];
    
    //創(chuàng)建發(fā)送觸發(fā)
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO];
    
    //設(shè)置一個發(fā)送請求標(biāo)識符
    NSString *identifier = @"media";
    
    //創(chuàng)建一個發(fā)送請求
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger ];
    
    //將發(fā)送請求添加到發(fā)送中心
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *error){
        if (error) {
            NSLog(@"發(fā)送失敗%@",error);
        } else {
            NSLog(@"發(fā)送成功%@",error);
        }
    }];
}

在顯示時,橫幅或者彈框?qū)⒏綆гO(shè)置的圖片,使用3D Touch pop通知或者下拉通知顯示詳細(xì)內(nèi)容時,圖片會被放大展示。
除了顯示圖片,我們還可以顯示音頻和視頻。你可以將MP3或者M(jìn)P4格式的文件在通知中展示和播放,<strong>不過這些文件有尺寸限制,圖片不能超過10MB 視頻不能超過50MB.</strong>

具體細(xì)節(jié)可以參照Demo中的MediaViewController

前臺顯示通知

截止目前我們發(fā)送的通知必須將手機(jī)鎖屏或者進(jìn)入后臺,通知才會觸發(fā)。如果想讓通知在前臺顯示的話,需要做一些額外工作。
UNUserNotificationCenterDelegate提供了兩個方法,分別對應(yīng)如何在應(yīng)用內(nèi)展示通知和收到通知響應(yīng)時要如果處理的工作,我們可以實現(xiàn)這個接口中對應(yīng)的方法來處理展示或處理通知的邏輯。

//只有應(yīng)用在前臺收到通知時才會調(diào)用,可以設(shè)置通知是否需要展示
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
//當(dāng)用戶與推送的通知進(jìn)行交互時被調(diào)用,包括用戶通過通知打開了應(yīng)用或者觸發(fā)了某個action
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler

注意:因為涉及到打開應(yīng)用的行為,所以實現(xiàn)這個方法的delegate必須在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions返回前賦值。

這里我們先創(chuàng)建一個Notificationhandler對象,實現(xiàn)UNUserNotificationCenterDelegate協(xié)議。將Demo中出現(xiàn)的通知都設(shè)置為可以前臺顯示,當(dāng)用戶和通知交互時什么也不做。直接告訴系統(tǒng)完成了所有的工作。

//.h文件
@interface Notificationhandler : NSObject<UNUserNotificationCenterDelegate>

@end

//.m文件
@implementation Notificationhandler

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    
    NSString *identifier = notification.request.identifier;
    UNNotificationPresentationOptions options = UNNotificationPresentationOptionNone; //默認(rèn)什么也不做,不顯示
    if (identifier == nil) {
        completionHandler(options);
        return;
    }
    //項目中出現(xiàn)過的通知都設(shè)置為前臺可以顯示
    if ([identifier isEqualToString:@"timeInterVal"]) {
        options = UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert;
    } else if ([identifier isEqualToString:@"pendingRemoval"]) {
        options = UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert;
    } else if ([identifier isEqualToString:@"pendingUpdate"]) {
        options = UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert;
    } else if ([identifier isEqualToString:@"deliveredRemoval"]) {
        options = UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert;
    } else if ([identifier isEqualToString:@"deliveredUpdate"]) {
        options = UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert;
    } else if ([identifier isEqualToString:@"category"]) {
        options = UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert;
    } else if ([identifier isEqualToString:@"media"]) {
        options = UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert;
    } else if ([identifier isEqualToString:@"costomize"]) {
        options = UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert;
    } else {
        options = UNNotificationPresentationOptionNone;
    }
    //設(shè)置完成之后必須調(diào)用這個回調(diào),
    completionHandler(options);
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
    completionHandler(); //默認(rèn)什么也不做
}
@end

//AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    //設(shè)置代理
    self.handler = [[Notificationhandler alloc] init];
    [UNUserNotificationCenter currentNotificationCenter].delegate = self.handler;
    return YES;
}

如此一來,本Demo中出現(xiàn)過的通知,都可以前臺顯示了。

具體細(xì)節(jié)可以參照Demo中的Notificationhandler

交互通知

除了正常的發(fā)送通知之外,我們可以與發(fā)送的通知,進(jìn)行交互。通過將一簇action放到一個category中,并將這個category進(jìn)行注冊,當(dāng)我們發(fā)送通知的時候?qū)⑼ㄖ腸ategory設(shè)置為注冊過的category,即可實現(xiàn)。

我們先注冊一個category:

- (void)registerNotificationCategory {
    //我們設(shè)置了三個action 一個UNTextInputNotificationAction,兩個UNNotificationAction,每個action都有一個標(biāo)識符,
    NSArray *actionsArray = @[
                              [UNTextInputNotificationAction actionWithIdentifier:@"input" title:@"Input" options:UNNotificationActionOptionForeground textInputButtonTitle:@"Send" textInputPlaceholder:@"說點(diǎn)什么吧?"],
                              [UNNotificationAction actionWithIdentifier:@"goodbye" title:@"Goodbye" options:UNNotificationActionOptionForeground],
                              [UNNotificationAction actionWithIdentifier:@"cancel" title:@"Cancel" options:UNNotificationActionOptionForeground]];
    //注意注冊的category的標(biāo)識符為 ljtAction
    UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"ljtAction" actions:actionsArray intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    
    NSSet *set = [NSSet setWithObjects:category,nil];
    [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:set];
}

在啟動的時候我們需要進(jìn)行注冊:

//AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    //注冊category
    [self registerNotificationCategory];
    //設(shè)置代理
    self.handler = [[Notificationhandler alloc] init];
    [UNUserNotificationCenter currentNotificationCenter].delegate = self.handler;
    return YES;
}

這樣我們可以在發(fā)送通知的時候,設(shè)置通知的categoryIdentifier屬性:

- (IBAction)categoryAction:(id)sender {
    //創(chuàng)建一個通知內(nèi)容
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"category";
    content.body = @"ljt&ths";
    
    
    //設(shè)置交互類型 與注冊的category的標(biāo)識符一樣
    content.categoryIdentifier = @"ljtAction";
    
    //創(chuàng)建觸發(fā)時間
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO];
    
    //設(shè)置通知標(biāo)識
    NSString *identifier = @"category";
    
    //創(chuàng)建通知請求
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
    
    //將通知請求添加到通知中心中
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *error){
        if (error) {
            NSLog(@"發(fā)送失敗%@",error);
        } else {
            NSLog(@"發(fā)送成功%@",error);
        }
    }];
}

這樣一來我們在接收到通知的時候,通過使用3D Touch pop通知或者下拉通知顯示詳細(xì)內(nèi)容時,通知下方會出現(xiàn)我們之前設(shè)置的action。當(dāng)然這里只是顯示,我們還沒有提供交互的邏輯。那么怎么交互呢?這就需要我們之前設(shè)置的代理對象Notificationhandler,在其方法- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler中處理相應(yīng)的響應(yīng)邏輯:

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
    NSString *categoryIdentifier = response.notification.request.content.categoryIdentifier;
    //比較categoryIdentifier
    if ([categoryIdentifier isEqualToString:@"ljtAction"]) {
        //交互邏輯
        [self handlerAction:response];
    }
    completionHandler();
}

- (void)handlerAction:(UNNotificationResponse *)response {
    NSString *textStr = nil;
    NSString *actionIdentifier = response.actionIdentifier;
    if (actionIdentifier == nil || [actionIdentifier isEqualToString:@""]) {
        return;
    }
    
    if ([actionIdentifier isEqualToString:@"input"]) {
        textStr = [(UNTextInputNotificationResponse *)response userText];
    } else if ([actionIdentifier isEqualToString:@"goodbye"]) {
        textStr = @"goodbye";
    } else {
        textStr = @"none";
    }
    NSLog(@"收到通知:%@",textStr);
}

具體細(xì)節(jié)可以參照Demo中的CategoryViewController

自定義UI通知樣式

iOS中添加了很多extension,作為應(yīng)用與系統(tǒng)的入口。與通知相關(guān)的extension有兩個:Service Extension和Content Extension。前者可以讓我們有機(jī)會在收到遠(yuǎn)程推送通知后,展示之前對通知內(nèi)容進(jìn)行修改;后者可以用來自定義通知視圖的樣式。這篇主要介紹本地通知,所以我們主要介紹一下Content Extension。
首先我們新建一個Content Extension,并添加到項目中,Xcode會為我們生成一些模板代碼。
1、將自定義通知和通知的category綁定。
在Extension的info.plist中指定這個通知樣式的category標(biāo)識符,這個標(biāo)識符與我們發(fā)送通知時設(shè)置的categoryIdentifier要一致。

NSExtentsion-->NSExtensionAttributes-->UNNotificationExtensionCategory = cuntomUI   

系統(tǒng)在接收到通知之后會先查找有沒有處理這類通知的Content Extension,如果存在,那么就交給Extension來處理。
2、實現(xiàn)方法 - (void)didReceiveNotification:(UNNotification *)notification
系統(tǒng)收到通知后,需要顯示自定義樣式的通知詳情視圖,這個方法將被調(diào)用,通過獲取消息的通知的具體內(nèi)容userInfo,你可以在其中配置具體的UI樣式
3、雖然我們可以使用包括按鈕在內(nèi)的各種UI,但是系統(tǒng)不允許我們對這些UI進(jìn)行交互。點(diǎn)擊通知視圖UI本身會將我們導(dǎo)航到應(yīng)用中,不過我們可以通過action的方式來對茲定于UI進(jìn)行更新。通過方法- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption option))completionw我們可以知道那個action被調(diào)用,隨后就可以更新UI。
這個函數(shù)中需要注意的是在completion回調(diào)中我么可以傳遞三個入?yún)ⅲ?/p>

  • UNNotificationContentExtensionResponseOptionDoNotDismiss : 保持通知繼續(xù)被顯示
  • UNNotificationContentExtensionResponseOptionDismiss: 直接解散這個通知
  • UNNotificationContentExtensionResponseOptionDismissAndForwardAction: 將通知的action繼續(xù)傳遞給應(yīng)用的UNUserNotificationCenterDelegate中的- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler函數(shù)繼續(xù)處理。

具體細(xì)節(jié)可以參照Demo中的CustomizeViewController類和NotificationViewController

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容