iOS消息推送機(jī)制

推送通知跟NSNotification不同
1.NSNotification是抽象的,不可見(jiàn)的
2.推送通知是可見(jiàn)的

iOS中提供了2中推送通知
1.本地推送通知(Local Notification)
2.遠(yuǎn)程推送通知(Remote Notification)

推送的作用:可以讓不在前臺(tái)運(yùn)行的app,告知客戶app內(nèi)部發(fā)生的事情.(QQ消息推送,微信消息推送等等)

推送通知的呈現(xiàn)效果:
1.在屏幕頂部顯示的一條橫幅
2.在屏幕中間彈出一個(gè)UIAlertView
3.在鎖屏界面顯示一塊橫幅
4.跟新app圖標(biāo)的數(shù)字
5.播放音效

本地通知

1.不需要服務(wù)器支持(無(wú)需聯(lián)網(wǎng))就能發(fā)出的推送通知
2.使用場(chǎng)景: 定時(shí)類任務(wù)(鬧鐘,簡(jiǎn)單的游戲等等)

本地通知推送的實(shí)現(xiàn)很簡(jiǎn)單:
1.創(chuàng)建本地推送通知對(duì)象
[[UILocalNotification alloc] init]創(chuàng)建一個(gè)本地通知
2.設(shè)置本地通知的相關(guān)屬性
必須設(shè)置的屬性
2.1.推送通知的觸發(fā)時(shí)間(何時(shí)發(fā)出推送通知)
@property(nonatomic,copy) NSDate *fireDate
2.2.推送通知的具體內(nèi)容
@property(nonatomic,copy) NSString *alertBody
2.3.在鎖屏?xí)r顯示的動(dòng)作標(biāo)題(完整測(cè)標(biāo)題:"滑動(dòng)來(lái)" + alertAction)
@property(nonatomic,copy) NSString *alertAction
2.4.設(shè)置鎖屏界面alertAction是否有效
localNote.hasAction = YES;
2.5.app圖標(biāo)數(shù)字
@property(nonatomic,assign) NSInteger applicationIconBadgeNumber
2.6.調(diào)度本地推送通知(調(diào)度完畢后,推動(dòng)通知會(huì)在特定時(shí)間fireDate發(fā)出)
[[UIApplication shareApplication] scheduleLocalNotification:ln]
可以進(jìn)行設(shè)置的設(shè)置
2.7.設(shè)置通知中心通知的標(biāo)題
localNote.alertTitle = @"222222222222";
2.8.設(shè)置音效(如果不設(shè)置就是系統(tǒng)默認(rèn)的音效, 設(shè)置的話會(huì)在mainBundle中查找)
localNote.soundName = @"buyao.wav";
2.9.每隔多久重復(fù)發(fā)一次推送通知
@property(nonatomic) NSCalendarUnit repeatInterval
2.10.點(diǎn)擊推送通知打開(kāi)app時(shí)顯示的啟動(dòng)圖片(mainBundle 中提取圖片)
@property(nonatomic,copy) NSSring *alertLaunchImage
2.11.附加的額外信息
@property(nonatomic,copy) NSDictionary *userInfo
2.12.時(shí)區(qū)
@property(nonatomic,copy) NSTimeZone *timeZone
(一般設(shè)置為[NSTimeZone defaultTimeZone],跟隨手機(jī)的時(shí)區(qū))

/*
 @property(nonatomic,copy) NSDate *fireDate;
 @property(nonatomic,copy) NSTimeZone *timeZone; 時(shí)區(qū)

 @property(nonatomic) NSCalendarUnit repeatInterval; 重復(fù)間隔(枚舉)
 @property(nonatomic,copy) NSCalendar *repeatCalendar; 重復(fù)日期(NSCalendar)

 @property(nonatomic,copy) CLRegion *region 設(shè)置區(qū)域(設(shè)置當(dāng)進(jìn)入某一個(gè)區(qū)域時(shí),發(fā)出一個(gè)通知)

 @property(nonatomic,assign) BOOL regionTriggersOnce YES,只會(huì)在第一次進(jìn)入某一個(gè)區(qū)域時(shí)發(fā)出通知.NO,每次進(jìn)入該區(qū)域都會(huì)發(fā)通知

 @property(nonatomic,copy) NSString *alertBody;      

 @property(nonatomic) BOOL hasAction;                是否隱藏鎖屏界面設(shè)置的alertAction
 @property(nonatomic,copy) NSString *alertAction;    設(shè)置鎖屏界面一個(gè)文字

 @property(nonatomic,copy) NSString *alertLaunchImage;   啟動(dòng)圖片
 @property(nonatomic,copy) NSString *alertTitle

 @property(nonatomic,copy) NSString *soundName;

 @property(nonatomic) NSInteger applicationIconBadgeNumber;

 @property(nonatomic,copy) NSDictionary *userInfo; // 設(shè)置通知的額外的數(shù)據(jù)
 */

