@react-native-firebase/crashlytics 26.3.3 → 27.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/RNFBCrashlytics.podspec +7 -1
  3. package/android/build.gradle +7 -0
  4. package/android/src/main/java/io/invertase/firebase/crashlytics/Constants.kt +42 -0
  5. package/android/src/main/java/io/invertase/firebase/crashlytics/{JavaScriptError.java → JavaScriptError.kt} +4 -6
  6. package/android/src/main/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsNativeHelper.kt +45 -0
  7. package/android/src/main/java/io/invertase/firebase/crashlytics/{UnhandledPromiseRejection.java → UnhandledPromiseRejection.kt} +4 -6
  8. package/android/src/test/java/io/invertase/firebase/crashlytics/ConstantsAndJsErrorTypesTest.java +84 -0
  9. package/android/src/test/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsNativeHelperTest.java +108 -0
  10. package/dist/module/version.js +1 -1
  11. package/dist/typescript/lib/index.d.ts +1 -1
  12. package/dist/typescript/lib/version.d.ts +1 -1
  13. package/ios/RNFBCrashlytics/RNFBCrashlyticsDebuggerProbe.swift +121 -0
  14. package/ios/RNFBCrashlytics/RNFBCrashlyticsHelper.h +58 -0
  15. package/ios/RNFBCrashlytics/RNFBCrashlyticsHelper.m +109 -0
  16. package/ios/RNFBCrashlytics/RNFBCrashlyticsModule.mm +39 -71
  17. package/ios/RNFBCrashlytics.xcodeproj/project.pbxproj +14 -0
  18. package/ios/RNFBCrashlyticsUnitTests/HostStubs/Firebase/FIRCrashlyticsHostStub.m +207 -0
  19. package/ios/RNFBCrashlyticsUnitTests/HostStubs/Firebase/Firebase.h +47 -0
  20. package/ios/RNFBCrashlyticsUnitTests/RNFBCrashlyticsDebuggerProbeTests.swift +112 -0
  21. package/ios/RNFBCrashlyticsUnitTests/RNFBCrashlyticsHelperHostStubTests.m +119 -0
  22. package/ios/RNFBCrashlyticsUnitTests/RNFBCrashlyticsUnitTests.xcodeproj/project.pbxproj +261 -0
  23. package/ios/RNFBCrashlyticsUnitTests/RNFBCrashlyticsUnitTests.xcodeproj/xcshareddata/xcschemes/RNFBCrashlyticsUnitTests.xcscheme +69 -0
  24. package/ios_config.sh +28 -5
  25. package/lib/version.ts +1 -1
  26. package/package.json +5 -4
  27. package/android/src/main/java/io/invertase/firebase/crashlytics/Constants.java +0 -29
  28. package/android/src/main/java/io/invertase/firebase/crashlytics/ReactNativeFirebaseCrashlyticsNativeHelper.java +0 -18
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #if __has_include(<Firebase/Firebase.h>)
19
+ #import <Firebase/Firebase.h>
20
+ #elif __has_include(<FirebaseCrashlytics/FirebaseCrashlytics.h>)
21
+ #import <FirebaseCore/FirebaseCore.h>
22
+ #import <FirebaseCrashlytics/FirebaseCrashlytics.h>
23
+ #else
24
+ @import FirebaseCore;
25
+ @import FirebaseCrashlytics;
26
+ #endif
27
+
28
+ #if __has_include(<RNFBCrashlytics/RNFBCrashlytics-Swift.h>)
29
+ #import <RNFBCrashlytics/RNFBCrashlytics-Swift.h>
30
+ #elif __has_include("RNFBCrashlytics-Swift.h")
31
+ #import "RNFBCrashlytics-Swift.h"
32
+ #elif __has_include("RNFBCrashlyticsDebuggerProbe-Swift.inc")
33
+ #import "RNFBCrashlyticsDebuggerProbe-Swift.inc"
34
+ #else
35
+ #error "RNFBCrashlyticsDebuggerProbe Swift interface not found"
36
+ #endif
37
+
38
+ #import "RNFBCrashlyticsHelper.h"
39
+
40
+ @implementation RNFBCrashlyticsHelper
41
+
42
+ + (BOOL)isDebuggerAttached {
43
+ return [RNFBCrashlyticsDebuggerProbe isDebuggerAttached];
44
+ }
45
+
46
+ + (void)checkForUnsentReportsWithCompletion:(void (^)(BOOL unsentReports))completion {
47
+ [[FIRCrashlytics crashlytics] checkForUnsentReportsWithCompletion:^(BOOL unsentReports) {
48
+ if (completion != nil) {
49
+ completion(unsentReports);
50
+ }
51
+ }];
52
+ }
53
+
54
+ + (void)deleteUnsentReports {
55
+ [[FIRCrashlytics crashlytics] deleteUnsentReports];
56
+ }
57
+
58
+ + (BOOL)didCrashDuringPreviousExecution {
59
+ return [[FIRCrashlytics crashlytics] didCrashDuringPreviousExecution];
60
+ }
61
+
62
+ + (void)log:(NSString *)message {
63
+ [[FIRCrashlytics crashlytics] log:message];
64
+ }
65
+
66
+ + (void)sendUnsentReports {
67
+ [[FIRCrashlytics crashlytics] sendUnsentReports];
68
+ }
69
+
70
+ + (void)setCustomValue:(NSString *)value forKey:(NSString *)key {
71
+ [[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
72
+ }
73
+
74
+ + (void)setCustomKeysAndValues:(NSDictionary *)attributes {
75
+ NSArray *keys = [attributes allKeys];
76
+ for (NSString *key in keys) {
77
+ [[FIRCrashlytics crashlytics] setCustomValue:attributes[key] forKey:key];
78
+ }
79
+ }
80
+
81
+ + (void)setUserID:(NSString *)userId {
82
+ [[FIRCrashlytics crashlytics] setUserID:userId];
83
+ }
84
+
85
+ + (void)recordJavaScriptErrorWithMessage:(NSString *)message
86
+ frames:(NSArray<NSDictionary *> *)frames
87
+ isUnhandledPromiseRejection:(BOOL)isUnhandledPromiseRejection {
88
+ NSMutableArray *stackTrace = [[NSMutableArray alloc] init];
89
+ for (NSDictionary *stackFrame in frames) {
90
+ NSString *symbol = stackFrame[@"fn"];
91
+ NSString *file = stackFrame[@"file"];
92
+ uint32_t line = (uint32_t)[stackFrame[@"line"] unsignedIntValue];
93
+ FIRStackFrame *customFrame = [FIRStackFrame stackFrameWithSymbol:symbol file:file line:line];
94
+ [stackTrace addObject:customFrame];
95
+ }
96
+
97
+ NSString *name = @"JavaScriptError";
98
+ if (isUnhandledPromiseRejection) {
99
+ name = @"UnhandledPromiseRejection";
100
+ }
101
+
102
+ FIRExceptionModel *exceptionModel = [FIRExceptionModel exceptionModelWithName:name
103
+ reason:message];
104
+ exceptionModel.stackTrace = stackTrace;
105
+
106
+ [[FIRCrashlytics crashlytics] recordExceptionModel:exceptionModel];
107
+ }
108
+
109
+ @end
@@ -15,23 +15,17 @@
15
15
  *
16
16
  */
17
17
 
18
- #include <Foundation/Foundation.h>
19
- #include <sys/sysctl.h>
20
-
18
+ // This module intentionally has no Firebase imports and no `*-Swift.h` —
19
+ // see RNFBCrashlyticsHelper.h. Every Firebase Crashlytics SDK call (and the
20
+ // Swift debugger probe) is routed through the plain Objective-C
21
+ // RNFBCrashlyticsHelper class instead, which can safely `@import`
22
+ // FirebaseCrashlytics / import the generated Swift interface because it
23
+ // compiles as ObjC, not ObjC++.
21
24
  #import <React/RCTConvert.h>
22
25
  #import <React/RCTLog.h>
23
- #import <React/RCTUtils.h>
24
-
25
- #if __has_include(<Firebase/Firebase.h>)
26
- #import <Firebase/Firebase.h>
27
- #elif __has_include(<FirebaseCrashlytics/FirebaseCrashlytics.h>)
28
- #import <FirebaseCore/FirebaseCore.h>
29
- #import <FirebaseCrashlytics/FirebaseCrashlytics.h>
30
- #else
31
- @import FirebaseCore;
32
- @import FirebaseCrashlytics;
33
- #endif
26
+
34
27
  #import "RNFBApp/RNFBSharedUtils.h"
28
+ #import "RNFBCrashlyticsHelper.h"
35
29
  #import "RNFBCrashlyticsInitProvider.h"
36
30
  #import "RNFBCrashlyticsModule.h"
37
31
  #import "RNFBPreferences.h"
@@ -58,7 +52,7 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
58
52
  constants[@"isCrashlyticsJavascriptExceptionHandlerChainingEnabled"] =
59
53
  @([RCTConvert BOOL:@([RNFBCrashlyticsInitProvider
60
54
  isCrashlyticsJavascriptExceptionHandlerChainingEnabled])]);
61
- if ([self isDebuggerAttached]) {
55
+ if ([RNFBCrashlyticsHelper isDebuggerAttached]) {
62
56
  RCTLog(
63
57
  @"Crashlytics - WARNING: Debugger detected. Crashlytics will not receive crash reports.");
64
58
  }
@@ -74,14 +68,15 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
74
68
  }
75
69
 
76
70
  - (void)checkForUnsentReports:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
77
- [[FIRCrashlytics crashlytics] checkForUnsentReportsWithCompletion:^(BOOL unsentReports) {
71
+ (void)reject;
72
+ [RNFBCrashlyticsHelper checkForUnsentReportsWithCompletion:^(BOOL unsentReports) {
78
73
  resolve([NSNumber numberWithBool:unsentReports]);
79
74
  }];
80
75
  }
81
76
 
82
77
  - (void)crash {
83
78
  if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
84
- if ([self isDebuggerAttached]) {
79
+ if ([RNFBCrashlyticsHelper isDebuggerAttached]) {
85
80
  RCTLog(
86
81
  @"Crashlytics - WARNING: Debugger detected. Crashlytics will not receive crash reports.");
87
82
  }
@@ -96,8 +91,9 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
96
91
  - (void)crashWithStackPromise:(JS::NativeRNFBTurboCrashlytics::JavaScriptErrorObject &)jsErrorDict
97
92
  resolve:(RCTPromiseResolveBlock)resolve
98
93
  reject:(RCTPromiseRejectBlock)reject {
94
+ (void)reject;
99
95
  if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
100
- if ([self isDebuggerAttached]) {
96
+ if ([RNFBCrashlyticsHelper isDebuggerAttached]) {
101
97
  RCTLog(
102
98
  @"Crashlytics - WARNING: Debugger detected. Crashlytics will not receive crash reports.");
103
99
  }
@@ -112,37 +108,41 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
112
108
  }
113
109
 
114
110
  - (void)deleteUnsentReports:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
115
- [[FIRCrashlytics crashlytics] deleteUnsentReports];
111
+ (void)reject;
112
+ [RNFBCrashlyticsHelper deleteUnsentReports];
116
113
  resolve([NSNull null]);
117
114
  }
118
115
 
119
116
  - (void)didCrashOnPreviousExecution:(RCTPromiseResolveBlock)resolve
120
117
  reject:(RCTPromiseRejectBlock)reject {
121
- BOOL didCrash = [[FIRCrashlytics crashlytics] didCrashDuringPreviousExecution];
118
+ (void)reject;
119
+ BOOL didCrash = [RNFBCrashlyticsHelper didCrashDuringPreviousExecution];
122
120
  resolve([NSNumber numberWithBool:didCrash]);
123
121
  }
124
122
 
125
123
  - (void)log:(NSString *)message {
126
- [[FIRCrashlytics crashlytics] log:message];
124
+ [RNFBCrashlyticsHelper log:message];
127
125
  }
128
126
 
129
127
  - (void)logPromise:(NSString *)message
130
128
  resolve:(RCTPromiseResolveBlock)resolve
131
129
  reject:(RCTPromiseRejectBlock)reject {
132
- [[FIRCrashlytics crashlytics] log:message];
130
+ (void)reject;
131
+ [RNFBCrashlyticsHelper log:message];
133
132
  resolve([NSNull null]);
134
133
  }
135
134
 
136
135
  - (void)sendUnsentReports {
137
- [[FIRCrashlytics crashlytics] sendUnsentReports];
136
+ [RNFBCrashlyticsHelper sendUnsentReports];
138
137
  }
139
138
 
140
139
  - (void)setAttribute:(NSString *)key
141
140
  value:(NSString *)value
142
141
  resolve:(RCTPromiseResolveBlock)resolve
143
142
  reject:(RCTPromiseRejectBlock)reject {
143
+ (void)reject;
144
144
  if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
145
- [[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
145
+ [RNFBCrashlyticsHelper setCustomValue:value forKey:key];
146
146
  }
147
147
  resolve([NSNull null]);
148
148
  }
@@ -150,12 +150,9 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
150
150
  - (void)setAttributes:(NSDictionary *)attributes
151
151
  resolve:(RCTPromiseResolveBlock)resolve
152
152
  reject:(RCTPromiseRejectBlock)reject {
153
+ (void)reject;
153
154
  if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
154
- NSArray *keys = [attributes allKeys];
155
-
156
- for (NSString *key in keys) {
157
- [[FIRCrashlytics crashlytics] setCustomValue:attributes[key] forKey:key];
158
- }
155
+ [RNFBCrashlyticsHelper setCustomKeysAndValues:attributes];
159
156
  }
160
157
  resolve([NSNull null]);
161
158
  }
@@ -163,8 +160,9 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
163
160
  - (void)setUserId:(NSString *)userId
164
161
  resolve:(RCTPromiseResolveBlock)resolve
165
162
  reject:(RCTPromiseRejectBlock)reject {
163
+ (void)reject;
166
164
  if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
167
- [[FIRCrashlytics crashlytics] setUserID:userId];
165
+ [RNFBCrashlyticsHelper setUserID:userId];
168
166
  }
169
167
  resolve([NSNull null]);
170
168
  }
@@ -178,6 +176,7 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
178
176
  - (void)recordErrorPromise:(JS::NativeRNFBTurboCrashlytics::JavaScriptErrorObject &)jsErrorDict
179
177
  resolve:(RCTPromiseResolveBlock)resolve
180
178
  reject:(RCTPromiseRejectBlock)reject {
179
+ (void)reject;
181
180
  if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
182
181
  [self recordJavaScriptError:jsErrorDict];
183
182
  }
@@ -187,6 +186,7 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
187
186
  - (void)setCrashlyticsCollectionEnabled:(BOOL)enabled
188
187
  resolve:(RCTPromiseResolveBlock)resolve
189
188
  reject:(RCTPromiseRejectBlock)reject {
189
+ (void)reject;
190
190
  [[RNFBPreferences shared] setBooleanValue:@"crashlytics_auto_collection_enabled"
191
191
  boolValue:enabled];
192
192
  resolve([NSNull null]);
@@ -195,52 +195,20 @@ RCT_EXPORT_MODULE(NativeRNFBTurboCrashlytics)
195
195
  - (void)recordJavaScriptError:(JS::NativeRNFBTurboCrashlytics::JavaScriptErrorObject &)jsErrorDict {
196
196
  NSString *message = jsErrorDict.message();
197
197
  auto stackFrames = jsErrorDict.frames();
198
- NSMutableArray *stackTrace = [[NSMutableArray alloc] init];
198
+ NSMutableArray *frames = [[NSMutableArray alloc] init];
199
199
  BOOL isUnhandledPromiseRejection = jsErrorDict.isUnhandledRejection();
200
200
 
201
201
  for (const auto &stackFrame : stackFrames) {
202
- FIRStackFrame *customFrame = [FIRStackFrame stackFrameWithSymbol:stackFrame.fn()
203
- file:stackFrame.file()
204
- line:(uint32_t)stackFrame.line()];
205
- [stackTrace addObject:customFrame];
202
+ [frames addObject:@{
203
+ @"fn" : stackFrame.fn() ?: @"",
204
+ @"file" : stackFrame.file() ?: @"",
205
+ @"line" : @((NSUInteger)stackFrame.line()),
206
+ }];
206
207
  }
207
208
 
208
- NSString *name = @"JavaScriptError";
209
- if (isUnhandledPromiseRejection) {
210
- name = @"UnhandledPromiseRejection";
211
- }
212
-
213
- FIRExceptionModel *exceptionModel = [FIRExceptionModel exceptionModelWithName:name
214
- reason:message];
215
- exceptionModel.stackTrace = stackTrace;
216
-
217
- [[FIRCrashlytics crashlytics] recordExceptionModel:exceptionModel];
218
- }
219
-
220
- - (BOOL)isDebuggerAttached {
221
- static BOOL debuggerIsAttached = NO;
222
-
223
- static dispatch_once_t debuggerPredicate;
224
- dispatch_once(&debuggerPredicate, ^{
225
- struct kinfo_proc info;
226
- size_t info_size = sizeof(info);
227
- int name[4];
228
-
229
- name[0] = CTL_KERN;
230
- name[1] = KERN_PROC;
231
- name[2] = KERN_PROC_PID;
232
- name[3] = getpid();
233
-
234
- if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
235
- ELog(@"Crashlytics ERROR: Checking for a running debugger via sysctl() failed: %s",
236
- strerror(errno));
237
- debuggerIsAttached = false;
238
- }
239
-
240
- if (!debuggerIsAttached && (info.kp_proc.p_flag & P_TRACED) != 0) debuggerIsAttached = true;
241
- });
242
-
243
- return debuggerIsAttached;
209
+ [RNFBCrashlyticsHelper recordJavaScriptErrorWithMessage:message
210
+ frames:frames
211
+ isUnhandledPromiseRejection:isUnhandledPromiseRejection];
244
212
  }
245
213
 
246
214
  @end
@@ -10,6 +10,8 @@
10
10
  2744B98621F45429004F8E3F /* RNFBCrashlyticsModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744B98521F45429004F8E3F /* RNFBCrashlyticsModule.mm */; };
11
11
  2748D82422371C1C00FC8DC8 /* RNFBCrashlyticsInitProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 2748D82322371C1C00FC8DC8 /* RNFBCrashlyticsInitProvider.m */; };
12
12
  C66637BB25FA560700DCAA51 /* RNFBCrashlyticsNativeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = C66637BA25FA560700DCAA51 /* RNFBCrashlyticsNativeHelper.m */; };
13
+ RNFBCL000000000000000001 /* RNFBCrashlyticsDebuggerProbe.swift in Sources */ = {isa = PBXBuildFile; fileRef = RNFBCL000000000000000002 /* RNFBCrashlyticsDebuggerProbe.swift */; };
14
+ RNFBCL000000000000000003 /* RNFBCrashlyticsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = RNFBCL000000000000000005 /* RNFBCrashlyticsHelper.m */; };
13
15
  /* End PBXBuildFile section */
