寫在前面
1.推送技術(shù)產(chǎn)生的場景
- 服務(wù)器端主動性: 客戶端與服務(wù)器交互都是客戶端主動的, 服務(wù)器一般不能主動與客戶端進行數(shù)據(jù)交互, 因為服務(wù)器端無法得知客戶端的 IP 地址 及 狀態(tài);
- 數(shù)據(jù)實時性: 如果服務(wù)器端有緊急數(shù)據(jù)要傳遞給客戶端, 就必須主動向客戶端發(fā)送數(shù)據(jù);
- 基本原理: 使客戶端實時獲取服務(wù)器端消息, Pull 方式, 小周期輪詢, 費電費流量; 另一個就是 Push 方式, 服務(wù)器端向客戶端主動推送數(shù)據(jù), 可以省電省流量喘落。
2.極光推送的原理 - .net應(yīng)用程序把要發(fā)送的消息、目的iPhone的標(biāo)識打包,發(fā)給APNS颗味。
- APNS在自身的已注冊Push服務(wù)的iPhone列表中,查找有相應(yīng)標(biāo)識的iPhone,并把消息發(fā)到iPhone。
- iPhone把發(fā)來的消息傳遞給相應(yīng)的應(yīng)用程序问芬, 并且按照設(shè)定彈出Push通知。
項目實現(xiàn)
1.關(guān)于環(huán)境的配置·證書申請寿桨,這個視頻里都有此衅,我相信比我寫出來的好,不懂的可以直接的看這個視頻,在這里就不贅述炕柔。視頻地址如下。
https://community.jiguang.cn/t/topic/6568
2.可能遇到的坑
根據(jù)上面的視頻配置好之后媒佣,可能遇到的坑匕累,下面是我自己配置之后,沒法實現(xiàn)的原因默伍,僅供參考欢嘿。
配置好之后,下面圖片的設(shè)置也糊,如果是這樣就ok了
只要上面的配置是這樣的狀態(tài)了炼蹦,就可以添加代碼實現(xiàn)推送的功能了
代碼實現(xiàn)
- 需要導(dǎo)入的頭文件和代理
#import "JPUSHService.h"
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h> // 這里是iOS10需要用到的框架
#endif
@interface AppDelegate ()<JPUSHRegisterDelegate>//新版的需要實現(xiàn)這個代理方法
- 用到的變量
static NSString *const JPUSHAPPKEY = @"極光appkey";//極光appkey
static NSString *const channel = @"Publish channel";//固定的
- 注冊及實現(xiàn)推送的全部代碼
1.注冊極光推送
//注冊apns通知
if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0)//ios大于10.0
{
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge | UNAuthorizationOptionSound;
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
#endif
}
else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) // iOS8, iOS9
{
//可以添加自定義categories
[JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];
}
else // iOS7
{
//categories 必須為nil
[JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert) categories:nil];
}
//注冊極光推送
[JPUSHService setupWithOption:launchOptions appKey:JPUSHAPPKEY
channel:channel
apsForProduction:false
advertisingIdentifier:nil];
[application setApplicationIconBadgeNumber:0];
2.推送的實現(xiàn)
/**
JPush
*/
#pragma mark - 注冊推送回調(diào)獲取 DeviceToken
#pragma mark -- 成功并上報DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// 注冊成功
// 極光: Required - 注冊 DeviceToken
[JPUSHService registerDeviceToken:deviceToken];
}
#pragma mark -- 實現(xiàn)注冊APNs失敗接口
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
// 注冊失敗
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
#pragma mark - iOS10: 收到推送消息調(diào)用(iOS10是通過Delegate實現(xiàn)的回調(diào))
#pragma mark- JPUSHRegisterDelegate
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
// 當(dāng)程序在前臺時, 收到推送彈出的通知
// 當(dāng)程序在前臺時, 收到推送彈出的通知
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
NSDictionary * userInfo = notification.request.content.userInfo;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]])
{
[JPUSHService handleRemoteNotification:userInfo];
NSString *message = [NSString stringWithFormat:@"will%@", [userInfo[@"aps"] objectForKey:@"alert"]];
NSLog(@"iOS10程序在前臺時收到的推送: %@", message);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil, nil];
[alert show];
}
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要執(zhí)行這個方法,選擇是否提醒用戶狸剃,有Badge掐隐、Sound、Alert三種類型可以設(shè)置
}
#pragma mark- JPUSHRegisterDelegate
// 程序關(guān)閉后, 通過點擊推送彈出的通知
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]])
{
[JPUSHService handleRemoteNotification:userInfo];
// 這個是程序打開之后會有一個彈框的提示
NSString *message = [NSString stringWithFormat:@"did%@", [userInfo[@"aps"] objectForKey:@"alert"]];
NSLog(@"iOS10程序關(guān)閉后通過點擊推送進入程序彈出的通知: %@", message);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil,nil];
[alert show];
}
completionHandler(); // 系統(tǒng)要求執(zhí)行這個方法
}
#endif
結(jié)語
- 上面的關(guān)于環(huán)境的配置之類的還請看視頻和官方的文檔钞馁,文檔里面的都很詳細
- 我這里做的效果是推送的條數(shù)的角標(biāo)是1虑省,當(dāng)打開app的時候,這個角標(biāo)就會消失僧凰,如果角標(biāo)想和具體的推送的條數(shù)一樣探颈,還需要后臺的配合
- 這里做的就是全部的推送,沒有標(biāo)簽训措,后續(xù)會更新伪节,針對不同用戶的推送。