iOS: 极光推送

简介:

之前做过环信和友盟的推送,照着官方文档集成其实挺简单的,今天公司需要,特地做了一下极光推送。不用不知道,原来极光推送集成如此简单,不得不说说了。

当然做推送钱需要做一些准备工作了,就是推送必须的p12推送证书:开发环境(开发时测试需要的推送证书)、生产环境(发布到AppStore时需要的推送证书),因为xcode已经升级到了7.0以上,所以一些真机测试的配置文件证书就不需要自己手动去创建了,只要有Apple ID,真机测试时,就能自动生成,免费测试:

制作证书的过程就不啰嗦了,详细看官方文档或者如下推荐:

http://jingyan.baidu.com/article/c1465413975cba0bfcfc4ccf.html

http://docs.jpush.io/client/ios_tutorials/#ios_1

http://docs.jpush.io/guideline/ios_guide/

http://allluckly.cn/投稿/tuogao28?utm_source=tuicool&utm_medium=referral

创建完证书,就是去极光官网注册账号,创建应用,截图如下:

将创建的证书上传到应用上了,上传成功后的截图如下:

证书上传成功后,生成APP Key,截图如下:

好了,这下工作做完了,剩下的就是代码实现了:

第一步:下载SDK,将需要的两个文件导入项目中:

集成压缩包内容

包名为JPush-iOS-SDK-{版本号}

  • lib文件夹:包含头文件 JPUSHService.h,静态库文件jpush-ios-x.x.x.a ,支持的iOS版本为 5.0 及以上版本。(请注意:模拟器不支持APNs)
  • pdf文件:集成指南
  • demo文件夹:示例

第二步:导入需要依赖的库文件:

必要的框架

  • CFNetwork.framework
  • CoreFoundation.framework
  • CoreTelephony.framework
  • SystemConfiguration.framework
  • CoreGraphics.framework
  • Foundation.framework
  • UIKit.framework
  • Security.framework
  • Xcode7需要的是libz.tbd;Xcode7以下版本是libz.dylib
  • Adsupport.framework (获取IDFA需要;如果不使用IDFA,请不要添加)

第三步:创建一个工具类,名称为KJJPushHelper,封装注册时的各种方法

.h

复制代码
//
//  KJJPushHelper.h
//
//  Created by xiayuanquan on 16/5/5.
//  Copyright © 2016年 mac. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface KJJPushHelper : NSObject

// 在应用启动的时候调用
+ (void)setupWithOption:(NSDictionary *)launchingOption
                 appKey:(NSString *)appKey
                channel:(NSString *)channel
       apsForProduction:(BOOL)isProduction
  advertisingIdentifier:(NSString *)advertisingId;

// 在appdelegate注册设备处调用
+ (void)registerDeviceToken:(NSData *)deviceToken;

// ios7以后,才有completion,否则传nil
+ (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion;

// 显示本地通知在最前面
+ (void)showLocalNotificationAtFront:(UILocalNotification *)notification;

@end
复制代码

.m

复制代码
//
//  KJJPushHelper.m

//  Created by xiayuanquan on 16/5/5.
//  Copyright © 2016年 mac. All rights reserved.
//

#import "KJJPushHelper.h"
#import "JPUSHService.h"

@implementation KJJPushHelper

+ (void)setupWithOption:(NSDictionary *)launchingOption
                 appKey:(NSString *)appKey
                channel:(NSString *)channel
       apsForProduction:(BOOL)isProduction
  advertisingIdentifier:(NSString *)advertisingId{
    // Required
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1
    // ios8之后可以自定义category
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        // 可以添加自定义categories
        [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                          UIUserNotificationTypeSound |
                                                          UIUserNotificationTypeAlert)
                                           categories:nil];
    } else {
#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
        // ios8之前 categories 必须为nil
        [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                          UIRemoteNotificationTypeSound |
                                                          UIRemoteNotificationTypeAlert)
                                           categories:nil];
