cobrowse-sdk-react-native 3.5.0 → 3.6.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/.github/workflows/lint.yaml +1 -1
- package/android/build.gradle +1 -1
- package/cobrowse-sdk-react-native.podspec +8 -3
- package/ios/RCTCobrowseIO.xcodeproj/project.pbxproj +6 -0
- package/ios/RCTSurfaceTouchHandler+Touch.h +20 -0
- package/ios/RCTSurfaceTouchHandler+Touch.mm +258 -0
- package/package.json +1 -1
package/android/build.gradle
CHANGED
|
@@ -45,7 +45,7 @@ android {
|
|
|
45
45
|
|
|
46
46
|
dependencies {
|
|
47
47
|
implementation 'com.facebook.react:react-native:+' // support react-native-v0.22-rc+
|
|
48
|
-
implementation 'io.cobrowse:cobrowse-sdk-android:3.13.
|
|
48
|
+
implementation 'io.cobrowse:cobrowse-sdk-android:3.13.2'
|
|
49
49
|
implementation 'androidx.webkit:webkit:1.4.0'
|
|
50
50
|
implementation 'androidx.activity:activity:1.6.0'
|
|
51
51
|
}
|
|
@@ -11,7 +11,12 @@ Pod::Spec.new do |s|
|
|
|
11
11
|
s.homepage = package["homepage"]
|
|
12
12
|
s.source = { :git => 'https://github.com/cobrowseio/cobrowse-sdk-react-native.git' }
|
|
13
13
|
s.platform = :ios, '12.0'
|
|
14
|
-
s.dependency 'CobrowseIO/XCFramework', '3.13.
|
|
15
|
-
s.
|
|
16
|
-
|
|
14
|
+
s.dependency 'CobrowseIO/XCFramework', '3.13.7'
|
|
15
|
+
s.source_files = 'ios/**/*.{h,m,mm}'
|
|
16
|
+
|
|
17
|
+
if defined?(install_modules_dependencies)
|
|
18
|
+
install_modules_dependencies(s)
|
|
19
|
+
else
|
|
20
|
+
s.dependency 'React'
|
|
21
|
+
end
|
|
17
22
|
end
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
A1368C9C237A2C7600728E42 /* CBIOCobrowseRedacted.m in Sources */ = {isa = PBXBuildFile; fileRef = A1368C9B237A2C7600728E42 /* CBIOCobrowseRedacted.m */; };
|
|
12
12
|
A1930DDD226FF9990011DF45 /* RCTTouchHandler+Touch.m in Sources */ = {isa = PBXBuildFile; fileRef = A1930DDC226FF9990011DF45 /* RCTTouchHandler+Touch.m */; };
|
|
13
13
|
A1BD99C6203105EA007F5AE5 /* RCTCobrowseIO.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BD99C5203105E9007F5AE5 /* RCTCobrowseIO.m */; };
|
|
14
|
+
EFCB9C682F31677D003C9EEF /* RCTSurfaceTouchHandler+Touch.mm in Sources */ = {isa = PBXBuildFile; fileRef = EFCB9C672F31677D003C9EEF /* RCTSurfaceTouchHandler+Touch.mm */; };
|
|
14
15
|
/* End PBXBuildFile section */
|
|
15
16
|
|
|
16
17
|
/* Begin PBXCopyFilesBuildPhase section */
|
|
@@ -35,6 +36,8 @@
|
|
|
35
36
|
A1930DDC226FF9990011DF45 /* RCTTouchHandler+Touch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTTouchHandler+Touch.m"; sourceTree = "<group>"; };
|
|
36
37
|
A19B6E3B2030F3FE00F6CF3B /* libRCTCobrowseIO.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTCobrowseIO.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
37
38
|
A1BD99C5203105E9007F5AE5 /* RCTCobrowseIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTCobrowseIO.m; sourceTree = "<group>"; };
|
|
39
|
+
EFCB9C662F31677D003C9EEF /* RCTSurfaceTouchHandler+Touch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTSurfaceTouchHandler+Touch.h"; sourceTree = "<group>"; };
|
|
40
|
+
EFCB9C672F31677D003C9EEF /* RCTSurfaceTouchHandler+Touch.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "RCTSurfaceTouchHandler+Touch.mm"; sourceTree = "<group>"; };
|
|
38
41
|
/* End PBXFileReference section */
|
|
39
42
|
|
|
40
43
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -53,6 +56,8 @@
|
|
|
53
56
|
children = (
|
|
54
57
|
A1368C9E237A2C8E00728E42 /* RCTCobrowseIO.h */,
|
|
55
58
|
A1BD99C5203105E9007F5AE5 /* RCTCobrowseIO.m */,
|
|
59
|
+
EFCB9C662F31677D003C9EEF /* RCTSurfaceTouchHandler+Touch.h */,
|
|
60
|
+
EFCB9C672F31677D003C9EEF /* RCTSurfaceTouchHandler+Touch.mm */,
|
|
56
61
|
A1368C9D237A2C7F00728E42 /* CBIOCobrowseRedacted.h */,
|
|
57
62
|
A1368C9B237A2C7600728E42 /* CBIOCobrowseRedacted.m */,
|
|
58
63
|
A114D583203A2D1900B297FA /* CBIOSession+Bridging.h */,
|
|
@@ -130,6 +135,7 @@
|
|
|
130
135
|
files = (
|
|
131
136
|
A1930DDD226FF9990011DF45 /* RCTTouchHandler+Touch.m in Sources */,
|
|
132
137
|
A1BD99C6203105EA007F5AE5 /* RCTCobrowseIO.m in Sources */,
|
|
138
|
+
EFCB9C682F31677D003C9EEF /* RCTSurfaceTouchHandler+Touch.mm in Sources */,
|
|
133
139
|
A1368C9C237A2C7600728E42 /* CBIOCobrowseRedacted.m in Sources */,
|
|
134
140
|
A114D585203A2D1A00B297FA /* CBIOSession+Bridging.m in Sources */,
|
|
135
141
|
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import "CobrowseSDK/CBIOTouch.h"
|
|
3
|
+
#import "CobrowseSDK/CBIOTouchEvent.h"
|
|
4
|
+
|
|
5
|
+
#if __has_include("RCTSurfaceTouchHandler.h")
|
|
6
|
+
#import "RCTSurfaceTouchHandler.h"
|
|
7
|
+
#elif __has_include(<React/RCTSurfaceTouchHandler.h>)
|
|
8
|
+
#import <React/RCTSurfaceTouchHandler.h>
|
|
9
|
+
#elif __has_include(<React-RCTFabric/RCTSurfaceTouchHandler.h>)
|
|
10
|
+
#import <React-RCTFabric/RCTSurfaceTouchHandler.h>
|
|
11
|
+
#else
|
|
12
|
+
#define CBIO_NO_SURFACE_TOUCH_HANDLER 1
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
#ifndef CBIO_NO_SURFACE_TOUCH_HANDLER
|
|
16
|
+
|
|
17
|
+
@interface RCTSurfaceTouchHandler (Touch)
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
#endif
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
#import <UIKit/UIGestureRecognizerSubclass.h>
|
|
3
|
+
#import <objc/runtime.h>
|
|
4
|
+
#import "RCTSurfaceTouchHandler+Touch.h"
|
|
5
|
+
|
|
6
|
+
// Check for RCTSurfaceTouchHandler availability
|
|
7
|
+
#if __has_include("RCTSurfaceTouchHandler.h")
|
|
8
|
+
#import "RCTSurfaceTouchHandler.h"
|
|
9
|
+
#elif __has_include(<React/RCTSurfaceTouchHandler.h>)
|
|
10
|
+
#import <React/RCTSurfaceTouchHandler.h>
|
|
11
|
+
#elif __has_include(<React-RCTFabric/RCTSurfaceTouchHandler.h>)
|
|
12
|
+
#import <React-RCTFabric/RCTSurfaceTouchHandler.h>
|
|
13
|
+
#else
|
|
14
|
+
#define CBIO_NO_SURFACE_TOUCH_HANDLER 1
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
#ifndef CBIO_NO_SURFACE_TOUCH_HANDLER
|
|
18
|
+
|
|
19
|
+
// Check for Fabric C++ headers
|
|
20
|
+
#if __has_include(<react/renderer/components/view/TouchEventEmitter.h>)
|
|
21
|
+
#import <react/renderer/components/view/TouchEventEmitter.h>
|
|
22
|
+
#elif __has_include(<React-Fabric/react/renderer/components/view/TouchEventEmitter.h>)
|
|
23
|
+
#import <React-Fabric/react/renderer/components/view/TouchEventEmitter.h>
|
|
24
|
+
#elif __has_include("react/renderer/components/view/TouchEventEmitter.h")
|
|
25
|
+
#import "react/renderer/components/view/TouchEventEmitter.h"
|
|
26
|
+
#else
|
|
27
|
+
#define CBIO_NO_FABRIC_HEADERS 1
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
#ifndef CBIO_NO_FABRIC_HEADERS
|
|
31
|
+
#include <exception>
|
|
32
|
+
#endif
|
|
33
|
+
|
|
34
|
+
#pragma mark - Logging
|
|
35
|
+
|
|
36
|
+
static BOOL _supportWarningLogged = NO;
|
|
37
|
+
|
|
38
|
+
static void logSupportWarning(NSString *issue) {
|
|
39
|
+
if (_supportWarningLogged) return;
|
|
40
|
+
_supportWarningLogged = YES;
|
|
41
|
+
|
|
42
|
+
NSLog(@"[Cobrowse WARNING] Fabric touch dispatch failed: %@. "
|
|
43
|
+
@"Please contact support@cobrowse.io with your React Native version.", issue);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#pragma mark - Helper Functions
|
|
47
|
+
|
|
48
|
+
typedef NS_ENUM(NSInteger, CBIOFabricTouchPhase) {
|
|
49
|
+
CBIOFabricTouchPhaseStart,
|
|
50
|
+
CBIOFabricTouchPhaseMove,
|
|
51
|
+
CBIOFabricTouchPhaseEnd,
|
|
52
|
+
CBIOFabricTouchPhaseCancel
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
#ifndef CBIO_NO_FABRIC_HEADERS
|
|
56
|
+
|
|
57
|
+
static SEL getEmitterSelector(void) {
|
|
58
|
+
static SEL sel;
|
|
59
|
+
static dispatch_once_t onceToken;
|
|
60
|
+
dispatch_once(&onceToken, ^{
|
|
61
|
+
sel = NSSelectorFromString(@"touchEventEmitterAtPoint:");
|
|
62
|
+
});
|
|
63
|
+
return sel;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Walk up from the hit-tested view to find the nearest ancestor that
|
|
67
|
+
// responds to touchEventEmitterAtPoint: (the "provider").
|
|
68
|
+
//
|
|
69
|
+
// In Fabric, touchEventEmitterAtPoint: is a simple getter that returns
|
|
70
|
+
// the view's own _eventEmitter, so the provider IS the target — its tag
|
|
71
|
+
// and coordinate space are used directly for the Touch struct.
|
|
72
|
+
//
|
|
73
|
+
// Simultaneously check whether we are inside a Fabric component subtree
|
|
74
|
+
// at all, so we warn if the emitter API has been removed or renamed in
|
|
75
|
+
// a future RN version.
|
|
76
|
+
static UIView * _Nullable findProvider(UIView *startView, BOOL *outSawFabric) {
|
|
77
|
+
SEL sel = getEmitterSelector();
|
|
78
|
+
|
|
79
|
+
static Protocol *componentViewProtocol = NSProtocolFromString(@"RCTComponentViewProtocol");
|
|
80
|
+
|
|
81
|
+
*outSawFabric = NO;
|
|
82
|
+
|
|
83
|
+
for (UIView *v = startView; v; v = v.superview) {
|
|
84
|
+
if (!*outSawFabric && componentViewProtocol && [v conformsToProtocol:componentViewProtocol]) *outSawFabric = YES;
|
|
85
|
+
if ([v respondsToSelector:sel]) {
|
|
86
|
+
return v;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return nil;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Get the touch event emitter from a provider view.
|
|
94
|
+
// In current Fabric, touchEventEmitterAtPoint: ignores the point
|
|
95
|
+
// parameter and simply returns the view's own emitter. We still
|
|
96
|
+
// pass the point for forward-compatibility.
|
|
97
|
+
static facebook::react::SharedTouchEventEmitter getEventEmitter(UIView *provider, CGPoint screenPoint) {
|
|
98
|
+
SEL sel = getEmitterSelector();
|
|
99
|
+
|
|
100
|
+
CGPoint localPoint = [provider convertPoint:screenPoint fromView:nil];
|
|
101
|
+
|
|
102
|
+
@try {
|
|
103
|
+
typedef facebook::react::SharedTouchEventEmitter (*GetEmitterIMP)(id, SEL, CGPoint);
|
|
104
|
+
GetEmitterIMP impl = (GetEmitterIMP)[provider methodForSelector:sel];
|
|
105
|
+
|
|
106
|
+
if (!impl) {
|
|
107
|
+
return nullptr;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return impl(provider, sel, localPoint);
|
|
111
|
+
} @catch (NSException *e) {
|
|
112
|
+
logSupportWarning([NSString stringWithFormat:@"Exception getting emitter: %@", e.reason]);
|
|
113
|
+
return nullptr;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static facebook::react::Touch createTouch(CGPoint screenPoint,
|
|
118
|
+
CGPoint localPoint,
|
|
119
|
+
NSInteger targetTag) {
|
|
120
|
+
facebook::react::Touch touch{};
|
|
121
|
+
|
|
122
|
+
facebook::react::Point screen = {
|
|
123
|
+
static_cast<facebook::react::Float>(screenPoint.x),
|
|
124
|
+
static_cast<facebook::react::Float>(screenPoint.y)
|
|
125
|
+
};
|
|
126
|
+
touch.pagePoint = screen;
|
|
127
|
+
touch.screenPoint = screen;
|
|
128
|
+
touch.offsetPoint = {
|
|
129
|
+
static_cast<facebook::react::Float>(localPoint.x),
|
|
130
|
+
static_cast<facebook::react::Float>(localPoint.y)
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
touch.identifier = 1;
|
|
134
|
+
touch.target = static_cast<facebook::react::Tag>(targetTag);
|
|
135
|
+
|
|
136
|
+
NSTimeInterval nowEpoch = [[NSDate date] timeIntervalSince1970];
|
|
137
|
+
NSTimeInterval nowUptime = [[NSProcessInfo processInfo] systemUptime];
|
|
138
|
+
touch.timestamp = (nowEpoch - nowUptime) + nowUptime;
|
|
139
|
+
|
|
140
|
+
touch.force = 1.0;
|
|
141
|
+
|
|
142
|
+
return touch;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
#endif // !CBIO_NO_FABRIC_HEADERS
|
|
146
|
+
|
|
147
|
+
#pragma mark - Category Implementation
|
|
148
|
+
|
|
149
|
+
@implementation RCTSurfaceTouchHandler (Touch)
|
|
150
|
+
|
|
151
|
+
- (BOOL)cobrowseDispatchEvent:(CBIOFabricTouchPhase)phase
|
|
152
|
+
withTouches:(NSSet<CBIOTouch *> *)touches
|
|
153
|
+
withEvent:(CBIOTouchEvent *)event {
|
|
154
|
+
#ifndef CBIO_NO_FABRIC_HEADERS
|
|
155
|
+
// No multi-touch support yet
|
|
156
|
+
if (touches.count != 1) return NO;
|
|
157
|
+
|
|
158
|
+
CBIOTouch *touch = touches.anyObject;
|
|
159
|
+
UIView *hitView = touch.target;
|
|
160
|
+
CGPoint screenPoint = event.position;
|
|
161
|
+
|
|
162
|
+
BOOL sawFabric = NO;
|
|
163
|
+
UIView *provider = findProvider(hitView, &sawFabric);
|
|
164
|
+
|
|
165
|
+
if (!provider) {
|
|
166
|
+
if (sawFabric) {
|
|
167
|
+
logSupportWarning(@"Fabric component view detected, but no ancestor responds to touchEventEmitterAtPoint");
|
|
168
|
+
}
|
|
169
|
+
return NO;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Get the emitter. ObjC messaging is wrapped in @try/@catch.
|
|
173
|
+
facebook::react::SharedTouchEventEmitter emitter = getEventEmitter(provider, screenPoint);
|
|
174
|
+
if (!emitter) return NO;
|
|
175
|
+
|
|
176
|
+
NSInteger targetTag = provider.tag;
|
|
177
|
+
CGPoint localPoint = [provider convertPoint:screenPoint fromView:nil];
|
|
178
|
+
|
|
179
|
+
facebook::react::Touch t = createTouch(screenPoint, localPoint, targetTag);
|
|
180
|
+
|
|
181
|
+
facebook::react::TouchEvent touchEvent{};
|
|
182
|
+
facebook::react::Touches touchSet;
|
|
183
|
+
touchSet.insert(t);
|
|
184
|
+
facebook::react::Touches emptySet;
|
|
185
|
+
|
|
186
|
+
switch (phase) {
|
|
187
|
+
case CBIOFabricTouchPhaseStart:
|
|
188
|
+
case CBIOFabricTouchPhaseMove:
|
|
189
|
+
touchEvent.touches = touchSet;
|
|
190
|
+
touchEvent.changedTouches = touchSet;
|
|
191
|
+
touchEvent.targetTouches = touchSet;
|
|
192
|
+
break;
|
|
193
|
+
|
|
194
|
+
case CBIOFabricTouchPhaseEnd:
|
|
195
|
+
case CBIOFabricTouchPhaseCancel:
|
|
196
|
+
touchEvent.touches = emptySet;
|
|
197
|
+
touchEvent.changedTouches = touchSet;
|
|
198
|
+
touchEvent.targetTouches = emptySet;
|
|
199
|
+
break;
|
|
200
|
+
|
|
201
|
+
default:
|
|
202
|
+
return NO;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
#if defined(__cpp_exceptions)
|
|
206
|
+
try {
|
|
207
|
+
#endif
|
|
208
|
+
switch (phase) {
|
|
209
|
+
case CBIOFabricTouchPhaseStart: emitter->onTouchStart(touchEvent); break;
|
|
210
|
+
case CBIOFabricTouchPhaseMove: emitter->onTouchMove(touchEvent); break;
|
|
211
|
+
case CBIOFabricTouchPhaseEnd: emitter->onTouchEnd(touchEvent); break;
|
|
212
|
+
case CBIOFabricTouchPhaseCancel: emitter->onTouchCancel(touchEvent); break;
|
|
213
|
+
default: return NO;
|
|
214
|
+
}
|
|
215
|
+
return YES;
|
|
216
|
+
#if defined(__cpp_exceptions)
|
|
217
|
+
} catch (const std::exception &e) {
|
|
218
|
+
logSupportWarning([NSString stringWithFormat:
|
|
219
|
+
@"C++ exception dispatching touch: %s", e.what()]);
|
|
220
|
+
return NO;
|
|
221
|
+
} catch (...) {
|
|
222
|
+
logSupportWarning(@"Unknown C++ exception dispatching touch");
|
|
223
|
+
return NO;
|
|
224
|
+
}
|
|
225
|
+
#endif
|
|
226
|
+
|
|
227
|
+
#else
|
|
228
|
+
return NO;
|
|
229
|
+
#endif
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
- (void)cobrowseTouchesBegan:(NSSet<CBIOTouch *> *)touches withEvent:(CBIOTouchEvent *)event {
|
|
233
|
+
if (![self cobrowseDispatchEvent:CBIOFabricTouchPhaseStart withTouches:touches withEvent:event]) return;
|
|
234
|
+
|
|
235
|
+
if (self.state == UIGestureRecognizerStatePossible) {
|
|
236
|
+
self.state = UIGestureRecognizerStateBegan;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
- (void)cobrowseTouchesMoved:(NSSet<CBIOTouch *> *)touches withEvent:(CBIOTouchEvent *)event {
|
|
241
|
+
if (![self cobrowseDispatchEvent:CBIOFabricTouchPhaseMove withTouches:touches withEvent:event]) return;
|
|
242
|
+
|
|
243
|
+
self.state = UIGestureRecognizerStateChanged;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
- (void)cobrowseTouchesEnded:(NSSet<CBIOTouch *> *)touches withEvent:(CBIOTouchEvent *)event {
|
|
247
|
+
[self cobrowseDispatchEvent:CBIOFabricTouchPhaseEnd withTouches:touches withEvent:event];
|
|
248
|
+
self.state = UIGestureRecognizerStateEnded;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
- (void)cobrowseTouchesCancelled:(NSSet<CBIOTouch *> *)touches withEvent:(CBIOTouchEvent *)event {
|
|
252
|
+
[self cobrowseDispatchEvent:CBIOFabricTouchPhaseCancel withTouches:touches withEvent:event];
|
|
253
|
+
self.state = UIGestureRecognizerStateCancelled;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@end
|
|
257
|
+
|
|
258
|
+
#endif // !CBIO_NO_SURFACE_TOUCH_HANDLER
|