react-native-quicktracking-analytics-module 1.0.4 → 2.0.1
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/android/.gradle/7.4/checksums/checksums.lock +0 -0
- package/android/.gradle/7.4/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/7.4/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/7.4/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/7.4/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/7.4/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/7.4/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.4/fileHashes/resourceHashesCache.bin +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
- package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/android/.idea/compiler.xml +6 -0
- package/android/.idea/gradle.xml +19 -0
- package/android/.idea/jarRepositories.xml +35 -0
- package/android/.idea/libraries/Gradle__androidx_activity_activity_1_2_4_aar.xml +16 -0
- package/android/.idea/libraries/Gradle__androidx_annotation_annotation_1_3_0.xml +11 -0
- package/android/.idea/libraries/Gradle__androidx_annotation_annotation_experimental_1_1_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_4_1_aar.xml +16 -0
- package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_4_1_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_arch_core_core_common_2_1_0.xml +11 -0
- package/android/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_1_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_autofill_autofill_1_1_0_aar.xml +16 -0
- package/android/.idea/libraries/Gradle__androidx_collection_collection_1_1_0.xml +11 -0
- package/android/.idea/libraries/Gradle__androidx_core_core_1_7_0_aar.xml +16 -0
- package/android/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml +16 -0
- package/android/.idea/libraries/Gradle__androidx_fragment_fragment_1_3_6_aar.xml +16 -0
- package/android/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_4_0.xml +11 -0
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_3_1_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_4_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_3_1_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_savedstate_2_3_1_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_savedstate_savedstate_1_1_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_swiperefreshlayout_swiperefreshlayout_1_0_0_aar.xml +16 -0
- package/android/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_1_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml +13 -0
- package/android/.idea/libraries/Gradle__com_facebook_fbjni_fbjni_java_only_0_2_2.xml +13 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_drawee_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_fbcore_2_5_0_aar.xml +18 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_fresco_2_5_0_aar.xml +18 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_imagepipeline_2_5_0_aar.xml +18 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_imagepipeline_base_2_5_0_aar.xml +18 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_imagepipeline_native_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_imagepipeline_okhttp3_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_memory_type_ashmem_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_memory_type_java_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_memory_type_native_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_nativeimagefilters_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_nativeimagetranscoder_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_fresco_ui_common_2_5_0_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_infer_annotation_infer_annotation_0_18_0.xml +13 -0
- package/android/.idea/libraries/Gradle__com_facebook_react_react_native_0_70_6_debug_aar.xml +14 -0
- package/android/.idea/libraries/Gradle__com_facebook_soloader_annotation_0_10_4.xml +13 -0
- package/android/.idea/libraries/Gradle__com_facebook_soloader_nativeloader_0_10_4.xml +13 -0
- package/android/.idea/libraries/Gradle__com_facebook_soloader_soloader_0_10_4_aar.xml +15 -0
- package/android/.idea/libraries/Gradle__com_facebook_yoga_proguard_annotations_1_19_0.xml +13 -0
- package/android/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml +13 -0
- package/android/.idea/libraries/Gradle__com_squareup_okhttp3_okhttp_4_9_2.xml +13 -0
- package/android/.idea/libraries/Gradle__com_squareup_okhttp3_okhttp_urlconnection_4_9_2.xml +13 -0
- package/android/.idea/libraries/Gradle__com_squareup_okio_okio_2_9_0.xml +13 -0
- package/android/.idea/libraries/Gradle__com_umeng_umsdk_qt_px_common_1_4_0_PX_aar.xml +11 -0
- package/android/.idea/libraries/Gradle__javax_inject_javax_inject_1.xml +13 -0
- package/android/.idea/libraries/Gradle__org_jetbrains_annotations_13_0.xml +13 -0
- package/android/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_annotations_jvm_1_3_72.xml +13 -0
- package/android/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_6_10.xml +13 -0
- package/android/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_6_10.xml +13 -0
- package/android/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_6_10.xml +13 -0
- package/android/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_6_10.xml +13 -0
- package/android/.idea/misc.xml +9 -0
- package/android/.idea/modules/android.iml +104 -0
- package/android/.idea/modules.xml +8 -0
- package/android/.idea/vcs.xml +6 -0
- package/android/build.gradle +2 -1
- package/android/local.properties +8 -0
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/QTSDKManager.java +93 -0
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/{QuicktrackingAnalyticsModuleModule.java → QuicktrackingAnalyticsModule.java} +35 -12
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/QuicktrackingAnalyticsModulePackage.java +1 -1
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/property/QTViewProperties.java +48 -0
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/QTLog.java +122 -0
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNPropertyManager.java +29 -0
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNTouchTargetHelper.java +139 -0
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNUtils.java +188 -0
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNViewUtils.java +148 -0
- package/ios/NSObject+QTReactNativeSwizzler.h +19 -0
- package/ios/NSObject+QTReactNativeSwizzler.m +38 -0
- package/ios/QTRNUtils.h +21 -0
- package/ios/QTRNUtils.m +48 -0
- package/ios/QTReactNativeRootViewManager.h +41 -0
- package/ios/QTReactNativeRootViewManager.m +100 -0
- package/ios/QTReactNativeViewProperty.h +28 -0
- package/ios/QTReactNativeViewProperty.m +27 -0
- package/ios/QuickTrackingSDKManager.h +25 -0
- package/ios/QuickTrackingSDKManager.m +140 -0
- package/ios/QuicktrackingAnalyticsModule.h +11 -1
- package/ios/QuicktrackingAnalyticsModule.m +46 -3
- package/ios/QuicktrackingAnalyticsModule.xcodeproj/project.pbxproj +42 -0
- package/ios/QuicktrackingAnalyticsModule.xcodeproj/project.xcworkspace/contents.xcworkspacedata +3 -0
- package/ios/QuicktrackingAnalyticsModule.xcodeproj/project.xcworkspace/xcuserdata/yuzhao.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/RCTRootView+QTReactNative.h +23 -0
- package/ios/RCTRootView+QTReactNative.m +56 -0
- package/lib/typescript/index.d.ts +3 -2
- package/package.json +30 -3
- package/react-native-quicktracking-analytics-module.podspec +1 -1
- package/src/hook.js +679 -0
- package/HISTORY.md +0 -17
- package/android/.gradle/7.4.2/checksums/checksums.lock +0 -0
- package/android/.gradle/7.4.2/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/7.4.2/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/7.4.2/fileChanges/last-build.bin +0 -0
- package/android/.gradle/7.4.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.4.2/gc.properties +0 -0
- package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/MainApplication.java +0 -47
- package/ios/.DS_Store +0 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
package com.reactnativequicktrackinganalyticsmodule.utils;
|
|
2
|
+
|
|
3
|
+
import android.graphics.drawable.AnimationDrawable;
|
|
4
|
+
|
|
5
|
+
import com.facebook.react.bridge.Arguments;
|
|
6
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
7
|
+
import com.facebook.react.bridge.ReadableNativeMap;
|
|
8
|
+
import com.facebook.react.bridge.WritableMap;
|
|
9
|
+
|
|
10
|
+
import java.security.MessageDigest;
|
|
11
|
+
import java.util.ArrayList;
|
|
12
|
+
import java.util.HashMap;
|
|
13
|
+
import java.util.Iterator;
|
|
14
|
+
import java.util.List;
|
|
15
|
+
import java.util.Map;
|
|
16
|
+
|
|
17
|
+
import org.json.JSONArray;
|
|
18
|
+
import org.json.JSONObject;
|
|
19
|
+
|
|
20
|
+
public class RNUtils {
|
|
21
|
+
public static final String TAG = "QuickTracking == ";
|
|
22
|
+
/**
|
|
23
|
+
* ReadableMap 转换成 JSONObject
|
|
24
|
+
* */
|
|
25
|
+
public static JSONObject convertToJSONObject(ReadableMap params) {
|
|
26
|
+
if (params == null) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
JSONObject json = null;
|
|
30
|
+
ReadableNativeMap nativeMap = null;
|
|
31
|
+
try {
|
|
32
|
+
nativeMap = (ReadableNativeMap) params;
|
|
33
|
+
json = new JSONObject(params.toString()).getJSONObject("NativeMap");
|
|
34
|
+
} catch (Exception e) {
|
|
35
|
+
android.util.Log.e(TAG, "JSON 解析失败!", e);
|
|
36
|
+
String superName = nativeMap.getClass().getSuperclass().getSimpleName();
|
|
37
|
+
try {
|
|
38
|
+
json = new JSONObject(params.toString()).getJSONObject(superName);
|
|
39
|
+
} catch (Exception e1) {
|
|
40
|
+
android.util.Log.e(TAG, "JSON 解析失败!", e1);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return json;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* JSONObject 转换成 WritableMap
|
|
48
|
+
* */
|
|
49
|
+
public static WritableMap convertToWritableMap(JSONObject json) {
|
|
50
|
+
if (json == null || json.length() == 0) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
WritableMap writableMap = Arguments.createMap();
|
|
54
|
+
Iterator<String> it = json.keys();
|
|
55
|
+
while(it.hasNext()) {
|
|
56
|
+
try {
|
|
57
|
+
String key = it.next();
|
|
58
|
+
writableMap.putString(key, json.optString(key));
|
|
59
|
+
} catch (Exception e) {
|
|
60
|
+
QTLog.i(TAG, "JSON to WritableMap 解析失败!", e);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return writableMap;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* ReadableMap 转换成 HashMap
|
|
68
|
+
* */
|
|
69
|
+
public static HashMap<String, Object> convertToHashMap(ReadableMap params) {
|
|
70
|
+
if (params == null) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
HashMap<String, Object> map = null;
|
|
74
|
+
try {
|
|
75
|
+
map = ((ReadableNativeMap)params).toHashMap();
|
|
76
|
+
}catch (Exception e){
|
|
77
|
+
android.util.Log.e(TAG, "ReadableMap to HashMap 解析失败!", e);
|
|
78
|
+
}
|
|
79
|
+
return map;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* merge JSONObject
|
|
84
|
+
* */
|
|
85
|
+
public static void mergeJSONObject(final JSONObject source, JSONObject dest) {
|
|
86
|
+
try {
|
|
87
|
+
Iterator<String> sourceIterator = source.keys();
|
|
88
|
+
while (sourceIterator.hasNext()) {
|
|
89
|
+
String key = sourceIterator.next();
|
|
90
|
+
Object value = source.get(key);
|
|
91
|
+
dest.put(key, value);
|
|
92
|
+
}
|
|
93
|
+
} catch (Exception e) {
|
|
94
|
+
android.util.Log.e(TAG, "JSONObject Merge失败!", e);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public static Map<String, Object> convertToMap(JSONObject jsonObject) {
|
|
99
|
+
try {
|
|
100
|
+
Map<String, Object> map = new HashMap<String, Object>();
|
|
101
|
+
Iterator<String> keys = jsonObject.keys();
|
|
102
|
+
while(keys.hasNext()) {
|
|
103
|
+
String key = keys.next();
|
|
104
|
+
Object value = jsonObject.get(key);
|
|
105
|
+
if (value instanceof JSONArray) {
|
|
106
|
+
value = toList((JSONArray) value);
|
|
107
|
+
} else if (value instanceof JSONObject) {
|
|
108
|
+
value = toMap((JSONObject) value);
|
|
109
|
+
}
|
|
110
|
+
map.put(key, value);
|
|
111
|
+
}
|
|
112
|
+
return map;
|
|
113
|
+
} catch (Exception e) {
|
|
114
|
+
QTLog.printStackTrace(e);
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public static List<Object> toList(JSONArray jsonArray) {
|
|
120
|
+
try {
|
|
121
|
+
List<Object> list = new ArrayList<Object>();
|
|
122
|
+
for (int i = 0; i < jsonArray.length(); i++) {
|
|
123
|
+
Object obj = jsonArray.get(i);
|
|
124
|
+
if (obj instanceof JSONArray) {
|
|
125
|
+
obj = toList((JSONArray) obj);
|
|
126
|
+
} else if (obj instanceof JSONObject) {
|
|
127
|
+
obj = toMap((JSONObject) obj);
|
|
128
|
+
}
|
|
129
|
+
list.add(obj);
|
|
130
|
+
}
|
|
131
|
+
} catch (Exception e) {
|
|
132
|
+
QTLog.printStackTrace(e);
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public static Map<String, Object> toMap(JSONObject jsonObject) {
|
|
138
|
+
try {
|
|
139
|
+
Map<String, Object> map = new HashMap<String, Object>();
|
|
140
|
+
Iterator<String> keysItr = jsonObject.keys();
|
|
141
|
+
while(keysItr.hasNext()) {
|
|
142
|
+
String key = keysItr.next();
|
|
143
|
+
Object value = jsonObject.get(key);
|
|
144
|
+
|
|
145
|
+
if(value instanceof JSONArray) {
|
|
146
|
+
value = toList((JSONArray) value);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
else if(value instanceof JSONObject) {
|
|
150
|
+
value = toMap((JSONObject) value);
|
|
151
|
+
}
|
|
152
|
+
map.put(key, value);
|
|
153
|
+
}
|
|
154
|
+
return map;
|
|
155
|
+
} catch (Exception e) {
|
|
156
|
+
QTLog.printStackTrace(e);
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public static String MD5(String str) {
|
|
162
|
+
try {
|
|
163
|
+
if (str != null) {
|
|
164
|
+
try {
|
|
165
|
+
byte[] defaultBytes = str.getBytes();
|
|
166
|
+
MessageDigest algorithm = MessageDigest.getInstance("MD5");
|
|
167
|
+
algorithm.reset();
|
|
168
|
+
algorithm.update(defaultBytes);
|
|
169
|
+
byte messageDigest[] = algorithm.digest();
|
|
170
|
+
StringBuffer hexString = new StringBuffer();
|
|
171
|
+
for (int i = 0; i < messageDigest.length; i++) {
|
|
172
|
+
hexString.append(String.format("%02X", messageDigest[i]));
|
|
173
|
+
}
|
|
174
|
+
return hexString.toString();
|
|
175
|
+
} catch (Exception e) {
|
|
176
|
+
return str.replaceAll("[^[a-z][A-Z][0-9][.][_]]", "");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
} catch (Exception e) {
|
|
181
|
+
android.util.Log.e(TAG, "MD5 e is " + e);
|
|
182
|
+
return null;
|
|
183
|
+
} catch (Throwable e) {
|
|
184
|
+
android.util.Log.e(TAG, "MD5 e is " + e);
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNViewUtils.java
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
package com.reactnativequicktrackinganalyticsmodule.utils;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.view.View;
|
|
5
|
+
import android.view.ViewGroup;
|
|
6
|
+
import android.view.ViewParent;
|
|
7
|
+
|
|
8
|
+
import org.json.JSONObject;
|
|
9
|
+
|
|
10
|
+
import java.lang.ref.WeakReference;
|
|
11
|
+
import java.util.WeakHashMap;
|
|
12
|
+
|
|
13
|
+
public class RNViewUtils {
|
|
14
|
+
private static WeakReference mWeakCurrentActivityReference;
|
|
15
|
+
private static String currentTitle;
|
|
16
|
+
private static String currentScreenName;
|
|
17
|
+
public static boolean isScreenVisiable = false;
|
|
18
|
+
private static JSONObject screenProperties;
|
|
19
|
+
private static WeakReference onTouchViewReference;
|
|
20
|
+
private static WeakHashMap<Activity, JSONObject> mScreenMap = new WeakHashMap<>();
|
|
21
|
+
|
|
22
|
+
public static void setOnTouchView(View nativeTargetView) {
|
|
23
|
+
onTouchViewReference = new WeakReference(nativeTargetView);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public static Activity getCurrentActivity() {
|
|
27
|
+
if (mWeakCurrentActivityReference == null) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return (Activity) mWeakCurrentActivityReference.get();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private static View getClickView(int viewId, View onTouchView) {
|
|
34
|
+
View currentView = onTouchView;
|
|
35
|
+
while (currentView.getId() != viewId) {
|
|
36
|
+
ViewParent parent = currentView.getParent();
|
|
37
|
+
if (!(parent instanceof View)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
currentView = (View) parent;
|
|
41
|
+
}
|
|
42
|
+
return currentView;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private static View getClickViewInChild(int viewId, ViewGroup currentView) {
|
|
46
|
+
int currentViewCount = currentView.getChildCount();
|
|
47
|
+
for (int i = 0; i < currentViewCount; i++) {
|
|
48
|
+
View childView = currentView.getChildAt(i);
|
|
49
|
+
if (childView != null) {
|
|
50
|
+
if (childView.getId() == viewId) {
|
|
51
|
+
return childView;
|
|
52
|
+
}
|
|
53
|
+
if (childView instanceof ViewGroup) {
|
|
54
|
+
View clickView = getClickViewInChild(viewId, (ViewGroup) childView);
|
|
55
|
+
if (clickView != null) {
|
|
56
|
+
return clickView;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public static View getTouchViewByTag(int viewTag) {
|
|
65
|
+
if(onTouchViewReference != null) {
|
|
66
|
+
View onTouchView = (View) onTouchViewReference.get();
|
|
67
|
+
if (onTouchView != null) {
|
|
68
|
+
View clickView = getClickView(viewTag, onTouchView);
|
|
69
|
+
if (clickView == null && (onTouchView instanceof ViewGroup)) {
|
|
70
|
+
clickView = getClickViewInChild(viewTag, (ViewGroup) onTouchView);
|
|
71
|
+
}
|
|
72
|
+
return clickView;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public static View getViewByTag(int viewTag) {
|
|
79
|
+
View clickView = null;
|
|
80
|
+
try {
|
|
81
|
+
Activity currentActivity = getCurrentActivity();
|
|
82
|
+
if (currentActivity != null) {
|
|
83
|
+
clickView = currentActivity.findViewById(viewTag);
|
|
84
|
+
}
|
|
85
|
+
if (clickView == null) {
|
|
86
|
+
clickView = getTouchViewByTag(viewTag);
|
|
87
|
+
}
|
|
88
|
+
} catch (Exception ignored) {
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
return clickView;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public static String getTitle() { return currentTitle; }
|
|
95
|
+
|
|
96
|
+
public static String getScreenName() { return currentScreenName; }
|
|
97
|
+
|
|
98
|
+
private static void setCurrentActivity(Activity currentActivity) {
|
|
99
|
+
clearCurrentActivityReference();
|
|
100
|
+
mWeakCurrentActivityReference = new WeakReference(currentActivity);
|
|
101
|
+
JSONObject properties = mScreenMap.get(currentActivity);
|
|
102
|
+
if (properties != null && properties.has("$screen_name")) {
|
|
103
|
+
saveScreenAndTitle(properties.optString("$screen_name"), properties.optString("$title"));
|
|
104
|
+
} else {
|
|
105
|
+
currentScreenName = null;
|
|
106
|
+
currentTitle = null;
|
|
107
|
+
screenProperties = null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public static void saveScreenAndTitle(String screenName, String title) {
|
|
112
|
+
currentScreenName = screenName;
|
|
113
|
+
currentTitle = title;
|
|
114
|
+
try {
|
|
115
|
+
screenProperties = new JSONObject();
|
|
116
|
+
screenProperties.put("$title", title);
|
|
117
|
+
screenProperties.put("$screen_name", screenName);
|
|
118
|
+
screenProperties.put("isSetRNViewTag", true);//标识当前页面已区分 RNView 和原生 View
|
|
119
|
+
} catch (Exception ignored) {
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
Activity currentActivity;
|
|
123
|
+
if ((currentActivity = getCurrentActivity()) != null) {
|
|
124
|
+
mScreenMap.put(currentActivity, screenProperties);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public static void clearCurrentActivityReference() {
|
|
129
|
+
if (mWeakCurrentActivityReference != null) {
|
|
130
|
+
mWeakCurrentActivityReference.clear();
|
|
131
|
+
mWeakCurrentActivityReference = null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public static void setScreenVisiable(boolean isVisiable) {
|
|
136
|
+
isScreenVisiable = isVisiable;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public static void onActivityResumed(Activity currentActivity) {
|
|
140
|
+
setScreenVisiable(true);
|
|
141
|
+
setCurrentActivity(currentActivity);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public static void onActivityPaused() {
|
|
145
|
+
setScreenVisiable(false);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// NSObject+QTReactNativeSwizzler.h
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 钰昭 on 2023/1/6.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
|
|
11
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
12
|
+
|
|
13
|
+
@interface NSObject (QTReactNativeSwizzler)
|
|
14
|
+
|
|
15
|
+
+ (BOOL)qt_reactnative_swizzle:(SEL)originSelector withSelector:(SEL)destinationSelector;
|
|
16
|
+
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//
|
|
2
|
+
// NSObject+QTReactNativeSwizzler.m
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 钰昭 on 2023/1/6.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import "NSObject+QTReactNativeSwizzler.h"
|
|
10
|
+
#import <objc/runtime.h>
|
|
11
|
+
|
|
12
|
+
@implementation NSObject (QTReactNativeSwizzler)
|
|
13
|
+
|
|
14
|
+
+ (BOOL)qt_reactnative_swizzle:(SEL)originSelector withSelector:(SEL)destinationSelector {
|
|
15
|
+
Method origMethod = class_getInstanceMethod(self, originSelector);
|
|
16
|
+
if (!origMethod) {
|
|
17
|
+
return NO;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Method altMethod = class_getInstanceMethod(self, destinationSelector);
|
|
21
|
+
if (!altMethod) {
|
|
22
|
+
return NO;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class_addMethod(self,
|
|
26
|
+
originSelector,
|
|
27
|
+
class_getMethodImplementation(self, originSelector),
|
|
28
|
+
method_getTypeEncoding(origMethod));
|
|
29
|
+
class_addMethod(self,
|
|
30
|
+
destinationSelector,
|
|
31
|
+
class_getMethodImplementation(self, destinationSelector),
|
|
32
|
+
method_getTypeEncoding(altMethod));
|
|
33
|
+
|
|
34
|
+
method_exchangeImplementations(class_getInstanceMethod(self, originSelector), class_getInstanceMethod(self, destinationSelector));
|
|
35
|
+
return YES;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@end
|
package/ios/QTRNUtils.h
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//
|
|
2
|
+
// QTRNUtils.h
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 钰昭 on 2023/1/11.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
|
|
11
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
12
|
+
|
|
13
|
+
@interface QTRNUtils : NSObject
|
|
14
|
+
|
|
15
|
+
#pragma mark - string tools
|
|
16
|
+
+ (NSString *)md5:(NSString *)string;
|
|
17
|
+
+ (BOOL)notEmptyString:(NSString *)string;
|
|
18
|
+
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
NS_ASSUME_NONNULL_END
|
package/ios/QTRNUtils.m
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// QTRNUtils.m
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 钰昭 on 2023/1/11.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import "QTRNUtils.h"
|
|
10
|
+
#import <CommonCrypto/CommonDigest.h>
|
|
11
|
+
|
|
12
|
+
@implementation QTRNUtils
|
|
13
|
+
|
|
14
|
+
#pragma mark - string tools
|
|
15
|
+
|
|
16
|
+
+ (BOOL)notEmptyString:(NSString *)string
|
|
17
|
+
{
|
|
18
|
+
BOOL bRet = YES;
|
|
19
|
+
if ((string == nil) ||
|
|
20
|
+
(string == NULL) ||
|
|
21
|
+
([string isKindOfClass:[NSNull class]]) ||
|
|
22
|
+
(![string isKindOfClass:[NSString class]]) ||
|
|
23
|
+
(([string isKindOfClass:[NSString class]])&&([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)))
|
|
24
|
+
{
|
|
25
|
+
bRet = NO;
|
|
26
|
+
}
|
|
27
|
+
return bRet;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
+ (NSString *)md5:(NSString *)string
|
|
31
|
+
{
|
|
32
|
+
if ([QTRNUtils notEmptyString:string]) {
|
|
33
|
+
const char *cStr = [string UTF8String];
|
|
34
|
+
unsigned char result[16];
|
|
35
|
+
CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
|
|
36
|
+
return [NSString stringWithFormat:
|
|
37
|
+
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
|
|
38
|
+
result[0], result[1], result[2], result[3],
|
|
39
|
+
result[4], result[5], result[6], result[7],
|
|
40
|
+
result[8], result[9], result[10], result[11],
|
|
41
|
+
result[12], result[13], result[14], result[15]
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
return @"";
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//
|
|
2
|
+
// QTReactNativeRootViewManager.h
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 未知 on 2023/1/6.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
#import "RCTRootView+QTReactNative.h"
|
|
11
|
+
#import "QTReactNativeViewProperty.h"
|
|
12
|
+
|
|
13
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
14
|
+
|
|
15
|
+
@interface QTReactNativeRootViewManager : NSObject
|
|
16
|
+
|
|
17
|
+
#pragma mark - rootView
|
|
18
|
+
|
|
19
|
+
+ (instancetype)sharedInstance;
|
|
20
|
+
|
|
21
|
+
/// 缓存 RCTRootView
|
|
22
|
+
/// @param rootView rootView
|
|
23
|
+
- (void)addRootView:(RCTRootView *)rootView;
|
|
24
|
+
|
|
25
|
+
/// 获取当前RootView
|
|
26
|
+
- (RCTRootView *)currentRootView;
|
|
27
|
+
|
|
28
|
+
#pragma mark - viewProperties
|
|
29
|
+
|
|
30
|
+
/// 缓存 RN 页面中的元素信息
|
|
31
|
+
/// @param property 元素信息
|
|
32
|
+
/// @param rootTag 当前 RN 页面 RCTRootView 对应的 reactTag
|
|
33
|
+
- (void)addViewProperty:(QTReactNativeViewProperty *)property withRootTag:(NSNumber *)rootTag;
|
|
34
|
+
|
|
35
|
+
/// 获取 RN 页面中的元素信息
|
|
36
|
+
/// @param rootTag 当前 RN 页面 RCTRootView 对应的 reactTag
|
|
37
|
+
- (NSSet<QTReactNativeViewProperty *> *)viewPropertiesWithRootTag:(NSNumber *)rootTag;
|
|
38
|
+
|
|
39
|
+
@end
|
|
40
|
+
|
|
41
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
//
|
|
2
|
+
// QTReactNativeRootViewManager.m
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 未知 on 2023/1/6.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import "QTReactNativeRootViewManager.h"
|
|
10
|
+
#import <React/RCTUIManager.h>
|
|
11
|
+
|
|
12
|
+
@interface QTReactNativeRootViewManager ()
|
|
13
|
+
|
|
14
|
+
@property (nonatomic, strong) NSPointerArray *rootViews;
|
|
15
|
+
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSMutableSet *> *viewProperties;
|
|
16
|
+
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@implementation QTReactNativeRootViewManager
|
|
20
|
+
|
|
21
|
+
+ (instancetype)sharedInstance {
|
|
22
|
+
static QTReactNativeRootViewManager *manager;
|
|
23
|
+
static dispatch_once_t onceToken;
|
|
24
|
+
dispatch_once(&onceToken, ^{
|
|
25
|
+
manager = [[QTReactNativeRootViewManager alloc] init];
|
|
26
|
+
});
|
|
27
|
+
return manager;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
- (instancetype)init {
|
|
31
|
+
self = [super init];
|
|
32
|
+
if (self) {
|
|
33
|
+
_rootViews = [NSPointerArray weakObjectsPointerArray];
|
|
34
|
+
_viewProperties = [NSMutableDictionary dictionary];
|
|
35
|
+
}
|
|
36
|
+
return self;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#pragma mark - rootView
|
|
40
|
+
|
|
41
|
+
- (void)addRootView:(RCTRootView *)rootView {
|
|
42
|
+
[self compact];
|
|
43
|
+
[self.rootViews addPointer:(__bridge void * _Nullable)(rootView)];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
- (RCTRootView *)currentRootView {
|
|
47
|
+
NSArray<RCTRootView *> *rootViews = self.rootViews.allObjects;
|
|
48
|
+
// 倒序遍历, 获取最上层正在显示的 RCTRootView
|
|
49
|
+
for (RCTRootView *rootView in rootViews.reverseObjectEnumerator) {
|
|
50
|
+
BOOL isVisible = rootView.alpha > 0.01 && !rootView.isHidden;
|
|
51
|
+
if (isVisible && rootView.window) {
|
|
52
|
+
return rootView;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// RCTRootView 初始化后, RN 插件就会触发页面浏览事件, 但此时 RCTRootView 可能还未显示到页面上
|
|
56
|
+
// 所以此处取最后一个 RCTRootView 作为兼容逻辑
|
|
57
|
+
return rootViews.lastObject;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
#pragma mark - viewProperties
|
|
61
|
+
|
|
62
|
+
- (void)addViewProperty:(QTReactNativeViewProperty *)property withRootTag:(NSNumber *)rootTag {
|
|
63
|
+
if (!property || !rootTag) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
NSMutableSet *viewProperties = self.viewProperties[rootTag];
|
|
67
|
+
if (!viewProperties) {
|
|
68
|
+
viewProperties = [NSMutableSet set];
|
|
69
|
+
self.viewProperties[rootTag] = viewProperties;
|
|
70
|
+
}
|
|
71
|
+
[viewProperties addObject:property];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
- (NSSet<QTReactNativeViewProperty *> *)viewPropertiesWithRootTag:(NSNumber *)rootTag {
|
|
75
|
+
return [self.viewProperties[rootTag] copy];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#pragma mark - utils
|
|
79
|
+
|
|
80
|
+
- (void)compact {
|
|
81
|
+
// NSPointerArray 内部有个标记 needsCompaction, 当 needsCompaction 为 true 时, compact 才会生效
|
|
82
|
+
// 向 NSPointerArray 添加一个正常元素, 该元素在后面被释放时, needsCompaction 不会变化
|
|
83
|
+
// 向 NSPointerArray 主动添加 NULL 时, needsCompaction 标记会被设置为 true
|
|
84
|
+
// 所以调用 compact 前需要先添加一个 NULL
|
|
85
|
+
// https://stackoverflow.com/questions/31322290/nspointerarray-weird-compaction
|
|
86
|
+
[self.rootViews addPointer:NULL];
|
|
87
|
+
[self.rootViews compact];
|
|
88
|
+
|
|
89
|
+
// 清除没有 RCRootView 的 viewProperty
|
|
90
|
+
NSMutableSet *rootTags = [NSMutableSet set];
|
|
91
|
+
for(RCTRootView *rootView in self.rootViews) {
|
|
92
|
+
[rootTags addObject:rootView.reactTag];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
NSMutableSet *removeTags = [NSMutableSet setWithArray:[self.viewProperties allKeys]];
|
|
96
|
+
[removeTags minusSet:rootTags];
|
|
97
|
+
[self.viewProperties removeObjectsForKeys:removeTags.allObjects];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//
|
|
2
|
+
// QTReactNativeViewProperty.h
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 钰昭 on 2023/1/6.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#import <Foundation/Foundation.h>
|
|
11
|
+
#import <UIKit/UIKit.h>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
15
|
+
|
|
16
|
+
#pragma mark - View Property
|
|
17
|
+
@interface QTReactNativeViewProperty : NSObject <NSCopying>
|
|
18
|
+
|
|
19
|
+
/// View 唯一标识符
|
|
20
|
+
@property (nonatomic, strong) NSNumber *reactTag;
|
|
21
|
+
/// View 可点击状态
|
|
22
|
+
@property (nonatomic, assign) BOOL clickable;
|
|
23
|
+
/// View 自定义属性
|
|
24
|
+
@property (nonatomic, copy) NSDictionary *properties;
|
|
25
|
+
|
|
26
|
+
@end
|
|
27
|
+
|
|
28
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//
|
|
2
|
+
// QTReactNativeViewProperty.m
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 钰昭 on 2023/1/6.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
#import "QTReactNativeViewProperty.h"
|
|
11
|
+
|
|
12
|
+
@implementation QTReactNativeViewProperty
|
|
13
|
+
|
|
14
|
+
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
|
|
15
|
+
QTReactNativeViewProperty *property = [[[self class] allocWithZone: zone] init];
|
|
16
|
+
property.reactTag = self.reactTag;
|
|
17
|
+
property.clickable = self.clickable;
|
|
18
|
+
property.properties = self.properties;
|
|
19
|
+
return property;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
- (NSString *)description {
|
|
23
|
+
return [NSString stringWithFormat:@"%@; reactTag: %@; clickable: %@; properties: %@", [super description], self.reactTag, (self.clickable ? @"YES" : @"NO"), self.properties];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//
|
|
2
|
+
// QuickTrackingSDKManager.h
|
|
3
|
+
// QuicktrackingAnalyticsModule
|
|
4
|
+
//
|
|
5
|
+
// Created by 钰昭 on 2023/1/6.
|
|
6
|
+
// Copyright © 2023 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#ifndef QuickTrackingSDKManager_h
|
|
11
|
+
#define QuickTrackingSDKManager_h
|
|
12
|
+
|
|
13
|
+
@interface QuickTrackingSDKManager : NSObject
|
|
14
|
+
|
|
15
|
+
+ (instancetype)sharedInstance;
|
|
16
|
+
|
|
17
|
+
- (void)prepareView:(NSNumber *)reactTag clickable:(BOOL)clickable paramters:(NSDictionary *)paramters;
|
|
18
|
+
|
|
19
|
+
- (void)prepareView:(NSNumber *)reactTag clickable:(BOOL)clickable paramters:(NSDictionary *)paramters rootTag:(NSNumber *)rootTag;
|
|
20
|
+
|
|
21
|
+
- (void)trackViewClick:(NSNumber *)reactTag;
|
|
22
|
+
|
|
23
|
+
@end
|
|
24
|
+
|
|
25
|
+
#endif /* QuickTrackingSDKManager_h */
|