消息推送实践ios推送iOS_Skill_Collect

阿里云推送SDK iOS端配置

2017-03-14  本文已影响1237人  蓝白七七

阿里云 SDK配置 请依官方为主,毕竟已经很详细了
https://help.aliyun.com/document_detail/30072.html?spm=5176.doc30071.6.648.No5CmA

SDK配置流程:
1、导入下载好的 OneSDK

引入Framework 在 Xcode 中,直接把下载SDK目录中的framework 拖入对应 Target 下即可,在弹出框勾选 Copy items if needed。

oneSDK 目录结构:
2、添加公共包依赖 在 Build Phases -> Link Binary With Libraries中,引入下列的公共包:
3、特殊要求
4、在AppDelegate.m 里面完成配置
# import <CloudPushSDK/CloudPushSDK.h>
5、Xcode 设置
6、常遇见的问题:
# import <UserNotifications/UserNotifications.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
附录一份具体代码:
//
//  AppDelegate.m
//  RAliMPushDemo
//
//  Created by mac on 2017/7/14.
//  Copyright © 2017年 rockey. All rights reserved.
//
#import "AppDelegate.h"

//导入头文件
#import <CloudPushSDK/CloudPushSDK.h>
static NSString *const testAppKey = @"*****";
static NSString *const testAppSecret = @"****************";

// iOS 10 notification
#import <UserNotifications/UserNotifications.h>

@interface AppDelegate ()<UNUserNotificationCenterDelegate>

@end

@implementation AppDelegate
{
    // iOS 10通知中心
    UNUserNotificationCenter *_notificationCenter;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   
    // 第一种情况:当程序处于关闭状态收到推送消息时,点击图标会调用该方法,那么消息给通过launchOptions这个参数获取到。
    //当app未运行的时候
    //在该方法中 didFinishLaunchingWithOptions:这个函数在你正常启动下 launchOptions 是空,如果你是从点击推送通知过来的,那么 laungchOptions里面会包含你的推送的内容。在这里就可以进行相应的处理,你就可以发一个通知,可以在rootViewController中接收执行相应的操作
    
    if (launchOptions) {
        NSLog(@"==============%@",launchOptions);
        NSDictionary* pushNotificationKey = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (pushNotificationKey) {
            //这里定义自己的处理方式
            // 如果需要代码控制BadgeNum(icon右上角的数字)
            [UIApplication sharedApplication].applicationIconBadgeNumber = 10;
        }
    }
    
    // 是否允许通知 并向苹果APNs注册 获取deviceToken
    [self authorizeNotification];
   
    // 初始化阿里云推送SDK
    [self initCloudPush];
    // 监听推送消息到达 推送消息到来监听;
    [self registerMessageReceive];
    
    //4、点击通知  将App从关闭状态启动时,将通知打开回执上报
    [CloudPushSDK sendNotificationAck:launchOptions];
    return YES;
}
#pragma mark 初始化阿里云推送SDK
- (void)initCloudPush {
    // 正式上线建议关闭
    [CloudPushSDK turnOnDebug];
    
    // 初始化SDK
    [CloudPushSDK asyncInit:testAppKey appSecret:testAppSecret callback:^(CloudPushCallbackResult *res) {
        if (res.success) {
            NSLog(@"Push SDK init success, \n====================================deviceId: %@.", [CloudPushSDK getDeviceId]);
        } else {
            NSLog(@"Push SDK init failed, error: %@", res.error);
        }
    }];
}

//==========================================================

