APP推送是基本的要求,今天记录一下,大致是iOS原生收到推送后直接发通知给RN,RN这边监听着iOS原生的这个通知,以此获取到推送的消息.

效果图:
pushRN.gif

实现思路 ==>
这次采用的友盟推送,至于采用什么推送都是一样的.

准备工作:iOS 集成推送,编写中间类,用于传值给RN.

RN 界面实现监听iOS原生的通知,通过以上获取到推送的内容.

iOS原生准备集成推送:



iOS写一个中间类传输通知给RN:

CheckInvoice.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//
// CheckInvoice.h
// aitepiao
//
// Created by tc on 2018/8/28.
// Copyright © 2018年 Facebook. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface CheckInvoice : RCTEventEmitter<RCTBridgeModule>



@end

CheckInvoice.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//
// CheckInvoice.m
// aitepiao
//
// Created by tc on 2018/8/28.
// Copyright © 2018年 Facebook. All rights reserved.
//

#import "CheckInvoice.h"
#import <React/RCTEventDispatcher.h>
#import <React/RCTBridge.h>

static CheckInvoice *_manager = nil;

@implementation CheckInvoice

RCT_EXPORT_MODULE()



-(instancetype)init{

if (self = [super init]) {

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(messageDidReceived:) name:@"didReceiveNotification" object:nil];
}

return self;
}

- (NSArray<NSString *> *)supportedEvents
{
return @[@"didReceiveNotification", ];//有几个就写几个
}

-(void)messageDidReceived:(NSNotification *)notification{

NSDictionary *body = notification.object;
[self sendEventWithName:@"didReceiveNotification" body:body];
}


+ (BOOL)requiresMainQueueSetup {

return YES;
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}




@end

ok.传输类写完.然后在AppDelegate里面直接通过通知传即可:
如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

// iOS 10以上
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
NSDictionary * userInfo = notification.request.content.userInfo;
NSLog(@"iOS 10以上%@",userInfo);
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//应用处于前台时的远程推送接受
//关闭U-Push自带的弹出框
[UMessage setAutoAlert:NO];
//必须加这句代码
[UMessage didReceiveRemoteNotification:userInfo];

}else{
//应用处于前台时的本地推送接受
}
//当应用处于前台时提示设置,需要哪个可以设置哪一个
if (@available(iOS 10.0, *)) {
completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);
} else {
// Fallback on earlier versions
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"didReceiveNotification" object:userInfo];
}
// 收到通知
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
NSDictionary * userInfo = response.notification.request.content.userInfo;
NSLog(@"iOS外部 %@",userInfo);
[[NSNotificationCenter defaultCenter] postNotificationName:@"didReceiveNotification" object:userInfo];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSLog(@"iOS 10以下%@",userInfo);
[[NSNotificationCenter defaultCenter] postNotificationName:@"didReceiveNotification" object:userInfo];
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"deviceToken==%@",[[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""]
stringByReplacingOccurrencesOfString: @" " withString: @""]);
[UMessage registerDeviceToken:deviceToken];
}

ok,iOS原生这边基本完成.剩下RN这边:

引入NativeModulesNativeEventEmitter组件
引入原生中间类

1
2
3
const { CheckInvoice } = NativeModules;
const checkInvoiceEmitter = new NativeEventEmitter(CheckInvoice);

然后直接在生命周期方法里面监听iOS通知即可.

1
2
3
4
5
6
7
8
9
10
11
componentDidMount() {
// 监听iOS原生 UM push 监听外部通知
checkInvoiceEmitter.addListener(
'didReceiveNotification', (info) => {
alert(info.aps.alert.body)
this.setState({
info:info.aps.alert.body
})
}
)
}

源码:只有iOS推送

Android也如此,集成推送.书写中间类传通知给RN.

这里就贴一下桥接代码了:

CommModule.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.eazytec.zqtong.gov.baseapp.RN;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.modules.core.DeviceEventManagerModule;

/**
* 通信Module类
* Created by Song on 2017/2/17.
*/
public class CommModule extends ReactContextBaseJavaModule {

private ReactApplicationContext mContext;
public static final String MODULE_NAME = "commModule";
public static final String EVENT_NAME = "EventName";
/**
* 构造方法必须实现
* @param reactContext
*/
public CommModule(ReactApplicationContext reactContext) {
super(reactContext);
this.mContext = reactContext;
}

/**
* 在rn代码里面是需要这个名字来调用该类的方法
* @return
*/
@Override
public String getName() {
return MODULE_NAME;
}

/**
* Native调用RN
* @param msg
*/
public void nativeCallRn(String msg) {
mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(EVENT_NAME,msg);
}


}


