序言
推送消息是APP中重要的一個部分,它可以在用戶不打開APP的情況下,告知用戶一些APP內的消息,甚至是進行一些簡易操作。推送一般分為兩種,本地推送和遠程推送。本篇文章主要介紹本地推送。
UserNotification
在iOS10中,蘋果升級了推送系統,使推送不僅僅能顯示文字,還能夠顯示更多類型的信息,以及進行操作。因此,蘋果廢棄了UILocalNotification等API,而改用UserNotification來實現推送的功能。
讓我們先來看看UserNotification都由哪些部分組成。
從上至下依次來解釋一下這些文件的作用。
NSString+UserNotifications.h
該文件是NSString的Category,提供了一個方法用來將文本信息進行本地化處理。UNError.h
該文件定義了一個枚舉類UNErrorCode,用來標示不同種類的錯誤。UNNotification.h
這個類是推送的基礎類。UNNotificationAction.h
這個類定義了推送通知中的交互操作。
它還有個子類UNTextNotificationAction,負責定義推送通知中的文本框。UNNotificationAttachment.h
這個類定義了推送通知中的附件。UNNotificationCategory.h
這個類定義了推送通知的類別,與UNNotificationAction搭配使用。UNNotificationContent.h
這個類定義了推送通知中的內容。
它還有個子類UNMutableNotificationContent,是可變版本。UNNotificationRequest.h
這個類是用來發起推送請求的UNNotificationResponse.h
這個類是在推送的回調中用來返回一些信息的。UNNotificationServiceExtension.h
這個類是在收到遠程推送后更改推送內容再向用戶展示的。UNNotificationSettings.h
這個類定義了推送通知的詳細設置,例如聲音、彈窗、紅點等。UNNotificationSound.h
這個類定義了推送通知的聲音。UNNotificationTrigger.h
這個類定義了推送通知的觸發器。
它有個子類UNPushNotificationTrigger,定義了基于遠程推送的觸發器。
它有個子類UNTimeIntervalNotificationTrigger,定義了基于定時器的觸發器。
它有個子類UNCalendarNotificationTrigger,定義了基于日期的觸發器。
它有個子類UNLocationNotificationTrigger,定義了基于位置的觸發器。UNUserNotificationCenter.h
這個類定義了管理中心,管理所有推送通知的行為。UserNotifications.apinotes
包含了這個模塊的一些注釋,主要是方便swift調用框架時的映射。UserNotifications.h
該文件引入了上述頭文件,方便外界引用。
實際應用
1. 獲取用戶授權
[[UNUserNotificationCenter currentNotificationCenter]requestAuthorizationWithOptions:UNAuthorizationOptionAlert|
UNAuthorizationOptionSound|
UNAuthorizationOptionBadge|
UNAuthorizationOptionCarPlay
completionHandler:^(BOOL granted, NSError * _Nullable error) {
//granted代表用戶是否同意授權。
}];
UNAuthorizationOptions的定義如下,每一條的作用已經標在注釋里
typedef NS_OPTIONS(NSUInteger, UNAuthorizationOptions) {
UNAuthorizationOptionBadge = (1 << 0),//是否可以更新App的小紅點
UNAuthorizationOptionSound = (1 << 1),//是否可以播放聲音
UNAuthorizationOptionAlert = (1 << 2),//是否可以顯示消息
UNAuthorizationOptionCarPlay = (1 << 3),//是否可以在車載模式下推送
UNAuthorizationOptionCriticalAlert __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 4),//是否可以播放警告消息的聲音
UNAuthorizationOptionProvidesAppNotificationSettings __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 5),//是否可以顯示推送設置的按鈕
UNAuthorizationOptionProvisional __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 6),//是否為臨時授權,臨時授權下用戶可以在收到推送的時候設置授權
UNAuthorizationOptionAnnouncement __API_AVAILABLE(ios(13.0), watchos(6.0)) __API_UNAVAILABLE(macos, tvos) = (1 << 7),//是否允許Siri自動播報
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0), tvos(10.0));
2. 帶文字的通知
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc]init];
content.title = [NSString localizedUserNotificationStringForKey:@"title" arguments:nil];
content.subtitle = [NSString localizedUserNotificationStringForKey:@"subtitle" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:@"body" arguments:nil];
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:10.0
repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"identifier"
content:content
trigger:trigger];
[[UNUserNotificationCenter currentNotificationCenter]addNotificationRequest:request
withCompletionHandler:^(NSError * _Nullable error) {
}];
顯示效果如下
3. 帶圖片的通知
在原有代碼上額外添加下面幾行
NSString *path = [[NSBundle mainBundle]pathForResource:@"TestImage" ofType:@"png"];
NSURL *URL = [NSURL fileURLWithPath:path];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment"
URL:URL
options:nil
error:nil];
content.attachments = @[attachment];
顯示效果如下
4. 帶視頻的通知
和帶圖片的通知是一樣的創建方式
NSString *path = [[NSBundle mainBundle]pathForResource:@"TestVideo" ofType:@"mov"];
NSURL *URL = [NSURL fileURLWithPath:path];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment"
URL:URL
options:nil
error:nil];
content.attachments = @[attachment];
顯示效果如下
5. 推送聲音設置
content.sound = [UNNotificationSound soundNamed:@"sound.caf"];//自定義聲音
//or
content.sound = [UNNotificationSound defaultSound];//默認聲音
//or
content.sound = [UNNotificationSound defaultCriticalSound];//默認警告聲
6. UNNotificationAction
UNNotificationAction * action = [UNNotificationAction actionWithIdentifier:@"action"
title:@"action"
options:UNNotificationActionOptionForeground];
NSArray *actionArr = @[action];
UNNotificationCategory * categoryNotification = [UNNotificationCategory categoryWithIdentifier:@"categoryOperationAction"
actions:actionArr
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
NSSet *categories = [NSSet setWithObject:categoryNotification];
[[UNUserNotificationCenter currentNotificationCenter]setNotificationCategories:categories];
content.categoryIdentifier = @"categoryOperationAction";
其中UNNotificationAction定義的是一個按鈕,動作,UNNotificationCategory則相當于一組Action的容器,方便管理。
UNNotificationActionOptions的定義如下。
typedef NS_OPTIONS(NSUInteger, UNNotificationActionOptions) {
// 該操作是否只能在一個已解鎖的設備上執行
UNNotificationActionOptionAuthenticationRequired = (1 << 0),
// 該操作是否是一個破壞性的操作,例如刪除
UNNotificationActionOptionDestructive = (1 << 1),
// 該操作是否會導致APP進入前臺
UNNotificationActionOptionForeground = (1 << 2),
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0)) __API_UNAVAILABLE(tvOS);
UNNotificationCategoryOptions的定義如下。
typedef NS_OPTIONS(NSUInteger, UNNotificationCategoryOptions) {
// 是否要讓Dismiss的操作也通過UNUserNotificationCenter的delegate回調
UNNotificationCategoryOptionCustomDismissAction = (1 << 0),
// 是否可以在車載模式中出現
UNNotificationCategoryOptionAllowInCarPlay __API_UNAVAILABLE(macos) = (1 << 1),
// 是否要顯示標題,即使用戶已經設置不可預覽通知
UNNotificationCategoryOptionHiddenPreviewsShowTitle __API_AVAILABLE(macos(10.14), ios(11.0)) __API_UNAVAILABLE(watchos, tvos) = (1 << 2),
// 是否要顯示副標題,即使用戶已經設置不可預覽通知
UNNotificationCategoryOptionHiddenPreviewsShowSubtitle __API_AVAILABLE(macos(10.14), ios(11.0)) __API_UNAVAILABLE(watchos, tvos) = (1 << 3),
// 是否允許Siri自動播報
UNNotificationCategoryOptionAllowAnnouncement __API_AVAILABLE(ios(13.0), watchos(6.0)) __API_UNAVAILABLE(macos, tvos) = (1 << 4),
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0)) __API_UNAVAILABLE(tvOS);
顯示效果如下
7. UNTextInputNotifactionAction
UNTextInputNotificationAction *action = [UNTextInputNotificationAction actionWithIdentifier:@"textAction"
title:@"textAction"
options:UNNotificationActionOptionNone
textInputButtonTitle:@"send"
textInputPlaceholder:@"placeholder"];
剩余代碼與UNNotificationAction的一樣。
點擊后會顯示輸入框,顯示效果如下
8. Action回調
Action的回調是通過UNNotificationDelegate中的方法返回的
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)(void))completionHandler {
if ([response isKindOfClass:[UNTextInputNotificationResponse class]]) {
UNTextInputNotificationResponse *textResponse = (UNTextInputNotificationResponse *)response;
NSString *text = textResponse.userText;
// text為用戶輸入的文本
} else {
if ([response.actionIdentifier isEqualToString:@"action"]) {
// 此為標識符為action的操作
}
}
completionHandler();
}
尾聲
創建一個本地推送的基本流程就是這樣,不過iOS上推送能做到的遠不止如此。通過UserNotificationsUI庫,開發者還可以自定義推送展開頁面,限于篇幅,本篇文章就不作展開了。