14
16
 
15
17
  /* Begin PBXCopyFilesBuildPhase section */
@@ -32,6 +34,9 @@
32
34
  2748D82322371C1C00FC8DC8 /* RNFBCrashlyticsInitProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFBCrashlyticsInitProvider.m; sourceTree = "<group>"; };
33
35
  C66637BA25FA560700DCAA51 /* RNFBCrashlyticsNativeHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFBCrashlyticsNativeHelper.m; sourceTree = "<group>"; };
34
36
  C66637BD25FA561D00DCAA51 /* RNFBCrashlyticsNativeHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNFBCrashlyticsNativeHelper.h; sourceTree = "<group>"; };
37
+ RNFBCL000000000000000002 /* RNFBCrashlyticsDebuggerProbe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBCrashlyticsDebuggerProbe.swift; path = RNFBCrashlytics/RNFBCrashlyticsDebuggerProbe.swift; sourceTree = SOURCE_ROOT; };
38
+ RNFBCL000000000000000004 /* RNFBCrashlyticsHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBCrashlyticsHelper.h; path = RNFBCrashlytics/RNFBCrashlyticsHelper.h; sourceTree = SOURCE_ROOT; };
39
+ RNFBCL000000000000000005 /* RNFBCrashlyticsHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBCrashlyticsHelper.m; path = RNFBCrashlytics/RNFBCrashlyticsHelper.m; sourceTree = SOURCE_ROOT; };
35
40
  /* End PBXFileReference section */
