IOS本地通知:UILocalNotification使用記錄

第一次接觸IOS的本地通知的使用,看到別人寫的一個比較詳細的記錄,本身整理過來,方便之後再次使用和拓展:數組

1.建立一個本地通知,添加到系統:app

 1 // 初始化本地通知對象
 2 UILocalNotification *notification = [[UILocalNotification alloc] init];
 3 if (notification) {
 4     // 設置通知的提醒時間
 5     NSDate *currentDate   = [NSDate date];
 6     notification.timeZone = [NSTimeZone defaultTimeZone]; // 使用本地時區
 7     notification.fireDate = [currentDate dateByAddingTimeInterval:5.0];
 8      
 9     // 設置重複間隔
10     notification.repeatInterval = kCFCalendarUnitDay;
11      
12     // 設置提醒的文字內容
13     notification.alertBody   = @"Wake up, man";
14     notification.alertAction = NSLocalizedString(@"起牀了", nil);
15      
16     // 通知提示音 使用默認的
17     notification.soundName= UILocalNotificationDefaultSoundName;
18      
19     // 設置應用程序右上角的提醒個數
20     notification.applicationIconBadgeNumber++;
21      
22     // 設定通知的userInfo,用來標識該通知
23     NSMutableDictionary *aUserInfo = [[NSMutableDictionary alloc] init];
24     aUserInfo[kLocalNotificationID] = @"LocalNotificationID";
25     notification.userInfo = aUserInfo;
26      
27     // 將通知添加到系統中
28     [[UIApplication sharedApplication] scheduleLocalNotification:notification];
29 }

repeatInterval表示通知的重複間隔,在SDK中定義以下:ui

 1 typedef CF_OPTIONS(CFOptionFlags, CFCalendarUnit) {
 2     kCFCalendarUnitEra = (1UL << 1),
 3     kCFCalendarUnitYear = (1UL << 2),
 4     kCFCalendarUnitMonth = (1UL << 3),
 5     kCFCalendarUnitDay = (1UL << 4),
 6     kCFCalendarUnitHour = (1UL << 5),
 7     kCFCalendarUnitMinute = (1UL << 6),
 8     kCFCalendarUnitSecond = (1UL << 7),
 9     kCFCalendarUnitWeek CF_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0) = (1UL << 8),
10     kCFCalendarUnitWeekday = (1UL << 9),
11     kCFCalendarUnitWeekdayOrdinal = (1UL << 10),
12     kCFCalendarUnitQuarter CF_ENUM_AVAILABLE(10_6, 4_0) = (1UL << 11),
13     kCFCalendarUnitWeekOfMonth CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 12),
14     kCFCalendarUnitWeekOfYear CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 13),
15     kCFCalendarUnitYearForWeekOfYear CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 14),
16 };

這裏比較很差的一點是該值不能自定義(很遺憾,NSCalendarUnit是個枚舉類型),例如你不能塞個10.0給它從而但願它每十秒重複一次。因此若是你想每20分鐘發送一次通知,一小時內發送3次,那麼只能同時設定三個通知了。atom

2.收到通知後委託內的自定義實現:spa

1 -(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
2     NSLog(@"Application did receive local notifications");
3      
4     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"welcome" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
5     [alert show];
6 }

3.如何取消(刪除本地通知)操作系統

有一點須要注意,若是咱們的應用程序給系統發送的本地通知是週期性的,那麼即便把程序刪了重裝,以前的本地通知在重裝時依然存在(沒有從系統中移除)。代理

所以咱們須要取消通知的方法,固然該對象也會在scheduledLocalNotifications數組中移除。code

取消方法分爲兩種。對象

第一種比較暴力,直接取消全部的本地通知:blog

[[UIApplication sharedApplication] cancelAllLocalNotifications];

這個適合在App重裝時第一次啓動的時候,或還原程序默認設置等場合下使用。

第二種方法是針對某個特定通知的:

- (void)cancelLocalNotification:(UILocalNotification *)notification 

4.如何標識一個本地通知

須要通知有一個標識,這樣咱們才能定位是哪個通知。能夠在notification的userInfo(一個字典)中指定。