- (IBAction)addLocalNote:(id)sender {
    // 1.創(chuàng)建一個(gè)本地通知
    UILocalNotification *localNote = [[UILocalNotification alloc] init];

    // 2.設(shè)置本地通知的一些屬性(通知發(fā)出的時(shí)間/通知的內(nèi)容)
    // 2.1.設(shè)置通知發(fā)出的時(shí)間
    localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:5.0];
    // 2.2.設(shè)置通知的內(nèi)容
    localNote.alertBody = @"吃飯了嗎?";
    // 2.3.設(shè)置鎖屏界面的文字
    localNote.alertAction = @"查看具體的消息";
    // 2.4.設(shè)置鎖屏界面alertAction是否有效
    localNote.hasAction = YES;
    // 2.5.設(shè)置通過(guò)點(diǎn)擊通知打開(kāi)APP的時(shí)候的啟動(dòng)圖片(無(wú)論字符串設(shè)置成什么內(nèi)容,都是顯示應(yīng)用程序的啟動(dòng)圖片)
    localNote.alertLaunchImage = @"111";
    // 2.6.設(shè)置通知中心通知的標(biāo)題
    localNote.alertTitle = @"222222222222";
    // 2.7.設(shè)置音效
    localNote.soundName = @"buyao.wav";
    // 2.8.設(shè)置應(yīng)用程序圖標(biāo)右上角的數(shù)字
    localNote.applicationIconBadgeNumber = 1;
    // 2.9.設(shè)置通知之后的屬性
    localNote.userInfo = @{@"name" : @"張三", @"toName" : @"李四"};

    // 3.調(diào)度通知
    [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
}

當(dāng)消息被推送過(guò)來(lái)時(shí),我們需要點(diǎn)擊推送消息,來(lái)完成一些特定的任務(wù).不如更新界面什么的(監(jiān)聽(tīng)本地推送通知的點(diǎn)擊)

當(dāng)用戶點(diǎn)擊本地推送通知的時(shí)候,會(huì)自動(dòng)打開(kāi)app,這里有2種情況

1.app沒(méi)有關(guān)閉,只是一直隱藏在后臺(tái)
讓app進(jìn)入前臺(tái),并會(huì)調(diào)用AppDelegate的下面的方法(并非重新啟動(dòng)app)

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
----代碼實(shí)現(xiàn)

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    // 在這里寫(xiě)跳轉(zhuǎn)代碼
    // 如果是應(yīng)用程序在前臺(tái),依然會(huì)收到通知,但是收到通知之后不應(yīng)該跳轉(zhuǎn)
    if (application.applicationState == UIApplicationStateActive) return;

    if (application.applicationState == UIApplicationStateInactive) {
        // 當(dāng)應(yīng)用在后臺(tái)收到本地通知時(shí)執(zhí)行的跳轉(zhuǎn)代碼
        [self jumpToSession];
    }

    NSLog(@"%@", notification);
}

- (void)jumpToSession
{
    UILabel *redView = [[UILabel alloc] init];
    redView.backgroundColor = [UIColor redColor];
    redView.frame = CGRectMake(0, 100, 300, 400);
    redView.numberOfLines = 0;
    // redView.text = [NSString stringWithFormat:@"%@", launchOptions];
    [self.window.rootViewController.view addSubview:redView];
}

2.app已經(jīng)被關(guān)閉(進(jìn)程被殺死)

啟動(dòng)app,啟動(dòng)完畢會(huì)調(diào)用AppDelegate的下面的方法

  • (BOOL)application:(UIApplication *)application didFinishLaunchWithOptions:(NSDictionary *)launchOptions;
    launchOptions參數(shù)通過(guò)UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對(duì)象
    需要特別注意的是:在iOS8.0以后本地通知有了一些變化,如果要使用本地通知,需要得到用戶的許可.
    在didFinishLaunchWithOptions方法中添加如下代碼:
#define IS_iOS8 ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)

 if (IS_iOS8) {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
        [application registerUserNotificationSettings:settings];
    }

-----代碼實(shí)現(xiàn)相關(guān)操作

