1. 程式人生 > >iOS開發 - ANPs推送通知 標簽: 推送通知ANPs遠程推送、本地推送

iOS開發 - ANPs推送通知 標簽: 推送通知ANPs遠程推送、本地推送

control con 垃圾 pre 條件 %20 常用 建立連接 mod

iOS開發 - ANPs推送通知

標簽: 推送通知ANPs遠程推送本地推送 本文章已收錄於: 技術分享 iOS知識庫 技術分享 分類:

目錄(?)[+]

推送通知

註意:這裏說的推送通知跟NSNotification有所區別
NSNotification是抽象的,不可見的
推送通知是可見的(能用肉眼看到)

iOS中提供了2種推送通知
本地推送通知(Local Notification)
遠程推送通知(Remote Notification)

推送通知的呈現效果總結

總結一下,推送通知有5種不同的呈現效果
在屏幕頂部顯示一塊橫幅(顯示具體內容)
在屏幕中間彈出一個UIAlertView(顯示具體內容)
在鎖屏界面顯示一塊橫幅(鎖屏狀態下,顯示具體內容)
更新app圖標的數字(說明新內容的數量)
播放音效(提醒作用)

發出推送通知時,如果當前程序正運行在前臺,那麽推送通知就不會被呈現出來
點擊推送通知後,默認會自動打開發出推送通知的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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
//調度本地推送通知(調度完畢後,推送通知會在特地時間fireDate發出)
[[UIApplication sharedApplication] scheduleLocalNotification:ln];

//獲得被調度(定制)的所有本地推送通知
@property(nonatomic,copy) NSArray *scheduledLocalNotifications;
(已經發出且過期的推送通知就算調度結束,會自動從這個數組中移除)

//取消調度本地推送通知
- (void)cancelLocalNotification:(UILocalNotification *)notification;
- (void)cancelAllLocalNotifications;

//立即發出本地推送通知
- (void)presentLocalNotificationNow:(UILocalNotification *)notification;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

本地推送通知的其他屬性

//每隔多久重復發一次推送通知
@property(nonatomic) NSCalendarUnit repeatInterval;

//點擊推送通知打開app時顯示的啟動圖片
@property(nonatomic,copy) NSString *alertLaunchImage;

//附加的額外信息
@property(nonatomic,copy) NSDictionary *userInfo;

//時區
@property(nonatomic,copy) NSTimeZone *timeZone;
(一般設置為[NSTimeZone defaultTimeZone] ,跟隨手機的時區)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

點擊本地推送通知

//當用戶點擊本地推送通知,會自動打開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取出本地推送通知對象
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

遠程推送通知

什麽是遠程推送通知
顧名思義,就是從遠程服務器推送給客戶端的通知(需要聯網)
遠程推送服務,又稱為APNs(Apple Push Notification Services)

為什麽需要遠程推送通知?
傳統獲取數據的局限性
只要用戶關閉了app,就無法跟app的服務器溝通,無法從服務器上獲得最新的數據內容

遠程推送通知可以解決以上問題
不管用戶打開還是關閉app,只要聯網了,都能接收到服務器推送的遠程通知

遠程推送通知使用須知

所有的蘋果設備,在聯網狀態下,都會與蘋果的服務器建立長連接
什麽是長連接
只要聯網了,就一直建立連接

長連接的作用
時間校準
系統升級
查找我的iPhone
.. …

長連接的好處
數據傳輸速度快
數據保持最新狀態

一.開發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 : 某臺電腦就能發布某個程序

註冊遠程通知

//客戶端如果想接收APNs的遠程推送通知,必須先註冊(得到用戶的授權)
//一般在App啟動完畢後就馬上註冊
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // 註冊遠程通知
       UIRemoteNotificationType type = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound;
    [application registerForRemoteNotificationTypes:type];
    return YES;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
//註冊成功後會調用AppDelegate的下面方法,得到設備的deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSLog(@"%@", deviceToken);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
//當用戶點擊遠程推送通知,會自動打開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取出服務器返回的字典內容
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

PushMeBaby

PushMeBaby是一款用來測試ANPs的開源Mac項目
它充當了服務器的作用,用法非常簡單
它負責將內容提交給蘋果的APNs服務器,蘋果的APNs服務器再將內容推送給用戶的設備
PushMeBaby的主頁
https://github.com/stefanhafeneger/PushMeBaby