36
41
 
37
42
  /* Begin PBXFrameworksBuildPhase section */
@@ -58,6 +63,9 @@
58
63
  children = (
59
64
  2744B98421F45429004F8E3F /* RNFBCrashlyticsModule.h */,
60
65
  2744B98521F45429004F8E3F /* RNFBCrashlyticsModule.mm */,
66
+ RNFBCL000000000000000004 /* RNFBCrashlyticsHelper.h */,
67
+ RNFBCL000000000000000005 /* RNFBCrashlyticsHelper.m */,
68
+ RNFBCL000000000000000002 /* RNFBCrashlyticsDebuggerProbe.swift */,
61
69
  2748D82222371C0900FC8DC8 /* RNFBCrashlyticsInitProvider.h */,
62
70
  2748D82322371C1C00FC8DC8 /* RNFBCrashlyticsInitProvider.m */,
63
71
  C66637BD25FA561D00DCAA51 /* RNFBCrashlyticsNativeHelper.h */,
@@ -133,8 +141,10 @@
133
141
  buildActionMask = 2147483647;
134
142
  files = (
135
143
  C66637BB25FA560700DCAA51 /* RNFBCrashlyticsNativeHelper.m in Sources */,
144
+ RNFBCL000000000000000003 /* RNFBCrashlyticsHelper.m in Sources */,
136
145
  2748D82422371C1C00FC8DC8 /* RNFBCrashlyticsInitProvider.m in Sources */,
137
146
  2744B98621F45429004F8E3F /* RNFBCrashlyticsModule.mm in Sources */,
147
+ RNFBCL000000000000000001 /* RNFBCrashlyticsDebuggerProbe.swift in Sources */,
138
148
  );
139
149
  runOnlyForDeploymentPostprocessing = 0;
140
150
  };
