reteno-react-native-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +22 -0
- package/android/build.gradle +87 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +17 -0
- package/android/src/main/java/com/retenosdk/RetenoPushReceiver.java +12 -0
- package/android/src/main/java/com/retenosdk/RetenoReactNativeApplication.java +7 -0
- package/android/src/main/java/com/retenosdk/RetenoSdkModule.java +129 -0
- package/android/src/main/java/com/retenosdk/RetenoSdkPackage.java +28 -0
- package/android/src/main/java/com/retenosdk/RetenoUserAttributes.java +127 -0
- package/ios/EventEmitter.swift +29 -0
- package/ios/RetenoSdk-Bridging-Header.h +3 -0
- package/ios/RetenoSdk.m +24 -0
- package/ios/RetenoSdk.swift +64 -0
- package/ios/RetenoSdk.xcodeproj/project.pbxproj +285 -0
- package/ios/RetenoUserAttributes.swift +127 -0
- package/lib/commonjs/index.js +40 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/index.js +31 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/index.d.ts +37 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/package.json +167 -0
- package/reteno-react-native-sdk.podspec +36 -0
- package/src/index.tsx +92 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Reteno
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# reteno-react-native-sdk
|
|
2
|
+
|
|
3
|
+
Reteno SDK
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
- [iOS](./docs/ios.md)
|
|
8
|
+
- [Android](./docs/android.md)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
- [API](./docs/api.md)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## License
|
|
17
|
+
|
|
18
|
+
MIT
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
// Buildscript is evaluated before everything else so we can't use getExtOrDefault
|
|
3
|
+
def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["RetenoSdk_kotlinVersion"]
|
|
4
|
+
|
|
5
|
+
repositories {
|
|
6
|
+
mavenCentral()
|
|
7
|
+
google()
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
dependencies {
|
|
11
|
+
classpath "com.android.tools.build:gradle:7.2.1"
|
|
12
|
+
// noinspection DifferentKotlinGradleVersion
|
|
13
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
14
|
+
// For Firebase Cloud Messaging.
|
|
15
|
+
classpath 'com.google.gms:google-services:4.3.14'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def isNewArchitectureEnabled() {
|
|
20
|
+
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
apply plugin: "com.android.library"
|
|
24
|
+
apply plugin: "kotlin-android"
|
|
25
|
+
|
|
26
|
+
if (isNewArchitectureEnabled()) {
|
|
27
|
+
apply plugin: "com.facebook.react"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
def getExtOrDefault(name) {
|
|
31
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["RetenoSdk_" + name]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def getExtOrIntegerDefault(name) {
|
|
35
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["RetenoSdk_" + name]).toInteger()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
android {
|
|
39
|
+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
40
|
+
|
|
41
|
+
defaultConfig {
|
|
42
|
+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
43
|
+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
44
|
+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
45
|
+
}
|
|
46
|
+
buildTypes {
|
|
47
|
+
release {
|
|
48
|
+
minifyEnabled false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
lintOptions {
|
|
53
|
+
disable "GradleCompatible"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
compileOptions {
|
|
57
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
58
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
repositories {
|
|
64
|
+
mavenCentral()
|
|
65
|
+
google()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
69
|
+
|
|
70
|
+
dependencies {
|
|
71
|
+
// For < 0.71, this will be from the local maven repo
|
|
72
|
+
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
|
|
73
|
+
//noinspection GradleDynamicVersion
|
|
74
|
+
implementation "com.facebook.react:react-native"
|
|
75
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
76
|
+
implementation 'com.reteno:fcm:1.4.0'
|
|
77
|
+
implementation "com.google.firebase:firebase-messaging:23.1.0"
|
|
78
|
+
implementation "com.google.firebase:firebase-messaging-ktx:23.1.0"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (isNewArchitectureEnabled()) {
|
|
82
|
+
react {
|
|
83
|
+
jsRootDir = file("../src/")
|
|
84
|
+
libraryName = "RetenoSdk"
|
|
85
|
+
codegenJavaPackageName = "com.retenosdk"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
package="com.retenosdk">
|
|
3
|
+
<application>
|
|
4
|
+
<receiver
|
|
5
|
+
android:name="com.retenosdk.RetenoPushReceiver"
|
|
6
|
+
android:enabled="true"
|
|
7
|
+
android:exported="true">
|
|
8
|
+
<intent-filter>
|
|
9
|
+
<action android:name="com.reteno.custom-push" />
|
|
10
|
+
</intent-filter>
|
|
11
|
+
</receiver>
|
|
12
|
+
<meta-data
|
|
13
|
+
android:name="com.reteno.Receiver.PushReceived"
|
|
14
|
+
android:value="com.retenosdk.RetenoPushReceiver" />
|
|
15
|
+
</application>
|
|
16
|
+
</manifest>
|
|
17
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package com.retenosdk;
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.content.Intent;
|
|
6
|
+
|
|
7
|
+
public class RetenoPushReceiver extends BroadcastReceiver {
|
|
8
|
+
@Override
|
|
9
|
+
public void onReceive(Context context, Intent intent) {
|
|
10
|
+
RetenoSdkModule.onRetenoPushReceived(context, intent);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
package com.retenosdk;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.content.Intent;
|
|
6
|
+
import android.os.Bundle;
|
|
7
|
+
|
|
8
|
+
import androidx.annotation.NonNull;
|
|
9
|
+
|
|
10
|
+
import com.facebook.react.bridge.Arguments;
|
|
11
|
+
import com.facebook.react.bridge.Promise;
|
|
12
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
13
|
+
import com.facebook.react.bridge.ReactContext;
|
|
14
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
15
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
16
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
17
|
+
import com.facebook.react.bridge.WritableMap;
|
|
18
|
+
import com.facebook.react.bridge.WritableNativeMap;
|
|
19
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
20
|
+
import com.reteno.core.RetenoApplication;
|
|
21
|
+
import com.reteno.core.domain.model.user.User;
|
|
22
|
+
|
|
23
|
+
public class RetenoSdkModule extends ReactContextBaseJavaModule {
|
|
24
|
+
public static final String NAME = "RetenoSdk";
|
|
25
|
+
ReactApplicationContext context;
|
|
26
|
+
|
|
27
|
+
public RetenoSdkModule(ReactApplicationContext reactContext) {
|
|
28
|
+
super(reactContext);
|
|
29
|
+
context = reactContext;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Override
|
|
33
|
+
@NonNull
|
|
34
|
+
public String getName() {
|
|
35
|
+
return NAME;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@ReactMethod
|
|
39
|
+
public void setDeviceToken(String deviceToken, Promise promise) {
|
|
40
|
+
// ((RetenoApplication) this.context.getCurrentActivity().getApplication()).getRetenoInstance();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@ReactMethod
|
|
44
|
+
public void setUserAttributes(ReadableMap payload, Promise promise) {
|
|
45
|
+
String externalUserId = payload.getString("externalUserId");
|
|
46
|
+
User user = RetenoUserAttributes.buildUserFromPayload(payload);
|
|
47
|
+
if (externalUserId == null) {
|
|
48
|
+
promise.reject("Parsing error", "externalUserId cannot be null");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
((RetenoApplication) this.context.getCurrentActivity().getApplication())
|
|
54
|
+
.getRetenoInstance()
|
|
55
|
+
.setUserAttributes(externalUserId, user);
|
|
56
|
+
} catch (Exception e) {
|
|
57
|
+
promise.reject("Reteno Android SDK Error", e);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
WritableMap res = new WritableNativeMap();
|
|
63
|
+
res.putBoolean("success", true);
|
|
64
|
+
|
|
65
|
+
promise.resolve(res);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public static void onRetenoPushReceived(Context context, Intent intent) {
|
|
69
|
+
WritableMap params;
|
|
70
|
+
Bundle extras = intent.getExtras();
|
|
71
|
+
if (extras != null) {
|
|
72
|
+
try {
|
|
73
|
+
params = Arguments.fromBundle(extras);
|
|
74
|
+
} catch (Exception e) {
|
|
75
|
+
params = Arguments.createMap();
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
params = Arguments.createMap();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
ReactContext reactContext = ((RetenoReactNativeApplication) context.getApplicationContext())
|
|
82
|
+
.getReactContext();
|
|
83
|
+
|
|
84
|
+
if (reactContext != null) {
|
|
85
|
+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
86
|
+
.emit("reteno-push-received", params);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public static void onRetenoPushClicked(Context context, Intent intent) {
|
|
91
|
+
WritableMap params;
|
|
92
|
+
Bundle extras = intent.getExtras();
|
|
93
|
+
if (extras != null) {
|
|
94
|
+
try {
|
|
95
|
+
params = Arguments.fromBundle(extras);
|
|
96
|
+
} catch (Exception e) {
|
|
97
|
+
params = Arguments.createMap();
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
params = Arguments.createMap();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private WritableMap parseIntent(Intent intent){
|
|
105
|
+
WritableMap params;
|
|
106
|
+
Bundle extras = intent.getExtras();
|
|
107
|
+
if (extras != null) {
|
|
108
|
+
try {
|
|
109
|
+
params = Arguments.fromBundle(extras);
|
|
110
|
+
} catch (Exception e){
|
|
111
|
+
params = Arguments.createMap();
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
params = Arguments.createMap();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return params;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@ReactMethod
|
|
121
|
+
public void getInitialNotification(Promise promise){
|
|
122
|
+
Activity activity = getCurrentActivity();
|
|
123
|
+
if(activity == null){
|
|
124
|
+
promise.resolve(null);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
promise.resolve(parseIntent(activity.getIntent()));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package com.retenosdk;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
|
|
5
|
+
import com.facebook.react.ReactPackage;
|
|
6
|
+
import com.facebook.react.bridge.NativeModule;
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
+
import com.facebook.react.uimanager.ViewManager;
|
|
9
|
+
|
|
10
|
+
import java.util.ArrayList;
|
|
11
|
+
import java.util.Collections;
|
|
12
|
+
import java.util.List;
|
|
13
|
+
|
|
14
|
+
public class RetenoSdkPackage implements ReactPackage {
|
|
15
|
+
@NonNull
|
|
16
|
+
@Override
|
|
17
|
+
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
|
18
|
+
List<NativeModule> modules = new ArrayList<>();
|
|
19
|
+
modules.add(new RetenoSdkModule(reactContext));
|
|
20
|
+
return modules;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@NonNull
|
|
24
|
+
@Override
|
|
25
|
+
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
|
26
|
+
return Collections.emptyList();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
package com.retenosdk;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
4
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
5
|
+
import com.reteno.core.domain.model.user.Address;
|
|
6
|
+
import com.reteno.core.domain.model.user.User;
|
|
7
|
+
import com.reteno.core.domain.model.user.UserAttributes;
|
|
8
|
+
import com.reteno.core.domain.model.user.UserCustomField;
|
|
9
|
+
|
|
10
|
+
import java.util.ArrayList;
|
|
11
|
+
import java.util.List;
|
|
12
|
+
|
|
13
|
+
public class RetenoUserAttributes {
|
|
14
|
+
private static String getStringOrNull(String input) {
|
|
15
|
+
if (input == null) return null;
|
|
16
|
+
if (input.isEmpty()) return null;
|
|
17
|
+
return input;
|
|
18
|
+
}
|
|
19
|
+
private static List<UserCustomField> buildUserCustomData(ReadableArray fields) {
|
|
20
|
+
int countView = fields.size();
|
|
21
|
+
if (countView == 0) return null;
|
|
22
|
+
|
|
23
|
+
List<UserCustomField> list = new ArrayList<>();
|
|
24
|
+
for (int i = 0; i < countView; i++) {
|
|
25
|
+
ReadableMap field = fields.getMap(i);
|
|
26
|
+
|
|
27
|
+
String key = null;
|
|
28
|
+
String value = null;
|
|
29
|
+
|
|
30
|
+
if (field.getString("key") != null) {
|
|
31
|
+
key = field.getString("key");
|
|
32
|
+
}
|
|
33
|
+
if (field.getString("value") != null) {
|
|
34
|
+
value = field.getString("value");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (key != null) {
|
|
38
|
+
list.add(new UserCustomField(key, value));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return list;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private static List<String> buildStringArr(ReadableMap user, String key) {
|
|
45
|
+
if (user == null) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
ReadableArray payloadStringArr = user.getArray("subscriptionKeys");
|
|
49
|
+
if (payloadStringArr == null) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
int countView = payloadStringArr.size();
|
|
54
|
+
if (countView == 0) return null;
|
|
55
|
+
|
|
56
|
+
List<String> stringArr = new ArrayList<>();
|
|
57
|
+
for (int i = 0; i < countView; i++) {
|
|
58
|
+
String str = payloadStringArr.getString(i);
|
|
59
|
+
stringArr.add(str);
|
|
60
|
+
}
|
|
61
|
+
return stringArr;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public static User buildUserFromPayload(ReadableMap payload) {
|
|
65
|
+
ReadableMap payloadUser = null;
|
|
66
|
+
ReadableMap payloadUserAttributes = null;
|
|
67
|
+
|
|
68
|
+
String payloadPhone = null;
|
|
69
|
+
String payloadEmail = null;
|
|
70
|
+
String payloadFirstName = null;
|
|
71
|
+
String payloadLastName = null;
|
|
72
|
+
String payloadLanguageCode = null;
|
|
73
|
+
String payloadTimeZone = null;
|
|
74
|
+
|
|
75
|
+
ReadableMap payloadAddress = null;
|
|
76
|
+
ReadableArray payloadFields = null;
|
|
77
|
+
|
|
78
|
+
Address address = null;
|
|
79
|
+
List<UserCustomField> fields = null;
|
|
80
|
+
|
|
81
|
+
payloadUser = payload.getMap("user");
|
|
82
|
+
|
|
83
|
+
if (payloadUser != null) {
|
|
84
|
+
payloadUserAttributes = payloadUser.getMap("userAttributes");
|
|
85
|
+
if (payloadUserAttributes != null) {
|
|
86
|
+
payloadPhone = payloadUserAttributes.getString("phone");
|
|
87
|
+
payloadEmail = payloadUserAttributes.getString("email");
|
|
88
|
+
payloadFirstName = payloadUserAttributes.getString("firstName");
|
|
89
|
+
payloadLastName = payloadUserAttributes.getString("lastName");
|
|
90
|
+
payloadLanguageCode = payloadUserAttributes.getString("languageCode");
|
|
91
|
+
payloadTimeZone = payloadUserAttributes.getString("timeZone");
|
|
92
|
+
payloadAddress = payloadUserAttributes.getMap("address");
|
|
93
|
+
payloadFields = payloadUserAttributes.getArray("fields");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (payloadAddress != null) {
|
|
98
|
+
address = new Address(
|
|
99
|
+
getStringOrNull(payloadAddress.getString("region")),
|
|
100
|
+
getStringOrNull(payloadAddress.getString("town")),
|
|
101
|
+
getStringOrNull(payloadAddress.getString("address")),
|
|
102
|
+
getStringOrNull(payloadAddress.getString("postcode"))
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (payloadFields != null) {
|
|
107
|
+
fields = buildUserCustomData(payloadFields);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
UserAttributes userAttributes = new UserAttributes(
|
|
111
|
+
getStringOrNull(payloadPhone),
|
|
112
|
+
getStringOrNull(payloadEmail),
|
|
113
|
+
getStringOrNull(payloadFirstName),
|
|
114
|
+
getStringOrNull(payloadLastName),
|
|
115
|
+
getStringOrNull(payloadLanguageCode),
|
|
116
|
+
getStringOrNull(payloadTimeZone),
|
|
117
|
+
address,
|
|
118
|
+
fields
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
List<String> subscriptionKeys = buildStringArr(payloadUser, "subscriptionKeys");
|
|
122
|
+
List<String> groupNamesInclude = buildStringArr(payloadUser, "groupNamesInclude");
|
|
123
|
+
List<String> groupNamesExclude = buildStringArr(payloadUser, "groupNamesExclude");
|
|
124
|
+
|
|
125
|
+
return new User(userAttributes, subscriptionKeys, groupNamesInclude, groupNamesExclude);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class EventEmitter {
|
|
2
|
+
|
|
3
|
+
/// Shared Instance.
|
|
4
|
+
public static var sharedInstance = EventEmitter()
|
|
5
|
+
|
|
6
|
+
// ReactNativeEventEmitter is instantiated by React Native with the bridge.
|
|
7
|
+
private var eventEmitter: RetenoSdk!
|
|
8
|
+
|
|
9
|
+
private init() {}
|
|
10
|
+
|
|
11
|
+
// When React Native instantiates the emitter it is registered here.
|
|
12
|
+
func registerEventEmitter(externalEventEmitter: RetenoSdk) {
|
|
13
|
+
eventEmitter = externalEventEmitter
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func dispatch(name: String, body: Any?) {
|
|
17
|
+
eventEmitter.sendEvent(withName: name, body: body)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/// All Events which must be support by React Native.
|
|
21
|
+
lazy var allEvents: [String] = {
|
|
22
|
+
var allEventNames: [String] = ["reteno-push-received"]
|
|
23
|
+
|
|
24
|
+
// Append all events here
|
|
25
|
+
|
|
26
|
+
return allEventNames
|
|
27
|
+
}()
|
|
28
|
+
|
|
29
|
+
}
|
package/ios/RetenoSdk.m
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import <React/RCTEventEmitter.h>
|
|
3
|
+
|
|
4
|
+
@interface RCT_EXTERN_MODULE(RetenoSdk, RCTEventEmitter)
|
|
5
|
+
|
|
6
|
+
RCT_EXTERN_METHOD(setDeviceToken:(NSString*)deviceToken
|
|
7
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
8
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
9
|
+
|
|
10
|
+
RCT_EXTERN_METHOD(setUserAttributes:(NSDictionary*)payload
|
|
11
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
12
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
13
|
+
|
|
14
|
+
RCT_EXTERN_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve
|
|
15
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
16
|
+
|
|
17
|
+
RCT_EXTERN_METHOD(supportedEvents)
|
|
18
|
+
|
|
19
|
+
+ (BOOL)requiresMainQueueSetup
|
|
20
|
+
{
|
|
21
|
+
return NO;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UserNotifications
|
|
3
|
+
import Reteno
|
|
4
|
+
|
|
5
|
+
@objc(RetenoSdk)
|
|
6
|
+
open class RetenoSdk: RCTEventEmitter {
|
|
7
|
+
|
|
8
|
+
override init() {
|
|
9
|
+
super.init()
|
|
10
|
+
EventEmitter.sharedInstance.registerEventEmitter(externalEventEmitter: self);
|
|
11
|
+
Reteno.userNotificationService.didReceiveNotificationUserInfo = {userInfo in
|
|
12
|
+
EventEmitter.sharedInstance.dispatch(name: "reteno-push-received", body: userInfo)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/// Base overide for RCTEventEmitter.
|
|
17
|
+
///
|
|
18
|
+
/// - Returns: all supported events
|
|
19
|
+
@objc open override func supportedEvents() -> [String] {
|
|
20
|
+
return EventEmitter.sharedInstance.allEvents;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@objc(setDeviceToken:withResolver:withRejecter:)
|
|
25
|
+
func setDeviceToken(deviceToken: String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
|
|
26
|
+
Reteno.userNotificationService.processRemoteNotificationsToken(deviceToken);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@objc(setUserAttributes:withResolver:withRejecter:)
|
|
30
|
+
func setUserAttributes(payload: NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
|
|
31
|
+
print("setUserAttributes was called")
|
|
32
|
+
let externalUserId = payload["externalUserId"] as? String;
|
|
33
|
+
|
|
34
|
+
do {
|
|
35
|
+
let requestPayload = try RetenoUserAttributes.buildSetUserAttributesPayload(payload: payload);
|
|
36
|
+
Reteno.updateUserAttributes(
|
|
37
|
+
externalUserId: externalUserId,
|
|
38
|
+
userAttributes: requestPayload.userAttributes,
|
|
39
|
+
subscriptionKeys: requestPayload.subscriptionKeys,
|
|
40
|
+
groupNamesInclude: requestPayload.groupNamesInclude,
|
|
41
|
+
groupNamesExclude: requestPayload.groupNamesExclude
|
|
42
|
+
);
|
|
43
|
+
let res:[String:Bool] = ["success":true];
|
|
44
|
+
|
|
45
|
+
resolve(res);
|
|
46
|
+
} catch {
|
|
47
|
+
reject("100", "Reteno iOS SDK Error", error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@objc(getInitialNotification:withRejecter:)
|
|
52
|
+
func getInitialNotification(_ resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
|
|
53
|
+
var initialNotif: Any? = nil;
|
|
54
|
+
let remoteUserInfo = bridge.launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification];
|
|
55
|
+
if (remoteUserInfo != nil) {
|
|
56
|
+
initialNotif = remoteUserInfo;
|
|
57
|
+
}
|
|
58
|
+
if (initialNotif != nil) {
|
|
59
|
+
resolve(initialNotif);
|
|
60
|
+
} else {
|
|
61
|
+
resolve(nil);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|