#define IS_iOS8 ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    /*
     UIUserNotificationTypeNone    = 0,      不發(fā)出通知
     UIUserNotificationTypeBadge   = 1 << 0, 改變應(yīng)用程序圖標(biāo)右上角的數(shù)字
     UIUserNotificationTypeSound   = 1 << 1, 播放音效
     UIUserNotificationTypeAlert   = 1 << 2, 是否運(yùn)行顯示橫幅
     */

    [application setApplicationIconBadgeNumber:0];

    if (IS_iOS8) {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
        [application registerUserNotificationSettings:settings];
    }

    // 如果是正常啟動(dòng)應(yīng)用程序,那么launchOptions參數(shù)是null
    // 如果是通過(guò)其它方式啟動(dòng)應(yīng)用程序,那么launchOptions就值
    if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
        // 當(dāng)被殺死狀態(tài)收到本地通知時(shí)執(zhí)行的跳轉(zhuǎn)代碼
        // [self jumpToSession];
        UILabel *redView = [[UILabel alloc] init];
        redView.backgroundColor = [UIColor redColor];
        redView.frame = CGRectMake(0, 100, 300, 400);
        redView.numberOfLines = 0;
        redView.text = [NSString stringWithFormat:@"%@", launchOptions];
        [self.window.rootViewController.view addSubview:redView];
    }

    return YES;
}

遠(yuǎn)程推送(Remote Notification)

1.從遠(yuǎn)程服務(wù)器推送給客戶端的通知(需要聯(lián)網(wǎng))
2.遠(yuǎn)程推送服務(wù), 蘋(píng)果起名為:APNS (Apple Push Notification Services)
解決問(wèn)題:只要聯(lián)網(wǎng)了, 就能夠接收到服務(wù)器推送的遠(yuǎn)程通知
使用須知:
所有的蘋(píng)果設(shè)備,在聯(lián)網(wǎng)狀態(tài)下,都會(huì)與蘋(píng)果服務(wù)器建立長(zhǎng)連接.
1.長(zhǎng)連接:一直連接,客戶端與服務(wù)器
2.長(zhǎng)連接作用:
1>事件校準(zhǔn)
2>系統(tǒng)升級(jí)
3>查找我的iPhone等....
3.長(zhǎng)連接的好處
1>數(shù)據(jù)傳輸速度快
2>數(shù)據(jù)保持最新?tīng)顟B(tài)

官方結(jié)實(shí)長(zhǎng)連接的使用

1.獲得deviceToken的過(guò)程

1.png
2.png

1>客戶端向蘋(píng)果服務(wù)APNS,發(fā)送設(shè)備的UDID和英語(yǔ)的Bundle Identifier.
2>經(jīng)蘋(píng)果服務(wù)器加密生成一個(gè)deviceToken
3>將當(dāng)前用戶的deviceToken(用戶標(biāo)識(shí)),發(fā)送給自己應(yīng)用的服務(wù)器
4>自己的服務(wù)器,將得到的deviceToken,進(jìn)行保存

2.利用deviceToken進(jìn)行數(shù)據(jù)傳輸,推送通知

3.png

5>需要推送的時(shí)候,將消息和deviceToken一起發(fā)送給APNS,蘋(píng)果服務(wù)器,再通過(guò)deviceToken找到用戶,并將消息發(fā)給用戶

4.png

這里不再演示關(guān)于證書(shū)的配置, 簡(jiǎn)單的只進(jìn)行說(shuō)明步驟:
1> 創(chuàng)建明確的AppID,只有明確的AppID才能進(jìn)行一些特殊的操作
2>真機(jī)調(diào)試的APNS SSL證書(shū)
3>發(fā)布程序的APNS SSL證書(shū)
4>生成描述文件
[依次安裝證書(shū), 再裝描述]

注冊(cè)遠(yuǎn)程推送通知:

1.客戶端如果想要接收APNs的遠(yuǎn)程推送通知,必須先進(jìn)行注冊(cè)(得到用戶授權(quán))
一般在APP啟動(dòng)完畢后就馬上進(jìn)行注冊(cè)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
        // 1.注冊(cè)UserNotification,以獲取推送通知的權(quán)限
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil];
        [application registerUserNotificationSettings:settings];

        // 2.注冊(cè)遠(yuǎn)程推送
        [application registerForRemoteNotifications];
    } else {
        [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeNewsstandContentAvailability | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
    }

    return YES;
}

2.注冊(cè)成功后, 調(diào)用AppDelegate的方法,獲取到用戶的deviceToken

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    // <32e7cf5f 8af9a8d4 2a3aaa76 7f3e9f8e 1f7ea8ff 39f50a2a e383528d 7ee9a4ea>
    // <32e7cf5f 8af9a8d4 2a3aaa76 7f3e9f8e 1f7ea8ff 39f50a2a e383528d 7ee9a4ea>
    NSLog(@"%@", deviceToken.description);
}