//是否允许通知
//并向苹果APNs注册 以获取deviceToken
- (void)authorizeNotification {
    
    float systemVerson = [[UIDevice currentDevice].systemVersion floatValue];
    
    if (systemVerson >= 10.0) {
        // iOS 10 notifications
        _notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
        _notificationCenter.delegate = self; //遵循协议
        // 创建category,并注册到通知中心
        [self createCustomNotificationCategory];
        // 请求推送权限
        [_notificationCenter requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                // granted
                NSLog(@"User authored notification.");
                // 向APNs注册,获取deviceToken 系统注册
                [[UIApplication sharedApplication] registerForRemoteNotifications];
            } else {
                // not granted
                NSLog(@"User denied notification.");
            }
        }];
        
        [_notificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            //进行判断做出相应的处理
            
            if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
                NSLog(@"未选择");
            } else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
                NSLog(@"未授权");
            } else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized){
                NSLog(@"已授权");
            }
        }];
        
    } else if (systemVerson >= 8.0) {//适配 iOS_8, iOS_10.0
       
        //提出弹窗,授权是否允许通知
        UIUserNotificationSettings * settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        // 注册远程通知 (iOS_8+)
        [[UIApplication sharedApplication] registerForRemoteNotifications];
     
        if ([[UIApplication sharedApplication] currentUserNotificationSettings].types  == UIUserNotificationTypeNone) { //判断用户是否打开通知开关
            NSLog(@"没有打开");
        }else {
            NSLog(@"已经打开");
        }
        
    } else { //适配 iOS 8 之前的版本 3_0, 8_0
        UIRemoteNotificationType types = UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert;
        [[UIApplication sharedApplication]registerForRemoteNotificationTypes:types];
    
        if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes]  == UIRemoteNotificationTypeNone) { //判断用户是否打开通知开关
        }
    }
}

//====================================================
//APNs推送注册成功回调,将苹果返回的deviceToken上传到CloudPush服务器
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken NS_AVAILABLE_IOS(3_0) {
    
    [CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *res) {
        if (res.success) {
            NSLog(@"Register deviceToken success, \n===================================deviceToken: %@", [CloudPushSDK getApnsDeviceToken]);
        } else {
            NSLog(@"Register deviceToken failed, error: %@", res.error);
        }
    }];
}

// APNs注册失败回调
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"didFailToRegisterForRemoteNotificationsWithError \n===========================%@", error);
}
//=====================================================================

//====== 监听 消息 到达 并处理推送的消息====================================
- (void)registerMessageReceive {
    [[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(onMessageReceived:) name:@"CCPDidReceiveMessageNotification" object:nil];
}
- (void)onMessageReceived:(NSNotification *)notification {
    CCPSysMessage *message = [notification object];
    NSString *title = [[NSString alloc] initWithData:message.title encoding:NSUTF8StringEncoding];
    NSString *body = [[NSString alloc] initWithData:message.body encoding:NSUTF8StringEncoding];
    NSLog(@"======================= title: %@, content: %@.", title, body);
}
//==============================================================


//App处于前台时,如果收到远程通知则调用该处理方法 iOS(3_0, 10_0) 程序处于后台的时候是无法接收到推送信息的
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    //通过远程通知进入应用时候
    application.applicationIconBadgeNumber = 0;
    /*
    1、在ios7上时,只要收到通知,就会调起didReceiveRemoteNotification
    1.2、当程序处于前台工作时,这时候若收到消息推送,会调用该这个方法
    1.3、当程序处于后台运行时,这时候若收到消息推送,如果点击消息或者点击消息图标时,也会调用该这个方法
     
    2、但在iOS_8 上时,只有app前台运行或充电时,才会调起didReceiveRemoteNotification
    2.1、并且 iOS_8 得开启后台模式下接收远程通知。工程配置 TARGATES --> Capabilities BackgroundModes -> ON 选择 RemoteNotification
   
     */
    
    //2.2、处理方法:
    if (application.applicationState == UIApplicationStateActive) {
        //前台时候
        if ([[userInfo objectForKey:@"aps"] objectForKey:@"alert"]!=NULL) {
        //处理情况
            
        }
    } else {
        //后台时候
        //这里定义自己的处理方式
    }
    
    
    /*
     
     iOS 如何判断是点击推送信息进入还是点击app图标进入程序
     设备接到apns发来的通知,应用处理通知有以下几种情况:
     1. 应用还没有加载
     这时如果点击通知的显示按钮,会调用didFinishLaunchingWithOptions,不会调用didReceiveRemoteNotification方法。
     如果点击通知的关闭按钮,再点击应用,只会调用didFinishLaunchingWithOptions方法。
     2. 应用在前台(foreground)
     这时如果收到通知,会触发didReceiveRemoteNotification方法。
     3. 应用在后台
     (1)此时如果收到通知,点击显示按钮,会调用didReceiveRemoteNotification方法。
     (2)点击关闭再点击应用,则上面两个方法都不会被调用这时,只能在applicationWillEnterForeground或者applicationDidBecomeActive,根据发过来通知中的badge进行判断是否有通知,然后发请求获取数据
   
     */
    
    // NSLog(@"Receive one notification.");
    // 取得APNS通知内容
    NSDictionary *aps = [userInfo valueForKey:@"aps"];
    // 内容
    NSString *content = [aps valueForKey:@"alert"];
    // badge数量
    NSInteger badge = [[aps valueForKey:@"badge"] integerValue];
    // 播放声音
    NSString *sound = [aps valueForKey:@"sound"];
    // 取得Extras字段内容
    //NSString *Extras = [userInfo valueForKey:@"Extras"]; //服务端中Extras字段,key是自己定义的
    //NSLog(@"content = [%@], badge = [%ld], sound = [%@], Extras = [%@]", content, (long)badge, sound, Extras);
    NSLog(@"content = [%@], badge = [%ld], sound = [%@],", content, (long)badge, sound);
    
    // iOS badge 清0
    application.applicationIconBadgeNumber = 0;
    // 通知打开回执上报
    // [CloudPushSDK handleReceiveRemoteNotification:userInfo];(Deprecated from v1.8.1)
    [CloudPushSDK sendNotificationAck:userInfo];
 
}

