iOS9~iOS10推送的變化詳解(一)

這兩天在做推送相關的功能,發現iOS10以后推送的變化還是很大的。在這里記錄下來,以供日后參考。

本文將以對比的形式來闡述iOS10本地推送的新特性。

準備工作

以下是判斷系統版本的宏定義,在后面要經常用到

#define IOS10_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0)

#define IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0)

#define IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

#define IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

一、推送注冊

iOS10以前

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];

[application registerUserNotificationSettings:settings];

iOS10以后

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

center.delegate = delegate;

[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {

if (granted) {

NSLog(@"注冊推送成功");

// 獲取注冊詳情

[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {

NSLog(@"注冊詳情-%@", settings);

}];

} else {

NSLog(@"注冊推送失敗");

if (error) {

NSLog(@"失敗詳情-%@",error.description);

}

}

}];

用戶同意推送通知以后,獲取設備DeviceToken的方法沒有變

// 注冊獲得device Token

[application registerForRemoteNotifications];

Appdelegate中會獲得DeviceToken的回調

// 獲得Device Token

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

NSString *deviceString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];

deviceString = [deviceString stringByReplacingOccurrencesOfString:@" " withString:@""];

NSLog(@"%@", [NSString stringWithFormat:@"設備Token: %@", deviceString]);

}

// 獲得Device Token失敗

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {

NSLog(@"注冊遠程推送(獲取Token)失敗: %@", error);

}

之后就可以對用戶進行推送了。

二、本地推送

iOS10以前

+ (void)creatLocalNotificationWithTitle:(NSString *)title subTitle:(NSString *)subTitle body:(NSString *)body userInfo:(NSDictionary *)userInfo fireDate:(NSDate *)fireDate repeatInterval:(NSCalendarUnit)repeatInterval {

UILocalNotification *notification = [[UILocalNotification alloc] init];

// 設置觸發通知的時間

notification.fireDate = fireDate;

// 時區

notification.timeZone = [NSTimeZone defaultTimeZone];

// 設置重復的間隔 iOS10以下無法基于自定義的時間重復,只能根據有限的枚舉進行重復NSCalendarUnit

notification.repeatInterval = repeatInterval;

// 通知內容

notification.alertBody = body;

notification.applicationIconBadgeNumber = 1;

// 通知被觸發時播放的聲音

notification.soundName = UILocalNotificationDefaultSoundName;

// 通知參數

notification.userInfo = userInfo;

// 執行通知注冊

[[UIApplication sharedApplication] scheduleLocalNotification:notification];

}

iOS10以后分為了兩種Trigger來創建一個本地通知

1.iOS10基于時間間隔,創建一個本地通知

+ (void)creatLocalNotificationWithTitle:(NSString *)title subTitle:(NSString *)subTitle body:(NSString *)body userInfo:(NSDictionary *)userInfo requestIdentifier:(NSString *)requestIdentifier afterTimeInterval:(NSTimeInterval)timeInterval repeats:(BOOL)repeats {

// 設置觸發條件 UNTimeIntervalNotificationTrigger

UNTimeIntervalNotificationTrigger *timeTrigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:timeInterval repeats:repeats];

// 創建通知內容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此對象為不可變對象。

UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];

content.title = title;

content.subtitle = subTitle;

content.body = body;

content.badge = @1;

content.sound = [UNNotificationSound defaultSound];

content.userInfo = userInfo;

// 創建通知請求 UNNotificationRequest 將觸發條件和通知內容添加到請求中

UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:timeTrigger];

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

// 將通知請求 add 到 UNUserNotificationCenter

[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {

if (!error) {

NSLog(@"推送已添加成功 %@", requestIdentifier);

}

}];

}

2.iOS基于日歷時間,創建一個本地通知

+ (void)creatLocalNotificationWithTitle:(NSString *)title subTitle:(NSString *)subTitle body:(NSString *)body userInfo:(NSDictionary *)userInfo requestIdentifier:(NSString *)requestIdentifier dateComponents:(NSDateComponents *)components repeats:(BOOL)repeats {

// 設置觸發條件 UNNotificationTrigger

UNCalendarNotificationTrigger *timeTrigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:repeats];

// 創建通知內容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此對象為不可變對象。

UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];

content.title = title;

content.subtitle = subTitle;

content.body = body;

content.badge = @1;

content.sound = [UNNotificationSound defaultSound];

content.userInfo = userInfo;

// 創建通知請求 UNNotificationRequest 將觸發條件和通知內容添加到請求中

UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:timeTrigger];

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

// 將通知請求 add 到 UNUserNotificationCenter

[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {

if (!error) {

NSLog(@"推送已添加成功 %@", requestIdentifier);

}

}];

}

這里在附上一個關于NSDateComponents類型的常用表達

/**

* 關于NSDateComponents類型

* components.month = 7; 表示7月

* components.weekOfMonth = 4; 表示7月第四周(標準從周日~周六是一周)

* components.weekday = 2; 表示每周第二天

* components.hour = 13; 表示下午1點

* components.minute = 52; 表示52分鐘

* 設置repeats=YES時,系統會按照如上規則進行重復提醒,缺省值忽略

*/

下面來說一下如何刪除或修改一個本地推送

iOS10以前

// 刪除某個指定通知

// 首先獲取所有通知

NSArray *notificaitons = [[UIApplication sharedApplication] scheduledLocalNotifications];

if (!notificaitons || notificaitons.count <= 0) {

return;

}

for (UILocalNotification *notify in notificaitons) {

// 這里的requestIdentifier是保存在userInfo當中的一個自己定義的字段,用來區分每個通知,每次刪除或修改都需要從所有的通知中進行遍歷,感覺很麻煩,iOS10就不用這樣了

if ([[notify.userInfo objectForKey:@"requestIdentifier"] isEqualToString:requestIdentifier]) {
// 取消一個特定的通知
[[UIApplication sharedApplication] cancelLocalNotification:notify];
break;
}
}

// 刪除所有通知
[[UIApplication sharedApplication] cancelAllLocalNotifications];

iOS10以后

// 刪除某個指定通知

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

// iOS10以后,requestIdentifier就變成了通知本身的一個屬性,可以通過系統提供的方法進行查詢獲取,不用再遍歷所有的通知了,方便了很多。修改通知只要創建一個同樣requestIdentifier的通知覆蓋原通知即可。

[center removePendingNotificationRequestsWithIdentifiers:@[requestIdentifier]];

[center removeDeliveredNotificationsWithIdentifiers:@[requestIdentifier]];

// 刪除所有通知

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

[center removeAllPendingNotificationRequests];

[center removeAllDeliveredNotifications];

以上只是最基本的添加和刪除操作,第二篇會詳說關于通知的樣式,Action的添加操作。

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

推薦閱讀更多精彩內容