這里是指推送通知跟NSNotification有區(qū)別:
1、NSNotification是系統(tǒng)內(nèi)部發(fā)出通知,一般用于內(nèi)部事件的監(jiān)聽(tīng),或者狀態(tài)的改變等等,是不可見(jiàn)的
2、本地通知與遠(yuǎn)程通知是可見(jiàn)的,主要用于告知用戶或者發(fā)送一些App的內(nèi)容更新,推送一些相關(guān)的消息,讓用戶知道App內(nèi)部發(fā)生了什么事情。

iOS常用通知
1、本地推送通知:(Local Notification)
2、遠(yuǎn)程推送通知:(Remote Notification)
iOS通知呈現(xiàn)效果(5)
1.設(shè)置音效,(提醒作用)
2.設(shè)置橫幅,
3.設(shè)置彈窗,
4.鎖屏下也可以呈現(xiàn),
5.App圖標(biāo)的數(shù)字 (即新內(nèi)容的數(shù)量)
至于顯示橫幅或者彈窗,取決于用戶的設(shè)置
iOS手機(jī)設(shè)置中:通知中心-選擇應(yīng)用-選擇應(yīng)用下的通知模式-OK!

通知的注意點(diǎn)
1、App在前臺(tái)運(yùn)行的時(shí)候,通知不會(huì)展示出來(lái)
2、點(diǎn)擊通知,默認(rèn)會(huì)自動(dòng)打開(kāi)推送通知的App
3、不管App是否打開(kāi),通知都可以如期發(fā)出
1、本地推送通知:
不需要聯(lián)網(wǎng)就可以發(fā)出的通知
使用場(chǎng)景:
提醒用戶完成一些任務(wù),比如:定時(shí)提醒,生活備注,看電影等等
推送通知屬性:
// 枚舉值-發(fā)出通知的時(shí)間(有局限性)
@property(nonatomic) NSCalendarUnit repeatInterval;
// 自定義-發(fā)出通知的時(shí)間(可以自由設(shè)定時(shí)間)
@property(nonatomic,copy) NSCalendar *repeatCalendar;
// 區(qū)域-創(chuàng)建只需要?jiǎng)?chuàng)建一個(gè)中心點(diǎn)與半徑就可以了
@property(nonatomic,copy) CLRegion *region
// 進(jìn)入?yún)^(qū)域發(fā)出一個(gè)通知,設(shè)置yes,只會(huì)發(fā)出一個(gè)通知,設(shè)置NO就會(huì)每次進(jìn)入這個(gè)區(qū)域都發(fā)送
@property(nonatomic,assign) BOOL regionTriggersOnce NO
// 設(shè)置通知的內(nèi)容
@property(nonatomic,copy) NSString *alertBody;
// 決定alertAction是否生效
@property(nonatomic) BOOL hasAction;
// 設(shè)置滑塊的文字
@property(nonatomic,copy) NSString *alertAction;
// 設(shè)置點(diǎn)擊通知的啟動(dòng)圖片(一般設(shè)置App啟動(dòng)圖片后,這里可以隨便寫(xiě))
@property(nonatomic,copy) NSString *alertLaunchImage;
// 設(shè)置alertTitle,就是通知內(nèi)容上面的文字
@property(nonatomic,copy) NSString *alertTitle
// 設(shè)置彈出的聲音
@property(nonatomic,copy) NSString *soundName;
// 設(shè)置App的消息條數(shù)
@property(nonatomic) NSInteger applicationIconBadgeNumber;
// 設(shè)置通知一些額外數(shù)據(jù)
@property(nonatomic,copy) NSDictionary *userInfo;
如何發(fā)出本地通知:
// 1.創(chuàng)建本地通知
UILocalNotification *localNote = [[UILocalNotification alloc] init];
// 2.設(shè)置本地通知的內(nèi)容
// 2.1.設(shè)置通知發(fā)出的時(shí)間
localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:3.0];
// 2.2.設(shè)置通知的內(nèi)容
localNote.alertBody = @"在干嗎?";
// 2.3.設(shè)置滑塊的文字(鎖屏狀態(tài)下:滑動(dòng)來(lái)“解鎖”)
localNote.alertAction = @"解鎖";
// 2.4.決定alertAction是否生效
localNote.hasAction = NO;
// 2.5.設(shè)置點(diǎn)擊通知的啟動(dòng)圖片
localNote.alertLaunchImage = @"123Abc";
// 2.6.設(shè)置alertTitle
localNote.alertTitle = @"你有一條新通知";
// 2.7.設(shè)置有通知時(shí)的音效
localNote.soundName = @"buyao.wav";
// 2.8.設(shè)置應(yīng)用程序圖標(biāo)右上角的數(shù)字
localNote.applicationIconBadgeNumber = 999;
// 2.9.設(shè)置額外信息
localNote.userInfo = @{@"type" : @1};
// 3.調(diào)用通知
[[UIApplication sharedApplication] scheduleLocalNotification:localNote];
}
使用注意:
iOS7,不需要用戶授權(quán)就可發(fā)出通知,而iOS8以后,必須用戶授權(quán)才可以發(fā)出通知
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 設(shè)置應(yīng)用程序的圖標(biāo)右上角的數(shù)字
[application setApplicationIconBadgeNumber:0];
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
}
// 界面的跳轉(zhuǎn)(針對(duì)應(yīng)用程序被殺死的狀態(tài)下的跳轉(zhuǎn))
// 殺死狀態(tài)下的,界面跳轉(zhuǎn)并不會(huì)執(zhí)行下面的方法- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification,
// 所以我們?cè)趯?xiě)本地通知的時(shí)候,要在這個(gè)與下面方法中寫(xiě),但要判斷,是通過(guò)哪種類型通知來(lái)打開(kāi)的
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
// 跳轉(zhuǎn)代碼
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;
}
監(jiān)聽(tīng)通知,如果用戶打開(kāi)通知,可以讓用戶進(jìn)入一些特定的界面
/*
應(yīng)用程序在進(jìn)入前臺(tái),或者在前臺(tái)的時(shí)候都會(huì)執(zhí)行該方法
*/
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// 必須要監(jiān)聽(tīng)--應(yīng)用程序在后臺(tái)的時(shí)候進(jìn)行的跳轉(zhuǎn)
if (application.applicationState == UIApplicationStateInactive) {
NSLog(@"進(jìn)行界面的跳轉(zhuǎn)");
// 如果在上面的通知方法中設(shè)置了一些,可以在這里打印額外信息的內(nèi)容,就做到監(jiān)聽(tīng),也就可以根據(jù)額外信息,做出相應(yīng)的判斷
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、遠(yuǎn)程推送通知:
從遠(yuǎn)程服務(wù)器推送給客戶端的通知(需要聯(lián)網(wǎng))
遠(yuǎn)程推送服務(wù)---就是APNs
模擬器無(wú)法調(diào)試遠(yuǎn)程推送
為什么需要遠(yuǎn)程推送通知:
解決獲取傳統(tǒng)數(shù)據(jù)的局限性,讓數(shù)據(jù)實(shí)時(shí)更新
使用場(chǎng)景:
聊天功能(一般非即時(shí)聊天)、推送一下App的內(nèi)部新功能、版本下載等
注:所有的蘋(píng)果設(shè)備,在聯(lián)網(wǎng)狀態(tài)下,都會(huì)與蘋(píng)果的服務(wù)器建立-長(zhǎng)連接
長(zhǎng)連接的作用:
時(shí)間效準(zhǔn)、系統(tǒng)升級(jí)、查找我的iphone、遠(yuǎn)程通知
好處:
數(shù)據(jù)傳輸快、數(shù)據(jù)保持最新?tīng)顟B(tài)