//当应用程序被用户从远程通知中选择操作时激活。调用该方法处理程序( iOS(8_0, 10_0))
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler {
  
}

//iOS 7+  //不论是前台还是后台只要有远程推送都会调用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
    NSLog(@"========================前台后台都会调用");
    
    /*
     建议使用该方法,还有一个作用。根据苹果给出的文档,系统给出30s的时间对推送的消息进行处理,此后就会运行CompletionHandler程序块。
     在处理这类推送消息(即程序被启动后接收到推送消息)的时候,通常会遇到这样的问题,
     就是当前的推送消息是当前程序正在前台运行时接收到的,还是说是程序在后台运行,用户点击系统消息通知栏对应项进入程序时而接收到的?这个其实很简单,用下面的代码就可以解决:
    */
     
    if (application.applicationState == UIApplicationStateActive) {
        NSLog(@"active");
        //程序当前正处于前台
        
        /*关于userInfo的结构,参照苹果的官方结构:
        {
            "aps" : {
                "alert" : "You got your emails.",
                "badge" : 9,
                "sound" : "bingbong.aiff"
                "acme1" : "bar",
                "acme2" : 42
            }
            即key aps对应了有一个字典,里面是该次推送消息的具体信息。具体跟我们注册的推送类型有关。另外剩下的一些key就是用户自定义的了。
         */

    }
    else if(application.applicationState == UIApplicationStateInactive)
    {
        NSLog(@"inactive");
        //程序处于后台
        
    }
   
}

//只有当应用程序位于前台时,该方法才会在委托上调用。如果方法未被执行或处理程序没有及时调用,则通知将不会被提交。应用程序可以选择将通知呈现为声音、徽章、警报和/或通知列表中。此决定应基于通知中的信息是否对用户可见。
//iOS 10 + 最后实现以下两个代理方法。 以后的 App处于前台状态时,通知打开回调
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    
    NSLog(@"Userinfo %@",notification.request.content.userInfo);
    //NSLog(@"Receive a notification in foregound.");
    
    //1. 处理通知  处理iOS 10通知,并上报通知打开回执
    [self handleiOS10Notification:notification];
    
    // 通知不弹出
    //completionHandler(UNNotificationPresentationOptionNone);
    //功能:可设置是否在应用内弹出通知
    //2. 处理完成后调用 completionHandler ,用于指示在前台显示通知的形式
    completionHandler(UNNotificationPresentationOptionAlert);
    
    // 通知弹出,且带有声音、内容和角标
    //completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
    
}

