推送通知
注意:這里說的推送通知跟NSNotification有所區別
NSNotification是抽象的,不可見的
推送通知是可見的(能用肉眼看到)
iOS中提供了2種推送通知
本地推送通知(Local Notification)
遠程推送通知(Remote Notification)
[圖片上傳中。。。(2)]
[圖片上傳中。。。(3)]
[圖片上傳中。。。(4)]
推送通知的呈現效果總結
總結一下,推送通知有5種不同的呈現效果
在屏幕頂部顯示一塊橫幅(顯示具體內容)
在屏幕中間彈出一個UIAlertView(顯示具體內容)
在鎖屏界面顯示一塊橫幅(鎖屏狀態下,顯示具體內容)
更新app圖標的數字(說明新內容的數量)
播放音效(提醒作用)
[圖片上傳中。。。(5)]
[圖片上傳中。。。(6)]
推送通知的使用細節
發出推送通知時,如果當前程序正運行在前臺,那么推送通知就不會被呈現出來
點擊推送通知后,默認會自動打開發出推送通知的app
不管app打開還是關閉,推送通知都能如期發出
本地推送通知
什么是本地推送通知
顧名思義,就是不需要聯網就能發出的推送通知(不需要服務器的支持)
本地推送通知的使用場景
常用來定時提醒用戶完成一些任務,比如
清理垃圾、記賬、買衣服、看電影、玩游戲
如何發出本地推送通知
創建本地推送通知對象
UILocalNotification *ln = [[UILocalNotification alloc] init];
設置本地推送通知屬性
推送通知的觸發時間(何時發出推送通知)
@property(nonatomic,copy) NSDate *fireDate;
推送通知的具體內容
@property(nonatomic,copy) NSString *alertBody;
在鎖屏時顯示的動作標題(完整標題:“滑動來” + alertAction)
@property(nonatomic,copy) NSString *alertAction;
音效文件名
@property(nonatomic,copy) NSString *soundName;
app圖標數字
@property(nonatomic) NSInteger applicationIconBadgeNumber;
如何發出本地推送通知
調度本地推送通知(調度完畢后,推送通知會在特地時間fireDate發出)
[[UIApplication sharedApplication] scheduleLocalNotification:ln];
獲得被調度(定制)的所有本地推送通知
@property(nonatomic,copy) NSArray *scheduledLocalNotifications;
(已經發出且過期的推送通知就算調度結束,會自動從這個數組中移除)
取消調度本地推送通知
(void)cancelLocalNotification:(UILocalNotification *)notification;
(void)cancelAllLocalNotifications;
立即發出本地推送通知(void)presentLocalNotificationNow:(UILocalNotification *)notification;
本地推送通知的其他屬性
每隔多久重復發一次推送通知
@property(nonatomic) NSCalendarUnit repeatInterval;
點擊推送通知打開app時顯示的啟動圖片
@property(nonatomic,copy) NSString *alertLaunchImage;
附加的額外信息
@property(nonatomic,copy) NSDictionary *userInfo;
時區
@property(nonatomic,copy) NSTimeZone *timeZone;
(一般設置為[NSTimeZone defaultTimeZone] ,跟隨手機的時區)
點擊本地推送通知
當用戶點擊本地推送通知,會自動打開app,這里有2種情況
app并沒有關閉,一直隱藏在后臺
讓app進入前臺,并會調用AppDelegate的下面方法(并非重新啟動app)
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
app已經被關閉(進程已死)
啟動app,啟動完畢會調用AppDelegate的下面方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
launchOptions參數通過UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對象
遠程推送通知(難)
什么是遠程推送通知
顧名思義,就是從遠程服務器推送給客戶端的通知(需要聯網)
遠程推送服務,又稱為APNs(Apple Push Notification Services)
為什么需要遠程推送通知?
傳統獲取數據的局限性
只要用戶關閉了app,就無法跟app的服務器溝通,無法從服務器上獲得最新的數據內容
遠程推送通知可以解決以上問題
不管用戶打開還是關閉app,只要聯網了,都能接收到服務器推送的遠程通知
[圖片上傳中。。。(7)]
遠程推送通知使用須知
所有的蘋果設備,在聯網狀態下,都會與蘋果的服務器建立長連接
什么是長連接
只要聯網了,就一直建立連接
長連接的作用
時間校準
系統升級
查找我的iPhone
.. ...
長連接的好處
數據傳輸速度快
數據保持最新狀態
[圖片上傳中。。。(8)]
[圖片上傳中。。。(9)]
[圖片上傳中。。。(10)]
[圖片上傳中。。。(11)]
[圖片上傳中。。。(12)]
[圖片上傳中。。。(13)]
[圖片上傳中。。。(14)]
一.開發iOS程序的推送功能, iOS端需要做的事
1.請求蘋果獲得deviceToken
2.得到蘋果返回的deviceToken
3.發送deviceToken給公司的服務器
4.監聽用戶對通知的點擊
二.調試iOS的遠程推送功能, 必備條件:
1.真機
2.調試推送需要的證書文件
1> aps_development.cer : 某臺電腦就能調試某個app的推送服務
2> ios_development.cer : 讓電腦具備真機調試的能力(調試設備)
3> iphone5_qq.mobileprovision : 某臺電腦就能利用某臺設備調試某個程序
三.發布具有推送服務的app
1> aps_production.cer : 如果發布的程序中包含了推送服務,就必須安裝此證書
2> ios_distribution.cer : 讓電腦具備發布程序的能力
3> qq.mobileprovision : 某臺電腦就能發布某個程序
[圖片上傳中。。。(15)]
[圖片上傳中。。。(16)]
[圖片上傳中。。。(17)]
[圖片上傳中。。。(18)]
[圖片上傳中。。。(19)]
[圖片上傳中。。。(20)]
[圖片上傳中。。。(21)]
注冊遠程推送通知
注冊成功后會調用AppDelegate的下面方法,得到設備的deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"%@", deviceToken);
}
點擊遠程推送通知
當用戶點擊遠程推送通知,會自動打開app,這里有2種情況
app并沒有關閉,一直隱藏在后臺
讓app進入前臺,并會調用AppDelegate的下面方法(并非重新啟動app)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
app已經被關閉(進程已死)
啟動app,啟動完畢會調用AppDelegate的下面方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
launchOptions參數通過UIApplicationLaunchOptionsRemoteNotificationKey取出服務器返回的字典內容
[圖片上傳中。。。(22)]
[圖片上傳中。。。(23)]
[圖片上傳中。。。(24)]
[圖片上傳中。。。(25)]
[圖片上傳中。。。(26)]
JPush
什么是JPush
一套遠程推送解決方案,支持android和iOS兩個平臺
它能夠快捷地為iOS App增加推送功能,減少集成APNs需要的工作量、開發復雜度
更多的信息,可以參考JPush官方網站:https://www.jpush.cn
集成iOS SDK的步驟可以參考
http://docs.jpush.cn/pages/viewpage.action?pageId=2621727
[圖片上傳中。。。(27)]
[圖片上傳中。。。(28)]
[圖片上傳中。。。(29)]
[圖片上傳中。。。(30)]
**********************筆記*******************
一. 推送通知
- 什么是推送通知?
首先明確:**此處的推送通知跟我們的”NSNotification”沒有半毛錢關系
可以理解為: 向用戶推送一條信息來通知用戶某件事情
作用: 可以在APP退到后臺,或者關閉時;繼續推送一條消息告訴用戶某件事情
推送通知的應用場景?
(1) 一些任務管理APP,會在任務時間即將到達時,通知你做該任務;
(2) 健身App定時提醒你應該健身了;
(3) 買過電影票后,提前半小時告訴你,電影即將開場;
(4) 當你QQ或者微信收到消息時,即使退到后臺,或者關閉APP,也可以收到信息通知告訴我們;
(5) 電商APP,推送一條消息通知我們有新品上架等等推送通知的展現樣式?
(1) 在屏幕頂部顯示一塊橫幅(顯示具體內容)
(2) 在屏幕中間彈出一個UIAlertView(顯示具體內容)
(3) 在鎖屏界面顯示一塊橫幅(鎖屏狀態下,顯示具體內容)
(4) 更新app圖標的數字(說明新內容的數量)
(5) 播放音效(提醒作用)
- 注意:以上樣式只能是用戶自己設置,我們無法通過代碼控制*
- 推送通知的分類
1.本地推送通知
“本地”可以理解為”不聯網”;即使沒有網絡情況下,也可以推送通知消息
應用場景: 確定知道未來某個時間點應該提醒用戶什么
2.遠程推送通知
概念:
與“本地”相對,表示,必須在聯網情況下才會向用戶推送通知消息
遠程推送服務,又稱為APNs(Apple Push Notification Services)
應用場景:
不確定未來某個時間點應該提醒用戶什么,臨時性的
當APP徹底退出時也想繼續讓用戶獲取一些最新消息
使用原則: 誰能確定通知時間和內容, 誰就可以發送(開發人員在APP內部通過代碼發送=本地通知; 服務器可以確定通知時間和內容=遠程通知)推送通知的實現
本地推送通知
1.創建UILocalNotification對象
2.設置一些必要屬性
推送通知的觸發時間(何時發出推送通知)
@property(nonatomic,copy) NSDate *fireDate;
推送通知的具體內容
@property(nonatomic,copy) NSString *alertBody;
3.開始推送通知
- 根據fireDate設定的時間進行推送
[[UIApplication sharedApplication] scheduleLocalNotification:ln]; - 立即推送
presentLocalNotificationNow:(UILocalNotification *)notification;
4.監聽用戶點擊通知
- app處于前臺
此時不會彈框通知用戶通知的到達,但是還是會調用對應的代理方法 - app并沒有關閉,一直隱藏在后臺時
此時用戶點擊通知信息后,會讓app進入前臺,并會調用AppDelegate的下面方法
application: didReceiveLocalNotification: - app已經被關閉(進程已死)
此時用戶點擊通知信息后,會啟動app,啟動完畢會調用AppDelegate的下面方法
application: didFinishLaunchingWithOptions:
launchOptions參數通過UIApplicationLaunchOptionsLocalNotif icationKey取出本推送通知對象
5.額外設置
每隔多久重復發一次推送通知
@property(nonatomic) NSCalendarUnit repeatInterval;
點擊推送通知打開app時顯示的啟動圖片
@property(nonatomic,copy) NSString *alertLaunchImage;
附加的額外信息
@property(nonatomic,copy) NSDictionary *userInfo;
時區
@property(nonatomic,copy) NSTimeZone *timeZone;
(一般設置為[NSTimeZone defaultTimeZone] ,跟隨手機的時區)
在鎖屏時顯示的動作標題(完整標題:“滑動來” + alertAction)
@property(nonatomic,copy) NSString *alertAction;
音效文件名
@property(nonatomic,copy) NSString *soundName;
app圖標數字
@property(nonatomic) NSInteger applicationIconBadgeNumber;
6.其他操作
- 獲得被調度(定制)的所有本地推送通知
@property(nonatomic,copy) NSArray *scheduledLocalNotifications;
已經發出且過期的推送通知就算調度結束,會自動從這個數組中移除 - 取消調度本地推送通知
- (void)cancelLocalNotification:(UILocalNotification *)notification;
- (void)cancelAllLocalNotifications;
7.注意事項
- 在iOS 8.0+,如果要使用本地通知,需要得到用戶的許可
在didFinishLaunchingWithOptions方法中添加如下代碼
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:settings];
8.額外補充
- 在iOS8.0之后,可以設置推送通知帶操作行為
在注冊設置時,設置categories:參數
監聽通知操作行為的點擊
- 遠程推送通知
1.遠程推送的原理
所有蘋果設備, 在聯網狀態下,都會與蘋果服務器建立一個長連接
“長連接”: 相對的一個概念是”短連接”
“長連接”優勢: 服務器可以向客戶端發送信息,保證數據即時性
劣勢: 占用客戶和服務器資源
“短連接”優勢: 節省資源,一個會話結束后,立即釋放資源
劣勢: 服務器無法主動向客戶端發信息
蘋果設備“長連接”作用:
時間校準
系統升級
查找我的iPhone
推送通知...
原理就是借助蘋果設備與APNs服務器之間的長連接, 借助APNs服務器將消息發送給客戶端
2.遠程推送通知實現的條件
只有真機可以調試推送通知
因為只有真機具備UDID, 才能夠生成deviceToken
需要真機調試證書, 推送測試證書
3.遠程推送通知實現, 客戶端需要做的事
- 請求蘋果獲得deviceToken
/**
- 請求通知授權,以及請求遠程通知
*/
-
(void)registerRemoteNotification
{
if (isIOS(8.0))
{
1. 請求通知授權
UIUserNotificationSettings *notificationSet = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSet];2. 注冊遠程通知 [[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
iOS8.0之前請求遠程推送通知
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound ];
}
}
- 得到蘋果返回的deviceToken,發送deviceToken給公司的服務器
/**
- 當遠程通知注冊后,APNs會通過調用這個方法,返回對應的deviceToken
*/
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"%@", deviceToken);
}
- 監聽用戶對通知的點擊
實現APP代理方法
接收到通知, 并且在以下場景
當APP在前臺時, 可以調用
當APP從后臺, 進入到前臺, 可以調用
注意:當APP 被徹底退出時, 不調用這個方法, 調用 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(@"%@", userInfo);
}
或者:
/**
- 當接收到遠程通知時調用(iOS7.0之后使用)
- 當前在前臺時; 或者app在后臺\app被徹底退出狀態下,點擊通知打開app進入前臺; 都可以執行以下方法
- 執行completionHandler 作用
1> 系統會估量App消耗的電量,并根據傳遞的UIBackgroundFetchResult 參數記錄新數據是否可用
2> 調用完成的處理代碼時,應用的界面縮略圖會自動更新
- 如果想要接收到通知后,不要用戶點擊通知, 就執行以下代碼, 那么必須有三個要求:
1> 必須勾選后臺模式Remote Notification ;
2> 告訴系統是否有新的內容更新(執行完成代碼塊)
3> 設置發送通知的格式("content-available":"隨便傳")
*/
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
}
4.遠程推送測試
PushMeBaby
- 編譯會出現錯誤, 直接把錯誤行注釋即可;
- 需要填寫對應的deviceToken;
- 需要將推送測試證書改名為aps.cer 拖入項目中;
5.第三方推送
極光推送(JPush)
個推
信鴿
具體集成步驟以及使用方法, 請查看對應的官方文檔, 非常詳細;
第三方服務合集: [http://mdsa.51cto.com/services/]
二. 應用程序間跳轉
- 什么是應用間跳轉,有什么作用?
- 應用場景
使用第三方用戶登錄,需要用戶授權,還需要"返回到調用的程序,同時返回授權的用戶名"
應用程序推廣,網易彩票,設置-推薦應用-有很多應用程序圖標如果本機已經安裝過,會直接跳轉到另外一個應用程序, 軟件的廣告,推廣結果,后續會有一些列的金錢上的結算
支付寶,第三方支付,淘寶,電話費充值。。。
應用程序間跳轉實現?
直接打開對應APP的scheme即可
1.概念須知
URL : 統一資源定位符
scheme(協議頭) : 決定通過什么方式查找資源 http:// ftp:// tel:// file://
path(路徑) : 資源路徑 www.baidu.com 192.168.1.1/資源 110 /User/Desktop
- 設置方式
默認情況下應用程序是沒有自己的URL的,如果想要擁有自己的URL,需要設置URL
項目 -> info -> URL Types -> URL Scheme
- 打開方式
代碼:
[[UIApplication shareApplication] openURL:appURL];
4.跳轉到對方APP, 對方APP執行的代理方法
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
}
iOS9.0跳轉適配
在info.plist文件中添加LSApplicationQueriesSchemes 字段 ,是數組類型
三. 社交分享
- 什么是社交分享, 有什么作用?
- 通過用戶的分享,讓更多的人去了解和使用這個App
- 目前移動互聯網應用程序推廣的最重要手段之一
- 屬于口碑營銷的范疇,經典成功案例是《瘋狂猜圖》
社交分享的實現方案
1.系統自帶社交分享導入Social.framework
判斷服務是否可用
[SLComposeViewController isAvailableForServiceType:SLServiceTypeSinaWeibo];彈出分享內容輸入界面
SLComposeViewController *cc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeSinaWeibo];
[self presentViewController:cc animated:YES completion:nil];額外設置
[cc setInitialText:@"測試文字"]; 初始化文字
[cc addImage:[UIImage imageNamed:@"lufy"]]; 配圖
2.第三方SDK實現(友盟分享)
下載地址: [http://www.umeng.com/]
1. 申請賬號,創建應用
2. 下載SDK
3. 參照集成文檔
****************************************************************重要**********************
遠程推送應用配置過程
- 創建支持遠程推送功能的App ID
- 創建調試證書,并選中剛剛創建的App ID
- 下載CER文件,并導入鑰匙串管理
- 創建發布證書,并選中剛剛創建的App ID
- 下載CER文件,并導入鑰匙串管理
- 檢查App ID,確認證書已經指定
- 生成描述文件
格式:{"aps":{"alert":"This is some fancy message.","badge":1,"sound":"default"}}
遠程推送應用程序開發過程
- 新建應用程序
- 指定AppID,在developer.apple.com上設置的AppID
if(系統版本 >= 8.0)
{
注冊接收通知的類型
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
注冊允許接收遠程推送通知
[application registerForRemoteNotifications];
}
else
{
如果是iOS7.0,使用以下方法注冊
[application registerForRemoteNotificationTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound];
}
當得到蘋果的APNs服務器返回的DeviceToken就會被調用
7040f7d5 5a974598 c5cf31b5 3e340b39 68affd25 122f0ce1 3f315226 396c2e5b
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"deviceToken是:%@", deviceToken);
}
接收到遠程通知,觸發方法和本地通知一致
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"%@", userInfo);
}
使用后臺的遠程消息推送
1> 在Capabilities中打開遠程推送通知
2> 實現代理方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
遠程消息數據格式:
{"aps" : {"content-available" : 1},"content-id" : 42}
執行completionHandler有兩個目的
1> 系統會估量App消耗的電量,并根據傳遞的UIBackgroundFetchResult 參數記錄新數據是否可用
2> 調用完成的處理代碼時,應用的界面縮略圖會自動更新
注意:接收到遠程通知到執行完網絡請求之間的時間不能超過30秒
if (userInfo) {
int contentId = [userInfo[@"content-id"] intValue];
ViewController *vc = (ViewController *)application.keyWindow.rootViewController;
[vc loadDataWithContentID:contentId completion:^(NSArray *dataList) {
vc.dataList = dataList;
NSLog(@"刷新數據結束");
completionHandler(UIBackgroundFetchResultNewData);
}];
} else {
completionHandler(UIBackgroundFetchResultNoData);
}alertView