注意:
UILocalNotification:本地通知,進行UI通知(iOS8以后也需要先注冊通知授權)。
這兩個類不在同一個框架中:
NSNotificationCenter在Foundation框架中
UILocalNotification在UIKit框架中
本地推送
iOS7:不需要授權
iOS8:以后需要授權
步驟:
1、通過在AppDelegate中判斷版本注冊通知授權
2、在需要的界面創建一個本地通知,設置通知的屬性,最后又AppDelegate調用通知
在#import "AppDelegate.h"中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
UIUserNotificationSettings *userNotification = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil ];
[application registerUserNotificationSettings:userNotification];
}
return YES;
}
在#import "ViewController.h"中
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 1.創建本地通知
UILocalNotification *localNote = [[UILocalNotification alloc] init];
// 2.設置本地通知的內容
// 2.1.設置通知發出的時間
localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:3.0];
// 2.2.設置通知的內容
localNote.alertBody = @"通知內容";
// 2.3.設置滑塊的文字
localNote.alertAction = @"滑塊文字";
// 2.4.決定alertAction是否生效
localNote.hasAction = NO;
// 2.5.設置點擊通知的啟動圖片
localNote.alertLaunchImage = @"隨便都可以";
// 2.6.設置alertTitle
localNote.alertTitle = @"123";
// 2.7.設置有通知時的音效
localNote.soundName = @"語音文件名";
// 2.8.設置應用程序圖標右上角的數字
localNote.applicationIconBadgeNumber = 9;
// 2.9.設置額外信息
localNote.userInfo = @{@"type" : @1};
// 3.調用通知
[[UIApplication sharedApplication] scheduleLocalNotification:localNote];
}
Application代理方法的launchOptions屬性
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions ;
launchOptions:用戶直接打開程序的時候這個參數是沒有值的。
若由其他應用程序通過openURL:啟動,則UIApplicationLaunchOptionsURLKey對應的對象為啟動URL(NSURL),
UIApplicationLaunchOptionsSourceApplicationKey對應啟動的源應用程序的bundle ID (NSString);
若由本地通知啟動,則UIApplicationLaunchOptionsLocalNotificationKey對應的是為啟動應用程序的的本地通知對象(UILocalNotification);
若由遠程通知啟動,則UIApplicationLaunchOptionsRemoteNotificationKey對應的是啟動應用程序的的遠程通知信息userInfo(NSDictionary)
根據通知跳轉到相應的界面
1、在AppDelegate中實現方法監聽通知,判斷是否進入后臺,根據通知設置的額外信息userInfo來打開相應的界面。
// 應用程序在進入前臺,或者在前臺的時候都會執行該方法
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// 針對應用程序在后臺的時候進行的跳轉
if (application.applicationState == UIApplicationStateInactive) {
NSLog(@"進行界面的跳轉");
NSLog(@"%@", notification.userInfo);
UIView *redView = [[UIView alloc] init];
redView.frame = CGRectMake(0, 0, 100, 100);
redView.backgroundColor = [UIColor redColor];
[self.window.rootViewController.view addSubview:redView];
}
}
2、當程序被殺死了,當再次點擊進來是不會來到實現的代理方法,此時需要在程序加載完畢之后判斷。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 界面的跳轉(針對應用程序被殺死的狀態下的跳轉)
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
// 跳轉代碼
UILabel *redView = [[UILabel alloc] init];
redView.frame = CGRectMake(0, 0, 200, 300);
redView.numberOfLines = 0;
redView.font = [UIFont systemFontOfSize:12.0];
redView.backgroundColor = [UIColor redColor];
redView.text = [NSString stringWithFormat:@"%@", launchOptions];
[self.window.rootViewController.view addSubview:redView];
}
return YES;
}
遠程推送原理
一.什么是遠程通知
概念:由服務器發送消息給用戶彈出消息的通知(需要聯網)
遠程推送服務,又稱為APNs(Apple Push Notification Services)
二.為什么需要遠程通知
例子:淘寶最近雙11搞活動,各種送紅包,想告知用戶.但是該用戶不經常打包淘寶APP.淘寶如何通知該用戶有最新的活動呢?
傳統方式:只有用戶打開了淘寶客戶端,客戶端向服務器請求是否有最新的活動,才能在APP中告知用戶活動.
局限性:只要用戶關閉了app,就無法跟app的服務器溝通,無法從服務器上獲得最新的數據內容
遠程通知的好處:不管用戶打開還是關閉app,只要聯網了,都能接收到服務器推送的遠程通知
如何做遠程通知
需要真機,配置證書。
以微信客戶端為例
1、客戶端將手機的唯一標識UDID和應用程序的唯一標識Bound Identifier發送給蘋果的APNs服務器。
2、蘋果的APNs服務器根據這兩個唯一標識生成一個加密的唯一標識deviceToken,并放回給客服端。
3、在AppDelegate中實現相應的方法攔截,并將這個deviceToken和微信帳號ID發送給客戶端的服務器,客戶端的服務器保存(deviceToke和微信帳號對應)。
4、當別人需要發送消息給特定的微信帳號好友,微信服務器將對應的帳號的deviceToken和消息發送給蘋果的APNs服務器。
5、蘋果的APNs服務器根據對應的deviceToken發送推送通知給微信客戶端。
6、根據推送的消息,監聽用戶的點擊(類似本地通知)
代碼
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//但程序被殺死,點擊推送通知進入程序來到這,根據不同iOS版本進行通知的授權與注冊
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { //iOS8
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
//注冊通知授權
[application registerUserNotificationSettings:settings];
//注冊通知
[application registerForRemoteNotifications];
} else { // iOS7
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNewsstandContentAvailability | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert];
}
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
// 跳轉
}
return YES;
}
//攔截蘋果APNs服務器返回的deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// 將DeviceToken傳給服務器
NSLog(@"%@", deviceToken.description);
}
//當程序從后臺點擊推送通知進入時會調用這個方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(@"%@", userInfo);
}
//當程序進入后臺,不點擊推送消息,也會調用這個方法,但是發送的通知有固定的格式,1.需要打開后臺模式 2.告訴系統是否有新內容的更新3、需要添加"content-available":"1";
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(@"11111111");
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
redView.frame = CGRectMake(100, 100, 100, 100);
[self.window.rootViewController.view addSubview:redView];
// 1.需要打開后臺模式 2.告訴系統是否有新內容的更新 3.發送的通知有固定的格式("content-available":"1")
completionHandler(UIBackgroundFetchResultNewData);
}
設置應用程序右上角顯示提示數字的兩種方法
方法一: [application setApplicationIconBadgeNumber:2]; (優先級高)
方法二: UILocalNotification *localNote = [[UILocalNotification alloc] init];
localNote.applicationIconBadgeNumber = 9;
遠程通知證書配置
- .配置一個明確的APPID
- 選擇明確的APPID,并且將遠程通知功能選中
-
顯示Push Notifications并非Enabled,而是Configurable.
屏幕快照 2016-06-05 下午12.50.44.png- 需要配置對應的證書
二 證書的配置
- 在Certificates中配置證書
- 選擇證書的類型(調試和發布都需要配置)
-
選擇為哪一個APPID配置證書
屏幕快照 2016-06-05 下午12.53.50.png 其他步驟同真機調試和發布程序
-
配置完成后獲得兩個證書文件
屏幕快照 2016-06-05 下午12.54.43.png 配置描述文件
- 和真機描述文件完全一致
獲取DeviceToken
1.在蘋果的APNs服務器注冊,以獲取DeviceToken
通常在didFinishLaunchingWithOptions中添加如下代碼進行注冊
if ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) {
// 1.向用戶請求可以給用戶推送消息
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:settings];
// 2.注冊遠程通知(拿到用戶的DeviceToken)
[application registerForRemoteNotifications];
} else {
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
}
注冊之后在另外一個代理方法中,拿到DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// 5e8cf393 9e950137 86ac8375 12185078 19eb3ebd 936777e1 f061caec a48cb236
// 將用戶的用戶名和deviceToken發送給服務器,讓服務器進行保存備份即可
NSLog(@"%@", deviceToken);
}
- 將DeviceToken發送到服務器即可
測試遠程通知
當前我們沒有自己的服務器,如何測試?
可以使用一個第三方的Mac程序來測試:PushMeBaby
-
使用該程序需要修改一些內容
-
編譯程序,報錯的行注釋掉
屏幕快照 2016-06-05 下午1.00.02.png
-
運動pushMeBaby程序

注意:填寫的內容
填寫推送給的DeviceToken
添加推送的內容:固定格式
{"aps":{"alert":"彈出的信息","badge":1,"sound":"聲音","info":"額外信息"}}