/*
 * 当APP处于后台(iOS 10+) 触发通知动作时回调,比如点击、删除通知和点击自定义action
 */
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
    
    NSLog(@"Userinfo %@",response.notification.request.content.userInfo);
    NSString *userAction = response.actionIdentifier;
    
    if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) {
        // NSLog(@"User opened the notification.");
        // 处理iOS 10通知,并上报通知打开回执
        [self handleiOS10Notification:response.notification];
    }
    // 通知dismiss,category创建时传入UNNotificationCategoryOptionCustomDismissAction才可以触发
    if ([userAction isEqualToString:UNNotificationDismissActionIdentifier]) {
        NSLog(@"User dismissed the notification.");
    }
    NSString *customAction1 = @"action1";
    NSString *customAction2 = @"action2";
    // 点击用户自定义Action1
    if ([userAction isEqualToString:customAction1]) {
        NSLog(@"User custom action1.");
    }
    
    // 点击用户自定义Action2
    if ([userAction isEqualToString:customAction2]) {
        NSLog(@"User custom action2.");
    }
    completionHandler();
    
    
}


// 1. 处理在前台收到通知 (iOS 10 + 并上报通知打开回执)
- (void)handleiOS10Notification:(UNNotification *)notification {
    
    UNNotificationRequest *request = notification.request;
    UNNotificationContent *content = request.content;
    NSDictionary *userInfo = content.userInfo;
    // 通知时间
    NSDate *noticeDate = notification.date;
    // 标题
    NSString *title = content.title;
    // 副标题
    NSString *subtitle = content.subtitle;
    // 内容
    NSString *body = content.body;
    // 角标
    int badge = [content.badge intValue];
    // 取得通知自定义字段内容,例:获取key为"Extras"的内容
    //NSString *extras = [userInfo valueForKey:@"Extras"];
    //NSLog(@"Notification, date: %@, title: %@, subtitle: %@, body: %@, badge: %d, extras: %@.", noticeDate, title, subtitle, body, badge, extras);
    NSLog(@"Notification, date: %@, title: %@, subtitle: %@, body: %@, badge: %d", noticeDate, title, subtitle, body, badge);
    // 通知打开回执上报
    [CloudPushSDK sendNotificationAck:userInfo];
    
}
//=============================================================

#pragma mark 创建category,并注册到通知中心
- (void)createCustomNotificationCategory {
    // 自定义`action1`和`action2`
    UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:@"action1" title:@"test1" options: UNNotificationActionOptionNone];
    UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"action2" title:@"test2" options: UNNotificationActionOptionNone];
    
    // 创建id为`test_category`的category,并注册两个action到category
    // UNNotificationCategoryOptionCustomDismissAction表明可以触发通知的dismiss回调
    
    UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"test_category" actions:@[action1, action2] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    // 注册category到通知中心
    [_notificationCenter setNotificationCategories:[NSSet setWithObjects:category, nil]];
}

- (void)applicationWillResignActive:(UIApplication *)application {

}

- (void)applicationDidEnterBackground:(UIApplication *)application {

}

- (void)applicationWillEnterForeground:(UIApplication *)application {

}

//2、当app在后台运行时 激活APP时会走
- (void)applicationDidBecomeActive:(UIApplication *)application {
    
    NSLog(@"在这里面里可以对推送消息做响应的处理");
    //点击app 从后台进入应用时,badge 的处理
    application.applicationIconBadgeNumber = 0;
    
}

- (void)applicationWillTerminate:(UIApplication *)application {

}

@end
上一篇 下一篇

猜你喜欢

热点阅读