我在面試中一般也比較喜歡問(wèn)面試者這個(gè)問(wèn)題。能解釋清楚肯定就有貨真價(jià)實(shí)的開(kāi)發(fā)經(jīng)驗(yàn)
使用遠(yuǎn)程推送
1、獲取蘋(píng)果獲得deviceToken-獲取手機(jī)UDID+應(yīng)用的唯一標(biāo)識(shí)(bundel ID)
2、得到蘋(píng)果返回的deviceToken
3、發(fā)送deviceToken給公司的服務(wù)器
4、監(jiān)聽(tīng)用戶對(duì)通知的點(diǎn)擊
如何調(diào)試遠(yuǎn)程推送功能
1、真機(jī)
2、調(diào)試推送需要的證書(shū)文件
證書(shū)自己配置。。。
3、發(fā)布具有推送服務(wù)的App
包含推送的cer證書(shū)+某個(gè)具有發(fā)布資格的電腦,就可以發(fā)布
如何推送
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
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];
}
// 根據(jù)遠(yuǎn)程通知通過(guò)UIApplicationLaunchOptionsRemoteNotificationKey打開(kāi)的情況來(lái)進(jìn)行
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
// 跳轉(zhuǎn)
// 添加一個(gè)紅色的View
}
return YES;
}
// 獲取DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// 將DeviceToken傳給服務(wù)器
NSLog(@"%@", deviceToken.description);
}
// 正常接到遠(yuǎn)程通知的時(shí)候會(huì)調(diào)用這個(gè)方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(@"%@", userInfo);
// 正常打開(kāi)推送后,
}
// 后臺(tái)操作(根據(jù)收到推送,讓程序自己執(zhí)行一些操作,不管用戶是否點(diǎn)擊推送)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(@"---------");
UIView *redV = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
redView.frame = CGRectMake(100, 100, 100, 100);
[self.window.rootViewController.view addSubview:redV];
// 1.打開(kāi)后臺(tái)模式 2.告訴系統(tǒng)是否有新內(nèi)容的更新 3.發(fā)送的通知有固定的格式("content-available":"1")
// 2.告訴系統(tǒng)有新內(nèi)容
completionHandler(UIBackgroundFetchResultNewData);
}
1、打開(kāi)后臺(tái)模式

2、告訴系統(tǒng)有新內(nèi)容
completionHandler(UIBackgroundFetchResultNewData);
3、發(fā)送通知有固定格式
("content-available":"1")
找的這張圖:也有相應(yīng)的模擬推送代碼,需要的可以聯(lián)系我

一般開(kāi)發(fā)中直接使用(jpush)激光推送就可以快速完成App的推送功能。具體按照官方文檔來(lái)進(jìn)行.(有空會(huì)寫(xiě)一篇專門(mén)針對(duì)激光推送的文稿)