@@ -160,6 +170,7 @@
160
170
  CODE_SIGN_STYLE = Automatic;
161
171
  COPY_PHASE_STRIP = NO;
162
172
  DEBUG_INFORMATION_FORMAT = dwarf;
173
+ DEFINES_MODULE = YES;
163
174
  GCC_C_LANGUAGE_STANDARD = gnu11;
164
175
  GCC_DYNAMIC_NO_PIC = NO;
165
176
  GCC_OPTIMIZATION_LEVEL = 0;
@@ -176,6 +187,7 @@
176
187
  PRODUCT_NAME = "$(TARGET_NAME)";
177
188
  SDKROOT = iphoneos;
178
189
  SKIP_INSTALL = YES;
190
+ SWIFT_VERSION = 5.10;
179
191
  TARGETED_DEVICE_FAMILY = "1,2";
180
192
  };
181
193
  name = Debug;
@@ -199,6 +211,7 @@
199
211
  CODE_SIGN_STYLE = Automatic;
200
212
  COPY_PHASE_STRIP = NO;
201
213
  DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
214
+ DEFINES_MODULE = YES;
202
215
  ENABLE_NS_ASSERTIONS = NO;
203
216
  GCC_C_LANGUAGE_STANDARD = gnu11;
204
217
  GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
