FIRCLSAnalyticsManager.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright 2021 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import "Crashlytics/Crashlytics/Controllers/FIRCLSAnalyticsManager.h"
  15. #import "Crashlytics/Crashlytics/Components/FIRCLSUserLogging.h"
  16. #import "Crashlytics/Crashlytics/Helpers/FIRCLSInternalLogging.h"
  17. #import "Interop/Analytics/Public/FIRAnalyticsInterop.h"
  18. #import "Interop/Analytics/Public/FIRAnalyticsInteropListener.h"
  19. static NSString *FIRCLSFirebaseAnalyticsEventLogFormat = @"$A$:%@";
  20. // Origin for events and user properties generated by Crashlytics.
  21. static NSString *const kFIREventOriginCrash = @"clx";
  22. // App exception event name.
  23. static NSString *const kFIREventAppException = @"_ae";
  24. // Timestamp key for the event payload.
  25. static NSString *const kFIRParameterTimestamp = @"timestamp";
  26. // Fatal key for the event payload.
  27. static NSString *const kFIRParameterFatal = @"fatal";
  28. FOUNDATION_STATIC_INLINE NSNumber *timeIntervalInMillis(NSTimeInterval timeInterval) {
  29. return @(llrint(timeInterval * 1000.0));
  30. }
  31. @interface FIRCLSAnalyticsManager () <FIRAnalyticsInteropListener>
  32. @property(nonatomic, strong) id<FIRAnalyticsInterop> analytics;
  33. @property(nonatomic, assign) BOOL registeredAnalyticsEventListener;
  34. @end
  35. @implementation FIRCLSAnalyticsManager
  36. - (instancetype)initWithAnalytics:(nullable id<FIRAnalyticsInterop>)analytics {
  37. self = [super init];
  38. if (!self) {
  39. return nil;
  40. }
  41. _analytics = analytics;
  42. return self;
  43. }
  44. - (void)registerAnalyticsListener {
  45. if (self.registeredAnalyticsEventListener) {
  46. return;
  47. }
  48. if (self.analytics == nil) {
  49. FIRCLSDeveloperLog(@"Crashlytics:Crash:Reports:Event",
  50. "Firebase Analytics SDK not detected. Crash-free statistics and "
  51. "breadcrumbs will not be reported");
  52. return;
  53. }
  54. [self.analytics registerAnalyticsListener:self withOrigin:kFIREventOriginCrash];
  55. FIRCLSDeveloperLog(@"Crashlytics:Crash:Reports:Event",
  56. "Registered Firebase Analytics event listener to receive breadcrumb logs");
  57. self.registeredAnalyticsEventListener = YES;
  58. }
  59. - (void)messageTriggered:(NSString *)name parameters:(NSDictionary *)parameters {
  60. NSDictionary *event = @{
  61. @"name" : name,
  62. @"parameters" : parameters,
  63. };
  64. NSString *json = FIRCLSFIRAEventDictionaryToJSON(event);
  65. if (json != nil) {
  66. FIRCLSLog(FIRCLSFirebaseAnalyticsEventLogFormat, json);
  67. }
  68. }
  69. + (void)logCrashWithTimeStamp:(NSTimeInterval)crashTimeStamp
  70. toAnalytics:(id<FIRAnalyticsInterop>)analytics {
  71. if (analytics == nil) {
  72. return;
  73. }
  74. FIRCLSDeveloperLog(@"Crashlytics:Crash:Reports:Event",
  75. "Sending app_exception event to Firebase Analytics for crash-free statistics");
  76. NSDictionary *params = @{
  77. kFIRParameterTimestamp : timeIntervalInMillis(crashTimeStamp),
  78. kFIRParameterFatal : @(INT64_C(1))
  79. };
  80. [analytics logEventWithOrigin:kFIREventOriginCrash name:kFIREventAppException parameters:params];
  81. }
  82. NSString *FIRCLSFIRAEventDictionaryToJSON(NSDictionary *eventAsDictionary) {
  83. NSError *error = nil;
  84. if (eventAsDictionary == nil) {
  85. return nil;
  86. }
  87. if (![NSJSONSerialization isValidJSONObject:eventAsDictionary]) {
  88. FIRCLSSDKLog("Firebase Analytics event is not valid JSON");
  89. return nil;
  90. }
  91. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:eventAsDictionary
  92. options:0
  93. error:&error];
  94. if (error == nil) {
  95. NSString *json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  96. return json;
  97. } else {
  98. FIRCLSSDKLog("Unable to convert Firebase Analytics event to json");
  99. return nil;
  100. }
  101. }
  102. @end