阿里云推送SDK iOS端配置

作者: 双门 | 来源:发表于2017-03-14 15:05 被阅读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 目录结构:
    • CloudPushSDK.framework
    • AlicloudUtils.framework
    • UTDID.framework
    • UTMini.framework(阿里云平台下载的SDK无需依赖,百川平台下载的SDK需要依赖)
    2、添加公共包依赖 在 Build Phases -> Link Binary With Libraries中,引入下列的公共包:
    • libz.tbd
    • libresolv.tbd
    • CoreTelephony.framework
    • SystemConfiguration.framework
    • UserNotifications.framework(iOS 10+)
      libsqlite3.tbd(阿里云平台下载的SDK无需依赖,百川平台下载的SDK需要依赖)
    3、特殊要求
    • 应用的 targets -> Build Settings -> Linking -> Other Linker Flags,请加上 -ObjC 这个属性,否则推送服务无法正常使用。
    • 移动推送 iOS SDK 已经完成 ATS 适配,请求都以 HTTPS发出,无需在 Info.plist 中进行ATS配置。
    4、在AppDelegate.m 里面完成配置
    • 工程引入头文件
    # import <CloudPushSDK/CloudPushSDK.h>
    
    5、Xcode 设置
    • 在 TARGET 下 Capabilities 勾选 Backgroud Modes -> Remote notifications,
    • 主要是 iOS7 之后,苹果支持后台运行,如果这里打开后,当接收到远程推送后,程序在后台也可以做一些处理。
    6、常遇见的问题:
    • 在项目 target 中,打开Capabilitie —> Push Notifications,并会自动在项目中生成 .entitlement【ɪn'taɪt(ə)lmənt 权利 】文件。(很多同学升级后,获取不到 deviceToken,大概率是由于没开这个选项)
      Capabilitie —> Push Notifications 自动生成 .entitlement
    • 确保添加了 UserNotifications.framework,并 import到 AppDelegate,记得实现 UNUserNotificationCenterDelegate 。
    # 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
    

    相关文章

      网友评论

        本文标题:阿里云推送SDK iOS端配置

        本文链接:https://www.haomeiwen.com/subject/ihhhnttx.html