此处我用的是jpush-react-native,这个是极光官网维护的,还有一个是react-antive-jpush,这是中文网的,我这里没用这个
上一篇讲了如何申请ios的开发和生产证书的流程,http://blog.csdn.net/liu__520/article/details/53133497
先按照官网的步骤来呗:(为了了解具体的过程,我都是用手动配置的,没有用自动配置)
今天是2017年2月16日,现在的RN版本是0.41.2,
for latest RN, use latest
for RN < 0.40.0, use v1.3.6
for jpush-react-native > 1.4.4, need install jcore-react-native
如果你的RN版本小于0.40.0,用极光的1.3.6版本;
如果>=0.40.0,就要用最新的;
而且如果jpush-react-native > 1.4.4,需要用到jcore-react-native
一、手动配置
1.1、进入你的项目目录,然后打开命令终端输入:
`npm install jpush-react-native --save`
`rnpm link jpush-react-native`
1.2、android版的具体配置:
使用 Android Studio import 你的 React Native 应用(选择你的 React Native 应用所在目录下的 android 文件夹即可)
修改 android 项目下的 settings.gradle 配置:
打开setting.gradle,然后添加如下代码:
include ':app', ':jpush-react-native'
project(':jpush-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/jpush-react-native/android')
修改app 下的 AndroidManifest 配置,将 jpush 相关的配置复制到这个文件中,参考 demo 的 AndroidManifest:(增加了 部分)
你的 react native project/android/app/AndroidManifest.xml
android:name=".MainApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
android:name=".MainActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="@string/app_name">
修改 app 下的 build.gradle 配置:
your react native project/android/app/build.gradle
android {
defaultConfig {
applicationId "yourApplicationId"
...
manifestPlaceholders = [
JPUSH_APPKEY: "yourAppKey", //在此替换你的APPKey
APP_CHANNEL: "developer-default" //应用渠道号,默认就好
]
}
}
...
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile project(':jpush-react-native')
compile "com.facebook.react:react-native:+" // From node_modules
}
将此处的 yourApplicationId 替换为你的项目的包名;yourAppKey 替换成你在官网上申请的应用的 AppKey。到此为止,配置完成。
现在重新 sync 一下项目,应该能看到 jpush-react-native 作为一个 android Library 项目导进来了
使用
打开 app 下的 MainActivity,在 ReactInstanceManager 的 build 方法中加入 JPushPackage:
app/MainActivity.java
打开 app 下的 MainApplication.java 文件,然后加入 JPushPackage,参考 demo:
app/MainApplication.java
private boolean SHUTDOWN_TOAST = false;
private boolean SHUTDOWN_LOG = false;
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List getPackages() {
return Arrays.asList(
new MainReactPackage(),
new JPushPackage(SHUTDOWN_TOAST, SHUTDOWN_LOG)
);
}
};
1.3、ios配置
iOS Usage
打开 iOS 工程,在 rnpm link 之后,RCTJPushModule.xcodeproj 工程会自动添加到 Libraries 目录里面
在 iOS 工程 target 的 Build Phases->Link Binary with Libraries 中加入如下库
libz.tbd
CoreTelephony.framework
Security.framework
CFNetwork.framework
CoreFoundation.framework
SystemConfiguration.framework
Foundation.framework
UIKit.framework
UserNotifications.framework
libresolv.tbd
在 AppDelegate.h 文件中 填写如下代码,这里的的 appkey、channel、和 isProduction 填写自己的
static NSString *appKey = @""; //填写appkey
static NSString *channel = @""; //填写channel 一般为nil
static BOOL isProduction = false; //填写isProdurion 平时测试时为false ,生产时填写true
在AppDelegate.m 的didFinishLaunchingWithOptions 方法里面添加如下代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
//可以添加自定义categories
[JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
UIUserNotificationTypeSound |
UIUserNotificationTypeAlert)
categories:nil];
} else {
//iOS 8以前 categories 必须为nil
[JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert)
categories:nil];
}
[JPUSHService setupWithOption:launchOptions appKey:appKey
channel:channel apsForProduction:isProduction];
}
在AppDelegate.m 的didRegisterForRemoteNotificationsWithDeviceToken 方法中添加 [JPUSHService registerDeviceToken:deviceToken]; 如下所示
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[JPUSHService registerDeviceToken:deviceToken];
}
为了在收到推送点击进入应用能够获取该条推送内容需要在 AppDelegate.m didReceiveRemoteNotification 方法里面添加
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo] 方法,
注意:这里需要在两个方法里面加一个是iOS7以前的一个是iOS7即以后的,如果AppDelegate.m 没有这个两个方法则直接复制这两个方法,
在 iOS10 的设备则可以使用JPush 提供的两个方法;如下所示
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// 取得 APNs 标准信息内容
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
//iOS 7 Remote Notification
- (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo fetchCompletionHandler:(void (^) (UIBackgroundFetchResult))completionHandler {
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
// Required
NSDictionary * userInfo = notification.request.content.userInfo;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
}
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
// Required
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
completionHandler(); // 系统要求执行这个方法
}
1.3.1、下面直接放我的代码图吧,上面的代码都是官网的,但是有几个地方是需要修改的,也是需要增加的,要不然各种报错,:
1.3.2、还有一个最重要的,把github上极光的代码都放到你的这个AppDelegate.m文件中,然后加一个接口
@interfaceAppDelegate();
而且用官网的代码会提示下面的警告信息:
/Users/vittorio/Desktop/log/ios/log/AppDelegate.m:39:55: 'UIRemoteNotificationTypeBadge' is deprecated:
first deprecated in iOS 8.0 - Use UserNotifications Framework's UNAuthorizationOptions for user notifications
and registerForRemoteNotifications for receiving remote notifications instead.
需要把代码里面的UIRemoteNotificationType改成:UNAuthorizationOption
具体看我以下的代码:
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "AppDelegate.h"
#import "RCTBundleURLProvider.h"
#import "RCTRootView.h"
// ---------------------------start极光推送--------------------------
#import "JPUSHService.h"
#import
#import
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import
#endif
@interface AppDelegate ()
// ---------------------------end极光推送---------------------------
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ---------------------------start极光推送--------------------------
//Required
if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound;
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
}
else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
//可以添加自定义categories
[JPUSHService registerForRemoteNotificationTypes:(UNAuthorizationOptionBadge |
UNAuthorizationOptionSound |
UNAuthorizationOptionAlert)
categories:nil];
}
else {
//categories 必须为nil
[JPUSHService registerForRemoteNotificationTypes:(UNAuthorizationOptionBadge |
UNAuthorizationOptionSound |
UNAuthorizationOptionAlert)
categories:nil];
}
[JPUSHService setupWithOption:launchOptions appKey:appKey
channel:nil apsForProduction:nil];
// ---------------------------end极光推送--------------------------
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"log"
initialProperties:nil
launchOptions:launchOptions];
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;
}
// ---------------------------start极光推送--------------------------
//-----------------------------------------------------------------------
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[JPUSHService registerDeviceToken:deviceToken];
}
//-----------------------------------------------------------------------
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// 取得 APNs 标准信息内容
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
//iOS 7 Remote Notification
- (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo fetchCompletionHandler:(void (^) (UIBackgroundFetchResult))completionHandler {
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
// Required
NSDictionary * userInfo = notification.request.content.userInfo;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
}
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
// Required
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
completionHandler(); // 系统要求执行这个方法
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
//Optional
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
// ---------------------------end极光推送--------------------------
@end
1.3.3、然后需要选择描述配置的东西吧:
具体看下面的两张图:
1.3.4、打开项目---capacities---打开push notifications,
1.3.5、打开项目--build settings---signing---code signing identify,都改成 ios developer,
1.3.6、然后把tests的signing也要改一下,要不然安装到真机上会报错的:
到此为止,配置基本就完成了,
2、下面我们在RN上进行操作了:
下面分两部分进行:2.1、普通推送;2.2、别名推送
2.1、普通的推送
打开js文件我的是在主页上进行的,
具体的代码如下:
componentDidMount() {
//---------------------------------android start---------------------------------
JPushModule.addReceiveCustomMsgListener((message) => {
//这是默认的通知消息
// this.setState({pushMsg:message});
});
JPushModule.addReceiveNotificationListener((map) => {
//自定义推送的消息
//console.log("alertContent: " + map.alertContent);
//extra是可选配置上的附件字段
//console.log("extras: " + map.extras);
var message = JSON.parse(map.extras);
this.storeDB(message);//我这里是把内容存在了数据库里面,你可以把这里的message放到state里面显示出来
//这里面解析json数据,并存在数据库中,同时显示在通知栏上
})
//点击通知进入应用的主页,相当于跳转到制定的页面
JPushModule.addReceiveOpenNotificationListener((map) => {
//console.log("Opening notification!");
this.props.navigator.replace({name: "HomePage",component:HomePage});
})
//---------------------------------android end---------------------------------
//---------------------------------ios start---------------------------------
NativeAppEventEmitter.addListener(
'ReceiveNotification',
(message) => {
//下面就是发送过来的内容,可以用stringfy打印发来的消息
console.log("content: " + JSON.stringify(message));
//下面的json就是我在极光推送上的附件字段内容就是上面的log打印出来的东西
// {
// "_j_msgid": 4572771355,
// "content": "日志第一天",
// "time": "2016-11-18/13:11:09",
// "aps": {
// "sound": "default",
// "badge": 1,
// "alert": "测试ios1"
// },
// "name": "刘成",
// "age": "28",
// "性别": "男",
//"qq":"674668211",
//"手机号":"674668211",
// } console.log("_j_msgid:" + message._j_msgid);
//这个是极光的消息id console.log("content:" + message.content);
//这是标题 console.log("aps:" + message.aps.sound);
//这是声音 console.log("aps:" + message.aps.badge);
//这是上标 console.log("aps:" + message.aps.alert);
//这是发送通知的主内容 this.storeDB(message); } );
//---------------------------------ios end---------------------------------
}
//最后在组件卸载的时间取消监听:
componentWillUnmount() {
JPushModule.removeReceiveCustomMsgListener();
JPushModule.removeReceiveNotificationListener();
BackAndroid.removeEventListener('hardwareBackPress');
NativeAppEventEmitter.removeAllListeners();
DeviceEventEmitter.removeAllListeners();
}
上面的android的推送内容都在message.content里面,附加的数据在message.extras,
message就是发送过来的消息内容:addReceiveNotificationListener
如果你没有附加的消息,只是显示消息内容,用这个方法就行了:addReceiveCustomMsgListener
如果你要点击通知打开某个应用,用:addReceiveOpenNotificationListener
ios的要用到注册监听事件:
NativeAppEventEmitter.addListener
消息内容都在message里面,可以看下我的示例,结合我极光推送的附加字段:就会明白的//我这里是把内容存在了数据库里面,
你可以把这里的message
放到state里面显示出来
2.2、别名推送
setAlias有三个参数,第一个是你要推送的别名,要注册到极光的,第二和第三个分别是设置成功的回调、设置失败的回调
import JPushModule from 'jpush-react-native';
'您的别名' !== '' ? (JPushModule.setAlias('您的别名',this.success,this.fail)):null
success=()=>{
NativeAppEventEmitter.addListener( 'ReceiveNotification', (message) => {JPushModule.setBadge(0,function(){
// console.log(message)
})} );
//---------------------------------android start---------------------------------
JPushModule.addReceiveCustomMsgListener((message) => {
//这是默认的通知消息
// console.log(message)
});
JPushModule.addReceiveNotificationListener((map) => {
// var message = JSON.parse(map.extras);
});
//点击通知进入应用的主页
JPushModule.addReceiveOpenNotificationListener((map) => {})
//---------------------------------android end---------------------------------
}
fail=()=>{
}
网友评论
就是一些 [JPUSHService setupWithOption:launchOptions appKey:@"0000000000000000"
channel:nil apsForProduction:nil];之类的.我看你的文章说还需要自己手写代码再appDelegate.m里面.这样吗?
2018-03-10 15:41:34.984473+0800 pluto[631:188430] [] nw_connection_get_connected_socket 17 Connection has no connected handler
2018-03-10 15:41:34.984610+0800 pluto[631:188430] TCP Conn 0x1c0172780 Failed : error 0:61 [61]
但是不影响运行 就是无休止的在报 是什么原因呢
如果是群发:则此应用还没有一个客户端用户注册。请检查 SDK 集成是否正常。
如果是推送给某别名或者标签:则此别名或者标签还没有在任何客户端SDK提交设置成功。
如果是根据 Registration ID 推送:则此 Registration ID 不存在。
大大请问这是怎么回事?
,之前这个推送是ios用过的,请问你知道吗
到这一步的时候 我的app 里 mainActivity 里没有你说的那个东西啊。我的mainActivity里只有
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "LunbotuTexe";
}
这个东西没有别的
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "LunbotuTexe";
}
}
只有这些东西
// Required
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:kJPFOpenNotification object:userInfo];
}
请使用 kJPFOpenNotification 而非 kJPFDidReceiveRemoteNotification
解决方案:找到 项目/node_modules/jpush-react-native/android/src/main/AndroidManifest.xml,里面的 ${applicationId} 全部换成 你自己的项目包名(也就是在 项目/android/app/src/main/AndroidManifest.xml的第三行一般是:package后面的com...的一大堆),这样就能很快解决问题了
rnpm-link ERR! ERRPACKAGEJSON No package found. Are you sure it's a React Native project?错误,求帮助。
我看上面的评论也有人遇到同样的问题,你回复是Android注册到极光需要一段时间,这个时间大概多久清楚吗?
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> A problem occurred configuring project ':jpush-react-native'.
> failed to find Build Tools revision 23.0.2
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
求帮助
appkey 需要配置2次吗? 1:项目下配置一次 2:安卓生成的极光包再配置一次..
极光后台错误提示:
没有满足条件的推送目标
如果是群发:则此应用还没有一个客户端用户注册。请检查 SDK 集成是否正常。
如果是推送给某别名或者标签:则此别名或者标签还没有在任何客户端SDK提交设置成功。
如果是根据 Registration ID 推送:则此 Registration ID 不存在。
在极光页面测试,就会提示错误,发送不成功
JPUSH_APPKEY: "后台appkey",
APP_CHANNEL: "jpush" //应用渠道号
]
我是这样配置的
提示-bash: rnpm: command not found
谢谢!