React-Native集成极光推送的具体流程如下:
本文选取的是极光官方维护的react-native推送插件,github地址:https://github.com/jpush/jpush-react-native
后台集成极光sdk的地址:https://github.com/jpush/jpush-api-java-client
需要注册极光开发者账号,注册地址:https://www.jiguang.cn
注册之后登录,然后找到极光推送,新建自己的app,包名必须跟实际一致,得到appKey和master secret,react-native前端集成需要用到appKey,极光后台SDK集成需要使用master secret
一、安装相关依赖库
npm install jpush-react-native --save
注意:如果项目里没有jcore-react-native,需要安装
npm install jcore-react-native --save
安装完成后连接原生库 进入到根目录执行
react-native link
或
react-native link jpush-react-native
react-native link jcore-react-native
二、进行相关配置
2.1 Android
-
build.gradle
android { defaultConfig { applicationId "yourApplicationId" //在此替换你的应用包名 ... manifestPlaceholders = [ JPUSH_APPKEY: "yourAppKey", //在此替换你的APPKey JPUSH_CHANNEL: "yourChannel" //在此替换你的channel ] } }
dependencies { ... implementation project(':jpush-react-native') // 添加 jpush 依赖 implementation project(':jcore-react-native') // 添加 jcore 依赖 }
-
setting.gradle
include ':jpush-react-native' project(':jpush-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/jpush-react-native/android') include ':jcore-react-native' project(':jcore-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/jcore-react-native/android')
-
AndroidManifest.xml
<meta-data android:name="JPUSH_CHANNEL" android:value="${JPUSH_CHANNEL}" /> <meta-data android:name="JPUSH_APPKEY" android:value="${JPUSH_APPKEY}" />
Android还需要对Application进行如下修改:
package com.example;
import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.List;
import cn.jiguang.plugins.push.JPushModule;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
//RN0.60以下需要打开,注意导包JPushPackage
//packages.add(new JPushPackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
//调用此方法:点击通知让应用从后台切到前台
JPushModule.registerActivityLifecycle(this);
}
}
2.2 iOS
注意:您需要打开ios目录下的.xcworkspace文件修改您的包名
2.2.1 pod
pod install
-
注意:如果项目里使用pod安装过,请先执行命令
pod deintegrate
2.2.2 手动方式
-
Libraries
Add Files to "your project name" node_modules/jcore-react-native/ios/RCTJCoreModule.xcodeproj node_modules/jpush-react-native/ios/RCTJPushModule.xcodeproj
-
Capabilities
Push Notification --- ON
-
Build Settings
All --- Search Paths --- Header Search Paths --- + $(SRCROOT)/../node_modules/jcore-react-native/ios/RCTJCoreModule/ $(SRCROOT)/../node_modules/jpush-react-native/ios/RCTJPushModule/
-
Build Phases
libz.tbd libresolv.tbd UserNotifications.framework libRCTJCoreModule.a libRCTJPushModule.a
ios的还需要如下设置:
xxx.xcodeproj的General需要添加以下库依赖:
Signing&Capabilities需要添加push notifications(这个要注意,只有编译的密钥包含push notification权限时才可以添加,否则点击添加Capabilities按钮,选择push notification长按之后也无法添加到Signing&Capabilities下面),如果不加该配置,极光推送无法成功;
AppDelegate.m文件的修改如下:
重点关注appKey,这个是极光后台的appKey,
然后是apsForProduction,如果是YES,表示是生产环境,如果是NO,表示是开发环境,需要注意,前端设置和后台设置需要保持一致,后台(platform.all())默认是生产环境
另外还需要注意一点,如果xcode工程和证书配置都没问题,那么要注意是不是第三方库重写了didRegisterForRemoteNotificationsWithDeviceToken方法,目前已知环信会有该问题,如果是这种情况,需要自己修改
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <CodePush/CodePush.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTBridge.h>
#import <RCTJPushModule.h>
#import <React/RCTLog.h>
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//设置日志级别,release默认只打印error,这样设置之后js console日志也会打印
//RCTSetLogThreshold(RCTLogLevelTrace);
RCTSetLogThreshold(RCTLogLevelInfo-1);
NSLog(@"jpush launchOptions");
// JPush初始化配置
//开发环境调试使用的证书(cn.com.whty.merchant)
// [JPUSHService setupWithOption:launchOptions appKey:@"d42ca563974184597fca2769"
// channel:@"dev" apsForProduction:NO];
//生产环境发布使用的证书(cn.com.whty.merchantApp)apsForProduction;yes表示生产环境,no表示开发环境
[JPUSHService setupWithOption:launchOptions appKey:@"d36889b3f357ffda4df224f8"
channel:@"pro" apsForProduction:YES];
// APNS
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
if (@available(iOS 12.0, *)) {
entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound|JPAuthorizationOptionProvidesAppNotificationSettings;
}
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
[launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
// 自定义消息
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil];
// 地理围栏
[JPUSHService registerLbsGeofenceDelegate:self withLaunchOptions:launchOptions];
// ReactNative环境配置
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"merchant_app"
initialProperties:nil];
NSLog(@"jpush launchOptions init end");
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
//************************************************JPush start************************************************
//注册 APNS 成功并上报 DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"jpush didRegisterForRemoteNotificationsWithDeviceToken deviceToken: %@" , deviceToken);
[JPUSHService registerDeviceToken:deviceToken];
}
//注册 APNS失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSData *)deviceToken {
NSLog(@"jpush didFailToRegisterForRemoteNotificationsWithError deviceToken: %@" , deviceToken);
}
//iOS 7 APNS
- (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// iOS 10 以下 Required
NSLog(@"jpush completionHandler iOS 7 APNS");
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:J_APNS_NOTIFICATION_ARRIVED_EVENT object:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
//iOS 10 前台收到消息
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
NSLog(@"jpush NotificationCenter iOS 10 APNS 前台收到消息");
NSDictionary * userInfo = notification.request.content.userInfo;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
// Apns
NSLog(@"jpush iOS 10 APNS 前台收到消息");
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:J_APNS_NOTIFICATION_ARRIVED_EVENT object:userInfo];
}
else {
// 本地通知 todo
NSLog(@"jpush iOS 10 本地通知 前台收到消息");
[[NSNotificationCenter defaultCenter] postNotificationName:J_LOCAL_NOTIFICATION_ARRIVED_EVENT object:userInfo];
}
//需要执行这个方法,选择是否提醒用户,有 Badge、Sound、Alert 三种类型可以选择设置
completionHandler(UNNotificationPresentationOptionAlert);
}
//iOS 10 消息事件回调
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler: (void (^)(void))completionHandler {
NSLog(@"jpush NotificationCenter iOS 10 APNS 消息事件回调");
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
// Apns
NSLog(@"jpush iOS 10 APNS 消息事件回调");
[JPUSHService handleRemoteNotification:userInfo];
// 保障应用被杀死状态下,用户点击推送消息,打开app后可以收到点击通知事件
[[RCTJPushEventQueue sharedInstance]._notificationQueue insertObject:userInfo atIndex:0];
[[NSNotificationCenter defaultCenter] postNotificationName:J_APNS_NOTIFICATION_OPENED_EVENT object:userInfo];
}
else {
// 本地通知
NSLog(@"jpush iOS 10 本地通知 消息事件回调");
// 保障应用被杀死状态下,用户点击推送消息,打开app后可以收到点击通知事件
[[RCTJPushEventQueue sharedInstance]._localNotificationQueue insertObject:userInfo atIndex:0];
[[NSNotificationCenter defaultCenter] postNotificationName:J_LOCAL_NOTIFICATION_OPENED_EVENT object:userInfo];
}
// 系统要求执行这个方法
completionHandler();
}
//自定义消息
- (void)networkDidReceiveMessage:(NSNotification *)notification {
NSDictionary * userInfo = [notification userInfo];
NSLog(@"jpush 自定义消息回调");
[[NSNotificationCenter defaultCenter] postNotificationName:J_CUSTOM_NOTIFICATION_EVENT object:userInfo];
}
//************************************************JPush end************************************************
@end
三、客户端集成成功之后,可以先使用极光开发者的控制台测试极光推送,能正常收到消息,说明极光推送配置成功。