CommPackage.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.eazytec.zqtong.gov.baseapp.RN;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
* 通信Module类
* Created by Song on 2017/2/17.
*/
public class CommPackage implements ReactPackage {

private static final CommPackage mCommPackage = new CommPackage();
public CommModule mModule;

/**
* 创建Native Module
* @param reactContext
* @return
*/
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
mModule = new CommModule(reactContext);
modules.add(mModule);
return modules;
}


@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

ok.上面就是桥接文件.然后只需要在返回通知类中发送通知给RN即可.如:

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package com.eazytec.zqtong.gov.baseapp;

import android.app.Application;
import android.widget.Toast;
import org.json.JSONObject;

import com.eazytec.zqtong.gov.baseapp.RN.CommModule;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.google.gson.Gson;

import android.content.Context;
import android.util.Log;
import com.eazytec.zqtong.gov.baseapp.BuildConfig;
import com.learnium.RNDeviceInfo.RNDeviceInfo;
import com.facebook.react.ReactApplication;
import cn.reactnative.httpcache.HttpCachePackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.react.rnspinkit.RNSpinkitPackage;
import java.util.Arrays;
import java.util.List;
import com.imagepicker.ImagePickerPackage;
import com.umeng.message.PushAgent;
import com.umeng.commonsdk.UMConfigure;
import com.umeng.message.IUmengRegisterCallback;
import com.umeng.message.MsgConstant;
import com.umeng.message.PushAgent;
import com.umeng.message.UTrack;
import com.umeng.message.UmengMessageHandler;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.entity.UMessage;
import com.facebook.react.bridge.ReactApplicationContext;

import android.provider.Settings;
import android.support.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.eazytec.zqtong.gov.baseapp.RN.CommPackage;


import java.util.List;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;


public class MainApplication extends Application implements ReactApplication {
//定义上下文对象
public static ReactContext myContext;
private static final CommPackage mCommPackage = new CommPackage();

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

private ReactApplicationContext mContext;


@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new HttpCachePackage(),
new RNSpinkitPackage(),
new RNDeviceInfo(),
new ImagePickerPackage(),
mCommPackage
);
}

@Override
protected String getJSMainModuleName() {
return "index";
}
};

@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}

//定义发送事件的函数
public void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params)
{
System.out.println("reactContext="+reactContext);

reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName,params);
}


@Override
public void onCreate() {
super.onCreate();
UMConfigure.setLogEnabled(true);
SoLoader.init(this, /* native exopackage */ false);

//友盟 push
PushAgent mPushAgent = PushAgent.getInstance(this);

UmengMessageHandler messageHandler = new UmengMessageHandler() {

/**
* 通知的回调方法(通知送达时会回调)
*/
@Override
public void dealWithNotificationMessage(Context context, UMessage msg) {
//调用super,会展示通知,不调用super,则不展示通知。
super.dealWithNotificationMessage(context, msg);
Gson gson = new Gson();
// 推送的内容
Log.i("msg来了内容", msg.text);
Log.i("msg来了头", msg.title);

String jsonStr = gson.toJson(msg);
Log.i("完整输出", jsonStr);

mCommPackage.mModule.nativeCallRn(jsonStr);


}

};
mPushAgent.setMessageHandler(messageHandler);

//注册推送服务,每次调用register方法都会回调该接口
mPushAgent.register(new IUmengRegisterCallback() {

@Override
public void onSuccess(String deviceToken) {
//注册成功会返回device token
Log.i(deviceToken,"deviceToken来了");
Log.i(deviceToken,deviceToken);
}

@Override
public void onFailure(String s, String s1) {
Log.i(s,s);
Log.i(s1,s1);
}



/**
* 程序是否在前台运行
*
* @return
*/
public boolean isAppOnForeground() {
// Returns a list of application processes that are running on the
// device

ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
String packageName = getApplicationContext().getPackageName();

List<RunningAppProcessInfo> appProcesses = activityManager
.getRunningAppProcesses();
if (appProcesses == null)
return false;

for (RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName)
&& appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}

return false;
}


});

}
}