3.點(diǎn)擊推送通知,和本地一樣有兩種狀況.
1> app沒(méi)有關(guān)閉,只是一直隱藏在后臺(tái)
讓app進(jìn)入前臺(tái), 并調(diào)用下面的方法(app沒(méi)有重新啟動(dòng))
過(guò)期的方法:

// 當(dāng)接受到遠(yuǎn)程退職時(shí)會(huì)執(zhí)行該方法(當(dāng)進(jìn)入前臺(tái)或者應(yīng)用程序在前臺(tái))
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    NSLog(@"%@", userInfo);

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    redView.frame = CGRectMake(100, 100, 100, 100);
    [self.window.rootViewController.view addSubview:redView];
}

蘋(píng)果系統(tǒng)建議使用下面的方法:

/*
 1.開(kāi)啟后臺(tái)模式
 2.調(diào)用completionHandler,告訴系統(tǒng)你現(xiàn)在是否有新的數(shù)據(jù)更新
 3.userInfo添加一個(gè)字段:"content-available" : "1" : 只要添加了該字段,接受到通知都會(huì)在后臺(tái)運(yùn)行
 */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"%@", userInfo);
    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    redView.frame = CGRectMake(100, 100, 100, 100);
    [self.window.rootViewController.view addSubview:redView];

    completionHandler(UIBackgroundFetchResultNewData);
}

2>app已經(jīng)關(guān)閉,需要重新開(kāi)啟,---基本實(shí)現(xiàn)方法和本地通知yi'zhi

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市虐秦,隨后出現(xiàn)的幾起案子漂辐,更是在濱河造成了極大的恐慌饺鹃,老刑警劉巖俊马,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呆瞻,死亡現(xiàn)場(chǎng)離奇詭異峭范,居然都是意外死亡萝嘁,警方通過(guò)查閱死者的電腦和手機(jī)梆掸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牙言,“玉大人酸钦,你說(shuō)我怎么就攤上這事≡弁鳎” “怎么了卑硫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蚕断。 經(jīng)常有香客問(wèn)我欢伏,道長(zhǎng),這世上最難降的妖魔是什么基括? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任颜懊,我火速辦了婚禮财岔,結(jié)果婚禮上风皿,老公的妹妹穿的比我還像新娘。我一直安慰自己匠璧,他們只是感情好桐款,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著夷恍,像睡著了一般魔眨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天遏暴,我揣著相機(jī)與錄音侄刽,去河邊找鬼。 笑死朋凉,一個(gè)胖子當(dāng)著我的面吹牛州丹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杂彭,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼墓毒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了亲怠?” 一聲冷哼從身側(cè)響起所计,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎团秽,沒(méi)想到半個(gè)月后主胧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡习勤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年讥裤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姻报。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡己英,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吴旋,到底是詐尸還是另有隱情损肛,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布荣瑟,位于F島的核電站治拿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏笆焰。R本人自食惡果不足惜劫谅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嚷掠。 院中可真熱鬧捏检,春花似錦、人聲如沸不皆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)霹娄。三九已至能犯,卻和暖如春鲫骗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背踩晶。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工执泰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人渡蜻。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓坦胶,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親晴楔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子顿苇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 推送通知跟NSNotification不同1.NSNotification是抽象的,不可見(jiàn)的2.推送通知是可見(jiàn)的 ...
    Little_Dragon閱讀 39,722評(píng)論 32 184
  • 極光推送: 1.JPush當(dāng)前版本是1.8.2,其SDK的開(kāi)發(fā)除了正常的功能完善和擴(kuò)展外也緊隨蘋(píng)果官方的步伐税弃,SD...
    Isspace閱讀 6,719評(píng)論 10 16
  • 推送通知 注意:這里說(shuō)的推送通知跟NSNotification有所區(qū)別 NSNotification是抽象的纪岁,不可...
    iOS開(kāi)發(fā)攻城獅閱讀 4,229評(píng)論 1 13
  • iOS消息推送的工作機(jī)制可以簡(jiǎn)單的用下圖來(lái)概括: Provider是指某個(gè)iPhone軟件的Push服務(wù)器,APN...
    zhouyuhan閱讀 2,682評(píng)論 0 4
  • 推送通知注意:這里說(shuō)的推送通知跟NSNotification有所區(qū)別NSNotification是抽象的则果,不可見(jiàn)的...
    醉葉惜秋閱讀 1,515評(píng)論 0 3