#endif
    }
#else
    // categories 必须为nil
    [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                      UIRemoteNotificationTypeSound |
                                                      UIRemoteNotificationTypeAlert)
                                          categories:nil];
#endif
    
    // Required
    [JPUSHService setupWithOption:launchingOption appKey:appKey channel:channel apsForProduction:isProduction advertisingIdentifier:advertisingId];
    return;
}

+ (void)registerDeviceToken:(NSData *)deviceToken {
    [JPUSHService registerDeviceToken:deviceToken];
    return;
}

+ (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion {
    [JPUSHService handleRemoteNotification:userInfo];
    
    if (completion) {
        completion(UIBackgroundFetchResultNewData);
    }
    return;
}

+ (void)showLocalNotificationAtFront:(UILocalNotification *)notification {
    [JPUSHService showLocalNotificationAtFront:notification identifierKey:nil];
    return;
}

@end
复制代码

第四步:创建一个APPDelegate的分类,在该类中调用KJJPushHelper中的类方法

复制代码
//  AppDelegate+KJJPushSDK.h
//
//  Created by xiayuanquan on 16/5/5.
//  Copyright © 2016年 mac. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate (KJJPushSDK)
-(void)JPushApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
@end



//  AppDelegate+KJJPushSDK.m
//
//  Created by xiayuanquan on 16/5/5.
//  Copyright © 2016年 mac. All rights reserved.
//

#import "AppDelegate+KJJPushSDK.h"
#import "KJJPushHelper.h"

#define JPushSDK_AppKey  @"31e01f6a2f6dxxxxxxxxxec"
#define isProduction     NO

@implementation AppDelegate (KJJPushSDK)
-(void)JPushApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
  
    [KJJPushHelper setupWithOption:launchOptions appKey:JPushSDK_AppKey channel:nil apsForProduction:isProduction advertisingIdentifier:nil];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    // Required - 注册 DeviceToken
    [KJJPushHelper registerDeviceToken:deviceToken];
}


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    
    // Required,For systems with less than or equal to iOS6
    [KJJPushHelper handleRemoteNotification:userInfo completion:nil];
}


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    
    // IOS 7 Support Required
    [KJJPushHelper handleRemoteNotification:userInfo completion:completionHandler];
    
    // 应用正处理前台状态下,不会收到推送消息,因此在此处需要额外处理一下
    if (application.applicationState == UIApplicationStateActive) {
        UIAlertView *alert = [[UIAlertView alloc]
                              initWithTitle:@"收到推送消息"
                              message:userInfo[@"aps"][@"alert"]
                              delegate:nil
                              cancelButtonTitle:@"取消"
                              otherButtonTitles:@"确定",nil];
        [alert show];
    }
}


- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    //Optional
    NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}


- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
    [KJJPushHelper showLocalNotificationAtFront:notification];
    return;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [application setApplicationIconBadgeNumber:0];
    return;
}

@end
复制代码

第五步:在AppDelegate中注册即可

//注册极光推送
[self JPushApplication:application didFinishLaunchingWithOptions:launchOptions];

好了,大功告成,插上真机运行:打印结果如下

去官网测试一下:

真机收到消息截图:

集成过程中遇到的问题,困扰了好久,后来找出来了,分享一下:

当时证书一切都没有问题,但是总是出现这个打印:

错误信息JPUSH | W - [JPUSHClientController] Not get deviceToken yet. Maybe: your certificate not configured APNs? or current network is not so good so APNs registration failed? or there is no APNs register code? Please refer to JPush docs.

推送消息时,出现的提示:

 

我的原因是:

由于项目之前用到了环信SDK,环信得已经注册了通知,在AppDelegate中注册通知,didRegisterForRemoteNotificationsWithDeviceToken与didFailToRegisterForRemoteNotificationsWithError方法,均不执行。。。需到环信注册通知的地方,再次注册极光通知。方可以获取到Token执行。

 

