本地通知常用來作為本地提醒,提醒使用者待辦事項,事物提醒,位置提示等功能
iOS 10.0前,本地通知通知使用的是UILocalNotification
,10.0後,蘋果推送了專門使用者通知提醒的庫UserNotificaiton.framework
1.使用 UILocalNotification
在iOS8.0
之前,通知許可權預設開啟,可直接使用,但是之後想要使用通知功能,必須提示使用者開啟通知許可權,所以首先需要註冊通知,
在didFinishLaunchingWithOptions
中
if ([[UIDevice currentDevice].systemVersion doubleValue]>=8.0) {
// iOS8以後 本地通知必須註冊(獲取許可權)
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:settings];
}
複製程式碼
接下來我們需要新增通知觸發行為,呼叫本地通知
1.建立本地通知例項
UILocalNotification * localNoty = [[UILocalNotification alloc]init];
複製程式碼
2.本地通知屬性設定
/* 本地通知觸發時間 */
localNoty.fireDate = [NSDate dateWithTimeIntervalSinceNow:4.0];
/* 通知提示框 */
localNoty.alertBody = @"提示文字";
/* 通知提示title */
localNoty.alertTitle = @"提示框內容";
/* 通知提示音 */
localNoty.soundName = UILocalNotificationDefaultSoundName;
/* 這裡接到本地通知,badge變為1 */
localNoty.applicationIconBadgeNumber = 1;
// 設定額外資訊,appdelegate中收到通知,可以根據不同的通知的額外資訊確定跳轉到不同的介面
localNoty.userInfo = @{@"notifaication":@"我是一條本地推送"};
複製程式碼
還有其他不常用的屬性,如timeZone
時區
repeatInterval
多長時間重複一次:一年,一個世紀,一天..
region
區域 : 傳入中心點和半徑就可以設定一個區域(如果進入這個區域或者出來這個區域就發出一個通知)
regionTriggersOnce
BOOL 預設為YES, 如果進入這個區域或者出來這個區域 只會發出 一次 通知,以後就不傳送了。
alertAction
: 設定鎖屏狀態下本地通知下面的 滑動來 ...字樣 預設為滑動來檢視
hasAction
: alertAction的屬性是否生效
alertLaunchImage
: 點選通知進入app的過程中顯示圖片,隨便寫,如果設定了(不管設定的是什麼),都會載入app預設的啟動圖
alertTitle
: 以前專案名稱所在的位置的文字: 不設定顯示專案名稱, 在通知內容上方
soundName
: 有通知時的音效 ,UILocalNotificationDefaultSoundName預設聲音
可以更改這個聲音: 只要將音效匯入到工程中,呼叫localNote.soundName = @"111.waw"
3.呼叫通知
[[UIApplication sharedApplication] scheduleLocalNotification:localNoty];
複製程式碼
通知發起後,我們需要接受本地通知,一般在AppDelegate
或者其分類中新增實現方法。
一般通知的接受分為三種:
1.前臺接收
2.後臺未殺死程式進入前臺接收
3.程式已經殺死,點選通知訊息啟動app
針對前兩中情況,app的程式仍在執行狀態,在didReceiveLocalNotification
方法中,新增執行程式碼,這裡可以通過application
的applicationState
屬性來判斷當前的執行狀態,一般執行的操作是app前臺執行彈出提示框,後臺執行點選通知進入前臺直接執行。可以通過notification.userInfo
來獲取傳送通知的userInfo
。
針對第三種情況,需要在didFinishLaunchingWithOptions
,程式啟動過程中新增執行方法
/* launchOptions: 1.點選圖示開啟是空的
2.應用間跳轉是有值的
3.殺死的應用接收到本地通知,也是有值的
雖然說launchOptions有值,但是他們不同的key有值
*/
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { // 如果這個key有值,代表是殺死的程式接收到本地通知跳轉
// 檢視launchOptions內容
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"本地通知" message:[NSString stringWithFormat:@"%@",launchOptions] delegate:self cancelButtonTitle:@"知道了" otherButtonTitles: nil];
[alert show];
NSLog(@"跳轉到指定頁面");
}
複製程式碼
UIApplicationLaunchOptionsLocalNotificationKey
這個屬性是啟動的時候用來判斷啟動來源的,Keys used to access values in the launch options dictionary passed to the application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: methods of the app delegate.
具體說明如下
UIApplicationLaunchOptionsURLKey
// A key indicating that the app was launched so that it could open the specified URL.
UIApplicationLaunchOptionsSourceApplicationKey
// A key indicating that another app requested the launch of your app.
UIApplicationLaunchOptionsRemoteNotificationKey
// A key indicating that a remote notification is available for the app to process.
UIApplicationLaunchOptionsLocalNotificationKey
// A key indicating that the app was launched to handle a local notification.
Deprecated
UIApplicationLaunchOptionsAnnotationKey
// A key indicating that the URL passed to your app contained custom annotation data from the source app.
UIApplicationLaunchOptionsLocationKey
// A key indicating that the app was launched to handle an incoming location event.
UIApplicationLaunchOptionsNewsstandDownloadsKey
// A key indicating that the app was launched to process newly downloaded Newsstand assets.
UIApplicationLaunchOptionsBluetoothCentralsKey
// A key indicating that the app was relaunched to handle Bluetooth-related events.
UIApplicationLaunchOptionsBluetoothPeripheralsKey
// A key indicating that the app should continue actions associated with its Bluetooth peripheral objects.
UIApplicationLaunchOptionsShortcutItemKey
// A key indicating that the app was launched in response to the user selecting a Home screen quick action.
UIApplicationLaunchOptionsUserActivityDictionaryKey
// A key indicating that the data associated with an activity that the user wants to continue.
UIApplicationLaunchOptionsUserActivityTypeKey
// A key indicating the type of user activity that the user wants to continue.
複製程式碼
類似,我們可以用 NSDictionary *remoteUserInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
來處理遠端通知。
需要注意一點,傳送多條通知,app的角標會一直累加,所以在啟動app的時候didFinishLaunchingWithOptions
需要將角標清零
[application setApplicationIconBadgeNumber:0 ];
複製程式碼
2.使用UserNotificaiton.framework
相關文件參照:developer.apple.com/documentati…
1.首先,我們需要將UserNotifications
引入工程。
然後在AppDelegate.m匯入庫檔案 #import <UserNotifications/UserNotifications.h>
2.授權應用通知許可權
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if(!error)
{
NSLog(@"@授權成功");
}
}];
複製程式碼
之前註冊推送服務,ios 8 及之前使用了不同的 API,並且返回結果也不同。現在 apple 不僅統一了這個 API,而且我們可以獲取到使用者更加詳細的設定了。
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"%@",settings);
}];
複製程式碼
列印結果如下:
<UNNotificationSettings: 0x60400009cd40; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, carPlaySetting: NotSupported, alertSetting: Enabled, alertStyle: Banner>
如果需要註冊遠端通知:
[[UIApplication sharedApplication] registerForRemoteNotifications];
複製程式碼
2.傳送本地通知
UserNotificaiton
傳送本地通知需要使用UNNotificationRequest
類,例項方法如下
+ (instancetype)requestWithIdentifier:(NSString *)identifier content:(UNNotificationContent *)content trigger:(nullable UNNotificationTrigger *)trigger;
複製程式碼
所以我們需要分別設定 UNNotificationContent
和UNNotificationTrigger
並設定一個識別符號。
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"this is Notifications";
content.subtitle = @"本地通知";
content.body = @"推送一條本地通知";
content.badge = @1;
content.userInfo = @{@"type":@"this is a userNotification"};
複製程式碼
Triggers
又是一個新的功能,有三種
-
UNTimeIntervalNotificationTrigger
-
UNCalendarNotificationTrigger
-
UNLocationNotificationTrigger 他們的使用方式如下:
//8s後提醒
UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:8 repeats:NO];
//每小時重複 1 次喊我喝水
UNTimeIntervalNotificationTrigger *trigger2 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3600 repeats:YES];
//每週一早上 8:00 提醒我給起床
NSDateComponents *components = [[NSDateComponents alloc] init];
components.weekday = 2;
components.hour = 8;
UNCalendarNotificationTrigger *trigger3 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
//需匯入定位庫 #import <CoreLocation/CoreLocation.h>
//一到距離(123.333, 123.344)點20米就喊我下車
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:CLLocationCoordinate2DMake(123.333, 123.344) radius:20 identifier:@"regionidentifier"];
UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:region repeats:NO];
複製程式碼
發出通知
NSString *requestIdentifier = @"sampleRequest";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier
content:content trigger:trigger1];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
複製程式碼
3.接收本地通知並處理。 與LocalNotificationL類似,有三種情況
(1).前臺接收
(2).後臺未殺死程式進入前臺接收
(3).程式已經殺死,點選通知訊息啟動app 需要遵循UNUserNotificationCenterDelegate代理協議方法
center.delegate = self;
複製程式碼
通過以下兩個UNUserNotificationCenterDelegate
的方法實現
// The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
// The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from application:didFinishLaunchingWithOptions:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;
複製程式碼
實現如下:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
NSLog(@"willPresentNotification:%@",notification.request.content.title);
// 這裡真實需要處理互動的地方
// 獲取通知所帶的資料
NSString *apsContent = [notification.request.content.userInfo objectForKey:@"type"];
NSLog(@"%@",apsContent);
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
//在沒有啟動本App(包括後臺執行中)時,收到伺服器推送訊息,下拉訊息會有快捷回覆的按鈕,點選按鈕後呼叫的方法,根據identifier來判斷點選的哪個按鈕
NSString *apsContent = [response.notification.request.content.userInfo objectForKey:@"type"];
NSLog(@"didReceiveNotificationResponse:%@",response.notification.request.content.title);
NSLog(@"%@",apsContent);
}
複製程式碼
我們可已通過removeIdentifier刪除計劃的推送事件:
[center removePendingNotificationRequestsWithIdentifiers:@[requestIdentifier]];
複製程式碼
如果我們需要更新推送,可以通過 addNotificationRequest: 方法,在 Identifier
不變的情況下重新新增,就可以重新整理原有的推送。