@@ -210,6 +223,7 @@
210
223
  PRODUCT_NAME = "$(TARGET_NAME)";
211
224
  SDKROOT = iphoneos;
212
225
  SKIP_INSTALL = YES;
226
+ SWIFT_VERSION = 5.10;
213
227
  TARGETED_DEVICE_FAMILY = "1,2";
214
228
  VALIDATE_PRODUCT = YES;
215
229
  };
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ */
4
+ #import <Firebase/Firebase.h>
5
+
6
+ @implementation FIRStackFrame {
7
+ NSString *_symbol;
8
+ NSString *_file;
9
+ uint32_t _line;
10
+ }
11
+
12
+ + (instancetype)stackFrameWithSymbol:(NSString *)symbol file:(NSString *)file line:(uint32_t)line {
13
+ FIRStackFrame *frame = [[FIRStackFrame alloc] init];
14
+ frame->_symbol = [symbol copy];
15
+ frame->_file = [file copy];
16
+ frame->_line = line;
17
+ return frame;
18
+ }
19
+
20
+ - (NSString *)symbol {
21
+ return _symbol;
22
+ }
23
+
24
+ - (NSString *)file {
25
+ return _file;
26
+ }
27
+
28
+ - (uint32_t)line {
29
+ return _line;
30
+ }
31
+
32
+ @end
33
+
34
+ @implementation FIRExceptionModel {
35
+ NSString *_name;
36
+ NSString *_reason;
37
+ }
38
+
39
+ + (instancetype)exceptionModelWithName:(NSString *)name reason:(NSString *)reason {
40
+ FIRExceptionModel *model = [[FIRExceptionModel alloc] init];
41
+ model->_name = [name copy];
42
+ model->_reason = [reason copy];
43
+ return model;
44
+ }
45
+
46
+ - (NSString *)name {
47
+ return _name;
48
+ }
49
+
50
+ - (NSString *)reason {
51
+ return _reason;
52
+ }
53
+
54
+ @end
55
+
56
+ @implementation FIRCrashlytics
57
+
58
+ static BOOL sDidCrashDuringPreviousExecutionValue;
59
+ static BOOL sCheckForUnsentReportsValue;
60
+ static NSMutableArray<NSString *> *sLoggedMessages;
61
+ static NSMutableDictionary *sCustomValues;
62
+ static NSString *sUserIDValue;
63
+ static NSUInteger sDeleteUnsentReportsCallCount;
64
+ static NSUInteger sSendUnsentReportsCallCount;
65
+ static FIRExceptionModel *sLastRecordedExceptionModel;
66
+
67
+ + (void)initialize {
68
+ if (self == [FIRCrashlytics class]) {
69
+ sLoggedMessages = [NSMutableArray new];
70
+ sCustomValues = [NSMutableDictionary new];
71
+ }
72
+ }
73
+
74
+ + (instancetype)crashlytics {
75
+ static FIRCrashlytics *shared;
76
+ static dispatch_once_t once;
77
+ dispatch_once(&once, ^{
78
+ shared = [[FIRCrashlytics alloc] init];
79
+ });
80
+ return shared;
81
+ }
82
+
83
+ + (BOOL)didCrashDuringPreviousExecutionValue {
84
+ return sDidCrashDuringPreviousExecutionValue;
85
+ }
86
+
87
+ + (void)setDidCrashDuringPreviousExecutionValue:(BOOL)didCrashDuringPreviousExecutionValue {
88
+ sDidCrashDuringPreviousExecutionValue = didCrashDuringPreviousExecutionValue;
89
+ }
90
+
91
+ + (BOOL)checkForUnsentReportsValue {
92
+ return sCheckForUnsentReportsValue;
93
+ }
94
+
95
+ + (void)setCheckForUnsentReportsValue:(BOOL)checkForUnsentReportsValue {
96
+ sCheckForUnsentReportsValue = checkForUnsentReportsValue;
97
+ }
98
+
99
+ + (NSArray<NSString *> *)loggedMessages {
100
+ return [sLoggedMessages copy];
101
+ }
102
+
103
+ + (void)setLoggedMessages:(NSArray<NSString *> *)loggedMessages {
104
+ [sLoggedMessages removeAllObjects];
105
+ if (loggedMessages != nil) {
106
+ [sLoggedMessages addObjectsFromArray:loggedMessages];
107
+ }
108
+ }
109
+
110
+ + (NSDictionary *)customValues {
111
+ return [sCustomValues copy];
112
+ }
113
+
114
+ + (void)setCustomValues:(NSDictionary *)customValues {
115
+ [sCustomValues removeAllObjects];
116
+ if (customValues != nil) {
117
+ [sCustomValues addEntriesFromDictionary:customValues];
118
+ }
119
+ }
120
+
121
+ + (NSString *)userIDValue {
122
+ return sUserIDValue;
123
+ }
124
+
125
+ + (void)setUserIDValue:(NSString *)userIDValue {
126
+ sUserIDValue = [userIDValue copy];
127
+ }
128
+
129
+ + (NSUInteger)deleteUnsentReportsCallCount {
130
+ return sDeleteUnsentReportsCallCount;
131
+ }
132
+
133
+ + (void)setDeleteUnsentReportsCallCount:(NSUInteger)deleteUnsentReportsCallCount {
134
+ sDeleteUnsentReportsCallCount = deleteUnsentReportsCallCount;
135
+ }
136
+
137
+ + (NSUInteger)sendUnsentReportsCallCount {
138
+ return sSendUnsentReportsCallCount;
139
+ }
140
+
141
+ + (void)setSendUnsentReportsCallCount:(NSUInteger)sendUnsentReportsCallCount {
142
+ sSendUnsentReportsCallCount = sendUnsentReportsCallCount;
143
+ }
144
+
145
+ + (FIRExceptionModel *)lastRecordedExceptionModel {
146
+ return sLastRecordedExceptionModel;
147
+ }
148
+
149
+ + (void)setLastRecordedExceptionModel:(FIRExceptionModel *)lastRecordedExceptionModel {
150
+ sLastRecordedExceptionModel = lastRecordedExceptionModel;
151
+ }
152
+
153
+ + (void)resetTestState {
154
+ sDidCrashDuringPreviousExecutionValue = NO;
155
+ sCheckForUnsentReportsValue = NO;
156
+ [sLoggedMessages removeAllObjects];
157
+ [sCustomValues removeAllObjects];
158
+ sUserIDValue = nil;
159
+ sDeleteUnsentReportsCallCount = 0;
160
+ sSendUnsentReportsCallCount = 0;
161
+ sLastRecordedExceptionModel = nil;
162
+ }
163
+
164
+ - (void)checkForUnsentReportsWithCompletion:(void (^)(BOOL unsentReports))completion {
165
+ if (completion != nil) {
166
+ completion(sCheckForUnsentReportsValue);
167
+ }
168
+ }
169
+
170
+ - (void)deleteUnsentReports {
171
+ sDeleteUnsentReportsCallCount += 1;
172
+ }
173
+
174
+ - (BOOL)didCrashDuringPreviousExecution {
175
+ return sDidCrashDuringPreviousExecutionValue;
176
+ }
177
+
178
+ - (void)log:(NSString *)message {
179
+ if (message != nil) {
180
+ [sLoggedMessages addObject:message];
181
+ }
182
+ }
183
+
184
+ - (void)sendUnsentReports {
185
+ sSendUnsentReportsCallCount += 1;
186
+ }
187
+
188
+ - (void)setCustomValue:(id)value forKey:(NSString *)key {
189
+ if (key == nil) {
190
+ return;
191
+ }
192
+ if (value == nil) {
193
+ [sCustomValues removeObjectForKey:key];
194
+ } else {
195
+ sCustomValues[key] = value;
196
+ }
197
+ }
198
+
199
+ - (void)setUserID:(NSString *)userID {
200
+ sUserIDValue = [userID copy];
201
+ }
202
+
203
+ - (void)recordExceptionModel:(FIRExceptionModel *)exceptionModel {
204
+ sLastRecordedExceptionModel = exceptionModel;
205
+ }
206
+
207
+ @end
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ * Enough of Firebase Crashlytics for compiling RNFBCrashlyticsHelper.m
4
+ * and asserting SDK call wiring without linking the real SDK.
5
+ */
6
+ #import <Foundation/Foundation.h>
7
+
8
+ @interface FIRStackFrame : NSObject
9
+ @property(nonatomic, readonly, copy) NSString *symbol;
10
+ @property(nonatomic, readonly, copy) NSString *file;
11
+ @property(nonatomic, readonly, assign) uint32_t line;
12
+ + (instancetype)stackFrameWithSymbol:(NSString *)symbol file:(NSString *)file line:(uint32_t)line;
13
+ @end
14
+
15
+ @interface FIRExceptionModel : NSObject
16
+ @property(nonatomic, readonly, copy) NSString *name;
17
+ @property(nonatomic, readonly, copy) NSString *reason;
18
+ @property(nonatomic, copy, nullable) NSArray<FIRStackFrame *> *stackTrace;
19
+ + (instancetype)exceptionModelWithName:(NSString *)name reason:(NSString *)reason;
20
+ @end
21
+
22
+ @interface FIRCrashlytics : NSObject
23
+
24
+ + (instancetype)crashlytics;
25
+
26
+ - (void)checkForUnsentReportsWithCompletion:(void (^)(BOOL unsentReports))completion;
27
+ - (void)deleteUnsentReports;
28
+ - (BOOL)didCrashDuringPreviousExecution;
29
+ - (void)log:(NSString *)message;
30
+ - (void)sendUnsentReports;
31
+ - (void)setCustomValue:(nullable id)value forKey:(NSString *)key;
32
+ - (void)setUserID:(NSString *)userID;
33
+ - (void)recordExceptionModel:(FIRExceptionModel *)exceptionModel;
34
+
35
+ /** Test seams */
36
+ @property(class, nonatomic, assign) BOOL didCrashDuringPreviousExecutionValue;
37
+ @property(class, nonatomic, assign) BOOL checkForUnsentReportsValue;
38
+ @property(class, nonatomic, copy, nullable) NSArray<NSString *> *loggedMessages;
39
+ @property(class, nonatomic, copy, nullable) NSDictionary *customValues;
40
+ @property(class, nonatomic, copy, nullable) NSString *userIDValue;
41
+ @property(class, nonatomic, assign) NSUInteger deleteUnsentReportsCallCount;
42
+ @property(class, nonatomic, assign) NSUInteger sendUnsentReportsCallCount;
43
+ @property(class, nonatomic, copy, nullable) FIRExceptionModel *lastRecordedExceptionModel;
44
+
45
+ + (void)resetTestState;
46
+
47
+ @end