iOS本地推送簡介

序言

推送消息是APP中重要的一個部分,它可以在用戶不打開APP的情況下,告知用戶一些APP內的消息,甚至是進行一些簡易操作。推送一般分為兩種,本地推送遠程推送。本篇文章主要介紹本地推送。

UserNotification

在iOS10中,蘋果升級了推送系統,使推送不僅僅能顯示文字,還能夠顯示更多類型的信息,以及進行操作。因此,蘋果廢棄了UILocalNotification等API,而改用UserNotification來實現推送的功能。

讓我們先來看看UserNotification都由哪些部分組成。


UserNotifications庫目錄概覽

從上至下依次來解釋一下這些文件的作用。

  • 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庫,開發者還可以自定義推送展開頁面,限于篇幅,本篇文章就不作展開了。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容