例如:

 1 -(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
 2     NSLog(@"Application did receive local notifications");
 3      
 4     // 取消某個特定的本地通知
 5     for (UILocalNotification *noti in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
 6         NSString *notiID = noti.userInfo[kLocalNotificationID];
 7         NSString *receiveNotiID = notification.userInfo[kLocalNotificationID];
 8         if ([notiID isEqualToString:receiveNotiID]) {
 9             [[UIApplication sharedApplication] cancelLocalNotification:notification];
10             return;
11         }
12     }
13      
14     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"welcome" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
15     [alert show];
16 }

 固然使用上述本地通知的前提是,應用獲取到了系統的通知權限,須要註冊通知:

 註冊以前有兩個前提條件必須準備好:

  •  開發配置文件(provisioning profile,也就是.mobileprovision後綴的文件)的App ID不能使用通配ID必須使用指定APP ID而且生成配置文件中選擇Push Notifications服務,通常的開發配置文件沒法完成註冊;
  •  應用 程序的Bundle Identifier必須和生成配置文件使用的APP ID徹底一致
 1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
 2   UIDevice *device = [UIDevice currentDevice];
 3     float sysVersion = [device.systemVersion floatValue];
 4     if (sysVersion >= 8.0f) {
 5         UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings];
 6         if (UIUserNotificationTypeNone != setting.types) {
[self addLocalNotification];
7 NSLog(@"已經容許了通知"); 8 }else{ 9 [[UIApplication sharedApplication]registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]]; 10 [[UIApplication sharedApplication] registerForRemoteNotifications]; 11 } 12 }else{ 13 UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; 14 if(UIRemoteNotificationTypeNone != type){ 15 NSLog(@"已經容許了通知"); 16 }else{ 17 [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationType)(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)]; 18 } 19 } 20 21 //[self registerRemoteNotification]; 22 return YES; 23 } 24 25 #pragma mark 調用過用戶註冊通知方法以後執行(也就是調用完registerUserNotificationSettings:方法以後執行) 26 -(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{ 27 if (notificationSettings.types!=UIUserNotificationTypeNone) { 28 //[self addLocalNotification]; 29 NSLog(@"容許了通知"); 30 } 31 } 32 33 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 34 NSLog(@"註冊成功"); 35 } 36 37 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { 38 NSLog(@"註冊失敗"); 39 }

注:

  • 在使用通知以前必須註冊通知類型,若是用戶不容許應用程序發送通知,則之後就沒法發送通知,除非用戶手動到iOS設置中打開通知。 
  • 本地通知是有操做系通通一調度的,只有在應用退出到後臺或者關閉才能收到通知。(注意:這一點對於後面的推送通知也是徹底適用的。 ) 
  • 通知的聲音是由iOS系統播放的,格式必須是Linear PCM、MA4(IMA/ADPCM)、µLaw、aLaw中的一種,而且播放時間必須在30s內,不然將被系統聲音替換,同時自定義聲音文件必須放到boundle中。 
  • 本地通知的數量是有限制的,最近的本地通知最多隻能有64個,超過這個數量將被系統忽略。 
  • 若是想要移除本地通知能夠調用UIApplication的cancelLocalNotification:cancelAllLocalNotifications移除指定通知或全部通知。

從上面的程序能夠看到userInfo這個屬性咱們設置了參數,那麼這個參數如何接收呢?

在iOS中若是點擊一個彈出通知(或者鎖屏界面滑動查看通知),默認會自動打開當前應用。因爲通知由系統調度那麼此時進入應用有兩種狀況:

  • 若是應用程序已經徹底退出那麼此時會調用- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法;
  • 若是此時應用程序還在運行(不管是在前臺仍是在後臺)則會調用-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification方法接收消息參數。

固然若是是後者天然沒必要多說,由於參數中已經能夠拿到notification對象,只要讀取userInfo屬性便可。若是是前者的話則能夠訪問launchOptions中鍵爲UIApplicationLaunchOptionsLocalNotificationKey的對象,這個對象就是發送的通知,由此對象再去訪問userInfo。爲了演示這個過程在下面的程序中將userInfo的內容寫入文件以便模擬關閉程序後再經過點擊通知打開應用獲取userInfo的過程。

 1 #pragma mark - 應用代理方法
 2 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 3     //添加通知
 4     [self addLocalNotification];
 5 
 6     //接收通知參數
 7     UILocalNotification *notification=[launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
 8     NSDictionary *userInfo= notification.userInfo;
 9     
10     [userInfo writeToFile:@"/Users/kenshincui/Desktop/didFinishLaunchingWithOptions.txt" atomically:YES];
11     NSLog(@"didFinishLaunchingWithOptions:The userInfo is %@.",userInfo);
12     
13     return YES;
14 }

 

上面的程序能夠分爲兩種狀況去運行:

  • 一種是啓動程序關閉程序,等到接收到通知以後點擊通知從新進入程序;
  • 另外一種是啓動程序後,進入後臺(其實在前臺也能夠,可是爲了明顯的體驗這個過程建議進入後臺),接收到通知後點擊通知進入應用。

兩種狀況會分別按照前面說的狀況調用不一樣的方法接收到userInfo寫入本地文件系統。有了userInfo通常來講就能夠根據這個信息進行一些處理,例如能夠根據不一樣的參數信息導航到不一樣的界面,假設是更新的通知則能夠導航到更新內容界面等。

相關文章
相關標籤/搜索