本地推送服務 UILocalNotification
原文 http://www.cnblogs.com/coltfoal/p/4591699.html
前言
之前接觸過iOS上的推送服務,當時做的是在線推送,雖然已經有很多開發商提供集成的推送服務,但作為了解原理的方式也是一個不錯的過程。
最近打算應用本地通推送的功能,本來以為會和在線推送一樣麻煩,又要弄證書,又要提交驗證,所以一直沒動手。今天稍微了解后,發現本地推送就是很簡單的一件事。
介紹
本地推送是什么
在線推送一般是通過服務器發送消息到對應設備,并由對應設備做出響應通知用戶。而本地推送則是直接在本地由程序控制發送消息通知用戶。由于減少了服務器以及驗證設備的過程,所以本地推送其實就是一個簡單的通知服務。
本地推送能做什么
GTD應用一般需要根據設定在規定時間通知用戶完成某個任務。GTD的事務在本地基本都有備份,也當然是通過本地來通知用戶何時應用完成任務。在這里,本地推送服務的作用就突顯出來了。
某些游戲,比如升級建筑裝備等,一般都需要時間去完成,玩家不可能在游戲前一直等待。當升級結束,游戲在本地把通知推送給玩家,玩家響應并再次進入游戲,不僅節約玩家的時間,也給游戲的激活帶來更多的流量。
雖然本地推送不如在線推送的使用頻率那么高,但還是很有用途的。
如何實現本地推送
添加通知
本地推送的實現很簡單,更多的是自定義的過程。來看看下面的代碼:
UILocalNotification *notification = [[UILocalNotification alloc] init]; // ARC環境 notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3]; // 推送時間 notification.timeZone = [NSTimeZone defaultTimeZone]; notification.repeatInterval = 0; // 推送間隔 notification.soundName = UILocalNotificationDefaultSoundName; // 推送聲音 notification.alertBody = @"Push Notification"; // 推送內容 notification.applicationIconBadgeNumber = 1; // 消息個數 notification.userInfo = [NSDictionary dictionaryWithObject:@"value" forKey:@"key"]; [[UIApplication sharedApplication] scheduleLocalNotification:notification];
實例化一個`UILocalNotification`對象,并根據具體的要求設置這個對象的屬性。
`fireDate`表示推送的時間。`timeZone`是對應的時區。
`repeatInterval`表示推送的重復間隔,它的類型是`NSCalendarUnit`,可以用這個枚舉值來賦值,表示每天、每周或每月等。如果為0則表示不重復推送。
`soundName`是推送的聲音,可以寫上bundle資源里已有的音樂文件名稱,這樣就可以自定義推送的聲音了。
`alertBody`是推送的內容。
`applicationIconBadgeNumber`表示顯示在該應用圖標上的消息個數。在接受消息后需要把這個屬性重置。
`userInfo`可以存放通知的相關信息。
最后,通過調用`scheduleLocalNotification`達到推送通知的目的。
接收通知
接收推送通知更加容易,在`AppDelegate`的`didReceiveLocalNotification`方法中就可以接收了。
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification*)notification { NSLog(@"Notification : %@", notification.alertBody); // 輸出推送信息 application.applicationIconBadgeNumber = 0; // 消息數置為0 }
上面在`didReceiveLocalNotification`方法中打印出了推送消息的內容,并把消息數置為0。當然也可以通過判斷`notification`的具體信息顯示彈窗、修改消息數等。
取消通知
NSArray *array = [[UIApplication sharedApplication] scheduledLocalNotifications]; // 獲取本地推送數組 [[UIApplication sharedApplication] cancelLocalNotification:notification]; // 取消某個推送 [[UIApplication sharedApplication] cancelAllLocalNotifications]; // 取消所有推送
上面這段代碼展示了幾個API,但其中沒有必然的調用關系。
`scheduledLocalNotifications`可以獲取本地的推送數組,其中的每個成員都是UILocalNotification,可以根據它們的userInfo區分推送的類型。
`cancelLocalNotification`可以取消某個具體的推送通知。比如取消通過`scheduledLocalNotifications`獲取的某個通知。
`cancelAllLocalNotifications`則可以一次性取消所有的通知。
本地推送會有哪些坑
iOS8
在iOS8之后,要使用本地推送都需要為本地注冊通知類型,否則無法接收到通知。具體的做法是在`AppDelegate`的`didFinishLaunchingWithOptions`中注冊。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]]; return YES; }
音樂
推送通知可以自定義音樂,但并不是所有音樂都可以調用。目前只支持30秒的音樂,因為推送最多只能維持30秒。
聲音
如果手機置為靜音,則音樂無法播放。
如果在手機打開的時候顯示通知,也不會播放音樂,甚至也不會震動。
applicationIconBadgeNumber
如果是從通知欄點擊通知進入應用,會響應通知的回調,同時在回調中獎消息數置為0。
而如果是在有消息的情況下直接打開應用,并不會走通知回調的流程。
可以根據需要接入這部分邏輯。
總結
本地通知的處理還是比較簡單的。
鬧鐘的實現原理也是利用了本地通知,但是如果要考慮震動等問題,則會更加復雜。有需要再慢慢研究。