遠程推送獲取DeviceToken實例


@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    if ([UIDevice currentDevice].systemVersion.doubleValue <= 8.0) {
        // 不是iOS8
        UIRemoteNotificationType type = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert;
        // 當用戶第一次啟動程序時就獲取deviceToke
        // 該方法在iOS8以及過期了
        // 只要調用該方法, 系統就會自動發送UDID和當前程序的Bunle ID到蘋果的APNs服務器
        [application registerForRemoteNotificationTypes:type];
    }else
    {
        // iOS8
        UIUserNotificationType type = UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound;

        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
        // 註冊通知類型
        [application registerUserNotificationSettings:settings];

        // 申請試用通知
        [application registerForRemoteNotifications];
    }

    // 1.取出數據
    NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];

    if (userInfo) {
        static int count = 0;
        count++;
        UILabel *label = [[UILabel alloc] init];
        label.frame = CGRectMake(0, 40, 200, 200);
        label.numberOfLines = 0;
        label.textColor = [UIColor whiteColor];
        label.font = [UIFont systemFontOfSize:11];
        label.backgroundColor = [UIColor orangeColor];
        label.text = [NSString stringWithFormat:@" %@ \n %d", userInfo, count];
        [self.window.rootViewController.view addSubview:label];
    }


    return YES;
}

/**
 *  獲取到用戶對應當前應用程序的deviceToken時就會調用
 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSLog(@"%@", deviceToken);
    // <47e58207 31340f18 ed83ba54 f999641a 3d68bc7b f3e2db29 953188ec 7d0cecfb>
    // <286c3bde 0bd3b122 68be655f 25ed2702 38e31cec 9d54da9f 1c62325a 93be801e>
}

/*
 ios7以前蘋果支持多任務, iOS7以前的多任務是假的多任務
 而iOS7開始蘋果才真正的推出了多任務
 */
// 接收到遠程服務器推送過來的內容就會調用
// 註意: 只有應用程序是打開狀態(前臺/後臺), 才會調用該方法
/// 如果應用程序是關閉狀態會調用didFinishLaunchingWithOptions
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    /*
     如果應用程序在後臺 , 只有用戶點擊了通知之後才會調用
     如果應用程序在前臺, 會直接調用該方法
     即便應用程序關閉也可以接收到遠程通知
     */
    NSLog(@"%@", userInfo);

//    static int count = 0;
//    count++;
//    UILabel *label = [[UILabel alloc] init];
//    label.frame = CGRectMake(0, 250, 200, 200);
//    label.numberOfLines = 0;
//    label.textColor = [UIColor whiteColor];
//    label.text = [NSString stringWithFormat:@"%@ \n %d", userInfo, count];
//    label.font = [UIFont systemFontOfSize:11];
//    label.backgroundColor = [UIColor grayColor];
//    [self.window.rootViewController.view addSubview:label];
}

//接收到遠程服務器推送過來的內容就會調用
// ios7以後用這個處理後臺任務接收到得遠程通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    /*
     UIBackgroundFetchResultNewData, 成功接收到數據
     UIBackgroundFetchResultNoData, 沒有;接收到數據
     UIBackgroundFetchResultFailed 接收失敗

     */
//    NSLog(@"%s",__func__);
//    NSLog(@"%@", userInfo);

    NSNumber *contentid =  userInfo[@"content-id"];
    if (contentid) {
        UILabel *label = [[UILabel alloc] init];
        label.frame = CGRectMake(0, 250, 200, 200);
        label.numberOfLines = 0;
        label.textColor = [UIColor whiteColor];
        label.text = [NSString stringWithFormat:@"%@", contentid];
        label.font = [UIFont systemFontOfSize:30];
        label.backgroundColor = [UIColor grayColor];
        [self.window.rootViewController.view addSubview:label];
        //註意: 在此方法中一定要調用這個調用block, 告訴系統是否處理成功.
        // 以便於系統在後臺更新UI等操作
        completionHandler(UIBackgroundFetchResultNewData);
    }else
    {
        completionHandler(UIBackgroundFetchResultFailed);
    }

}
@end

iOS開發 - ANPs推送通知 標簽: 推送通知ANPs遠程推送、本地推送