推送通知就是向用戶推送一條信息來通知用戶某件事件,可以在應用退到後台後,或者關閉後,能夠通過推送一條消息通知用戶某件事情,比如版本更新等等。
使用原則:誰確定通知時間和內容,誰就可以發生。
UILocalNotification
本地通知對象,並設置必要屬性開始本地推送通知:
第一種方法,延時推送,根據本地通知對象的fireDate
設置進行本地推送通知
[[UIApplication shareApplication] scheduleLocalNotification:notification];
第二種方法,立刻推送,忽略本地通知對象的fireDate
設置進行本地推送通知
[[UIApplication shareApplication] presentLocalNotificationNow:notification];
4- 監聽用戶點擊通知:
APP處於前台,此時不會彈框通知用戶,但會調用對應的代理方法 :
-(void)application:(UIApplication *)application didReceiveLocalNotification;
APP處於後台,屏幕上方會彈出橫幅,用戶點擊橫幅後,會進入前台,調用上面的代理方法。 APP已關閉,屏幕上方會彈出橫幅,用戶點擊橫幅後,會啟動APP,調用以下方法:
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
/* 通過參數launchOptions獲取本地推送通知內容 */
UILocalNotification *local = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
5- 調用UIApplication
的對象方法,取消本地推送通知:
/* 取消指定的本地推送通知 */
-(void)cancelLocalNotification:(UILocalNotification *)notification;
/* 取消全部本地推送通知 */
-(void)cancelAllLocalNotification;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//因為是storyboard啟動,這裡就沒有其他啟動代碼了
//iOS8.0以後,如果需要使用推送通知,需要得到用戶許可
if (application.currentUserNotificationSettings.types == UIUserNotificationTypeNone) {
//注冊通知,有橫幅通知、應用數字通知、應用聲音通知
UIUserNotificationSettings * setting =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound
categories:nil];
[application registerUserNotificationSettings:setting];
} else {
//當APP關閉後接收到通知,在啟動中獲取本地推送通知對象
UILocalNotification *notification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
[self showLocalNotification:notification];
}
return YES;
}
/* 彈框UIAlertView顯示本地通知的信息 */
- (void)showLocalNotification:(UILocalNotification *)notification
{
/* 顯示本地通知 */
NSDictionary *userInfo = notification.userInfo;
NSString *title = @"本地通知";
NSString *msg = userInfo[@"msg"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:nil
cancelButtonTitle:@"取消"
otherButtonTitles:@"確定", nil];
[alert show];
//移除本地通知
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
/* 創建一個本地通知 */
- (UILocalNotification *)makeLocalNotification{
//創建本地推送通知對象
UILocalNotification *notification = [[UILocalNotification alloc] init];
//設置調用時間
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10.0];//通知觸發的時間,10s以後
notification.repeatInterval = NSCalendarUnitMinute;//每隔多久重復發一次本地通知
//設置通知屬性
notification.alertBody = @"最近添加了諸多有趣的特性,是否立即體驗?";//通知主體
notification.applicationIconBadgeNumber = 1;//應用程序圖標右上角顯示的消息數
notification.alertAction = @"打開應用"; //待機界面的滑動動作提示
notification.alertLaunchImage = @"Default";//通過點擊通知打開應用時的啟動圖片,這裡使用程序啟動圖片
notification.soundName = UILocalNotificationDefaultSoundName;//收到通知時播放的聲音,默認消息聲音
//設置用戶信息
notification.userInfo = @{ @"id":@1,
@"user":@"Kenshin Cui",
@"msg":@"我來了一發本地通知"};//綁定到通知上的其他附加信息
return notification;
}
如果需要每天的中午12點准時本地推送怎麼辦呢?
就像這麼辦,修改fireDate
和repeatInterval
屬性
NSDateFormatter *formatter1 = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yyyy-MM-dd HH-mm-sss"];
NSDate *resDate = [formatter dateFromString:@"2016-04-09 12-00-00"];
notification.fireDate = resDate;//設定為明天中午12點觸發通知
//記得設置當前時區,沒有設置的話,fireDate將不考慮時區,這樣的通知會不准確
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.repeatInterval = NSCalendarUnitDay;//每隔一天觸發一次
/* 注冊本地通知完成會調用,即用戶點擊確定授權後調用 */
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//在這裡我們嘗試發送本地推送通知
if (notificationSettings.types != UIUserNotificationTypeNone) {
UILocalNotification *notification = [self makeLocalNotification];
//延遲調用通知
[application scheduleLocalNotification:notification];
//立刻發送通知
//[application presentLocalNotificationNow:notification];
}
}
/* 應用還在運行,無論前台還是後台,都會調用該方法處理通知 */
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
if( notification ) {
[self showLocalNotification:notification];
}
}
/* 應用進入前台,去除應用邊角數字顯示 */
- (void)applicationWillEnterForeground:(UIApplication *)application {
//去除應用邊角數字
[application setApplicationIconBadgeNumber:0];
}
device token
)發送給蘋果的消息推送服務器APNs。 APNs根據設備令牌在已注冊的設備(iPhone、iPad、iTouch、Mac等)查找對應的設備,將消息發送給相應的設備。客戶端設備接將接收到的消息傳遞給相應的應用程序,應用程序根據用戶設置彈出通知消息。
所有的蘋果設備,在聯網狀態下,都會和蘋果服務器APNs建立一個長連接
* 長連接:服務器可以向客戶端發送消息,保證數據的即時性,但比較占用資源
* 短連接:服務器無法主動向客戶端發消息,會話結束後,就立即釋放資源,節省資源
遠程推送通知就是借助蘋果設備與APNs服務器之間的長連接,借助APNs服務器講消息發送給客戶端。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoNiBpZD0="遠程推送通知實現的條件">
遠程推送通知實現的條件:
必須有真機,只有真機具備UDID,才能生成deviceToken
設備令牌需要開發推送Cer證書
證書的申請請參考:iOS學習筆記21-推送證書與秘鑰申請
deviceToken
的生成算法只有Apple掌握,為了確保算法發生變化後仍然能夠正常接收服務器端發送的通知,每次應用程序啟動都重新獲得deviceToken
deviceToken
設備令牌:
-(void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
3- 把deviceToken
設備令牌發送給服務器,時刻保持deviceToken
是最新的
4- 監聽遠程推送通知:
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//iOS8.0以後,如果需要使用本地推送通知,需要得到用戶許可
if (![application isRegisteredForRemoteNotifications]) {
UIUserNotificationSettings * setting =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound
categories:nil];
[application registerUserNotificationSettings:setting];
//注冊遠程推送通知
[application registerForRemoteNotifications];
}
return YES;
}
/* 注冊遠程推送通知成功會調用 ,在此接收設備令牌deviceToken */
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[self addDeviceToken:deviceToken];
}
/* 保存deviceToken,並同步服務器上保存的deviceToken,以便能正確推送通知 */
- (void)addDeviceToken:(NSData *)deviceToken
{
NSString *key = @"DeviceToken";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//取出原來的deviceToken,進行比較
NSData *oldToken = [defaults objectForKey:key];
if ([oldToken isEqualToData:deviceToken]) {
//存入新的deviceToken
[defaults setObject:deviceToken forKey:key];
[defaults synchronize];
//發送網絡請求到服務器,說明deviceToken發生了改變
[self sendDeviceTokenWithOldDeviceToken:oldToken newDeviceToken:deviceToken];
}
}
/* 發送網絡請求到服務器,說明deviceToken發生了改變,服務器那邊也要同步改變 */
- (void)sendDeviceTokenWithOldDeviceToken:(NSData *)oldToken newDeviceToken:(NSData *)newToken
{
//發送到服務器,下面是服務器的一個接口
NSString *urlStr = @"http://192.168.1.101/RegisterDeviceToken.aspx";
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
//POST網絡請求
NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
requestM.HTTPMethod = @"POST";
//POST請求的請求體
NSString *bodyStr = [NSString stringWithFormat:@"oldToken=%@&newToken=%@",oldToken,newToken];
requestM.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
//使用會話來發送網絡請求
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask =
[session dataTaskWithRequest:requestM
completionHandler:^(NSData *data,NSURLResponse *response,NSError *error){
if(!error){
NSLog(@"Send Success !");
} else {
NSLog(@"Send Failure, error = %@",error.localizedDescription);
}
}];
//網絡請求任務啟動
[dataTask resume];
}
/* 收到遠程推送通知時會調用 */
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSString *title = @"遠程推送通知";
NSString *msg = userInfo[@"msg"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:nil
cancelButtonTitle:@"取消"
otherButtonTitles:@"確定", nil];
[alert show];
}
上面的遠程推送過程如果覺得實現比較麻煩,你可以使用第三方推送,例如:
極光推送( JPush ),我只用過這個,界面還不錯,這不是在打廣告! 個推 騰訊信鴿
具體的集成步驟及使用方法,請查看對應的官方文檔,非常詳細。