扩展:极光推送中的定向推送

极光推送中,不使用广播推送,那么怎样做到定向推送,是开发者和需求一定会出现的问题,极光推送中可以有两个唯一值:

(1)注册Jpush成功后生成的registrationID,这个registrationID是标记设备唯一性的,你发现,当你在启动多次,注册Jpush时,这个值是不变的;在同一个设备上,更换用户登录,这个值仍然不变;最后,你删除应用程序,再下载时启动注册Jpush,这个值还是不变。这就可以定向向某台设备做推送,如果你能给自己的服务器上传这个值,并且给这个值绑定一些东西,是不是可以做更多事情呢。

(2)alias:只要了解极光推送的都知道这是设置别名的,官方文档上说明了这个值不是唯一的,但是建议开发者把它作为用户的唯一标记。我觉得这个作为唯一值是最好的,当你想定向向某个用户做推送,或者召唤他回归我们的应用程序,这个值就太好了。你可以将它设置为userId,这个时候推送就能知道向哪个用户发了。

 

本人原创,转载须注明出处,谢谢!

程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!

本文转自当天真遇到现实博客园博客,原文链接:http://www.cnblogs.com/XYQ-208910/p/5463802.html ,如需转载请自行联系原作者
相关文章
|
2月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
106 3
|
4月前
|
存储 iOS开发
iOS 开发,如何进行应用的本地化(Localization)?
iOS 开发,如何进行应用的本地化(Localization)?
123 2
|
4月前
|
存储 数据建模 数据库
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
43 0
|
4月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
106 2
|
2月前
|
API 开发工具 Android开发
iOS 和 Android 平台的开发有哪些主要区别?
iOS与Android开发区别:iOS用Objective-C/Swift,App Store唯一下载渠道;Android用Java/Kotlin,多商店发布(如Google Play、华为市场)。设计上,iOS简洁一致,Android灵活可定制。开发工具,iOS用Xcode,Android用Android Studio。硬件和系统多样性,iOS统一,Android复杂。权限管理、审核流程及API各有特点,开发者需依据目标平台特性进行选择。
38 3
|
12天前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
12天前
|
存储 Swift iOS开发
使用Swift开发一个简单的iOS应用的详细步骤。
使用Swift开发iOS应用的步骤包括:创建Xcode项目,设计界面(Storyboard或代码),定义数据模型,实现业务逻辑,连接界面和逻辑,处理数据存储(如Core Data),添加网络请求(必要时),调试与测试,根据测试结果优化改进,最后提交至App Store或其它平台发布。
32 0
|
12天前
|
安全 Swift iOS开发
【Swift 开发专栏】Swift 与 UIKit:构建 iOS 应用界面
【4月更文挑战第30天】本文探讨了Swift和UIKit在构建iOS应用界面的关键技术和实践方法。Swift的简洁语法、类型安全和高效编程模型,加上与UIKit的紧密集成,使开发者能便捷地创建用户界面。UIKit提供视图、控制器、布局、动画和事件处理等功能,支持灵活的界面设计。实践中,遵循设计原则,合理组织视图层次,运用布局和动画,以及实现响应式设计,能提升界面质量和用户体验。文章通过登录、列表和详情界面的实际案例展示了Swift与UIKit的结合应用。
|
12天前
|
存储 安全 Swift
【Swift 开发专栏】使用 Swift 开发一个简单的 iOS 应用
【4月更文挑战第30天】本文介绍了使用 Swift 开发简单 iOS 待办事项应用的步骤。首先,阐述了 iOS 开发的吸引力及 Swift 语言的优势。接着,详细说明了应用的需求和设计,包括添加、查看和删除待办事项的功能。开发步骤包括创建项目、界面搭建、数据存储、功能实现,并提供了相关代码示例。最后,强调了实际开发中需注意的细节和优化,旨在帮助初学者掌握 Swift 和 iOS 开发基础。