diff --git a/BitBotATVTests/BitBot.xctestplan b/BitBotATVTests/BitBot.xctestplan index 0041066d..51f7a4ee 100644 --- a/BitBotATVTests/BitBot.xctestplan +++ b/BitBotATVTests/BitBot.xctestplan @@ -17,7 +17,6 @@ }, "testTargets" : [ { - "parallelizable" : true, "target" : { "containerPath" : "container:Bitrise.xcodeproj", "identifier" : "0E42CAEA20EC7A800033CD03", diff --git a/BitBotATVTests/BitBotATVTests.swift b/BitBotATVTests/BitBotATVTests.swift index 999c30ad..b2109f35 100644 --- a/BitBotATVTests/BitBotATVTests.swift +++ b/BitBotATVTests/BitBotATVTests.swift @@ -10,24 +10,4 @@ import XCTest class BitBotATVTests: XCTestCase { - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testExample() throws { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - - func testPerformanceExample() throws { - // This is an example of a performance test case. - measure { - // Put the code you want to measure the time of here. - } - } - } diff --git a/Bitrise.xcodeproj/project.pbxproj b/Bitrise.xcodeproj/project.pbxproj index 26712076..a5821bde 100644 --- a/Bitrise.xcodeproj/project.pbxproj +++ b/Bitrise.xcodeproj/project.pbxproj @@ -102,7 +102,7 @@ 0ED38CDC220DE9000006FE69 /* ASLogLoadingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38CDB220DE9000006FE69 /* ASLogLoadingOperation.m */; }; 0ED38CDD220DE9000006FE69 /* ASLogLoadingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38CDB220DE9000006FE69 /* ASLogLoadingOperation.m */; }; 0EDC5DE321BBBB0A00AD41FE /* ASQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EDC5DDF21BBBB0A00AD41FE /* ASQueue.m */; }; - 0EDC5DE421BBBB0A00AD41FE /* ASOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EDC5DE221BBBB0A00AD41FE /* ASOperation.m */; }; + 0EDC5DE421BBBB0A00AD41FE /* BROperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EDC5DE221BBBB0A00AD41FE /* BROperation.m */; }; 0EDC5DE721BBFB0A00AD41FE /* BRSyncOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EDC5DE621BBFB0A00AD41FE /* BRSyncOperation.m */; }; 0EDE7D0821B9346200A39CC4 /* BRSyncEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EDE7D0721B9346200A39CC4 /* BRSyncEngine.m */; }; 0EDE7D0921B9346200A39CC4 /* BRSyncEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EDE7D0721B9346200A39CC4 /* BRSyncEngine.m */; }; @@ -119,7 +119,7 @@ 0EFD891520F1FDE10023FCCE /* BRBuild+Mapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFD891420F1FDE10023FCCE /* BRBuild+Mapping.m */; }; 0EFD891820F201400023FCCE /* BRAppInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFD891720F201400023FCCE /* BRAppInfo.m */; }; 0EFD893D20F4893B0023FCCE /* BRApp+Mapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFD893C20F4893B0023FCCE /* BRApp+Mapping.m */; }; - 8605E0C237B585EB9BC0356C /* libPods-BitriseATV.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E2C5865B43E250E9D3620EC /* libPods-BitriseATV.a */; }; + B6085FB37966F37D39919AAA /* libPods-BitBotATV.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A1C47D1452DDE09A85608B0F /* libPods-BitBotATV.a */; }; D90BFBA025372FF800DA473E /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D90BFB9F25372FF800DA473E /* CloudKit.framework */; }; D90BFBA62537388000DA473E /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D90BFBA52537388000DA473E /* CloudKit.framework */; }; D91BD9C625A1BE7000EF8D66 /* BitBotATVTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91BD9C525A1BE7000EF8D66 /* BitBotATVTests.swift */; }; @@ -177,7 +177,7 @@ DE3CD07D25246A0400DD5948 /* BRBuildsRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EB3ED7221E7BC92003F0364 /* BRBuildsRequest.m */; }; DE3CD08125246A0A00DD5948 /* BRAppsRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EB3ED7521E88E8C003F0364 /* BRAppsRequest.m */; }; DE3CD08525246A1100DD5948 /* BRCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3C0B122117627700F2EA35 /* BRCommand.m */; }; - DE3CD08925246A2E00DD5948 /* ASOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EDC5DE221BBBB0A00AD41FE /* ASOperation.m */; }; + DE3CD08925246A2E00DD5948 /* BROperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EDC5DE221BBBB0A00AD41FE /* BROperation.m */; }; DE3CD08F25246A7500DD5948 /* AccountCommandsDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3CD08E25246A7500DD5948 /* AccountCommandsDispatcher.swift */; }; DE3CD09625246F5400DD5948 /* BRStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E93B6F620F0837B001A6C15 /* BRStorage.m */; }; DE3CD09A25246F5A00DD5948 /* BRBitriseAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E8E9B5420F0819E00494DEB /* BRBitriseAPI.m */; }; @@ -462,9 +462,9 @@ 0ED38CDA220DE9000006FE69 /* ASLogLoadingOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASLogLoadingOperation.h; sourceTree = ""; }; 0ED38CDB220DE9000006FE69 /* ASLogLoadingOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASLogLoadingOperation.m; sourceTree = ""; }; 0EDC5DDF21BBBB0A00AD41FE /* ASQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASQueue.m; sourceTree = ""; }; - 0EDC5DE021BBBB0A00AD41FE /* ASOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASOperation.h; sourceTree = ""; }; + 0EDC5DE021BBBB0A00AD41FE /* BROperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BROperation.h; sourceTree = ""; }; 0EDC5DE121BBBB0A00AD41FE /* ASQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASQueue.h; sourceTree = ""; }; - 0EDC5DE221BBBB0A00AD41FE /* ASOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASOperation.m; sourceTree = ""; }; + 0EDC5DE221BBBB0A00AD41FE /* BROperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BROperation.m; sourceTree = ""; }; 0EDC5DE521BBFB0A00AD41FE /* BRSyncOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BRSyncOperation.h; sourceTree = ""; }; 0EDC5DE621BBFB0A00AD41FE /* BRSyncOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BRSyncOperation.m; sourceTree = ""; }; 0EDE7D0621B9346200A39CC4 /* BRSyncEngine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BRSyncEngine.h; sourceTree = ""; }; @@ -496,9 +496,11 @@ 4592E252F47089546A803FDB /* libPods-BitBot.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-BitBot.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 6206DED9400023C6320DD7AB /* libPods-BitBotTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-BitBotTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 64F51DE74237213D947FD5AF /* Pods-BitBotTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BitBotTests.release.xcconfig"; path = "Target Support Files/Pods-BitBotTests/Pods-BitBotTests.release.xcconfig"; sourceTree = ""; }; - 7E2C5865B43E250E9D3620EC /* libPods-BitriseATV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-BitriseATV.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 8737EB33A867885C0D9BD854 /* Pods-BitriseATV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BitriseATV.release.xcconfig"; path = "Target Support Files/Pods-BitriseATV/Pods-BitriseATV.release.xcconfig"; sourceTree = ""; }; A0D4B65651B1B5745349F720 /* Pods-BitriseATV.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BitriseATV.debug.xcconfig"; path = "Target Support Files/Pods-BitriseATV/Pods-BitriseATV.debug.xcconfig"; sourceTree = ""; }; + A1C47D1452DDE09A85608B0F /* libPods-BitBotATV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-BitBotATV.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + C032C508CB7EA3215E3C4EEA /* Pods-BitBotATV.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BitBotATV.debug.xcconfig"; path = "Target Support Files/Pods-BitBotATV/Pods-BitBotATV.debug.xcconfig"; sourceTree = ""; }; + D84A7482A583FF266B3A58C9 /* Pods-BitBotATV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BitBotATV.release.xcconfig"; path = "Target Support Files/Pods-BitBotATV/Pods-BitBotATV.release.xcconfig"; sourceTree = ""; }; D90BFB9F25372FF800DA473E /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; }; D90BFBA42537387D00DA473E /* BitBotATVRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = BitBotATVRelease.entitlements; sourceTree = ""; }; D90BFBA52537388000DA473E /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; }; @@ -652,8 +654,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8605E0C237B585EB9BC0356C /* libPods-BitriseATV.a in Frameworks */, D90BFBA62537388000DA473E /* CloudKit.framework in Frameworks */, + B6085FB37966F37D39919AAA /* libPods-BitBotATV.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -667,7 +669,7 @@ D90BFB9F25372FF800DA473E /* CloudKit.framework */, 4592E252F47089546A803FDB /* libPods-BitBot.a */, 6206DED9400023C6320DD7AB /* libPods-BitBotTests.a */, - 7E2C5865B43E250E9D3620EC /* libPods-BitriseATV.a */, + A1C47D1452DDE09A85608B0F /* libPods-BitBotATV.a */, ); name = Frameworks; sourceTree = ""; @@ -1078,8 +1080,8 @@ children = ( 0EDC5DE121BBBB0A00AD41FE /* ASQueue.h */, 0EDC5DDF21BBBB0A00AD41FE /* ASQueue.m */, - 0EDC5DE021BBBB0A00AD41FE /* ASOperation.h */, - 0EDC5DE221BBBB0A00AD41FE /* ASOperation.m */, + 0EDC5DE021BBBB0A00AD41FE /* BROperation.h */, + 0EDC5DE221BBBB0A00AD41FE /* BROperation.m */, ); path = Queue; sourceTree = ""; @@ -1145,6 +1147,8 @@ 64F51DE74237213D947FD5AF /* Pods-BitBotTests.release.xcconfig */, A0D4B65651B1B5745349F720 /* Pods-BitriseATV.debug.xcconfig */, 8737EB33A867885C0D9BD854 /* Pods-BitriseATV.release.xcconfig */, + C032C508CB7EA3215E3C4EEA /* Pods-BitBotATV.debug.xcconfig */, + D84A7482A583FF266B3A58C9 /* Pods-BitBotATV.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -1759,7 +1763,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-BitriseATV-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-BitBotATV-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1843,7 +1847,7 @@ 0E8E9B5520F0819E00494DEB /* BRBitriseAPI.m in Sources */, 0EC53F45221B19F900F47B47 /* BRLogsTextViewController.m in Sources */, 0EB3ED7021E7B7F4003F0364 /* BRAbortRequest.m in Sources */, - 0EDC5DE421BBBB0A00AD41FE /* ASOperation.m in Sources */, + 0EDC5DE421BBBB0A00AD41FE /* BROperation.m in Sources */, 0E93B70D20F0F9BB001A6C15 /* BTRAccount+Mapping.m in Sources */, 0EFD893D20F4893B0023FCCE /* BRApp+Mapping.m in Sources */, 0E3C0B022117008200F2EA35 /* BRBuildStateInfo.m in Sources */, @@ -2011,7 +2015,7 @@ DE48664725245A6100D5D80F /* BRAccountRequest.m in Sources */, DE2A26B4252313DB00D5762E /* bitrise.xcdatamodeld in Sources */, DEBE8C1C2513B7FB00CF079A /* BitriseATVApp.swift in Sources */, - DE3CD08925246A2E00DD5948 /* ASOperation.m in Sources */, + DE3CD08925246A2E00DD5948 /* BROperation.m in Sources */, DED411102534A27900A711BC /* SettingsProvider.swift in Sources */, DEF04DA0252C9335008C4C97 /* BRAbortRequest.m in Sources */, DE4866162523633E00D5D80F /* AccountsConnector.swift in Sources */, @@ -2335,7 +2339,7 @@ }; DEBE8C252513B7FD00CF079A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A0D4B65651B1B5745349F720 /* Pods-BitriseATV.debug.xcconfig */; + baseConfigurationReference = C032C508CB7EA3215E3C4EEA /* Pods-BitBotATV.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "Brand Assets"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -2367,7 +2371,7 @@ }; DEBE8C262513B7FD00CF079A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8737EB33A867885C0D9BD854 /* Pods-BitriseATV.release.xcconfig */; + baseConfigurationReference = D84A7482A583FF266B3A58C9 /* Pods-BitBotATV.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "Brand Assets"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; diff --git a/Bitrise/Environment/BRAnalytics.h b/Bitrise/Environment/BRAnalytics.h index a5ddeb81..0ee7cdc1 100644 --- a/Bitrise/Environment/BRAnalytics.h +++ b/Bitrise/Environment/BRAnalytics.h @@ -16,11 +16,17 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)analytics; +// Controls if services are running - (void)start; -- (void)toggle; +- (void)stop; + +// Controls if analytics is allowed by user - (void)setEnabled:(BOOL)isEnabled; - (BOOL)isEnabled; +// Switches enabled state and calls start/stop +- (void)toggle; + #pragma mark - Events - - (void)trackQuitApp; @@ -31,11 +37,13 @@ NS_ASSUME_NONNULL_BEGIN - (void)trackAnalyticsToggle; - (void)trackAccountAdd; -- (void)trackAccountAddFailure; +- (void)trackAccountAddFailure:(NSError *)error; - (void)trackAccountRemove; +- (void)trackAccountRemoveError:(NSError *)error; - (void)trackSyncWithStarted:(NSUInteger)started running:(NSUInteger)running finished:(NSUInteger)finished; +- (void)trackSyncError:(NSError *)error; - (void)trackRebuildAction; - (void)trackAbortAction; - (void)trackLoadLogsAction; diff --git a/Bitrise/Environment/BRAnalytics.m b/Bitrise/Environment/BRAnalytics.m index 0e41b9cc..79e1b896 100644 --- a/Bitrise/Environment/BRAnalytics.m +++ b/Bitrise/Environment/BRAnalytics.m @@ -9,12 +9,21 @@ #import "BRAnalytics.h" #import +#import static NSString * const kBRAnalyticsAvailabilityKey = @"kBRAnalyticsAvailabilityKey"; static NSString * const kBRMixpanelOSXToken = @"ae64ff4c78b73e7f945f63aa02677fbb"; static NSString * const kBRMixpanelATVToken = @"4d209b738bd7dc6965ad1325080f83f1"; +#if DEBUG +static NSString * const kBRSentryOSXDSNPath = @"https://16702f55ff1346e49d6ae3aa41bffc8b@o577211.ingest.sentry.io/5731739"; +#else +static NSString * const kBRSentryOSXDSNPath = @"https://c955ed8ebdfc4db6bc206bfec0db2af2@o577211.ingest.sentry.io/5783183"; +#endif + +static NSString * const kBRSentryATVDSNPath = @"https://eb1b1d1669e344d2a0799c79ec1c78ce@o577211.ingest.sentry.io/5737938"; + typedef NSString BRAnalyticsEvent; static BRAnalyticsEvent * const kQuitAppEvent = @"app_quit"; @@ -63,22 +72,42 @@ + (instancetype)analytics { } - (void)start { + // First launch, enable by default + if ([[NSUserDefaults standardUserDefaults] objectForKey:kBRAnalyticsAvailabilityKey] == nil) { + [[BRAnalytics analytics] setEnabled:YES]; + } + + // Start services if enabled + if ([self isEnabled]) { #if TARGET_OS_OSX - [Mixpanel sharedInstanceWithToken:kBRMixpanelOSXToken]; + [self startMixpanel:kBRMixpanelOSXToken]; + [self startSentry:kBRSentryOSXDSNPath]; #else - [Mixpanel sharedInstanceWithToken:kBRMixpanelATVToken]; + [self startMixpanel:kBRMixpanelATVToken]; + [self startSentry:kBRSentryATVDSNPath]; #endif - - if ([[NSUserDefaults standardUserDefaults] objectForKey:kBRAnalyticsAvailabilityKey] == nil) { - [[BRAnalytics analytics] setEnabled:YES]; } } +- (void)stop { + [self stopMixpanel]; + [self stopSentry]; +} + - (void)toggle { [self setEnabled:![self isEnabled]]; + if ([self isEnabled]) { + [self start]; + } else { + [self stop]; + } } - (void)setEnabled:(BOOL)isEnabled { + if (isEnabled == [self isEnabled]) { + return; + } + [self.defaults setBool:isEnabled forKey:kBRAnalyticsAvailabilityKey]; [self.defaults synchronize]; } @@ -87,6 +116,32 @@ - (BOOL)isEnabled { return [self.defaults boolForKey:kBRAnalyticsAvailabilityKey]; } +#pragma mark - Providers - + +- (void)startMixpanel:(NSString *)token { + [Mixpanel sharedInstanceWithToken:token]; + if ([[Mixpanel sharedInstance] hasOptedOutTracking]) { + [[Mixpanel sharedInstance] optInTracking]; + } +} + +- (void)stopMixpanel { + [[Mixpanel sharedInstance] flush]; + [[Mixpanel sharedInstance] reset]; + [[Mixpanel sharedInstance] optOutTracking]; +} + +- (void)startSentry:(NSString *)dsn { + [SentrySDK startWithConfigureOptions:^(SentryOptions *options) { + options.dsn = dsn; + options.tracesSampleRate = @1.0; + }]; +} + +- (void)stopSentry { + [SentrySDK close]; +} + #pragma mark - Events - - (void)trackQuitApp { [self sendEvent:kQuitAppEvent properties:@{}]; } @@ -97,13 +152,23 @@ - (void)trackNotificationsToggle { [self sendEvent:kNotificationsToggleEvent pro - (void)trackAnalyticsToggle { [self sendEvent:kAnalyticsToggleEvent properties:@{}]; } - (void)trackAccountAdd { [self sendEvent:kAddAccountEvent properties:@{}]; } -- (void)trackAccountAddFailure { [self sendEvent:kAddAccountFailureEvent properties:@{}]; } +- (void)trackAccountAddFailure:(NSError *)error { + [self sendEvent:kAddAccountFailureEvent properties:@{}]; + [self sendError:error]; +} - (void)trackAccountRemove { [self sendEvent:kRemoveAccountEvent properties:@{}]; } +- (void)trackAccountRemoveError:(NSError *)error { + [self sendEvent:kRemoveAccountEvent properties:@{}]; + [self sendError:error]; +} - (void)trackSyncWithStarted:(NSUInteger)started running:(NSUInteger)running finished:(NSUInteger)finished { [self sendEvent:kSyncEvent properties:@{ @"started" : @(started), @"running" : @(running), @"finished" : @(finished) }]; } +- (void)trackSyncError:(NSError *)error { + [self sendError:error]; +} - (void)trackRebuildAction { [self sendEvent:kRebuildActionEvent properties:@{}]; } - (void)trackAbortAction { [self sendEvent:kAbortActionEvent properties:@{}]; } @@ -118,4 +183,14 @@ - (void)sendEvent:(BRAnalyticsEvent *)name properties:(NSDictionary *)properties } } +#pragma mark - Issues - + +- (void)sendError:(NSError *)error { + [SentrySDK captureError:error]; + +// SentryEvent *event = [[SentryEvent alloc] initWithError:error]; +// event.message = [[SentryMessage alloc] initWithFormatted:error.localizedDescription]; +// [SentrySDK captureEvent:event]; +} + @end diff --git a/Bitrise/Environment/BRNotificationDispatcher.m b/Bitrise/Environment/BRNotificationDispatcher.m index b6ed0f15..e8ab39dd 100644 --- a/Bitrise/Environment/BRNotificationDispatcher.m +++ b/Bitrise/Environment/BRNotificationDispatcher.m @@ -113,7 +113,7 @@ - (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNot switch (notification.activationType) { case NSUserNotificationActivationTypeActionButtonClicked: { BRLog(LL_VERBOSE, LL_CORE, @"Action clicked"); - BROpenBuildCommand *openCommand = [[BROpenBuildCommand alloc] initWithBuildSlug:notification.userInfo[kBRNotificationBuildSlugKey]]; + BROpenBuildCommand *openCommand = [[BROpenBuildCommand alloc] initWithBuildSlug:notification.userInfo[kBRNotificationBuildSlugKey] tab:BRBuildPageTabLogs]; [openCommand execute:nil]; break; } diff --git a/Bitrise/Info.plist b/Bitrise/Info.plist index ae0d96aa..314679ea 100644 --- a/Bitrise/Info.plist +++ b/Bitrise/Info.plist @@ -23,7 +23,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 2040 + 2094 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/Bitrise/Networking/Commands/Account/BRGetAccountCommand.m b/Bitrise/Networking/Commands/Account/BRGetAccountCommand.m index 659f7454..6439c03e 100644 --- a/Bitrise/Networking/Commands/Account/BRGetAccountCommand.m +++ b/Bitrise/Networking/Commands/Account/BRGetAccountCommand.m @@ -45,7 +45,7 @@ - (void)execute:(BRCommandResult)callback { [self.syncEngine addAccount:self.token callback:^(NSError * _Nullable error) { callback(error == nil, error); if (error) { - [[BRAnalytics analytics] trackAccountAddFailure]; + [[BRAnalytics analytics] trackAccountAddFailure:error]; } else { [[BRAnalytics analytics] trackAccountAdd]; } diff --git a/Bitrise/Networking/Commands/Account/BRRemoveAccountCommand.m b/Bitrise/Networking/Commands/Account/BRRemoveAccountCommand.m index 6878aa1a..c519d8ba 100644 --- a/Bitrise/Networking/Commands/Account/BRRemoveAccountCommand.m +++ b/Bitrise/Networking/Commands/Account/BRRemoveAccountCommand.m @@ -34,8 +34,12 @@ - (void)execute:(BRCommandResult)callback { [self.storage perform:^{ NSError *error; BOOL result = [self.storage removeAccount:self.slug error:&error]; + if (result) { + [[BRAnalytics analytics] trackAccountRemove]; + } else { + [[BRAnalytics analytics] trackAccountRemoveError:error]; + } BR_SAFE_CALL(callback, result, error); - [[BRAnalytics analytics] trackAccountRemove]; }]; } diff --git a/Bitrise/Networking/Commands/Actions/BRCommandFactory.h b/Bitrise/Networking/Commands/Actions/BRCommandFactory.h index 23e1cc04..d31d61fb 100644 --- a/Bitrise/Networking/Commands/Actions/BRCommandFactory.h +++ b/Bitrise/Networking/Commands/Actions/BRCommandFactory.h @@ -38,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN - (BRAbortCommand *)abortCommand:(BRBuild *)build; #if TARGET_OS_OSX - (BRDownloadLogsCommand *)logsCommand:(NSString *)buildSlug; -- (BROpenBuildCommand *)openCommand:(NSString *)buildSlug; +- (BROpenBuildCommand *)openCommand:(NSString *)buildSlug tab:(BRBuildPageTab)tab; #endif - (BRSyncCommand *)syncCommand; diff --git a/Bitrise/Networking/Commands/Actions/BRCommandFactory.m b/Bitrise/Networking/Commands/Actions/BRCommandFactory.m index 7ae8b911..ddfddd07 100644 --- a/Bitrise/Networking/Commands/Actions/BRCommandFactory.m +++ b/Bitrise/Networking/Commands/Actions/BRCommandFactory.m @@ -59,8 +59,8 @@ - (BRDownloadLogsCommand *)logsCommand:(NSString *)buildSlug { return [[BRDownloadLogsCommand alloc] initWithBuildSlug:buildSlug]; } -- (BROpenBuildCommand *)openCommand:(NSString *)buildSlug { - return [[BROpenBuildCommand alloc] initWithBuildSlug:buildSlug]; +- (BROpenBuildCommand *)openCommand:(NSString *)buildSlug tab:(BRBuildPageTab)tab { + return [[BROpenBuildCommand alloc] initWithBuildSlug:buildSlug tab:tab]; } #endif diff --git a/Bitrise/Networking/Commands/Actions/BROpenBuildCommand.h b/Bitrise/Networking/Commands/Actions/BROpenBuildCommand.h index ec0e883c..316bd98f 100644 --- a/Bitrise/Networking/Commands/Actions/BROpenBuildCommand.h +++ b/Bitrise/Networking/Commands/Actions/BROpenBuildCommand.h @@ -12,12 +12,17 @@ NS_ASSUME_NONNULL_BEGIN +typedef NS_ENUM(NSUInteger, BRBuildPageTab) { + BRBuildPageTabLogs = 0, + BRBuildPageTabArtefacts +}; + @interface BROpenBuildCommand : BRCommand - (instancetype)new NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithBuildSlug:(NSString *)buildSlug NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithBuildSlug:(NSString *)buildSlug tab:(BRBuildPageTab)tab NS_DESIGNATED_INITIALIZER; @end diff --git a/Bitrise/Networking/Commands/Actions/BROpenBuildCommand.m b/Bitrise/Networking/Commands/Actions/BROpenBuildCommand.m index aaf8d579..06f35541 100644 --- a/Bitrise/Networking/Commands/Actions/BROpenBuildCommand.m +++ b/Bitrise/Networking/Commands/Actions/BROpenBuildCommand.m @@ -13,21 +13,33 @@ @interface BROpenBuildCommand () @property (copy, nonatomic) NSString *buildSlug; +@property (assign, nonatomic) BRBuildPageTab tab; @end @implementation BROpenBuildCommand -- (instancetype)initWithBuildSlug:(NSString *)buildSlug { +- (instancetype)initWithBuildSlug:(NSString *)buildSlug tab:(BRBuildPageTab)tab { if (self = [super init]) { _buildSlug = buildSlug; + _tab = tab; } return self; } - (void)execute:(BRCommandResult)callback { - NSString *buildPath = [NSString stringWithFormat:@"https://app.bitrise.io/build/%@", self.buildSlug]; + NSMutableString *buildPath = [[NSString stringWithFormat:@"https://app.bitrise.io/build/%@", self.buildSlug] mutableCopy]; + switch (self.tab) { + case BRBuildPageTabLogs: + [buildPath appendFormat:@"/#?tab=logs"]; + break; + + case BRBuildPageTabArtefacts: + [buildPath appendFormat:@"/#?tab=artifacts"]; + break; + } + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:buildPath]]; BR_SAFE_CALL(callback, YES, nil); diff --git a/Bitrise/Networking/Commands/BRSyncCommand.m b/Bitrise/Networking/Commands/BRSyncCommand.m index 8509b6c7..e2613ea2 100644 --- a/Bitrise/Networking/Commands/BRSyncCommand.m +++ b/Bitrise/Networking/Commands/BRSyncCommand.m @@ -39,7 +39,8 @@ - (instancetype)initSyncEngine:(BRSyncEngine *)engine environment:(BREnvironment return self; } -#endif + +#else - (instancetype)initSyncEngine:(BRSyncEngine *)engine { if (self = [super init]) { @@ -53,6 +54,8 @@ - (instancetype)initSyncEngine:(BRSyncEngine *)engine { return self; } +#endif + - (void)execute:(BRCommandResult)callback { [self.syncEngine sync]; } diff --git a/Bitrise/Networking/LogObserver/ASLogLoadingOperation.h b/Bitrise/Networking/LogObserver/ASLogLoadingOperation.h index c7f6e4ae..aedf0bc0 100644 --- a/Bitrise/Networking/LogObserver/ASLogLoadingOperation.h +++ b/Bitrise/Networking/LogObserver/ASLogLoadingOperation.h @@ -6,7 +6,7 @@ // Copyright © 2019 Bitrise. All rights reserved. // -#import "ASOperation.h" +#import "BROperation.h" #import "ASLogOperation.h" #import "BRStorage.h" @@ -22,7 +22,7 @@ typedef NS_ENUM(NSUInteger, BRLogLoadingState) { }; typedef void(^BRLogLoadingCallback)(BRLogLoadingState state, NSProgress * _Nullable progress); -@interface ASLogLoadingOperation : ASOperation +@interface ASLogLoadingOperation : BROperation @property (copy, nonatomic, readonly) NSString *buildSlug; @property (copy, nonatomic) BRLogLoadingCallback loadingCallback; diff --git a/Bitrise/Networking/LogObserver/ASLogObservingOperation.h b/Bitrise/Networking/LogObserver/ASLogObservingOperation.h index db07eec5..f931b844 100644 --- a/Bitrise/Networking/LogObserver/ASLogObservingOperation.h +++ b/Bitrise/Networking/LogObserver/ASLogObservingOperation.h @@ -6,7 +6,7 @@ // Copyright © 2019 Bitrise. All rights reserved. // -#import "ASOperation.h" +#import "BROperation.h" #import "ASLogOperation.h" #import "BRStorage.h" @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface ASLogObservingOperation : ASOperation +@interface ASLogObservingOperation : BROperation @property (copy, nonatomic, readonly) NSString *buildSlug; diff --git a/Bitrise/Networking/LogObserver/BRLogObserver.m b/Bitrise/Networking/LogObserver/BRLogObserver.m index 46959441..8d4fd9a2 100644 --- a/Bitrise/Networking/LogObserver/BRLogObserver.m +++ b/Bitrise/Networking/LogObserver/BRLogObserver.m @@ -53,7 +53,7 @@ - (void)startObservingBuild:(NSString *)buildSlug { - (void)stopObservingBuild:(NSString *)buildSlug { @synchronized (self) { - [[self operationsForBuild:buildSlug] enumerateObjectsUsingBlock:^(ASOperation *operation, NSUInteger idx, BOOL *stop) { + [[self operationsForBuild:buildSlug] enumerateObjectsUsingBlock:^(BROperation *operation, NSUInteger idx, BOOL *stop) { BRLog(LL_DEBUG, LL_LOGSYNC, @"BRLogObserver: cancelling observing operation: %@", buildSlug); [operation cancel]; }]; @@ -71,7 +71,7 @@ - (void)loadLogsForBuild:(NSString *)buildSlug callback:(BRLogLoadingCallback)ca #pragma mark - Private API - -- (NSArray *> *)operationsForBuild:(NSString *)buildSlug { +- (NSArray *> *)operationsForBuild:(NSString *)buildSlug { __block NSMutableArray > *operations = [NSMutableArray array]; [self.queue.operations enumerateObjectsUsingBlock:^(id operation, NSUInteger idx, BOOL *stop) { if ([[operation buildSlug] isEqualToString:buildSlug]) { diff --git a/Bitrise/Sync/BRAddAccountOperation.h b/Bitrise/Sync/BRAddAccountOperation.h index 9660ec5a..26d3213e 100644 --- a/Bitrise/Sync/BRAddAccountOperation.h +++ b/Bitrise/Sync/BRAddAccountOperation.h @@ -6,14 +6,14 @@ // Copyright © 2018 BitBot. All rights reserved. // -#import "ASOperation.h" +#import "BROperation.h" #import "BRStorage.h" #import "BRBitriseAPI.h" NS_ASSUME_NONNULL_BEGIN -@interface BRAddAccountOperation : ASOperation +@interface BRAddAccountOperation : BROperation @property (copy, nonatomic, nullable) void (^resultCallback)(NSError * __nullable error); diff --git a/Bitrise/Sync/BRAddAccountOperation.m b/Bitrise/Sync/BRAddAccountOperation.m index de5f675f..055a5b94 100644 --- a/Bitrise/Sync/BRAddAccountOperation.m +++ b/Bitrise/Sync/BRAddAccountOperation.m @@ -8,12 +8,15 @@ #import "BRAddAccountOperation.h" +#import #import "BRMacro.h" #import "BRSyncOperation.h" #import "BRAccountRequest.h" @interface BRAddAccountOperation () +@property (strong, nonatomic) id sentryTransaction; + @property (strong, nonatomic) BRStorage *storage; @property (strong, nonatomic) BRBitriseAPI *api; diff --git a/Bitrise/Sync/BRSyncOperation.h b/Bitrise/Sync/BRSyncOperation.h index 4292cf43..5e9004a9 100644 --- a/Bitrise/Sync/BRSyncOperation.h +++ b/Bitrise/Sync/BRSyncOperation.h @@ -6,7 +6,7 @@ // Copyright © 2018 BitBot. All rights reserved. // -#import "ASOperation.h" +#import "BROperation.h" #import "BRStorage.h" #import "BRBitriseAPI.h" @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface BRSyncOperation : ASOperation +@interface BRSyncOperation : BROperation @property (copy, nonatomic, nullable) void (^syncCallback)(BRSyncResult *result); diff --git a/Bitrise/Sync/BRSyncOperation.m b/Bitrise/Sync/BRSyncOperation.m index 5b94163e..1b118be4 100644 --- a/Bitrise/Sync/BRSyncOperation.m +++ b/Bitrise/Sync/BRSyncOperation.m @@ -8,7 +8,10 @@ #import "BRSyncOperation.h" +#import #import "BRLogger.h" +#import "BRMacro.h" +#import "BRAnalytics.h" #import "NSArray+FRP.h" #import "BRBuild+CoreDataClass.h" @@ -18,8 +21,13 @@ #import "BRBuildsRequest.h" #import "BRBuildInfo.h" +typedef void (^AppSyncCompletion)(NSError * _Nullable error); + @interface BRSyncOperation () +@property (assign, nonatomic) NSUInteger accountsCount; +@property (assign, nonatomic) NSUInteger appsCount; + @property (strong, nonatomic) BRStorage *storage; @property (strong, nonatomic) BRBitriseAPI *api; @@ -33,6 +41,8 @@ - (instancetype)initWithStorage:(BRStorage *)storage api:(BRBitriseAPI *)api { if (self = [super init]) { _storage = storage; _api = api; + _accountsCount = 0; + _appsCount = 0; } return self; @@ -46,20 +56,26 @@ - (void)start { [self.storage perform:^{ NSError *accFetchError; NSArray *accounts = [self.storage accounts:&accFetchError]; + if (!accounts) { BRLog(LL_DEBUG, LL_STORAGE, @"Failed to get accounts: %@", accFetchError); - [super finish]; + [self handleError:accFetchError]; + [self finish]; return; } if (accounts.count == 0) { BRLog(LL_DEBUG, LL_STORAGE, @"No accounts, nothing to do..."); - [super finish]; + [self finish]; return; } + self.accountsCount = accounts.count; + [accounts enumerateObjectsUsingBlock:^(BTRAccount *account, NSUInteger idx, BOOL *stop) { dispatch_group_enter(self.group); + id accountSpan = [self.sentryTransaction startChildWithOperation:[NSString stringWithFormat:@"account-sync-%lu", (unsigned long)idx]]; + BRAppsRequest *appsRequest = [[BRAppsRequest alloc] initWithToken:account.token]; [self.api getApps:appsRequest completion:^(NSArray *appsInfo, NSError *error) { // Handle failure @@ -74,8 +90,12 @@ - (void)start { } else { BRLog(LL_WARN, LL_STORAGE, @"Failed to disable account: %@", updateError); } + } else { + [self handleError:error]; } - [super finish]; + + [accountSpan finish]; + dispatch_group_leave(self.group); return; } @@ -86,6 +106,7 @@ - (void)start { BRLog(LL_WARN, LL_STORAGE, @"Account %@ enabled", account.email); } else { BRLog(LL_WARN, LL_STORAGE, @"Failed to enable account: %@", updateError); + [self handleError:updateError]; } } @@ -93,7 +114,9 @@ - (void)start { NSError *updateAppsError; if (![self.storage updateApps:appsInfo forAccount:account error:&updateAppsError]) { BRLog(LL_WARN, LL_STORAGE, @"Failed to update apps: %@", updateAppsError); - [super finish]; + [self handleError:updateAppsError]; + [accountSpan finish]; + dispatch_group_leave(self.group); return; } @@ -101,28 +124,44 @@ - (void)start { NSArray *apps = [self.storage appsForAccount:account error:&appsFetchError]; if (!apps) { BRLog(LL_WARN, LL_STORAGE, @"Failed to fetch updated apps: %@", appsFetchError); - [super finish]; + [self handleError:appsFetchError]; + [accountSpan finish]; + dispatch_group_leave(self.group); return; } - + + [accountSpan.context setTagValue:[NSString stringWithFormat:@"%lu", (unsigned long)apps.count] forKey:@"apps"]; + NSError *fetchError; NSArray *runningBuildSlugs = [[self.storage runningBuilds:&fetchError] aps_map:^id(BRBuild *build) { return build.slug; }]; [apps enumerateObjectsUsingBlock:^(BRApp *app, NSUInteger idx, BOOL *stop) { - [self updateBuilds:app token:account.token runningBuilds:runningBuildSlugs]; + id appSpan = [accountSpan startChildWithOperation:[NSString stringWithFormat:@"app-sync-%lu", (unsigned long)idx]]; + [self updateBuilds:app token:account.token runningBuilds:runningBuildSlugs completion:^(NSError *error) { + if (error) { + [self handleError:error]; + } + [appSpan finish]; + }]; }]; - + + [accountSpan finish]; dispatch_group_leave(self.group); }]; }]; dispatch_group_notify(self.group, self.queue.underlyingQueue, ^{ - [super finish]; + [self finish]; }); }]; } +- (void)finish { + [self.sentryTransaction.context setTagValue:[NSString stringWithFormat:@"%lu", (unsigned long)self.accountsCount] forKey:@"accounts"]; + [super finish]; +} + - (NSTimeInterval)fetchTime:(BRApp *)app { BRBuild *latestBuild = [self.storage latestBuild:app error:NULL]; NSTimeInterval fetchTime = latestBuild ? [latestBuild.triggerTime timeIntervalSince1970] - 1 : 0; @@ -130,7 +169,7 @@ - (NSTimeInterval)fetchTime:(BRApp *)app { return fetchTime; } -- (void)updateBuilds:(BRApp *)app token:(NSString *)token runningBuilds:(NSArray *)runningBuildSlugs { +- (void)updateBuilds:(BRApp *)app token:(NSString *)token runningBuilds:(NSArray *)runningBuildSlugs completion:(AppSyncCompletion)completion { dispatch_group_enter(self.group); NSTimeInterval fetchTime = [self fetchTime:app]; @@ -155,8 +194,10 @@ - (void)updateBuilds:(BRApp *)app token:(NSString *)token runningBuilds:(NSArray } } else { BRLog(LL_WARN, LL_STORAGE, @"Failed to get builds from API: %@", error); + [self handleError:error]; } + BR_SAFE_CALL(completion, error); dispatch_group_leave(self.group); }]; } @@ -186,4 +227,8 @@ - (BRSyncDiff *)diffForBuilds:(NSArray *)remoteBuilds runningBui return [[BRSyncDiff alloc] initWithStartedBuilds:started runningBuilds:running finishedBuilds:finished]; } +- (void)handleError:(NSError *)error { + [[BRAnalytics analytics] trackSyncError:error]; +} + @end diff --git a/Bitrise/Tools/BRLogger.h b/Bitrise/Tools/BRLogger.h index aa5e47e8..50d5e4eb 100644 --- a/Bitrise/Tools/BRLogger.h +++ b/Bitrise/Tools/BRLogger.h @@ -16,6 +16,7 @@ static NSString * const LL_UI = @"UI"; static NSString * const LL_STORAGE = @"STORAGE"; static NSString * const LL_CORE = @"CORE"; +static NSString * const LL_SYNC = @"SYNC"; static NSString * const LL_LOGSYNC = @"LOGSYNC"; diff --git a/Bitrise/Tools/Queue/ASQueue.m b/Bitrise/Tools/Queue/ASQueue.m index 05ae7616..deef81df 100644 --- a/Bitrise/Tools/Queue/ASQueue.m +++ b/Bitrise/Tools/Queue/ASQueue.m @@ -8,7 +8,7 @@ #import "ASQueue.h" -#import "ASOperation.h" +#import "BROperation.h" static dispatch_queue_t underlyingQueue; @@ -29,8 +29,8 @@ - (instancetype)init { } - (void)addOperation:(NSOperation *)op { - if ([op isKindOfClass:[ASOperation class]]) { - [(ASOperation *)op setQueue:self]; + if ([op isKindOfClass:[BROperation class]]) { + [(BROperation *)op setQueue:self]; } [super addOperation:op]; diff --git a/Bitrise/Tools/Queue/ASOperation.h b/Bitrise/Tools/Queue/BROperation.h similarity index 64% rename from Bitrise/Tools/Queue/ASOperation.h rename to Bitrise/Tools/Queue/BROperation.h index 0c5b24e9..9a9e633c 100644 --- a/Bitrise/Tools/Queue/ASOperation.h +++ b/Bitrise/Tools/Queue/BROperation.h @@ -7,9 +7,13 @@ // #import + +#import #import "ASQueue.h" -@interface ASOperation : NSOperation +@interface BROperation : NSOperation + +@property (strong, nonatomic, readonly) id sentryTransaction; @property (strong, nonatomic) ASQueue *queue; diff --git a/Bitrise/Tools/Queue/ASOperation.m b/Bitrise/Tools/Queue/BROperation.m similarity index 77% rename from Bitrise/Tools/Queue/ASOperation.m rename to Bitrise/Tools/Queue/BROperation.m index 1d533aae..a27a0ef1 100644 --- a/Bitrise/Tools/Queue/ASOperation.m +++ b/Bitrise/Tools/Queue/BROperation.m @@ -1,23 +1,23 @@ // -// ASOperation.m -// AppSpector +// BROperation.m +// BitBot // // Created by Deszip on 24/12/2017. // Copyright © 2017 Deszip. All rights reserved. // -#import "ASOperation.h" +#import "BROperation.h" #import "BRLogger.h" -@interface ASOperation () +@interface BROperation () @property (assign, nonatomic) NSTimeInterval duration; @property (assign, nonatomic) BOOL processing; @end -@implementation ASOperation +@implementation BROperation - (void)setProcessing:(BOOL)processingState { [self trackDuration:processingState]; @@ -58,7 +58,11 @@ - (void)finish { - (void)trackDuration:(BOOL)processing { NSTimeInterval current = [[NSDate date] timeIntervalSince1970]; self.duration = processing ? current : current - self.duration; - if (!processing) { + + if (processing) { + _sentryTransaction = [SentrySDK startTransactionWithName:NSStringFromClass([self class]) operation:NSStringFromClass([self class])]; + } else { + [_sentryTransaction finish]; BRLog(LL_DEBUG, LL_CORE, @"%@: %f", NSStringFromClass([self class]), self.duration); } } diff --git a/Bitrise/View/Base.lproj/Main.storyboard b/Bitrise/View/Base.lproj/Main.storyboard index e2a81665..f5798fd8 100644 --- a/Bitrise/View/Base.lproj/Main.storyboard +++ b/Bitrise/View/Base.lproj/Main.storyboard @@ -1342,7 +1342,10 @@ https://discuss.bitrise.io/t/personal-access-tokens-beta/1383 - + + + + @@ -1511,15 +1514,15 @@ https://discuss.bitrise.io/t/personal-access-tokens-beta/1383 - + - + - + @@ -1530,7 +1533,7 @@ https://discuss.bitrise.io/t/personal-access-tokens-beta/1383 - + diff --git a/Bitrise/View/Menus/BRBuildMenuController.m b/Bitrise/View/Menus/BRBuildMenuController.m index 46091ea9..13ca5c4b 100644 --- a/Bitrise/View/Menus/BRBuildMenuController.m +++ b/Bitrise/View/Menus/BRBuildMenuController.m @@ -11,13 +11,14 @@ #import "BRBuild+CoreDataClass.h" #import "BRBuildInfo.h" -static const NSUInteger kMenuItemsCount = 5; +static const NSUInteger kMenuItemsCount = 6; typedef NS_ENUM(NSUInteger, BRBuildMenuItem) { BRBuildMenuItemRebuild = 0, BRBuildMenuItemAbort, BRBuildMenuItemShowLog, BRBuildMenuItemDownload, - BRBuildMenuItemOpenBuild + BRBuildMenuItemOpenBuild, + BRBuildMenuItemOpenArtefacts }; @interface BRBuildMenuController () @@ -52,13 +53,16 @@ - (void)setMenu:(NSMenu *)menu { [self.menu.itemArray[BRBuildMenuItemAbort] setAction:@selector(abort)]; [self.menu.itemArray[BRBuildMenuItemShowLog] setAction:@selector(showLog)]; [self.menu.itemArray[BRBuildMenuItemDownload] setAction:@selector(downloadLog)]; - [self.menu.itemArray[BRBuildMenuItemOpenBuild] setAction:@selector(openBuild)]; + [self.menu.itemArray[BRBuildMenuItemOpenBuild] setAction:@selector(openBuildLogs)]; + [self.menu.itemArray[BRBuildMenuItemOpenArtefacts] setAction:@selector(openBuildArtefacts)]; } } - (void)bindToOutline:(NSOutlineView *)outline { self.outlineView = outline; self.outlineView.menu = self.menu; + [self.outlineView setTarget:self]; + self.outlineView.doubleAction = @selector(handleDoubleClick:); } - (void)bindToButton:(NSButton *)button { @@ -76,6 +80,10 @@ - (void)showMenu:(NSButton *)button { #pragma mark - Actions - +- (void)handleDoubleClick:(id)sender { + [self openBuildLogs]; +} + - (void)rebuild { BRBuild *build = [self selectedBuild]; if (build) { @@ -118,10 +126,18 @@ - (void)downloadLog { } } -- (void)openBuild { +- (void)openBuildLogs { + [self openBuildTab:BRBuildPageTabLogs]; +} + +- (void)openBuildArtefacts { + [self openBuildTab:BRBuildPageTabArtefacts]; +} + +- (void)openBuildTab:(BRBuildPageTab)tab { BRBuild *build = [self selectedBuild]; if (build) { - BROpenBuildCommand *command = [self.commandFactory openCommand:build.slug]; + BROpenBuildCommand *command = [self.commandFactory openCommand:build.slug tab:tab]; [command execute:nil]; } } @@ -139,6 +155,7 @@ - (BOOL)menuItem:(NSMenuItem *)menuItem isValidFor:(BRBuildInfo *)buildInfo { BOOL buildCouldBeAborted = buildInfo.stateInfo.state == BRBuildStateInProgress || buildInfo.stateInfo.state == BRBuildStateHold; BOOL buildLogAvailable = buildInfo.stateInfo.state != BRBuildStateHold && !buildInProgress; + BOOL buildArtefactsAvailable = buildLogAvailable; switch (menuItem.tag) { case BRBuildMenuItemRebuild: return !buildInProgress; @@ -146,6 +163,7 @@ - (BOOL)menuItem:(NSMenuItem *)menuItem isValidFor:(BRBuildInfo *)buildInfo { case BRBuildMenuItemShowLog: return buildLogAvailable; case BRBuildMenuItemDownload: return buildLogAvailable; case BRBuildMenuItemOpenBuild: return YES; + case BRBuildMenuItemOpenArtefacts: return buildArtefactsAvailable; default: return NO; } } diff --git a/BitriseATV/Supporting Files/Info.plist b/BitriseATV/Supporting Files/Info.plist index 9b64cf4d..c8b96c29 100644 --- a/BitriseATV/Supporting Files/Info.plist +++ b/BitriseATV/Supporting Files/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.0 CFBundleVersion - 328 + 344 LSRequiresIPhoneOS UIAppFonts diff --git a/Podfile b/Podfile index 64e5308a..75d3a5b7 100644 --- a/Podfile +++ b/Podfile @@ -2,6 +2,7 @@ def sharedPods pod 'EasyMapping' + pod 'Sentry', :git => 'https://github.com/getsentry/sentry-cocoa.git', :tag => '7.1.0' pod 'Mixpanel' end @@ -10,6 +11,7 @@ target 'BitBot' do platform :osx, '10.12' pod "NSPopover+MISSINGBackgroundView" pod 'SDWebImage', '~> 5.0.6' + sharedPods() target 'BitBotTests' do @@ -22,7 +24,7 @@ target 'BitBot' do end -target 'BitriseATV' do +target 'BitBotATV' do platform :tvos, '14.0' pod 'Kingfisher/SwiftUI' sharedPods() diff --git a/Podfile.lock b/Podfile.lock index c02fe6c8..5681257e 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -12,6 +12,9 @@ PODS: - SDWebImage (5.0.6): - SDWebImage/Core (= 5.0.6) - SDWebImage/Core (5.0.6) + - Sentry (7.0.0-beta.0): + - Sentry/Core (= 7.0.0-beta.0) + - Sentry/Core (7.0.0-beta.0) DEPENDENCIES: - EasyMapping @@ -21,6 +24,7 @@ DEPENDENCIES: - "NSPopover+MISSINGBackgroundView" - OCMock (~> 3.4.3) - SDWebImage (~> 5.0.6) + - Sentry (from `https://github.com/getsentry/sentry-cocoa.git`) SPEC REPOS: https://github.com/CocoaPods/Specs.git: @@ -33,6 +37,15 @@ SPEC REPOS: - Mixpanel - "NSPopover+MISSINGBackgroundView" +EXTERNAL SOURCES: + Sentry: + :git: https://github.com/getsentry/sentry-cocoa.git + +CHECKOUT OPTIONS: + Sentry: + :commit: cd561c7b8f5e0396f3510600167c17b2c076deed + :git: https://github.com/getsentry/sentry-cocoa.git + SPEC CHECKSUMS: EasyMapping: 52860151d1df5db1b245b1d1568e2e05a27a4689 Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 @@ -41,7 +54,8 @@ SPEC CHECKSUMS: "NSPopover+MISSINGBackgroundView": 06a134ea85280a8f0436c9c99fa18400ae84cf15 OCMock: 43565190abc78977ad44a61c0d20d7f0784d35ab SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 + Sentry: 542abd1868a121f29cd2303ac7cf78000e3f797c -PODFILE CHECKSUM: 40817729a4f63b60420d73a810dea5439b97fa67 +PODFILE CHECKSUM: 79ffa78a333106e69ea5528d095b885b05600a88 -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.1 diff --git a/Pods/Headers/Private/Sentry/Container+SentryDeepSearch.h b/Pods/Headers/Private/Sentry/Container+SentryDeepSearch.h new file mode 120000 index 00000000..e543de87 --- /dev/null +++ b/Pods/Headers/Private/Sentry/Container+SentryDeepSearch.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/NSArray+SentrySanitize.h b/Pods/Headers/Private/Sentry/NSArray+SentrySanitize.h new file mode 120000 index 00000000..0da765ac --- /dev/null +++ b/Pods/Headers/Private/Sentry/NSArray+SentrySanitize.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/NSArray+SentrySanitize.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/NSData+SentryCompression.h b/Pods/Headers/Private/Sentry/NSData+SentryCompression.h new file mode 120000 index 00000000..aa670f57 --- /dev/null +++ b/Pods/Headers/Private/Sentry/NSData+SentryCompression.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/NSData+SentryCompression.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/NSDate+SentryExtras.h b/Pods/Headers/Private/Sentry/NSDate+SentryExtras.h new file mode 120000 index 00000000..a957e64e --- /dev/null +++ b/Pods/Headers/Private/Sentry/NSDate+SentryExtras.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/NSDate+SentryExtras.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/NSDictionary+SentrySanitize.h b/Pods/Headers/Private/Sentry/NSDictionary+SentrySanitize.h new file mode 120000 index 00000000..6709ddb0 --- /dev/null +++ b/Pods/Headers/Private/Sentry/NSDictionary+SentrySanitize.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/NSDictionary+SentrySanitize.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/NSError+SentrySimpleConstructor.h b/Pods/Headers/Private/Sentry/NSError+SentrySimpleConstructor.h new file mode 120000 index 00000000..e61a740e --- /dev/null +++ b/Pods/Headers/Private/Sentry/NSError+SentrySimpleConstructor.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/NSString+SentryUnsignedLongLongValue.h b/Pods/Headers/Private/Sentry/NSString+SentryUnsignedLongLongValue.h new file mode 120000 index 00000000..2121bf1e --- /dev/null +++ b/Pods/Headers/Private/Sentry/NSString+SentryUnsignedLongLongValue.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/NSString+SentryUnsignedLongLongValue.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/Sentry.h b/Pods/Headers/Private/Sentry/Sentry.h new file mode 120000 index 00000000..b0462a81 --- /dev/null +++ b/Pods/Headers/Private/Sentry/Sentry.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/Sentry.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryAppState.h b/Pods/Headers/Private/Sentry/SentryAppState.h new file mode 120000 index 00000000..9a0de98e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryAppState.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryAppState.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryAsynchronousOperation.h b/Pods/Headers/Private/Sentry/SentryAsynchronousOperation.h new file mode 120000 index 00000000..6acb15b3 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryAsynchronousOperation.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryAsynchronousOperation.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryAttachment.h b/Pods/Headers/Private/Sentry/SentryAttachment.h new file mode 120000 index 00000000..92a93508 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryAttachment.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryAttachment.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryAutoBreadcrumbTrackingIntegration.h b/Pods/Headers/Private/Sentry/SentryAutoBreadcrumbTrackingIntegration.h new file mode 120000 index 00000000..8611bd11 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryAutoBreadcrumbTrackingIntegration.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryAutoBreadcrumbTrackingIntegration.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryAutoSessionTrackingIntegration.h b/Pods/Headers/Private/Sentry/SentryAutoSessionTrackingIntegration.h new file mode 120000 index 00000000..f420823d --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryAutoSessionTrackingIntegration.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryAutoSessionTrackingIntegration.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryBreadcrumb.h b/Pods/Headers/Private/Sentry/SentryBreadcrumb.h new file mode 120000 index 00000000..ff283c07 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryBreadcrumb.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryBreadcrumb.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryBreadcrumbTracker.h b/Pods/Headers/Private/Sentry/SentryBreadcrumbTracker.h new file mode 120000 index 00000000..f9dac44e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryBreadcrumbTracker.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryBreadcrumbTracker.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryClient+Private.h b/Pods/Headers/Private/Sentry/SentryClient+Private.h new file mode 120000 index 00000000..36ce2d5d --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryClient+Private.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryClient+Private.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryClient.h b/Pods/Headers/Private/Sentry/SentryClient.h new file mode 120000 index 00000000..d3704d08 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryClient.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryClient.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryConcurrentRateLimitsDictionary.h b/Pods/Headers/Private/Sentry/SentryConcurrentRateLimitsDictionary.h new file mode 120000 index 00000000..eee8eea1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryConcurrentRateLimitsDictionary.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryConcurrentRateLimitsDictionary.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrash.h b/Pods/Headers/Private/Sentry/SentryCrash.h new file mode 120000 index 00000000..8ab3bf33 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrash.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrash.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashAdapter.h b/Pods/Headers/Private/Sentry/SentryCrashAdapter.h new file mode 120000 index 00000000..64f6b5fa --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashAdapter.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashAdapter.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashBinaryImageProvider.h b/Pods/Headers/Private/Sentry/SentryCrashBinaryImageProvider.h new file mode 120000 index 00000000..500be0ac --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashBinaryImageProvider.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashBinaryImageProvider.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashC.h b/Pods/Headers/Private/Sentry/SentryCrashC.h new file mode 120000 index 00000000..0af221c4 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashC.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashC.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashCPU.h b/Pods/Headers/Private/Sentry/SentryCrashCPU.h new file mode 120000 index 00000000..398c3a88 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashCPU.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashCPU_Apple.h b/Pods/Headers/Private/Sentry/SentryCrashCPU_Apple.h new file mode 120000 index 00000000..31c1eeb5 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashCPU_Apple.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_Apple.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashCString.h b/Pods/Headers/Private/Sentry/SentryCrashCString.h new file mode 120000 index 00000000..4f004786 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashCString.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Reporting/Tools/SentryCrashCString.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashCachedData.h b/Pods/Headers/Private/Sentry/SentryCrashCachedData.h new file mode 120000 index 00000000..0f6f3c68 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashCachedData.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashCachedData.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashDate.h b/Pods/Headers/Private/Sentry/SentryCrashDate.h new file mode 120000 index 00000000..62040329 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashDate.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDate.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashDebug.h b/Pods/Headers/Private/Sentry/SentryCrashDebug.h new file mode 120000 index 00000000..7f754308 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashDebug.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDebug.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashDefaultBinaryImageProvider.h b/Pods/Headers/Private/Sentry/SentryCrashDefaultBinaryImageProvider.h new file mode 120000 index 00000000..1040a0b9 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashDefaultBinaryImageProvider.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashDefaultBinaryImageProvider.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashDefaultMachineContextWrapper.h b/Pods/Headers/Private/Sentry/SentryCrashDefaultMachineContextWrapper.h new file mode 120000 index 00000000..acd5b64b --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashDefaultMachineContextWrapper.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashDefaultMachineContextWrapper.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashDoctor.h b/Pods/Headers/Private/Sentry/SentryCrashDoctor.h new file mode 120000 index 00000000..28ec528e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashDoctor.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashDoctor.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashDynamicLinker.h b/Pods/Headers/Private/Sentry/SentryCrashDynamicLinker.h new file mode 120000 index 00000000..349544eb --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashDynamicLinker.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashExceptionApplication.h b/Pods/Headers/Private/Sentry/SentryCrashExceptionApplication.h new file mode 120000 index 00000000..1e8afb6f --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashExceptionApplication.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryCrashExceptionApplication.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashFileUtils.h b/Pods/Headers/Private/Sentry/SentryCrashFileUtils.h new file mode 120000 index 00000000..5d353bf7 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashFileUtils.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashID.h b/Pods/Headers/Private/Sentry/SentryCrashID.h new file mode 120000 index 00000000..2ae7c344 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashID.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashID.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashInstallation+Private.h b/Pods/Headers/Private/Sentry/SentryCrashInstallation+Private.h new file mode 120000 index 00000000..926a88e2 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashInstallation+Private.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation+Private.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashInstallation.h b/Pods/Headers/Private/Sentry/SentryCrashInstallation.h new file mode 120000 index 00000000..1c800bc1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashInstallation.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashInstallationReporter.h b/Pods/Headers/Private/Sentry/SentryCrashInstallationReporter.h new file mode 120000 index 00000000..1617fe1a --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashInstallationReporter.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashInstallationReporter.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashIntegration.h b/Pods/Headers/Private/Sentry/SentryCrashIntegration.h new file mode 120000 index 00000000..fc112003 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashIntegration.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashIntegration.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashIsAppImage.h b/Pods/Headers/Private/Sentry/SentryCrashIsAppImage.h new file mode 120000 index 00000000..3931f17f --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashIsAppImage.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashIsAppImage.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashJSONCodec.h b/Pods/Headers/Private/Sentry/SentryCrashJSONCodec.h new file mode 120000 index 00000000..4dca1d90 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashJSONCodec.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashJSONCodecObjC.h b/Pods/Headers/Private/Sentry/SentryCrashJSONCodecObjC.h new file mode 120000 index 00000000..c7f2e2f7 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashJSONCodecObjC.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashLogger.h b/Pods/Headers/Private/Sentry/SentryCrashLogger.h new file mode 120000 index 00000000..85ebe786 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashLogger.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashLogger.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMach.h b/Pods/Headers/Private/Sentry/SentryCrashMach.h new file mode 120000 index 00000000..bb097c09 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMach.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMach.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMachineContext.h b/Pods/Headers/Private/Sentry/SentryCrashMachineContext.h new file mode 120000 index 00000000..b9e8fdd4 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMachineContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMachineContextWrapper.h b/Pods/Headers/Private/Sentry/SentryCrashMachineContextWrapper.h new file mode 120000 index 00000000..26df92b9 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMachineContextWrapper.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashMachineContextWrapper.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMachineContext_Apple.h b/Pods/Headers/Private/Sentry/SentryCrashMachineContext_Apple.h new file mode 120000 index 00000000..6c616b3c --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMachineContext_Apple.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext_Apple.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMemory.h b/Pods/Headers/Private/Sentry/SentryCrashMemory.h new file mode 120000 index 00000000..bcf0ca3d --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMemory.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMemory.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor.h new file mode 120000 index 00000000..2e99907b --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitorContext.h b/Pods/Headers/Private/Sentry/SentryCrashMonitorContext.h new file mode 120000 index 00000000..140d881e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitorContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitorType.h b/Pods/Headers/Private/Sentry/SentryCrashMonitorType.h new file mode 120000 index 00000000..5d3dd4d4 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitorType.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_AppState.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_AppState.h new file mode 120000 index 00000000..a04b792e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_AppState.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_CPPException.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_CPPException.h new file mode 120000 index 00000000..9573ac03 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_CPPException.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_Deadlock.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_Deadlock.h new file mode 120000 index 00000000..bb9f65e9 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_Deadlock.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_MachException.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_MachException.h new file mode 120000 index 00000000..eaa9122c --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_MachException.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_NSException.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_NSException.h new file mode 120000 index 00000000..36f2ed1f --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_NSException.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_Signal.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_Signal.h new file mode 120000 index 00000000..a3e14660 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_Signal.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_System.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_System.h new file mode 120000 index 00000000..6a271fc4 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_System.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_User.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_User.h new file mode 120000 index 00000000..44ff0b06 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_User.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashMonitor_Zombie.h b/Pods/Headers/Private/Sentry/SentryCrashMonitor_Zombie.h new file mode 120000 index 00000000..7dd9cf38 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashMonitor_Zombie.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashObjC.h b/Pods/Headers/Private/Sentry/SentryCrashObjC.h new file mode 120000 index 00000000..debcbadd --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashObjC.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjC.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashObjCApple.h b/Pods/Headers/Private/Sentry/SentryCrashObjCApple.h new file mode 120000 index 00000000..498e41c3 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashObjCApple.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjCApple.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReport.h b/Pods/Headers/Private/Sentry/SentryCrashReport.h new file mode 120000 index 00000000..b4e4f004 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReport.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashReport.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportConverter.h b/Pods/Headers/Private/Sentry/SentryCrashReportConverter.h new file mode 120000 index 00000000..3ed788b7 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportConverter.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashReportConverter.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportFields.h b/Pods/Headers/Private/Sentry/SentryCrashReportFields.h new file mode 120000 index 00000000..ce588e80 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportFields.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashReportFields.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportFilter.h b/Pods/Headers/Private/Sentry/SentryCrashReportFilter.h new file mode 120000 index 00000000..bf8b5c9c --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportFilter.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilter.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportFilterBasic.h b/Pods/Headers/Private/Sentry/SentryCrashReportFilterBasic.h new file mode 120000 index 00000000..8f548168 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportFilterBasic.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportFixer.h b/Pods/Headers/Private/Sentry/SentryCrashReportFixer.h new file mode 120000 index 00000000..3e84c86a --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportFixer.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashReportFixer.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportSink.h b/Pods/Headers/Private/Sentry/SentryCrashReportSink.h new file mode 120000 index 00000000..6c33d4ea --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportSink.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashReportSink.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportStore.h b/Pods/Headers/Private/Sentry/SentryCrashReportStore.h new file mode 120000 index 00000000..2dc056e1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportStore.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashReportStore.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportVersion.h b/Pods/Headers/Private/Sentry/SentryCrashReportVersion.h new file mode 120000 index 00000000..eefbd0f9 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportVersion.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashReportVersion.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashReportWriter.h b/Pods/Headers/Private/Sentry/SentryCrashReportWriter.h new file mode 120000 index 00000000..c0e34ce6 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashReportWriter.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashReportWriter.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashSignalInfo.h b/Pods/Headers/Private/Sentry/SentryCrashSignalInfo.h new file mode 120000 index 00000000..a506acfc --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashSignalInfo.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashStackCursor.h b/Pods/Headers/Private/Sentry/SentryCrashStackCursor.h new file mode 120000 index 00000000..1b58ac70 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashStackCursor.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashStackCursor_Backtrace.h b/Pods/Headers/Private/Sentry/SentryCrashStackCursor_Backtrace.h new file mode 120000 index 00000000..8017d229 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashStackCursor_Backtrace.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashStackCursor_MachineContext.h b/Pods/Headers/Private/Sentry/SentryCrashStackCursor_MachineContext.h new file mode 120000 index 00000000..c046cb63 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashStackCursor_MachineContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashStackCursor_SelfThread.h b/Pods/Headers/Private/Sentry/SentryCrashStackCursor_SelfThread.h new file mode 120000 index 00000000..54177525 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashStackCursor_SelfThread.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashStackEntryMapper.h b/Pods/Headers/Private/Sentry/SentryCrashStackEntryMapper.h new file mode 120000 index 00000000..cf640341 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashStackEntryMapper.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCrashStackEntryMapper.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashString.h b/Pods/Headers/Private/Sentry/SentryCrashString.h new file mode 120000 index 00000000..9104d035 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashString.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashString.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashSymbolicator.h b/Pods/Headers/Private/Sentry/SentryCrashSymbolicator.h new file mode 120000 index 00000000..ed043d9a --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashSymbolicator.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashSysCtl.h b/Pods/Headers/Private/Sentry/SentryCrashSysCtl.h new file mode 120000 index 00000000..adb5c2f7 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashSysCtl.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashSystemCapabilities.h b/Pods/Headers/Private/Sentry/SentryCrashSystemCapabilities.h new file mode 120000 index 00000000..aca5e396 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashSystemCapabilities.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/SentryCrashSystemCapabilities.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashThread.h b/Pods/Headers/Private/Sentry/SentryCrashThread.h new file mode 120000 index 00000000..f397da87 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashThread.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashThread.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashUUIDConversion.h b/Pods/Headers/Private/Sentry/SentryCrashUUIDConversion.h new file mode 120000 index 00000000..4dd57fae --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashUUIDConversion.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCrashVarArgs.h b/Pods/Headers/Private/Sentry/SentryCrashVarArgs.h new file mode 120000 index 00000000..f27eb487 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCrashVarArgs.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Reporting/Filters/Tools/SentryCrashVarArgs.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCurrentDate.h b/Pods/Headers/Private/Sentry/SentryCurrentDate.h new file mode 120000 index 00000000..2f1e4a04 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCurrentDate.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCurrentDate.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryCurrentDateProvider.h b/Pods/Headers/Private/Sentry/SentryCurrentDateProvider.h new file mode 120000 index 00000000..cc779128 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryCurrentDateProvider.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryCurrentDateProvider.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryDateUtil.h b/Pods/Headers/Private/Sentry/SentryDateUtil.h new file mode 120000 index 00000000..51dd2480 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryDateUtil.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryDateUtil.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryDebugMeta.h b/Pods/Headers/Private/Sentry/SentryDebugMeta.h new file mode 120000 index 00000000..ad85b6f0 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryDebugMeta.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryDebugMeta.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryDebugMetaBuilder.h b/Pods/Headers/Private/Sentry/SentryDebugMetaBuilder.h new file mode 120000 index 00000000..97328ab6 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryDebugMetaBuilder.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryDebugMetaBuilder.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryDefaultCurrentDateProvider.h b/Pods/Headers/Private/Sentry/SentryDefaultCurrentDateProvider.h new file mode 120000 index 00000000..39665d3f --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryDefaultCurrentDateProvider.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryDefaultCurrentDateProvider.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryDefaultRateLimits.h b/Pods/Headers/Private/Sentry/SentryDefaultRateLimits.h new file mode 120000 index 00000000..0ea9e03a --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryDefaultRateLimits.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryDefaultRateLimits.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryDefines.h b/Pods/Headers/Private/Sentry/SentryDefines.h new file mode 120000 index 00000000..d4991e20 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryDefines.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryDefines.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryDispatchQueueWrapper.h b/Pods/Headers/Private/Sentry/SentryDispatchQueueWrapper.h new file mode 120000 index 00000000..c284c93e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryDispatchQueueWrapper.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryDispatchQueueWrapper.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryDsn.h b/Pods/Headers/Private/Sentry/SentryDsn.h new file mode 120000 index 00000000..762f7385 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryDsn.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryDsn.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryEnvelope.h b/Pods/Headers/Private/Sentry/SentryEnvelope.h new file mode 120000 index 00000000..b4eaf78d --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryEnvelope.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryEnvelope.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryEnvelopeItemType.h b/Pods/Headers/Private/Sentry/SentryEnvelopeItemType.h new file mode 120000 index 00000000..aa252d5d --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryEnvelopeItemType.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryEnvelopeItemType.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryEnvelopeRateLimit.h b/Pods/Headers/Private/Sentry/SentryEnvelopeRateLimit.h new file mode 120000 index 00000000..77a7dc0e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryEnvelopeRateLimit.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryEnvelopeRateLimit.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryError.h b/Pods/Headers/Private/Sentry/SentryError.h new file mode 120000 index 00000000..b784cb8e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryError.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryError.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryEvent.h b/Pods/Headers/Private/Sentry/SentryEvent.h new file mode 120000 index 00000000..6019093a --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryEvent.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryEvent.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryException.h b/Pods/Headers/Private/Sentry/SentryException.h new file mode 120000 index 00000000..65f05347 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryException.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryException.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryFileContents.h b/Pods/Headers/Private/Sentry/SentryFileContents.h new file mode 120000 index 00000000..6f7e04d4 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryFileContents.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryFileContents.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryFileManager.h b/Pods/Headers/Private/Sentry/SentryFileManager.h new file mode 120000 index 00000000..6d0226b8 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryFileManager.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryFileManager.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryFrame.h b/Pods/Headers/Private/Sentry/SentryFrame.h new file mode 120000 index 00000000..dbe01824 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryFrame.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryFrame.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryFrameInAppLogic.h b/Pods/Headers/Private/Sentry/SentryFrameInAppLogic.h new file mode 120000 index 00000000..ca93cb69 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryFrameInAppLogic.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryFrameInAppLogic.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryFrameRemover.h b/Pods/Headers/Private/Sentry/SentryFrameRemover.h new file mode 120000 index 00000000..b7578904 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryFrameRemover.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryFrameRemover.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryGlobalEventProcessor.h b/Pods/Headers/Private/Sentry/SentryGlobalEventProcessor.h new file mode 120000 index 00000000..1429f07a --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryGlobalEventProcessor.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryGlobalEventProcessor.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryHexAddressFormatter.h b/Pods/Headers/Private/Sentry/SentryHexAddressFormatter.h new file mode 120000 index 00000000..856face1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryHexAddressFormatter.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryHexAddressFormatter.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryHook.h b/Pods/Headers/Private/Sentry/SentryHook.h new file mode 120000 index 00000000..9ce33c03 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryHook.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/SentryHook.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryHttpDateParser.h b/Pods/Headers/Private/Sentry/SentryHttpDateParser.h new file mode 120000 index 00000000..98857e49 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryHttpDateParser.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryHttpDateParser.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryHttpTransport.h b/Pods/Headers/Private/Sentry/SentryHttpTransport.h new file mode 120000 index 00000000..ef58c0d9 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryHttpTransport.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryHttpTransport.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryHub+Private.h b/Pods/Headers/Private/Sentry/SentryHub+Private.h new file mode 120000 index 00000000..893a2d08 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryHub+Private.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryHub+Private.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryHub.h b/Pods/Headers/Private/Sentry/SentryHub.h new file mode 120000 index 00000000..8d49587c --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryHub.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryHub.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryId.h b/Pods/Headers/Private/Sentry/SentryId.h new file mode 120000 index 00000000..2a27ba06 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryId.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryId.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryInstallation.h b/Pods/Headers/Private/Sentry/SentryInstallation.h new file mode 120000 index 00000000..cae1736c --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryInstallation.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryInstallation.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryIntegrationProtocol.h b/Pods/Headers/Private/Sentry/SentryIntegrationProtocol.h new file mode 120000 index 00000000..2f3195c6 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryIntegrationProtocol.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryIntegrationProtocol.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryInternalNotificationNames.h b/Pods/Headers/Private/Sentry/SentryInternalNotificationNames.h new file mode 120000 index 00000000..10911862 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryInternalNotificationNames.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryInternalNotificationNames.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryLevelMapper.h b/Pods/Headers/Private/Sentry/SentryLevelMapper.h new file mode 120000 index 00000000..eed4cf9c --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryLevelMapper.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryLevelMapper.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryLog.h b/Pods/Headers/Private/Sentry/SentryLog.h new file mode 120000 index 00000000..c3aa3958 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryLog.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryLog.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryLogOutput.h b/Pods/Headers/Private/Sentry/SentryLogOutput.h new file mode 120000 index 00000000..756826b1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryLogOutput.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryLogOutput.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryMechanism.h b/Pods/Headers/Private/Sentry/SentryMechanism.h new file mode 120000 index 00000000..5888c7c5 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryMechanism.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryMechanism.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryMechanismMeta.h b/Pods/Headers/Private/Sentry/SentryMechanismMeta.h new file mode 120000 index 00000000..e9983dcf --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryMechanismMeta.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryMechanismMeta.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryMessage.h b/Pods/Headers/Private/Sentry/SentryMessage.h new file mode 120000 index 00000000..598f02e7 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryMessage.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryMessage.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryMeta.h b/Pods/Headers/Private/Sentry/SentryMeta.h new file mode 120000 index 00000000..54145c4c --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryMeta.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryMeta.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryMigrateSessionInit.h b/Pods/Headers/Private/Sentry/SentryMigrateSessionInit.h new file mode 120000 index 00000000..bb2dddbc --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryMigrateSessionInit.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryMigrateSessionInit.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryNSError.h b/Pods/Headers/Private/Sentry/SentryNSError.h new file mode 120000 index 00000000..b67e839e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryNSError.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryNSError.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryNSURLRequest.h b/Pods/Headers/Private/Sentry/SentryNSURLRequest.h new file mode 120000 index 00000000..2f6f1385 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryNSURLRequest.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryNSURLRequest.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryOptions.h b/Pods/Headers/Private/Sentry/SentryOptions.h new file mode 120000 index 00000000..06fb4264 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryOptions.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryOptions.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryOutOfMemoryLogic.h b/Pods/Headers/Private/Sentry/SentryOutOfMemoryLogic.h new file mode 120000 index 00000000..f10a599d --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryOutOfMemoryLogic.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryOutOfMemoryLogic.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryOutOfMemoryTracker.h b/Pods/Headers/Private/Sentry/SentryOutOfMemoryTracker.h new file mode 120000 index 00000000..3e031ca7 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryOutOfMemoryTracker.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryOutOfMemoryTracker.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryOutOfMemoryTrackingIntegration.h b/Pods/Headers/Private/Sentry/SentryOutOfMemoryTrackingIntegration.h new file mode 120000 index 00000000..a83888de --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryOutOfMemoryTrackingIntegration.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryOutOfMemoryTrackingIntegration.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryQueueableRequestManager.h b/Pods/Headers/Private/Sentry/SentryQueueableRequestManager.h new file mode 120000 index 00000000..d9b35941 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryQueueableRequestManager.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryQueueableRequestManager.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryRandom.h b/Pods/Headers/Private/Sentry/SentryRandom.h new file mode 120000 index 00000000..58abf7db --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryRandom.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryRandom.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryRateLimitCategory.h b/Pods/Headers/Private/Sentry/SentryRateLimitCategory.h new file mode 120000 index 00000000..3b458f47 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryRateLimitCategory.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryRateLimitCategory.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryRateLimitCategoryMapper.h b/Pods/Headers/Private/Sentry/SentryRateLimitCategoryMapper.h new file mode 120000 index 00000000..7d8edb6b --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryRateLimitCategoryMapper.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryRateLimitCategoryMapper.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryRateLimitParser.h b/Pods/Headers/Private/Sentry/SentryRateLimitParser.h new file mode 120000 index 00000000..60693240 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryRateLimitParser.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryRateLimitParser.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryRateLimits.h b/Pods/Headers/Private/Sentry/SentryRateLimits.h new file mode 120000 index 00000000..e86c9ce5 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryRateLimits.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryRateLimits.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryRequestManager.h b/Pods/Headers/Private/Sentry/SentryRequestManager.h new file mode 120000 index 00000000..d44c08d2 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryRequestManager.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryRequestManager.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryRequestOperation.h b/Pods/Headers/Private/Sentry/SentryRequestOperation.h new file mode 120000 index 00000000..d4a751ea --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryRequestOperation.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryRequestOperation.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryRetryAfterHeaderParser.h b/Pods/Headers/Private/Sentry/SentryRetryAfterHeaderParser.h new file mode 120000 index 00000000..fdf18ff1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryRetryAfterHeaderParser.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryRetryAfterHeaderParser.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySDK+Private.h b/Pods/Headers/Private/Sentry/SentrySDK+Private.h new file mode 120000 index 00000000..992a4002 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySDK+Private.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentrySDK+Private.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySDK.h b/Pods/Headers/Private/Sentry/SentrySDK.h new file mode 120000 index 00000000..71d13c1d --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySDK.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySDK.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySampleDecision.h b/Pods/Headers/Private/Sentry/SentrySampleDecision.h new file mode 120000 index 00000000..1c55fcb1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySampleDecision.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySampleDecision.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySamplingContext.h b/Pods/Headers/Private/Sentry/SentrySamplingContext.h new file mode 120000 index 00000000..04d26bca --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySamplingContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySamplingContext.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryScope+Private.h b/Pods/Headers/Private/Sentry/SentryScope+Private.h new file mode 120000 index 00000000..82fa3e44 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryScope+Private.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryScope+Private.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryScope.h b/Pods/Headers/Private/Sentry/SentryScope.h new file mode 120000 index 00000000..368380e1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryScope.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryScope.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySdkInfo.h b/Pods/Headers/Private/Sentry/SentrySdkInfo.h new file mode 120000 index 00000000..5211f54e --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySdkInfo.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySdkInfo.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySerializable.h b/Pods/Headers/Private/Sentry/SentrySerializable.h new file mode 120000 index 00000000..962393b9 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySerializable.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySerializable.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySerialization.h b/Pods/Headers/Private/Sentry/SentrySerialization.h new file mode 120000 index 00000000..7a5f25c2 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySerialization.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentrySerialization.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySession+Private.h b/Pods/Headers/Private/Sentry/SentrySession+Private.h new file mode 120000 index 00000000..85792f3d --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySession+Private.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentrySession+Private.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySession.h b/Pods/Headers/Private/Sentry/SentrySession.h new file mode 120000 index 00000000..b7e3a6ab --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySession.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySession.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySessionCrashedHandler.h b/Pods/Headers/Private/Sentry/SentrySessionCrashedHandler.h new file mode 120000 index 00000000..644d9ab0 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySessionCrashedHandler.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentrySessionCrashedHandler.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySessionTracker.h b/Pods/Headers/Private/Sentry/SentrySessionTracker.h new file mode 120000 index 00000000..0aa6f5b0 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySessionTracker.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentrySessionTracker.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySpan.h b/Pods/Headers/Private/Sentry/SentrySpan.h new file mode 120000 index 00000000..5482f3ab --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySpan.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentrySpan.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySpanContext.h b/Pods/Headers/Private/Sentry/SentrySpanContext.h new file mode 120000 index 00000000..80510d0b --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySpanContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySpanContext.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySpanId.h b/Pods/Headers/Private/Sentry/SentrySpanId.h new file mode 120000 index 00000000..d2ccd500 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySpanId.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySpanId.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySpanProtocol.h b/Pods/Headers/Private/Sentry/SentrySpanProtocol.h new file mode 120000 index 00000000..ed191c6f --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySpanProtocol.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySpanProtocol.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySpanStatus.h b/Pods/Headers/Private/Sentry/SentrySpanStatus.h new file mode 120000 index 00000000..1bce01f1 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySpanStatus.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySpanStatus.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryStacktrace.h b/Pods/Headers/Private/Sentry/SentryStacktrace.h new file mode 120000 index 00000000..125596fb --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryStacktrace.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryStacktrace.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryStacktraceBuilder.h b/Pods/Headers/Private/Sentry/SentryStacktraceBuilder.h new file mode 120000 index 00000000..fc942dda --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryStacktraceBuilder.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryStacktraceBuilder.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySwizzle.h b/Pods/Headers/Private/Sentry/SentrySwizzle.h new file mode 120000 index 00000000..9f915dd8 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySwizzle.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentrySwizzle.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentrySystemEventsBreadcrumbs.h b/Pods/Headers/Private/Sentry/SentrySystemEventsBreadcrumbs.h new file mode 120000 index 00000000..ffb0dc99 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentrySystemEventsBreadcrumbs.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentrySystemEventsBreadcrumbs.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryThread.h b/Pods/Headers/Private/Sentry/SentryThread.h new file mode 120000 index 00000000..275b2173 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryThread.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryThread.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryThreadInspector.h b/Pods/Headers/Private/Sentry/SentryThreadInspector.h new file mode 120000 index 00000000..b96a746a --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryThreadInspector.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryThreadInspector.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryTracer.h b/Pods/Headers/Private/Sentry/SentryTracer.h new file mode 120000 index 00000000..483e3c33 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryTracer.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryTracer.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryTransaction.h b/Pods/Headers/Private/Sentry/SentryTransaction.h new file mode 120000 index 00000000..909ace10 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryTransaction.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryTransaction.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryTransactionContext.h b/Pods/Headers/Private/Sentry/SentryTransactionContext.h new file mode 120000 index 00000000..358d10b0 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryTransactionContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryTransactionContext.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryTransport.h b/Pods/Headers/Private/Sentry/SentryTransport.h new file mode 120000 index 00000000..7f56cc95 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryTransport.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryTransport.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryTransportFactory.h b/Pods/Headers/Private/Sentry/SentryTransportFactory.h new file mode 120000 index 00000000..80054d7b --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryTransportFactory.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/SentryTransportFactory.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryUser.h b/Pods/Headers/Private/Sentry/SentryUser.h new file mode 120000 index 00000000..366b1025 --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryUser.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryUser.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/SentryUserFeedback.h b/Pods/Headers/Private/Sentry/SentryUserFeedback.h new file mode 120000 index 00000000..101673ab --- /dev/null +++ b/Pods/Headers/Private/Sentry/SentryUserFeedback.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryUserFeedback.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/TracesSampler.h b/Pods/Headers/Private/Sentry/TracesSampler.h new file mode 120000 index 00000000..eeee56d6 --- /dev/null +++ b/Pods/Headers/Private/Sentry/TracesSampler.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/include/TracesSampler.h \ No newline at end of file diff --git a/Pods/Headers/Private/Sentry/fishhook.h b/Pods/Headers/Private/Sentry/fishhook.h new file mode 120000 index 00000000..006c63d6 --- /dev/null +++ b/Pods/Headers/Private/Sentry/fishhook.h @@ -0,0 +1 @@ +../../../Sentry/Sources/SentryCrash/Recording/Tools/fishhook.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/Sentry.h b/Pods/Headers/Public/Sentry/Sentry.h new file mode 120000 index 00000000..b0462a81 --- /dev/null +++ b/Pods/Headers/Public/Sentry/Sentry.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/Sentry.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryAttachment.h b/Pods/Headers/Public/Sentry/SentryAttachment.h new file mode 120000 index 00000000..92a93508 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryAttachment.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryAttachment.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryBreadcrumb.h b/Pods/Headers/Public/Sentry/SentryBreadcrumb.h new file mode 120000 index 00000000..ff283c07 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryBreadcrumb.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryBreadcrumb.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryClient.h b/Pods/Headers/Public/Sentry/SentryClient.h new file mode 120000 index 00000000..d3704d08 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryClient.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryClient.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryCrashExceptionApplication.h b/Pods/Headers/Public/Sentry/SentryCrashExceptionApplication.h new file mode 120000 index 00000000..1e8afb6f --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryCrashExceptionApplication.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryCrashExceptionApplication.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryDebugMeta.h b/Pods/Headers/Public/Sentry/SentryDebugMeta.h new file mode 120000 index 00000000..ad85b6f0 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryDebugMeta.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryDebugMeta.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryDefines.h b/Pods/Headers/Public/Sentry/SentryDefines.h new file mode 120000 index 00000000..d4991e20 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryDefines.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryDefines.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryDsn.h b/Pods/Headers/Public/Sentry/SentryDsn.h new file mode 120000 index 00000000..762f7385 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryDsn.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryDsn.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryEnvelope.h b/Pods/Headers/Public/Sentry/SentryEnvelope.h new file mode 120000 index 00000000..b4eaf78d --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryEnvelope.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryEnvelope.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryEnvelopeItemType.h b/Pods/Headers/Public/Sentry/SentryEnvelopeItemType.h new file mode 120000 index 00000000..aa252d5d --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryEnvelopeItemType.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryEnvelopeItemType.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryError.h b/Pods/Headers/Public/Sentry/SentryError.h new file mode 120000 index 00000000..b784cb8e --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryError.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryError.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryEvent.h b/Pods/Headers/Public/Sentry/SentryEvent.h new file mode 120000 index 00000000..6019093a --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryEvent.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryEvent.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryException.h b/Pods/Headers/Public/Sentry/SentryException.h new file mode 120000 index 00000000..65f05347 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryException.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryException.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryFrame.h b/Pods/Headers/Public/Sentry/SentryFrame.h new file mode 120000 index 00000000..dbe01824 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryFrame.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryFrame.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryHub.h b/Pods/Headers/Public/Sentry/SentryHub.h new file mode 120000 index 00000000..8d49587c --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryHub.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryHub.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryId.h b/Pods/Headers/Public/Sentry/SentryId.h new file mode 120000 index 00000000..2a27ba06 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryId.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryId.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryIntegrationProtocol.h b/Pods/Headers/Public/Sentry/SentryIntegrationProtocol.h new file mode 120000 index 00000000..2f3195c6 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryIntegrationProtocol.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryIntegrationProtocol.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryMechanism.h b/Pods/Headers/Public/Sentry/SentryMechanism.h new file mode 120000 index 00000000..5888c7c5 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryMechanism.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryMechanism.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryMechanismMeta.h b/Pods/Headers/Public/Sentry/SentryMechanismMeta.h new file mode 120000 index 00000000..e9983dcf --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryMechanismMeta.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryMechanismMeta.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryMessage.h b/Pods/Headers/Public/Sentry/SentryMessage.h new file mode 120000 index 00000000..598f02e7 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryMessage.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryMessage.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryNSError.h b/Pods/Headers/Public/Sentry/SentryNSError.h new file mode 120000 index 00000000..b67e839e --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryNSError.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryNSError.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryOptions.h b/Pods/Headers/Public/Sentry/SentryOptions.h new file mode 120000 index 00000000..06fb4264 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryOptions.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryOptions.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySDK.h b/Pods/Headers/Public/Sentry/SentrySDK.h new file mode 120000 index 00000000..71d13c1d --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySDK.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySDK.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySampleDecision.h b/Pods/Headers/Public/Sentry/SentrySampleDecision.h new file mode 120000 index 00000000..1c55fcb1 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySampleDecision.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySampleDecision.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySamplingContext.h b/Pods/Headers/Public/Sentry/SentrySamplingContext.h new file mode 120000 index 00000000..04d26bca --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySamplingContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySamplingContext.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryScope.h b/Pods/Headers/Public/Sentry/SentryScope.h new file mode 120000 index 00000000..368380e1 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryScope.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryScope.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySdkInfo.h b/Pods/Headers/Public/Sentry/SentrySdkInfo.h new file mode 120000 index 00000000..5211f54e --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySdkInfo.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySdkInfo.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySerializable.h b/Pods/Headers/Public/Sentry/SentrySerializable.h new file mode 120000 index 00000000..962393b9 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySerializable.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySerializable.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySession.h b/Pods/Headers/Public/Sentry/SentrySession.h new file mode 120000 index 00000000..b7e3a6ab --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySession.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySession.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySpanContext.h b/Pods/Headers/Public/Sentry/SentrySpanContext.h new file mode 120000 index 00000000..80510d0b --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySpanContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySpanContext.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySpanId.h b/Pods/Headers/Public/Sentry/SentrySpanId.h new file mode 120000 index 00000000..d2ccd500 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySpanId.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySpanId.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySpanProtocol.h b/Pods/Headers/Public/Sentry/SentrySpanProtocol.h new file mode 120000 index 00000000..ed191c6f --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySpanProtocol.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySpanProtocol.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentrySpanStatus.h b/Pods/Headers/Public/Sentry/SentrySpanStatus.h new file mode 120000 index 00000000..1bce01f1 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentrySpanStatus.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentrySpanStatus.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryStacktrace.h b/Pods/Headers/Public/Sentry/SentryStacktrace.h new file mode 120000 index 00000000..125596fb --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryStacktrace.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryStacktrace.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryThread.h b/Pods/Headers/Public/Sentry/SentryThread.h new file mode 120000 index 00000000..275b2173 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryThread.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryThread.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryTransactionContext.h b/Pods/Headers/Public/Sentry/SentryTransactionContext.h new file mode 120000 index 00000000..358d10b0 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryTransactionContext.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryTransactionContext.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryUser.h b/Pods/Headers/Public/Sentry/SentryUser.h new file mode 120000 index 00000000..366b1025 --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryUser.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryUser.h \ No newline at end of file diff --git a/Pods/Headers/Public/Sentry/SentryUserFeedback.h b/Pods/Headers/Public/Sentry/SentryUserFeedback.h new file mode 120000 index 00000000..101673ab --- /dev/null +++ b/Pods/Headers/Public/Sentry/SentryUserFeedback.h @@ -0,0 +1 @@ +../../../Sentry/Sources/Sentry/Public/SentryUserFeedback.h \ No newline at end of file diff --git a/Pods/Local Podspecs/Sentry.podspec.json b/Pods/Local Podspecs/Sentry.podspec.json new file mode 100644 index 00000000..ee2eca0a --- /dev/null +++ b/Pods/Local Podspecs/Sentry.podspec.json @@ -0,0 +1,41 @@ +{ + "name": "Sentry", + "version": "7.0.0-beta.0", + "summary": "Sentry client for cocoa", + "homepage": "https://github.com/getsentry/sentry-cocoa", + "license": "mit", + "authors": "Sentry", + "source": { + "git": "https://github.com/getsentry/sentry-cocoa.git", + "tag": "7.0.0-beta.0" + }, + "platforms": { + "ios": "9.0", + "osx": "10.10", + "tvos": "9.0", + "watchos": "2.0" + }, + "module_name": "Sentry", + "requires_arc": true, + "frameworks": "Foundation", + "libraries": [ + "z", + "c++" + ], + "xcconfig": { + "GCC_ENABLE_CPP_EXCEPTIONS": "YES" + }, + "default_subspecs": [ + "Core" + ], + "subspecs": [ + { + "name": "Core", + "source_files": [ + "Sources/Sentry/**/*.{h,m}", + "Sources/SentryCrash/**/*.{h,m,mm,c,cpp}" + ], + "public_header_files": "Sources/Sentry/Public/*.h" + } + ] +} diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index c02fe6c8..5681257e 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -12,6 +12,9 @@ PODS: - SDWebImage (5.0.6): - SDWebImage/Core (= 5.0.6) - SDWebImage/Core (5.0.6) + - Sentry (7.0.0-beta.0): + - Sentry/Core (= 7.0.0-beta.0) + - Sentry/Core (7.0.0-beta.0) DEPENDENCIES: - EasyMapping @@ -21,6 +24,7 @@ DEPENDENCIES: - "NSPopover+MISSINGBackgroundView" - OCMock (~> 3.4.3) - SDWebImage (~> 5.0.6) + - Sentry (from `https://github.com/getsentry/sentry-cocoa.git`) SPEC REPOS: https://github.com/CocoaPods/Specs.git: @@ -33,6 +37,15 @@ SPEC REPOS: - Mixpanel - "NSPopover+MISSINGBackgroundView" +EXTERNAL SOURCES: + Sentry: + :git: https://github.com/getsentry/sentry-cocoa.git + +CHECKOUT OPTIONS: + Sentry: + :commit: cd561c7b8f5e0396f3510600167c17b2c076deed + :git: https://github.com/getsentry/sentry-cocoa.git + SPEC CHECKSUMS: EasyMapping: 52860151d1df5db1b245b1d1568e2e05a27a4689 Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 @@ -41,7 +54,8 @@ SPEC CHECKSUMS: "NSPopover+MISSINGBackgroundView": 06a134ea85280a8f0436c9c99fa18400ae84cf15 OCMock: 43565190abc78977ad44a61c0d20d7f0784d35ab SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 + Sentry: 542abd1868a121f29cd2303ac7cf78000e3f797c -PODFILE CHECKSUM: 40817729a4f63b60420d73a810dea5439b97fa67 +PODFILE CHECKSUM: 79ffa78a333106e69ea5528d095b885b05600a88 -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.1 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 5413f59d..149a197b 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,993 +7,1970 @@ objects = { /* Begin PBXBuildFile section */ - 00301FABA708E07673968C6E9F9685EE /* SDImageAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D08CFD0ACE4C85B21B2BFE8F037E58E /* SDImageAssetManager.m */; }; - 007C778C9961B07D41E4CF1C92B1FCA6 /* EKMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C3CBC28B037AB6A9DBB7C58473725CF /* EKMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0114FB20C311C29C8494010970C7E44E /* UIColor+HexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BB323D9D7D7016C8AD08C2E3E150D08 /* UIColor+HexString.m */; }; - 02025BF71C9F2C50DFAAE14236584E10 /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 570A465B0497E83886347A5D4E94102B /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 02157386A058474A315E1A290585944D /* SDImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = D8E7588C6AFE9808A46E814936CA84E2 /* SDImageLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 027F3E9665A51CB5972FE41A5569A066 /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = DB0F4C1F56DCCAAEECFB8F0FA1242FBE /* SDmetamacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 03C321596EC119A1F8EF4E988752270B /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF9D2408F0179139A6EE67D8C782CADB /* Deprecated.swift */; }; - 04DDC981AAD7F73EFDFD96393C227827 /* EXPUnsupportedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E5DA0F73EA2D5964035418953C3748B /* EXPUnsupportedObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 04E724A97339965ACA4E5D60226DA001 /* EXPMatchers+beIdenticalTo.m in Sources */ = {isa = PBXBuildFile; fileRef = EFCD5E8499D6681EF43BD1B9686D12B6 /* EXPMatchers+beIdenticalTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 0514C2AC6F2ABF04CFBEB20EDDDA2C50 /* OCMRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 7088AC11AE8AF76D0ACEC401EF65AB5F /* OCMRecorder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 051D4B5709A6257B6F79D54D9139E812 /* EXPMatchers+beGreaterThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 708F9116E82E223F9775AA96F1EF8AB8 /* EXPMatchers+beGreaterThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 071608B620AAA9AD806BEC14D6721DE3 /* NSData+ImageContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = EF98DF418E129E42ACB5735BCF2BF2DA /* NSData+ImageContentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0726A08EB130C4FCCE7A8B14C8F35A02 /* EasyMapping-tvOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0FB84539B3D19B7FFC818161CE30CFF9 /* EasyMapping-tvOS-dummy.m */; }; - 07968CFA4E57CEBC4DF23D2A15DE388E /* Mixpanel-tvOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C54643A14053405BDB4037BC6923EEB /* Mixpanel-tvOS-dummy.m */; }; - 07E5854E45B4F185DAE8FDC36C94EECE /* EXPMatchers+beLessThanOrEqualTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A45A1DA22EEDF7CB3E3C2FBF2C94C67 /* EXPMatchers+beLessThanOrEqualTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 08972BEC745F3895C5FE98732BB0E646 /* EXPMatcherHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = FD36DF9DEA7AAFADFD9A80C290313970 /* EXPMatcherHelpers.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 09993F0619B95EFC4E4E62BF50022D2E /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90B1A399F5283F7832DC8F712C6C446 /* Delegate.swift */; }; - 0A79813D171A8D87C2D2E9E6B005C18A /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A37018142E46FB872419EF3966E8ECC /* ImageDownloader.swift */; }; - 0B9729009B52B1F83A03B398B43D2AB8 /* SDAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A9D899A31143DE07964B6EBB4EE2084 /* SDAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0DB4433111B4ED4C8F2F9C32888A9F27 /* GIFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5657918E85BD137F9793730413845AE0 /* GIFAnimatedImage.swift */; }; - 0E66A0F36DD725E82041A51F593EA534 /* EXPMatchers+conformTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 38C45A85D39A9B8B7ABE3423AF6C7262 /* EXPMatchers+conformTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0F72B24EF424B11E17F35B5E63DF856A /* NSPopover+MISSINGBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = 38F1E72982CFDB8599746F32A1F0AE2B /* NSPopover+MISSINGBackgroundView.m */; }; - 0FE351CF21E5FB05948FCA25DA714E20 /* OCMBlockCaller.h in Headers */ = {isa = PBXBuildFile; fileRef = 96C752DC496BB2334FBC711B6DDD2A5A /* OCMBlockCaller.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1012286B28D43DAAFC7BF5AECD94DDA3 /* EasyMapping-macOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 583B47951CD7CBE1EA97C970D494BBC4 /* EasyMapping-macOS-dummy.m */; }; - 103616B200DAE8A3AA9EC3AF8A1A0DBD /* SDDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 14A88043724A1C2FF5276F579A74A83A /* SDDiskCache.m */; }; - 1222560B913CB9C9C0D14221D02C8306 /* EXPMatchers+beTruthy.m in Sources */ = {isa = PBXBuildFile; fileRef = BC7405D5402B6BFF2D28CD1EC298E665 /* EXPMatchers+beTruthy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 14122D6356629DE6958BF7E2D2F10328 /* OCMInvocationStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 43338F28496A583931F32BF4E684495B /* OCMInvocationStub.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 14726DFA1A1C8CD6D90D482A44DDF487 /* UIImage+MultiFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = A8AF61BDDA49BA0BC455083325050B9F /* UIImage+MultiFormat.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 14C7625735FDF34CB497D8AA8DEFFD4D /* OCMStubRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = C2DFCA49B2CE55091A7252F70073E4D9 /* OCMStubRecorder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 159F81DC613185E5D038DECF196C9352 /* ImageDataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE2C372744DEFF3EFC56881622D25937 /* ImageDataProcessor.swift */; }; - 163CA6B366B2EEB01CB5F00D1759BF8C /* NSMethodSignature+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D5A6014B717BFC26FF621490622E081 /* NSMethodSignature+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1655589080B07484CFC0959B2CC2689B /* OCMPassByRefSetter.m in Sources */ = {isa = PBXBuildFile; fileRef = F51DC93A2A3D54A2D4F61A23822537CE /* OCMPassByRefSetter.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 16D119900A2EFF37CC7D5737A761290D /* EKObjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = EB4E0393C303A359234E843EF87DF639 /* EKObjectModel.m */; }; - 17B47C54800CAD288E8A16767F283101 /* OCClassMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 475B134AC1BCAE5FB01505BBA2261DE5 /* OCClassMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 18A81E582E9A975270C6E32EA47EB8DE /* EKManagedObjectMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 06603B8AC9B141505673852488A83DE1 /* EKManagedObjectMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 19B8A147AE34E2B5E59F104313720636 /* MixpanelGroupPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F8C2BCD9F1BBFAAB59F270D2B46CF7FC /* MixpanelGroupPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1A39A8AA098EDD950FCD1C5C7490C53E /* Mixpanel-macOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D63ED8C5E87F5585A4A167D6E5FB9767 /* Mixpanel-macOS-dummy.m */; }; - 1CE288226DA4D5164FDE93288F20616B /* EXPMatchers+beNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 318683794EA84AA46B81F67D9B6A5C41 /* EXPMatchers+beNil.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 1D287EFBD7E47AAC1F2E7EBA359EAC94 /* NSPopover+MISSINGBackgroundView.h in Headers */ = {isa = PBXBuildFile; fileRef = A31D86646D8CE32EACAB67E8117537C0 /* NSPopover+MISSINGBackgroundView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1DD728FE53DADBA98A838C0F260E89EE /* OCMIndirectReturnValueProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DCC4C3FF9A74FFBEEB2AD03F66E76B /* OCMIndirectReturnValueProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1DF5ECB76476BA3197B6C803B7F9A588 /* AuthenticationChallengeResponsable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DFE2561372FBEC8433424B1A3A78FAB /* AuthenticationChallengeResponsable.swift */; }; - 1E0138011438F599DD914AF8FA9D75B0 /* MixpanelGroupPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F8C2BCD9F1BBFAAB59F270D2B46CF7FC /* MixpanelGroupPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1E58E12AEF469FD04EE76BA0CF146635 /* EKManagedObjectMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 72B0ED45761C3EADB29E9166055000A4 /* EKManagedObjectMapper.m */; }; - 1F250882122AB915F3FD7B0CF2F5EB9B /* SDImageGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 09C7E99EBC284F25C7F8ADED9BFDCB12 /* SDImageGraphics.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1F3315414DEC5158097B9B9A54ECE5E0 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29266D803785F362E1AB4EEACA447597 /* Box.swift */; }; - 2010039F5D1F5F4AB05D0C106D527D5D /* EKObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = EF50D0E3C285699A5C23F1433D765799 /* EKObjectMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 211A21A6B25A968B0632C27A984C273E /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0AFA15C417FF566E42E3944E9CA79B6 /* UIButton+Kingfisher.swift */; }; - 21D97B29CD24881CDB275150FFACB46C /* EXPMatchers+raiseWithReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 31AC3F6479D957A7F4E7816F61098F4A /* EXPMatchers+raiseWithReason.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 225460728C5092E4E08968652684DD94 /* OCObserverMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 64B36E4A5223DC3E8BA26A6EEB6B2779 /* OCObserverMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 22ECA059E65D73DA50BDB13FCCCF3286 /* EKManagedObjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 249B7DEFAAD79ED621BF410C85E4E76A /* EKManagedObjectModel.m */; }; - 235BB46399C919E853BD78A4DB20FAE8 /* SDWebImageDownloaderConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = F2F4BAD2957BC72E97702E11DDD7C68F /* SDWebImageDownloaderConfig.m */; }; - 23910BE384DC89AD2F8F011EF9847609 /* MixpanelPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C5CEDC685B0DAF949C106E84D43A94C /* MixpanelPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 24037CD96B3797AC808840774B5A1B3D /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A77DFF172A3A9B3729D9A8DDA0481D /* ImageModifier.swift */; }; - 246BAB24CF6BFE7344492720C2B3B118 /* SDImageCacheDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = ECA18B43D913EC3A721AAC261D96C6C7 /* SDImageCacheDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2612A3ED4E1D25EF47797B1CE18E69C2 /* OCMArg.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B20C9C2696FB4B6D8468F8C0CA32447 /* OCMArg.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 26340C119D8DC11C5D0A66D471895277 /* NSDateFormatter+EasyMappingAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = AAEDA914FE1738DB4662140B337F1253 /* NSDateFormatter+EasyMappingAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 26656B2A7E2D85C40761063B8E8B13F3 /* EKRelationshipMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BFF7D460EC190F4EF6ED180A3017FC0 /* EKRelationshipMapping.m */; }; - 26E33CBCA823C72C51357582994E746C /* EXPMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C0C745CE85F9303B8FFDAC722E056D0 /* EXPMatcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2700518F3FDFB549DA3A258448FA4198 /* SDAnimatedImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CB305224A079CA6B534CB5DA4136DC6 /* SDAnimatedImageRep.m */; }; - 27795A61A33C0A1A0EE7BC1099284DA5 /* SDImageCacheDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = AB955BF0D2B4CEC905C17CFD967F487E /* SDImageCacheDefine.m */; }; - 28886A3C19965402C2DBDAEBF7E6D0EB /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FB273327E44E351B5D4832E76556BF /* ImageTransition.swift */; }; - 293358E44E368F842BD4203919EBDFB7 /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2A17A5B37C3FE1B72A0FA6216116FBC /* MemoryStorage.swift */; }; - 295E07FCB2E9A427323FE2A0D404EF7C /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C241A712E068D87A38E56EF0F0DEB5DB /* KingfisherOptionsInfo.swift */; }; - 29FDD7D64DD97DC7C341E1450BED0BB0 /* MixpanelPeople.m in Sources */ = {isa = PBXBuildFile; fileRef = BAED2AAE5E9EA784319F20AD830C8A32 /* MixpanelPeople.m */; }; - 2A83F376A90E8DAA9A28D2AEA8E1CC87 /* EKObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = EF50D0E3C285699A5C23F1433D765799 /* EKObjectMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2B28795761CA8E052BC46D60C69DF0F0 /* MixpanelPeople.h in Headers */ = {isa = PBXBuildFile; fileRef = CE8F4F22CA4D6315D5E43C50269C56E5 /* MixpanelPeople.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2B8DBBD0B12779D9C62B30D8D30BA557 /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C51171701AD5DE91435B7C6FD44F6D03 /* SDImageCache.m */; }; - 2BDEDB0CFA0B2BC566A697B3D47FA60C /* SDWebImageError.h in Headers */ = {isa = PBXBuildFile; fileRef = F636E0DDE0B197D611D4A55CAA456E8A /* SDWebImageError.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2D5858A78F99A1196B5416C63B18F8AA /* EXPMatchers+haveCountOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 5765F80701F6F392447C2ABA53BCD83D /* EXPMatchers+haveCountOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2E7E23F3948479C7324DEBEF52AC88C9 /* OCMExceptionReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A2EC3E9C1B6EA6971044D90C040768F /* OCMExceptionReturnValueProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 2EE6DC6F9610EE4F4C947170DC4D194E /* SDImageGIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D823CF7CA5CAC63795CA9BBD5473A44 /* SDImageGIFCoder.m */; }; - 2F004A303B65F61BF5955637C1D0348A /* SDAsyncBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 22D2D345016F9C053B3D1566570DA5EC /* SDAsyncBlockOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2F197C91E76D2335F5FED44C3DFEFAAC /* OCMObserverRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A0B00C0866927A55EB7CF92B97DBEA1 /* OCMObserverRecorder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2F747801DA2AFDF9E1069ACCC4AAB343 /* OCProtocolMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C2868DF29A9449DC2CB6512DC6F2458 /* OCProtocolMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 2FEC1C3CEE441535210ECFDECB448F93 /* EKManagedObjectMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 72B0ED45761C3EADB29E9166055000A4 /* EKManagedObjectMapper.m */; }; - 3010F2355B89399CD23D206AA0618EE5 /* OCMConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 6551499803C2FE69FD6CA4FB03E5FEE6 /* OCMConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3015CA46040CF18E0F71602202C29338 /* SDImageCachesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B77606847A2016C77AD6833DC877F24D /* SDImageCachesManager.m */; }; - 306CE82B21363D3A2BE5791B0441F22C /* EXPMatchers+beKindOf.h in Headers */ = {isa = PBXBuildFile; fileRef = E50EC90DBAC89E8993831BC6DC782C31 /* EXPMatchers+beKindOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 30FB698D984E3201F70BC6809D5DA022 /* OCProtocolMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = B49D6160F7105005451C92A516BDF8A3 /* OCProtocolMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3170D006F584356009EC14D9AEBD6227 /* EKObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 83490DAFF67A0197CFB5F511B3FE126F /* EKObjectMapping.m */; }; - 32BA8E1007096A8E8D09AB22CFC54EDB /* UIImage+Metadata.m in Sources */ = {isa = PBXBuildFile; fileRef = B777B3F9C209D8C8FCDE4A8CD995CF28 /* UIImage+Metadata.m */; }; - 332F7401BFB8CA9CF20EDA92B99E4554 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7771685DCCEB9E674423E98EFC435C /* Placeholder.swift */; }; - 3544268F1900FEA515469308E34B5843 /* NSNotificationCenter+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = E64B5C4A3967E3452D518761D1B3B356 /* NSNotificationCenter+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3726CD36BF4080EE1145EC822AA6BF4C /* EXPMatchers+match.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F0E14AADA908BBB95E09797A0968416 /* EXPMatchers+match.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 38D46DB9704C8E2658ADCC67FF846440 /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D00809841220351032F8DECD98C2663 /* SDWebImageCompat.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 38F31B524B46F859887154AAB4E659AB /* NSPopover+MISSINGBackgroundView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 49424D224EA68C64A3D1A8ED64880769 /* NSPopover+MISSINGBackgroundView-dummy.m */; }; - 3923D7BFA8E5EB8D7153F94931556FAC /* OCMInvocationMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 729E44DF9F35A91C782042717748FC55 /* OCMInvocationMatcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 3933A57238E726E8FB97C695F18B8B0D /* OCMArg.m in Sources */ = {isa = PBXBuildFile; fileRef = CF60C676F1FF87B5008152CBE76B8114 /* OCMArg.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 39DEE11CF63642BF01433A0CEA2D0070 /* OCPartialMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A37F4CA923DD13D2E2820A08C0F334FD /* OCPartialMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3A20B0B018A3ACBD288A530E01CCA61A /* NSMethodSignature+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B08140437A792EA7441A031763E63BD5 /* NSMethodSignature+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 3A73912B0BE0281F3DD177F3D361DCA2 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D4CAD6A25521E9242F03EE13302FB7A /* UIButton+WebCache.m */; }; - 3A90B8CAC14516118DD2B9F045FAD7D7 /* EKSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E042C755F61BFCB46472E73B468A7F8 /* EKSerializer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3AC2A7F58EB378F6B9493E38019591CC /* OCMMacroState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F6312424838238EECCB0C1BA1002684 /* OCMMacroState.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3B5F00F3E5996A8910F60C3C0D7FB45B /* SDImageCoderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = D5AB3D0F067AB772EEF8D8D8D9A117DF /* SDImageCoderHelper.m */; }; - 3BCE4893063AC34B03686EDB4327204E /* Kingfisher.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D39C95C6BA2F7ACA778BFE91D762354 /* Kingfisher.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3C2A6844C54198CB7CF7AD0FA63358E7 /* MixpanelGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = EA4CC493C28070726E85F63F85A7A9AE /* MixpanelGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3CAF2A050912D6E9F376201660C8251D /* MixpanelType.h in Headers */ = {isa = PBXBuildFile; fileRef = 708DE1D96C6A00BBDCE27C80AA4D2AA3 /* MixpanelType.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3D6085CD92FFD56CA7DC96F005C53502 /* SDWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 57EB895450DA2C40A1B05B17486D7202 /* SDWeakProxy.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3D7AF741C5E7EB2D3EAF8B1B36581701 /* OCMPassByRefSetter.h in Headers */ = {isa = PBXBuildFile; fileRef = 32370B87A6CE0AA519B6CEDF99F910BF /* OCMPassByRefSetter.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3F199CE43433677AE6B4874DCB4762D6 /* SDMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEA1E80C1838E1C1C3C444B2BDB99C1 /* SDMemoryCache.m */; }; - 3F431010BAE68FB8C5879FAD53A7B01F /* SDWebImageIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 69318348B3B55B4AC7307DBB4F4DAC01 /* SDWebImageIndicator.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3F47B2EAE92B0E2623C18FA59EF28A90 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = F64D0719D26112193FCA87432721368E /* SDImageGraphics.m */; }; - 3FB675C0E73B6F8058EA1467E1A33C16 /* EXPMatchers+conformTo.m in Sources */ = {isa = PBXBuildFile; fileRef = A89D74222F1515674053BCA1F96B288F /* EXPMatchers+conformTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 3FDB128F4EAD763A8F37183E70F2C8F6 /* SDWebImagePrefetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = BAB9C1F071E04BF93DF16CB45635E34F /* SDWebImagePrefetcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 40CD9DDB04FE5E72D8B56512EBDA6EAB /* EasyMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = A6ABFDFEBAB6F775540166E8CB0A76EF /* EasyMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 410AF8F3097D212405D3876B99371DB6 /* EKMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C3CBC28B037AB6A9DBB7C58473725CF /* EKMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 416522372FF901287AD5829BE288865D /* Mixpanel.m in Sources */ = {isa = PBXBuildFile; fileRef = A2DFB5FB1FBF6BDE66D3761B057DC4AF /* Mixpanel.m */; }; - 4205F8923996C784064E36B57266AC03 /* SDImageIOCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AD3CE5E6A7204EFCF0A94875B0F200C /* SDImageIOCoder.m */; }; - 4249C373DF03DB91A9578953A77E5294 /* OCMRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 474825B5D9CD57231E0863576494A2A1 /* OCMRecorder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 43163FF5C47E1BAAC12E171C188302E1 /* EXPExpect.m in Sources */ = {isa = PBXBuildFile; fileRef = E36EE74316446360E858F1A44D7319F5 /* EXPExpect.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 433A302BAED3761EDB444D894B914CAC /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6C56A9F51004DF35A9E404C806859D9 /* Result.swift */; }; - 45F2317E23C1AD3DA0B4FF4706A82FC6 /* SessionMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA6B926575B4BFD799AB7AB428D480C /* SessionMetadata.m */; }; - 464B6F049C941AF8720487C77948EC74 /* EKObjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = EB4E0393C303A359234E843EF87DF639 /* EKObjectModel.m */; }; - 476B11C84AE969E07A4CAD5E8BB79277 /* SDAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = E4B961693B51CABFAC71DD5C6A5A4BD9 /* SDAnimatedImage.m */; }; - 477C77170BBEBE5DA4591B9C45A375B4 /* EXPMatchers+postNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = B861323ED525752EA47B9D3053F1AB69 /* EXPMatchers+postNotification.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 47D455560D66ACA017BB920AF7BB356C /* MPFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 736FE3B1A3FD3F00512B7171439D130F /* MPFoundation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 482815DD16475606993475C0878895E0 /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A3FDEAC8848912398C906327E13BA3 /* Source.swift */; }; - 4905496C02DBD3900AFCFD193E891C08 /* UIImage+ForceDecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 913EBD22558950862D0830EE189B272F /* UIImage+ForceDecode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4954A385199A818B177E146777CF37D6 /* EXPMatchers+beGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = BAB9E6683D0915936373DC5385FC954E /* EXPMatchers+beGreaterThan.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 498A6B8E37EC169EA181D0AA9F7E402D /* SDImageCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 247A6911F6FD4DACEE1AEF5DF4F49FAD /* SDImageCoder.m */; }; - 4AC19F9738754BBD6A5153269565556A /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1565092550B223C4AA495868EA9ACCAE /* Resource.swift */; }; - 4BAD3027F3A6591BB8958FA35CB29CAE /* ImageBinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D94943ABA018F8FE56BDBE9FC1191 /* ImageBinder.swift */; }; - 4DEC4FC7A759ED6E40C6706E5E500543 /* EXPMatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = 99FFE72BA41D124C3E66032BEA09225D /* EXPMatchers.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4FA6C0019A7A03D5FB351D7A615205E8 /* OCMFunctionsPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0672A0F9DA8817B2A4DA4AE2F34F966F /* OCMFunctionsPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4FFB458AB69D654B292BB9D95B88149D /* SessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EBA2351A93813A05034F31E228E3098 /* SessionMetadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 51377BF4356F8692EB7BBC4109C44702 /* MPNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = B1867608EDF91D60A4545F8CC26ABAD6 /* MPNetwork.m */; }; - 517362AF8B4FD68DE2F6FD2B66EF79F4 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 992D60F0497E6F51CEAB91FF2C9FE24F /* ImageFormat.swift */; }; - 5203CD8079771375D574EDBD84DDABAB /* OCMArgAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 293AD8FB310917B27312010B015B0E5B /* OCMArgAction.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 52575DC3F9AA6A335B83F9DDEE23CA48 /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = EAAE51390887C89B5D97F214B2C00459 /* UIView+WebCacheOperation.m */; }; - 527A1FD6FD79117C535D19213B9011D1 /* EXPMatcherHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = BD81E51E7A577A51A5C7F3AA815C5DAC /* EXPMatcherHelpers.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 52C26A7F0403CDD87ACEBE4EE446F8BA /* SessionMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA6B926575B4BFD799AB7AB428D480C /* SessionMetadata.m */; }; - 52E483485002A85C047D787E31073223 /* SDWebImageDownloaderRequestModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 230B187CA6AF6024F2B0036E0D164D04 /* SDWebImageDownloaderRequestModifier.m */; }; - 530AF873B64BEE3AF9373FC9FECC6F03 /* EKManagedObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = DF94BD6EDCCFD2443825163FB8B65A38 /* EKManagedObjectMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 538035ACBF1CEF83E939B0450AE2642A /* NSDateFormatter+EasyMappingAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = AAEDA914FE1738DB4662140B337F1253 /* NSDateFormatter+EasyMappingAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 54E3A61D1BD1F996442AFDA0018BA2AB /* EKManagedObjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CF995B7342B40A45E27459B69A702C2 /* EKManagedObjectModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 55202EA582A7BEDFDACA6D85B01868F5 /* MPNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = CA228BFDCE8A94062372DD786096FF3A /* MPNetwork.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5599DB34088E6C5B4139B7026425B826 /* EKObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 83490DAFF67A0197CFB5F511B3FE126F /* EKObjectMapping.m */; }; - 55BBA612AF1D05409029A7DA39F45906 /* OCMMacroState.m in Sources */ = {isa = PBXBuildFile; fileRef = B346D043EFE755C02515D77ED01AE799 /* OCMMacroState.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 55E5FF4DC5EEEC6B400A0D87E3193890 /* EXPMatchers+beInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 7049926894FD903D522F31E5CBCA8396 /* EXPMatchers+beInstanceOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 560AD3C0BED5BEBDD79B407F8889B536 /* SDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = AF8D241D92929702644AC3C080CA4D97 /* SDWeakProxy.m */; }; - 5759BFCCCC8BC50A3DDB156CA486F98A /* SDImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 827735D4D43CE0DDCD15D60859120C75 /* SDImageLoader.m */; }; - 57BA46DFE2F32F04F308289610F73EDD /* EXPMatchers+equal.h in Headers */ = {isa = PBXBuildFile; fileRef = DA17C17C59D9A85314409E681085E34B /* EXPMatchers+equal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 57DDE2FCBF802264158E6D33F5649EE6 /* ImageDownloaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2C6CCA336F42607F337E1EFA0006F8 /* ImageDownloaderDelegate.swift */; }; - 59112B54182E65582F65FF4B8E771918 /* OCMVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = B10A8149DBAEB5276086C1A25968D7C1 /* OCMVerifier.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5A43305F185AD6B24558485ACBAC13D3 /* EXPMatchers+beInstanceOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 37A99D4A2DF1C02DCA3946CF86D88A1B /* EXPMatchers+beInstanceOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 5CEA958400E5BD28FEE35EB2CB170B05 /* EKPropertyHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = A6CF50AFABAA83508F094E26284AF209 /* EKPropertyHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5D9A2A4AED9115CD67B89FE161666920 /* SDImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = B4BE72DFF35188F0868B96621E9941CB /* SDImageFrame.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5DBCFA008E75D73ADFFEF24C210E6CB5 /* UIButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 2067A7813FC3405752095AB40D062988 /* UIButton+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5E12BCB2A3CC2DD19A7DDE775EBFA878 /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 97ABC7DE2E6E7D85D21D2C42E767EDC4 /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5E6233C210A6AF47C79AC729CE57536E /* Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = FD2AF4F508F39F4D9663F4F03F9771E5 /* Expecta.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5FB300212268804AE44612C65A4C1C31 /* EKCoreDataImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 189145CF4A26929B148653BA2D875C0D /* EKCoreDataImporter.m */; }; - 604313AB7820FCE93E4F572AC2BC9242 /* OCMNotificationPoster.m in Sources */ = {isa = PBXBuildFile; fileRef = 61A13E39F8EC94CD85DD2643FE333FD7 /* OCMNotificationPoster.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 60CA1324A2DECD22D0DFD2B86BFB166F /* SDImageGIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D9ABE2D50C0C884ED625EA5D881E8AC0 /* SDImageGIFCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 62139DE96318240FD52A1DE99EF984ED /* MPNetworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 512768F8B3FF93AED6AA35F6FB770F30 /* MPNetworkPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6214814A6B4ED5038353C2DE0F71DE04 /* EXPMatchers+beKindOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F31796752F8CF5D9D0D58B025055067 /* EXPMatchers+beKindOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 622F767AC051109722554A4BEDB28970 /* NSArray+FlattenArray.h in Headers */ = {isa = PBXBuildFile; fileRef = DE0029E0313EE4BBF6B907525159A0A5 /* NSArray+FlattenArray.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 62611DD528701129520532D66E9A5781 /* SDWebImageDownloaderRequestModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B65178DEB4E187ADC99E5892714533 /* SDWebImageDownloaderRequestModifier.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 62652BB410F8BED2B0F2906158B458AA /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 186F2A0989590D228E0BEE7E95FD3268 /* String+MD5.swift */; }; - 632F2CF8BAFDCFB7E46DBF992FFBCA9D /* OCMInvocationExpectation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCDB3631B71D0F22347F02109F35CE70 /* OCMInvocationExpectation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 655F9B3E71080105163364275A80F6EE /* SDImageCodersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C65DA8ADE9DE5648BC51913F68D68BAF /* SDImageCodersManager.m */; }; - 6613C1B05B8CB97CF3255CE665F50898 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 8959A8DF80C3F2AD13A28DF2D9F0AFAA /* SDWebImageCompat.m */; }; - 661BF6CBE08556C7569DC807BB861219 /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = EA8160747C5E6AB38E0ACF3334FC8E0A /* SDWebImageDownloader.m */; }; - 667490CD7ED2AF0A7D30F4674B8048E5 /* MPNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = B1867608EDF91D60A4545F8CC26ABAD6 /* MPNetwork.m */; }; - 6696CBE4654AD391C63CD4E85ACF2C97 /* EXPMatchers+beLessThan.h in Headers */ = {isa = PBXBuildFile; fileRef = FB5F5C16EA219A45277F93692511FE19 /* EXPMatchers+beLessThan.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 67F5852AF2E03411C6A46ED316366865 /* EKMappingBlocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 39819557A29A9D29DD6D53EB13C399F4 /* EKMappingBlocks.m */; }; - 685A65378327C1F6C51FBD7BB138764B /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2F761AAA0A1F14AFF60CDD39F72515 /* SessionDelegate.swift */; }; - 685AA6CF713D63B325787424C7DD6279 /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 67DD828DE7647C11596D9C8075277B0B /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 68C225A6C4301799D596A2A96F652640 /* OCMStubRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = CF710639283DDEDD96354E54E3A7E665 /* OCMStubRecorder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 69349BECD39FBA209D2ECA0AFE6550AE /* EXPMatchers+endWith.m in Sources */ = {isa = PBXBuildFile; fileRef = 955CBA37DD5C01B043411285DB126CB0 /* EXPMatchers+endWith.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 6A977385E9AD0106433204C53EF1332F /* UIImage+MemoryCacheCost.h in Headers */ = {isa = PBXBuildFile; fileRef = FF0058A401EA270668A032E2940DB3A9 /* UIImage+MemoryCacheCost.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6AB635E53472AFA729AD959EB18363B1 /* EXPMatchers+beFalsy.m in Sources */ = {isa = PBXBuildFile; fileRef = F1A219168B99676409EC7DFBA7644FD2 /* EXPMatchers+beFalsy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 6B4C8C7378DD51AB86A2CFDFE5B63ECE /* SDImageAssetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 58AB2C510FC2C1A8E0B56D19E4967D17 /* SDImageAssetManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6BD5D41D0FD19C27AAD3536B0484671F /* OCMock.h in Headers */ = {isa = PBXBuildFile; fileRef = A28937E8173CD476E20A4CB541E2F618 /* OCMock.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6C15F811A1380F7A7ABAC575E40D505E /* SDWebImageIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = A347DD9E83894ECF9E18A1321AF0DB4F /* SDWebImageIndicator.m */; }; - 6C2B1FA8BDF3452AD5C6E640AE95AA6C /* EXPDoubleTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D7624BD7181C0A641F064CB8136FF73 /* EXPDoubleTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 6D311E7FBE67BFDE9E812885324764C3 /* EXPFloatTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = 6904639B2FA8645216AE60AAC09C6246 /* EXPFloatTuple.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6DBEFA84693305F4EFC8EC490833C890 /* SizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FF9B9E3CA15D993513213755D00B89B /* SizeExtensions.swift */; }; - 6E4181C1011A7D01C5E2CFAFDBE05282 /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B960D4FD6AAA51C641D3555812B4072 /* KingfisherManager.swift */; }; - 6E84C445C8AA0A251B93F40C2479FB4B /* SDWebImageCacheSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 97D86A9D76DC8AE9454534808B623C55 /* SDWebImageCacheSerializer.m */; }; - 6FADB33F5F1305B1DEF22D8C2DB60DFB /* NSObject+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 78045319F740F63C57B362B9AB2A8748 /* NSObject+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 7021D3AF25EC280F69E49EC9FBE59484 /* EXPMatchers+contain.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D2D40E796780AAE41183B9F4680FA66 /* EXPMatchers+contain.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7036A3887A246B05E8CF15D86FEC6DAA /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC34D53E5B62AFBC01AA6E7C79EDFE4 /* KFImage.swift */; }; - 70384A05DD64D46FE1E31969F1C4F88D /* EXPMatchers+beGreaterThan.m in Sources */ = {isa = PBXBuildFile; fileRef = C8A287D51E44E395A8E8B248838B4501 /* EXPMatchers+beGreaterThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 70CFEF39BE41BB3FD25F511B8997BCA0 /* EKPropertyMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = DD84EF43057F7DFB3FA4F18A6B3077C3 /* EKPropertyMapping.m */; }; - 70DC6E4A54FD93C0AF97BCE150DDCEDE /* MixpanelExceptionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = E37875E266D4B7C82B4F961406679121 /* MixpanelExceptionHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 71452DB3DB742B4035096C41B1A00261 /* SDAsyncBlockOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CF287C63E99637D48551E625B228C5D /* SDAsyncBlockOperation.m */; }; - 71F17CC4A600EEE9EB9B371C531A39F5 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E11CFD92FC370BCCF6D215A51D9C5197 /* Storage.swift */; }; - 71F6061C24B4C1B6A766F9ADD5C44D58 /* EKPropertyMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 92C2004006AECCC51DCE4B55AD73B019 /* EKPropertyMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7204E0104BAE2059158C15A8ABAF164A /* SDImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = B12A44060AD90C50C600229C1BF30CE6 /* SDImageCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 729FA3889610818FD32181DE049486D5 /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7CB631287A52D62DF7B28B085B33FF1 /* RequestModifier.swift */; }; - 7385647AF22E08DA35FEB3BE0346F783 /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = D9927B59B79490141F493494FE1CBDC3 /* SDWebImageDownloader.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 738B88E8018D3400546022C0A2641846 /* EXPMatchers+beNil.h in Headers */ = {isa = PBXBuildFile; fileRef = 76BFB8CE05074AF39CC140752DEB82FE /* EXPMatchers+beNil.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 745CD20F091C1079A7E4741A2CC524FB /* EKMappingBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = E5E86E996D1B62900F3CCF346D1721A1 /* EKMappingBlocks.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 746E6DD4C3E469E15DE3BA3E3F39857A /* EKRelationshipMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = E40BB8DAF48D8157DA1CF09C26A8A2BB /* EKRelationshipMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 74BD5C0BC281CBD516E17FF2C7E93277 /* EKManagedObjectMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 06603B8AC9B141505673852488A83DE1 /* EKManagedObjectMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 756508F66332DF225107FD25BDF0EB09 /* SDWebImage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 14BF7FAE70B1B4B7DAA59DBCEB9CF9B8 /* SDWebImage-dummy.m */; }; - 75E1E8967716404B6E4A8AFFBC46E88E /* SDImageCachesManagerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 508C1A1C5A4AFFB6E7B04F71FE0E0F71 /* SDImageCachesManagerOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 76BF29D0C90B3EEF57A4885BFEEC365C /* ImageDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528A49D37E1026AEB96C97C085C90019 /* ImageDrawing.swift */; }; - 7756CDA1D1906D164DB8FB1DDC6DF102 /* EKManagedObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C141A466F16A0C707E292C28A7A0411 /* EKManagedObjectMapping.m */; }; - 77CB3489AE0B02B5995F1DB1CC9C13C1 /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C299D6117A127858E519895CF940442 /* SDWebImageDownloaderOperation.m */; }; - 783B759B1E57DC7A2E883D8031A0281D /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C8DDBE02D435933578C3D9CF9DB3219 /* Kingfisher.swift */; }; - 783BE48835B54903BDC6226708B41AA7 /* SDImageAPNGCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F0526B10B105C72A02DCB7A5FE5042FD /* SDImageAPNGCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 78779DACEACE53197EE58B4BC72302C0 /* NSImage+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = E9A310A735E4E90BCC6A9FD46539E260 /* NSImage+Compatibility.m */; }; - 78BC790FC7EDA25CA786A67152CBF264 /* EKMappingBlocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 39819557A29A9D29DD6D53EB13C399F4 /* EKMappingBlocks.m */; }; - 79D6B35393FF7B46CDFF85FDE6ACE8A7 /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 697AF15476B4F23A75BDC507ED83ABB5 /* UIImage+MultiFormat.m */; }; - 7A27F29E5AEEEDDD7404CAD1B52069DE /* SDImageFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = C7125132C005FB99631CECCD953414BE /* SDImageFrame.m */; }; - 7C1632A83B80B163FAC5297F8E9576D1 /* EXPMatchers+beIdenticalTo.h in Headers */ = {isa = PBXBuildFile; fileRef = D05EB1789A448153E0F229D5CC5BA22A /* EXPMatchers+beIdenticalTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7C477CF08C23CB76868B185DAAE8AFF0 /* SDImageCodersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E1F9C7D969CDEFF23E17FF615A85E88D /* SDImageCodersManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7C5AB855327E04A23448FD9EBBB04D93 /* OCMInvocationExpectation.m in Sources */ = {isa = PBXBuildFile; fileRef = 053A44FACD30EF6E275D6704FBE18CCE /* OCMInvocationExpectation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 7C60688F5BE4D20029112A2A88665036 /* SDAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 45967075B8CB5A601521BEDEDDDF70B6 /* SDAnimatedImageView+WebCache.m */; }; - 7DABAAF600D1305912C1B4B889A2FA30 /* OCMBlockCaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 047081A3E965601782291A1E4B25BEF0 /* OCMBlockCaller.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 7E571DCF762EE26E3829FA6120EC7C14 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D929F40722EA1C8DDAA7A14BE7CF771 /* Image.swift */; }; - 7E8F3B346FBFF1B578F470376D94FABE /* Mixpanel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D0D4DA41BE5383DA49503DAFA6F1445 /* Mixpanel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7EC7E5CC084FC6A07AA4E71F0F377BB8 /* SDWebImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = E6D8C758008A57827694D4028880F6AF /* SDWebImageOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7F07D7FB69CA93077F46B714739AE7C7 /* NSButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B6AFD85D4587CFCB86308270A778F3 /* NSButton+Kingfisher.swift */; }; - 7FD25AE74C165D37BB9909EF2026746C /* EXPMatchers+beginWith.m in Sources */ = {isa = PBXBuildFile; fileRef = AAFF91ADD6AC060E30D04D8E2DDACF61 /* EXPMatchers+beginWith.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 801F4A028FAE7D5798927FF6CD74EADB /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 664A0614E5FE37713C8FCFFC25070016 /* Kingfisher-dummy.m */; }; - 80612C4104A4DE34DF86B6D030C9E358 /* OCMFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4483DDBD04DB89E950F27F6C029DE7 /* OCMFunctions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 80DA2EA015D0BB48D62E6B423532FE2C /* UIImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A79507197F400407AD16AB92E7929F26 /* UIImageView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 80E371FE77A34E12BA35EE5C7EEC092C /* EXPMatchers+beLessThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = F51B87BA367652C3BCC69A7011799597 /* EXPMatchers+beLessThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 8121DE3E632E3DDF585BBD663D632609 /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 104C5B6C851601D859293E092AC36D08 /* UIImageView+HighlightedWebCache.m */; }; - 81BE7BE25048573093CABE94BC9A8FA3 /* NSBezierPath+RoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = FE84606C704FBD829A674F2E080A6873 /* NSBezierPath+RoundedCorners.m */; }; - 81C743D1A490A6A0AA25F871822B5A68 /* OCMArgAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FBDC4AD70DE3D06B76913290ED7B449 /* OCMArgAction.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 8278FE30343E81033150AB284ECC98D8 /* OCMBlockArgCaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 473387FDA75A441BDCAD6FD610A4E523 /* OCMBlockArgCaller.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 82CC384514F38830F5724C59278B2414 /* EKManagedObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C141A466F16A0C707E292C28A7A0411 /* EKManagedObjectMapping.m */; }; - 83FA5A3892B988C55601B32E470F2919 /* EKPropertyHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 355A7BC4978D41B9A315D86124F632C4 /* EKPropertyHelper.m */; }; - 84A174D550C67B2EAA26D32E4C309755 /* OCMExpectationRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 034943133D11EBBBF83DA60CEFA92DE2 /* OCMExpectationRecorder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 84A35BECD5CBE4F0042B3B740C779539 /* SDAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 704865349FC0AA93ABA47EC6250E2567 /* SDAnimatedImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 858025A6AD1BEC27F2D46242D7C459CF /* EKObjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7834F6AE8114671D7CB158B5EFFCA3 /* EKObjectModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 85F1E88FEEBF9B0337821E05C048AC39 /* EXPDoubleTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = 7236B3230AD0889A724CF497043F01A6 /* EXPDoubleTuple.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 86F0DB19CBDCA60F4582EDFEB4D9A1D0 /* SDImageTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = C7066153845C9CB987D2089FEA9C46FB /* SDImageTransformer.m */; }; - 8723D39A8D99C3B96431EF99BF42DF25 /* OCMVerifier.m in Sources */ = {isa = PBXBuildFile; fileRef = CA7B1F26AECE4763BAE90DED00BAA021 /* OCMVerifier.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 8873174683E2EE234F3A3EB7A9B4F15D /* ExpectaSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B82369BE8E0B9F11564DBC9E55086EC /* ExpectaSupport.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 896FECD7595629ABE8B25034A2A13163 /* MixpanelGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = EA4CC493C28070726E85F63F85A7A9AE /* MixpanelGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 89FB2A1B7F24A11BC8F6905ADA195FB5 /* NSNotificationCenter+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 360B43EA2822638B014CA70237DF74A3 /* NSNotificationCenter+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 8A424AADCE5CCA866E98F9C6DB5A4E47 /* SDInternalMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = 86BD8B43E38AFBC6B15B04EA3903A324 /* SDInternalMacros.m */; }; - 8A7ADB85ED8400CB25372625B2911BC7 /* MixpanelExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5E5CB7681E3DEE123040E6870391D7B /* MixpanelExceptionHandler.m */; }; - 8B353BCA87165AFF3FCD922D0E1CF291 /* OCMLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 720EF1ED28AC3B688CE6F3FB9E438EBE /* OCMLocation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 8C3B6032548EF72F9E3C1BF7EEE2BA76 /* MixpanelPeople.h in Headers */ = {isa = PBXBuildFile; fileRef = CE8F4F22CA4D6315D5E43C50269C56E5 /* MixpanelPeople.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8D391AE0D74C488F594AB16A59C02C8C /* SDImageCachesManagerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 88B972C3230D9A90FF61B58C59DF04F5 /* SDImageCachesManagerOperation.m */; }; - 8D6B3DEFA9CBF0F82DFAA713A4AC014C /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8205653621A0B670E7F3FDF4C5C36A58 /* Filter.swift */; }; - 8E088D678DE289C2E34825D26F391E2F /* EKObjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = FB7834F6AE8114671D7CB158B5EFFCA3 /* EKObjectModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8E971E2458163B8D717523B8D8BC892D /* EXPMatchers+match.m in Sources */ = {isa = PBXBuildFile; fileRef = D493740B17BEFB6678A8F660966907B4 /* EXPMatchers+match.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 8EB5BB5E22A7E21ED79A0B1A8D0DAE50 /* MixpanelPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C5CEDC685B0DAF949C106E84D43A94C /* MixpanelPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8F5B10D2E6BD453C535653D36FFFE4BB /* NSObject+Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5502588214C14362D4206E958AB4DC /* NSObject+Expecta.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 90C43317EED4C897B75945B5AFBF2327 /* EKMappingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D6A91E801016258D4C031AE91650396 /* EKMappingProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9195DDF9B870700CF68EE05472DAE884 /* OCMInvocationStub.h in Headers */ = {isa = PBXBuildFile; fileRef = 66C80F683A1878C39827AB1A8ADE2339 /* OCMInvocationStub.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 919E9BB52F6A9A369C54A8844E6B9D51 /* EKPropertyMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = DD84EF43057F7DFB3FA4F18A6B3077C3 /* EKPropertyMapping.m */; }; - 92BCD6A5BE8CA77A76752EB429B1B3EF /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = C148126AF9126A0D5EF8C178F3DD06A4 /* SDAnimatedImageView.m */; }; - 92CE0D8352F847E3FB4F88388A9835DC /* OCMExpectationRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = D485CBA57281576025CB61EA90A15158 /* OCMExpectationRecorder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 938E70A81407D700DD36CB557E17CE42 /* SDImageCacheConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = B34983A86DB520A9C8E487CE9F7777E1 /* SDImageCacheConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 93EB0B8CE0AE7FFC996562B4DB55CE24 /* SDImageCachesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A2370785CF931AAD343E57522428185 /* SDImageCachesManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9494B8B6DA4552D1A006F5ECBF9673FF /* MixpanelPeoplePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = D1EB4E17FB5EAD0DC2A47732102AED43 /* MixpanelPeoplePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 94A899454728A627B3A09E219D11F90B /* NSValue+Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A0BBFFD2EA27DA6B09E2875385A2052 /* NSValue+Expecta.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 94BD694E8B0DA875351BCB512772B1E0 /* RetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F59A8E40E78247C519309C3B12780135 /* RetryStrategy.swift */; }; - 95EDE12789CC1195FDAF5E5CB86112AD /* EKSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E042C755F61BFCB46472E73B468A7F8 /* EKSerializer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9652E46AC6C2B8C6579C903EADB667A2 /* MixpanelType.m in Sources */ = {isa = PBXBuildFile; fileRef = 65C68E58B21D695F281A118140FF2F4E /* MixpanelType.m */; }; - 9736BF32F948068A322BF8E06B6ABE58 /* OCMBoxedReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 6081C8356E7ECFDEDE70DCC46FC0D70B /* OCMBoxedReturnValueProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 9807A78A9140DBC2E065BBC0B55E3685 /* UIImageView+HighlightedWebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 140022B9A102D37A032DBA6B152CA4E5 /* UIImageView+HighlightedWebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9912B758EFE345DB72EE03DB4ED86630 /* SDImageGIFCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D3DE9686C65C2AA5CCCAED5C15AB8CD /* SDImageGIFCoderInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9934E1DEC10D877E5E59AE57C318ECFD /* SDImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = AB96CAFC5DCCB7374C5A881110FB8849 /* SDImageCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 99ECAD246F5A6D4B1484C48D09A81D21 /* EasyMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = A6ABFDFEBAB6F775540166E8CB0A76EF /* EasyMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9A68B49491E89F69DDDFFD78A3D99061 /* SDWebImageCacheKeyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 64B05964124210B349236926810AC127 /* SDWebImageCacheKeyFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9AC2BFADBB45D261140975D95CDDF6C2 /* EKCoreDataImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 189145CF4A26929B148653BA2D875C0D /* EKCoreDataImporter.m */; }; - 9C6BF74B2BB020EDF3390BAEF20F9C91 /* OCClassMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AE081BC4555FD7F02A0623282541F09 /* OCClassMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9CD2BCD7072F93A5FC9FF9E340437E21 /* OCMConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = B61DD45F82B8A39F266EC2207D8A76C6 /* OCMConstraint.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 9D856D3CF2508C51A92D7F4B0CD53F59 /* NSInvocation+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DA71E408B0A6D56446C2E5779AD7559 /* NSInvocation+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 9D96E887F3AF3FCB896F40F6167D03AF /* ExpectaObject.m in Sources */ = {isa = PBXBuildFile; fileRef = EFBD8DF4B22DC67C05839F4DEFC4965E /* ExpectaObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 9E2AE23F44E947FB14BCBEECBF1F41B4 /* Mixpanel.m in Sources */ = {isa = PBXBuildFile; fileRef = A2DFB5FB1FBF6BDE66D3761B057DC4AF /* Mixpanel.m */; }; - 9FC370801990ED9E104479E716BAC81B /* Pods-BitBotTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AD872128EF47421633BDF1B46487FC4 /* Pods-BitBotTests-dummy.m */; }; - A039049BD1ACE347793D15694312ED48 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B05FBC154203BB747B882B6E725E759 /* SDWebImagePrefetcher.m */; }; - A05EC45CE67973AFF41D00EBF1BACC2B /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 61FCFC3F530E4D72E86BE5E1C3002D95 /* SDWebImageTransition.m */; }; - A12CFB59F38100C987161083B914187D /* EXPMatchers+beSubclassOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BC2E0DACFEAD5F5379C305F858D25B6 /* EXPMatchers+beSubclassOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A15945657307EC5A623B2A8F0EF06F6E /* Mixpanel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D0D4DA41BE5383DA49503DAFA6F1445 /* Mixpanel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A181A081D11DA62F39C1A1EC420F2DF3 /* AVAssetImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D24152DABCFDC9F1C6AB214D1B4287E /* AVAssetImageDataProvider.swift */; }; - A194DE7323C4BD30401CD361961E5F74 /* SDAnimatedImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 95563B1EA47DD86FC4817BE8339B6101 /* SDAnimatedImageRep.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A26ADE1931856B9F72370EB470D145D7 /* EXPMatchers+beTruthy.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C63BC121FDC54C77FBD9748ACCBC838 /* EXPMatchers+beTruthy.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A36A02BE4A44F7BA5F2B0FC110B6CCE6 /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 797C915C816B98FD9BD12C5C555F9F81 /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A3E9D8D3FCC116B9977B4D9D15931763 /* EXPMatchers+beInTheRangeOf.m in Sources */ = {isa = PBXBuildFile; fileRef = F793FB1C97CF78722676CC204B89E8E5 /* EXPMatchers+beInTheRangeOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - A454AF3F4AF742B2E9E118F5446E9FB3 /* OCMLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 22B9F0B59BE15B06B82FFF9A49E8EC66 /* OCMLocation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A51F7ECF32728036C3977EA073A559AD /* EXPBlockDefinedMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C87AB4B61D62461E9958E2BF8D9EA3 /* EXPBlockDefinedMatcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A5D55782524E9DA98FB2CF6C28E84110 /* EXPMatchers+respondTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 49022F133FF236AA7B02EBB4B4827D07 /* EXPMatchers+respondTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A5F6EE5AE62E7FC137C84315CB651395 /* MixpanelType.m in Sources */ = {isa = PBXBuildFile; fileRef = 65C68E58B21D695F281A118140FF2F4E /* MixpanelType.m */; }; - A5F8B9CA051B11573C979B2AF9499A3B /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A33E007596522D13A845FC4E36F8249 /* FormatIndicatedCacheSerializer.swift */; }; - A6A1ED7188FCA275C31A024E93A6D4A0 /* NSImage+Compatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 524F0C8BF02AF437472F424326751775 /* NSImage+Compatibility.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A6DFD379AD92DA495E880DA2AF2EA845 /* EKManagedObjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 249B7DEFAAD79ED621BF410C85E4E76A /* EKManagedObjectModel.m */; }; - A75CD5CB8D97034FC5B7903E111E4BC1 /* MixpanelGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 8341906BAF78F592CBBECCA1690241F6 /* MixpanelGroup.m */; }; - A7AFF805552754168FE472102902BEE8 /* EXPExpect.h in Headers */ = {isa = PBXBuildFile; fileRef = F2DF1B744FF4D6FEE1E610217915FC33 /* EXPExpect.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A7B2109E598125ED8B51B8F03559E45B /* OCMObserverRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 9446B364CFDB08ADB0802CC3DFCB3D16 /* OCMObserverRecorder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - A7C9F3D124E5E6BC56306580B4BBF12F /* SDWebImageDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D77C7ACC32A1A1AD494E09082CAD36 /* SDWebImageDefine.m */; }; - A7CE151D48A5DD876ED10486B9C4FBB4 /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = FFD7C099325EE5900027A4F8102FF204 /* UIImageView+WebCache.m */; }; - A7EEA4CAAD20EB07A0F0A19B45035CA9 /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B515D14713BF4D5C47A28E2BF5C779 /* DiskStorage.swift */; }; - A81926638FF550204E63D7D76C419C02 /* NSValue+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0426F8771A05633CAB423C142380FDAF /* NSValue+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - A88F704CBD4D82BB5D02AEECCB5D6436 /* SDImageIOCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = A66E333CE92847BEBA79B50C188F884F /* SDImageIOCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A899FC847C293004CDDE2082820097F6 /* NSArray+FlattenArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 57148ECBF1DD36D149E773F13491AC48 /* NSArray+FlattenArray.m */; }; - A95E3534D0F0F3D77D95DFD16D7ABC77 /* OCMExceptionReturnValueProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 46209163AE3F1146C82075ECDBD3EC77 /* OCMExceptionReturnValueProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; - AA4B15DEBAB34C1E23C8797FAF8FB9FD /* MPNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = CA228BFDCE8A94062372DD786096FF3A /* MPNetwork.h */; settings = {ATTRIBUTES = (Project, ); }; }; - AAA15CF17FF4F4FA07ECE64351789D5A /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C60B7348A877E265B19BBA7EE57AFF /* UIView+WebCache.m */; }; - AD2CF66258C344DB8B748A7D7325059E /* EXPMatchers+endWith.h in Headers */ = {isa = PBXBuildFile; fileRef = 351E1639156085007A4F6BA6D161F9F3 /* EXPMatchers+endWith.h */; settings = {ATTRIBUTES = (Project, ); }; }; - ADB269445976EB1535E532F7E853E83F /* SDImageAPNGCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A0CF62073129C73345E453F1671A2E7 /* SDImageAPNGCoderInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - AF4EEDDC8B4D37D4105C7AC3A571A6B3 /* EXPMatchers+postNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = E87388CE197F1A31AEB8AD9280A4837C /* EXPMatchers+postNotification.h */; settings = {ATTRIBUTES = (Project, ); }; }; - AF61EE2DB798B07B41DE57B88148C5F8 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350AB591550DC8BE6E78A18724372109 /* Indicator.swift */; }; - B0010BBE7F27AA63239F8B31D4AB4366 /* EXPMatchers+beSupersetOf.h in Headers */ = {isa = PBXBuildFile; fileRef = D83248A5D588A9C43ABA5B21486F7E1A /* EXPMatchers+beSupersetOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B037286C4815742A15E134466A379DBE /* EKCoreDataImporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 73CA4DF78364101A233A47EDD6EEA713 /* EKCoreDataImporter.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B05EF0263571719D669495825B89200D /* OCMInvocationMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = FE7AEC369A0AEE80E22A9B7E80A1E866 /* OCMInvocationMatcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B14FAEB37710ABF8E15D138A4B2AC02E /* OCMRealObjectForwarder.h in Headers */ = {isa = PBXBuildFile; fileRef = BDEBF23624FC6144C3220520A42B55A5 /* OCMRealObjectForwarder.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B353DEE0F707A17093B0D8A5F53894D9 /* Expecta-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F86E9C0BC3ADA6A7A59A633361DA940 /* Expecta-dummy.m */; }; - B38B31930E04412FF4390F40B506868F /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = 717A6A925F8110E257AE946485EDA856 /* UIImage+GIF.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B458BC2D677BFE2781CA179888E41364 /* EXPMatchers+beInTheRangeOf.h in Headers */ = {isa = PBXBuildFile; fileRef = AFFB60D7E65E67C42E01EB132DB30B60 /* EXPMatchers+beInTheRangeOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B4AE70BB3B7544E6E79FC96E60E6BA1F /* SDWebImageDownloaderOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 05AFD55F4788466522B9FA8D8BA16EAE /* SDWebImageDownloaderOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B5308E889740F697E0432FFFC05971F6 /* MixpanelType.h in Headers */ = {isa = PBXBuildFile; fileRef = 708DE1D96C6A00BBDCE27C80AA4D2AA3 /* MixpanelType.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B5D629B65A97D9E8EF4D5BAA4F40C0FC /* EXPMatchers+beSubclassOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDEE8194B56CF2FED272F0BF55F6583 /* EXPMatchers+beSubclassOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - B6EE74F7C6A89BB6B351FE8E7FB922B3 /* SDWebImageCacheKeyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 99D75CBB7C8193D992BF15A7EBAA9F4D /* SDWebImageCacheKeyFilter.m */; }; - B7603387DF30944EE2AF64E8AFD9B996 /* EXPMatchers+beCloseTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 760EC8BECFAB5CE1F17ABEB898648C77 /* EXPMatchers+beCloseTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - B7A75A336ECD93F3B97B3C3E6D74AB98 /* UIImage+ForceDecode.m in Sources */ = {isa = PBXBuildFile; fileRef = C53946AE1D25D3DC688DD052BB4CB2E2 /* UIImage+ForceDecode.m */; }; - B8C924F7983360C20BCC019E89DF874C /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7A4B88754D7601CDEE23791D4591E1 /* ImagePrefetcher.swift */; }; - B91E5F7AF68E8B24E40FF9B2C80A648D /* ImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C28179F76171CCE9AEBC4B5827CF3E9 /* ImageDataProvider.swift */; }; - B996D4516F1B0CC3D1EDF8D26977EFB0 /* EKSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3494C85ECF06448B0147FD86227506AA /* EKSerializer.m */; }; - BA3411323C165C1133911719BDF696E3 /* UIImage+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 890A2F3CF1A55C6200A25E16CE6BAB19 /* UIImage+Transform.m */; }; - BA50B2813238B73794AA166ACC10D0EB /* SDImageCoderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = DE92320C17159F72A6BA50CD088843A8 /* SDImageCoderHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BB6A366F78C059717E395840E9906792 /* MPFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 736FE3B1A3FD3F00512B7171439D130F /* MPFoundation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BBCC9987EE8E58C698E6AAD5FA838798 /* NSBezierPath+RoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = E0B8907B5FA48B7D00DB2A720E163707 /* NSBezierPath+RoundedCorners.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BC860116C8605FFF88ACC3520C231D76 /* SDWebImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF61E9AD9175C992A05DFE48ACC2DA1 /* SDWebImageManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BCCC03AB3BEC74DAD5170A8441D9BBEC /* EXPFloatTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F469FC4B15200F7960D4286CC2DD92D /* EXPFloatTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - BD769EA7F521A62B01BA7C52FBFE218B /* EXPMatchers+equal.m in Sources */ = {isa = PBXBuildFile; fileRef = 674EF19E7E47344921FFEA25FC8EAE0F /* EXPMatchers+equal.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - BE0AAA2A08954EA36461820A3F4157BD /* MixpanelGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 8341906BAF78F592CBBECCA1690241F6 /* MixpanelGroup.m */; }; - BED84F19DDD265A8DC03B3F4DFFEA254 /* EXPMatchers+beginWith.h in Headers */ = {isa = PBXBuildFile; fileRef = D7DBBFCB3167A86CC54D0C3B37C27514 /* EXPMatchers+beginWith.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BF0E9FC2F301F77F02220AA076BE6443 /* EXPMatchers+beCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 89777E5F7D16F4D26949703CC7890AFB /* EXPMatchers+beCloseTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BF353A7249397BFA345229E3DE348AFD /* OCObserverMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 963F1099A35439CB4AC27D2E19814B39 /* OCObserverMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BF60AD1CBB20952ADA29421BDA01B37D /* SDWebImageDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 460A2613309D6A90A54CEB827940AF8C /* SDWebImageDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BF9E3937CCFD78E7DBE3EF757C4B9093 /* EXPMatchers+beGreaterThanOrEqualTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DC77D01AD9862B5693CDB9BCB87267C /* EXPMatchers+beGreaterThanOrEqualTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BFEA3D2CED9609B4C44CCF34B903F3BC /* OCMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = BF0B3717271485DB8B8D4FCA96D24E52 /* OCMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - C1667BC4C33118E0CDB9185A6EBC4F71 /* EKCoreDataImporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 73CA4DF78364101A233A47EDD6EEA713 /* EKCoreDataImporter.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C37A3EC15BF828DDE5546F8E78E3599A /* Pods-BitriseATV-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8734B79633EB68199F968AD242A66EC8 /* Pods-BitriseATV-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C3AF5195A000CF02EB5F0A0FF2A6EC28 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A690A9A6C6A1F35D533D71672AE8D /* SDWebImageError.m */; }; - C4265AE0D54889CE2EC8E1188D7537AC /* OCMBlockArgCaller.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FEDDA3B696F572A41CCB38C8E8A8B /* OCMBlockArgCaller.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C4985A1BD4CEC211AD8E2B3998A6C601 /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 914886C9DE73B54DB69A91E71C457CCF /* NSData+ImageContentType.m */; }; - C4D05730886A2DD720E67068E81556A1 /* KingfisherError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF364F43D01D31692287DD1152F310C /* KingfisherError.swift */; }; - C5ABCAD032D262081CC9D9A46F2315E4 /* EXPUnsupportedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 26BED9F59C1EC352A91517BE7ED5DA93 /* EXPUnsupportedObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - C5CF2EF707C0069DDB121980C937253E /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DC2EB0F2557488F898BF21B5847CD85 /* ImageCache.swift */; }; - C677BDC98B12FF3C78C5E3C8420A80A6 /* ExtensionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD77A9208BF0386967CD1A399611065 /* ExtensionHelpers.swift */; }; - C6FA4FE61B5E13962BC1418D10A41951 /* OCPartialMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 98F64D946D0D5EAA81CC1B0F9D334199 /* OCPartialMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - C7C6C69274B596C67FF19D6CAC2857C5 /* MixpanelExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5E5CB7681E3DEE123040E6870391D7B /* MixpanelExceptionHandler.m */; }; - C94614DC549748A43D25911D3FABA1BB /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAC12ECB76F6C71543B1881C9B5C61CB /* RedirectHandler.swift */; }; - C99D1B26354103BA0B0099F014182E4D /* EKMappingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D6A91E801016258D4C031AE91650396 /* EKMappingProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CA5A9C560B039EB6C0E64E3B1D5CF665 /* EKMappingBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = E5E86E996D1B62900F3CCF346D1721A1 /* EKMappingBlocks.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CA66064D1C2C0469323961DB9B8F3AE0 /* CallbackQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DBA344177BE60B9FC857B007F7899D1 /* CallbackQueue.swift */; }; - CA6A3D4528883BD431B92ECE28AACCCA /* EKMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8CE8F303F0D4706A0082068622A245 /* EKMapper.m */; }; - CAE8D9E60604DD9EEC6F00A0E01E0C4F /* EXPMatchers+contain.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A05896299BDD20F8E0B2FBC121EDD15 /* EXPMatchers+contain.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - CAE9158CFE1E16FCF2671C86F94F9896 /* ImageProgressive.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE6870ABB57D3FAD177D239F959883AA /* ImageProgressive.swift */; }; - CD6EB00C1A5FAFEAE9DF50F30619FFF6 /* UIImage+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = EF5ED803BC5085BF65F2CF57CD8552BE /* UIImage+Transform.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CDBF888FAAEB4A9761E5383285135E84 /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51944D9571F5EFD1BED19D1CFCBF2FF7 /* Runtime.swift */; }; - CE1C625D67497149BAC2B217ED583B4A /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EE7E1C448B38B420808CC8605F8256B /* SDWebImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CE7F92241F7F1F212EFE404C89B75622 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB705C2A74FFD57028D54FF85DF69212 /* ImageView+Kingfisher.swift */; }; - CE8E6348397F931435D960E6B9434C2D /* OCMBoxedReturnValueProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = B0DC0C140D05CC9480A2E31FE8270445 /* OCMBoxedReturnValueProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CF03DE4B17880C53755AA5483A33A701 /* EKRelationshipMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BFF7D460EC190F4EF6ED180A3017FC0 /* EKRelationshipMapping.m */; }; - CF2B46DA0C8D824B1BA270A06F2DE0AE /* UIView+WebCacheOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = CDFEF876C8EAD0CF4C05038DE14DCF71 /* UIView+WebCacheOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D1025678CE5CA89A7D52795E91E5A3CD /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B470B8C6258E527FACDE6F72DFFF4D27 /* AnimatedImageView.swift */; }; - D10C2AE0012DF7F4CFD9E309BE12F3C6 /* OCMIndirectReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BF93FF0D3C987DFC760391725FE25CA /* OCMIndirectReturnValueProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - D1BF0D14765A5F2B82A53A58E7912DF5 /* EXPMatchers+respondTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0855654A0B2D8977CEEC37544E90A9 /* EXPMatchers+respondTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - D33C600E6B5E582C65F3EF397CAD3338 /* EXPMatchers+raise.m in Sources */ = {isa = PBXBuildFile; fileRef = 90D9077EE66C60A9B04C97F6FDD53C0C /* EXPMatchers+raise.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - D8CEADFE74807E34CDCFBF3C4730CA8C /* EKSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3494C85ECF06448B0147FD86227506AA /* EKSerializer.m */; }; - D91A995950BE8D4006C46F49418118E4 /* OCMNotificationPoster.h in Headers */ = {isa = PBXBuildFile; fileRef = AE51649E85A3F7A92B1AB21D524878B9 /* OCMNotificationPoster.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D9A5D0337898B020B76567375DAB6055 /* MPLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = AE5EF5CE5A54E9221AA60FE934863F4A /* MPLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DA177C99E993E85CAADBBF5B6F262069 /* Pods-BitBot-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 130BFADFF57F3645DF20CCE614833C47 /* Pods-BitBot-dummy.m */; }; - DA3775C2C80E037A7D623C59A5378A94 /* MixpanelExceptionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = E37875E266D4B7C82B4F961406679121 /* MixpanelExceptionHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DA3822D5C69C9017CBB78978E24A248B /* NSInvocation+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 31AF941F182276F2B40F2B726E75143E /* NSInvocation+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DA7B989AFE2B409E9EF6BF04120B8C13 /* EXPBlockDefinedMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B53664E19E87DE3381B734459ABCFC4 /* EXPBlockDefinedMatcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - DCAAB0FA1F0B7A3F26FEAC67F8FD832B /* EKPropertyMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 92C2004006AECCC51DCE4B55AD73B019 /* EKPropertyMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DCE86B34B441CCAEC489D1130513A967 /* OCMReturnValueProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = BAF78013740FC8148179C3E81058804A /* OCMReturnValueProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DD1276257A6B652303591E341BB03CAD /* WKInterfaceImage+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = E53CB9C53DE644CC0018E828836F22E8 /* WKInterfaceImage+Kingfisher.swift */; }; - DD1467164E14367DA250DEE821A80907 /* SDImageTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEEF6F299FC1EF75CECA90833D64E31 /* SDImageTransformer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DDC6384AD423F30771D505780BCA7786 /* SDWebImageCacheSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = F3984CAB8C188467A7244F99E6549DBA /* SDWebImageCacheSerializer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DE13883D559603ACC417F69DE5A92E05 /* EKPropertyHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 355A7BC4978D41B9A315D86124F632C4 /* EKPropertyHelper.m */; }; - DE8C5CA9E2CCE05776810E280BFD8EEB /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F7E833D00F12D9C5B291BDACCB608EF3 /* SDWebImageManager.m */; }; - DFEEB75EA1B2172C382FA8594ADA0241 /* EXPMatchers+beLessThan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7F63D471560A79A81C8EAD9832854AF /* EXPMatchers+beLessThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - E001752B149F4E972A5880981FFE9E8B /* OCMock-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AD3C6229239FD004ECDF3767CC55B62 /* OCMock-dummy.m */; }; - E00A0A877F8E4BE010DD342DFDAEB18A /* OCMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C0DCDD5D84614288FC9861FADD8501 /* OCMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E0E6B540426A4C5F5A7EB4774410C42A /* SessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EBA2351A93813A05034F31E228E3098 /* SessionMetadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E1CD0533CE2A3DB5684304BA1019B542 /* SDDiskCache.h in Headers */ = {isa = PBXBuildFile; fileRef = C7F1EF4C2BBDB132CCEA2EF7D0E40DB7 /* SDDiskCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E2188A86DF2633379C99FBA18C8E55C3 /* NSObject+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 85ECDF65524CC0F3870C9F005C733141 /* NSObject+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E30AC13C618EE16EF2D4DED21B229B8B /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 95DD4922510FE102A4125D8B906D4721 /* UIImage+GIF.m */; }; - E4BB882234A977C7AA36C1839E70D113 /* SessionDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = B451B418484BAF6ECD5CF187FC6C969A /* SessionDataTask.swift */; }; - E6F1A2BA1620552CA15C02996D717800 /* MPLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = AE5EF5CE5A54E9221AA60FE934863F4A /* MPLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E80589588CC157119F1FB96A03B30BF5 /* NSArray+FlattenArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 57148ECBF1DD36D149E773F13491AC48 /* NSArray+FlattenArray.m */; }; - EA7CCE29307048D044A60D1F8D63D87A /* EXPMatchers+raise.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C4DBA9148322CD3B09452E7AAB0C0F /* EXPMatchers+raise.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EADF972AB8FB2C89321CE3F8FCE0D70D /* EKPropertyHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = A6CF50AFABAA83508F094E26284AF209 /* EKPropertyHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EC720B96E61C5F88F94DED9088653DE7 /* NSArray+FlattenArray.h in Headers */ = {isa = PBXBuildFile; fileRef = DE0029E0313EE4BBF6B907525159A0A5 /* NSArray+FlattenArray.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EDC19D69387F113F3C4FE1F0B3A60F9E /* SDImageAPNGCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C70B107A43E113F3F1055B97D5C64B2 /* SDImageAPNGCoder.m */; }; - EDC6D94569FE806DC0BB7477131B78D0 /* MPNetworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 512768F8B3FF93AED6AA35F6FB770F30 /* MPNetworkPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EDF666FA20CB8D6D89A8F0E36EC21CF9 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787B08443FD92595FA0DC41A0BC847C3 /* ImageProcessor.swift */; }; - EE62D51B4F4A55731CCD546D25BA1064 /* NSValue+Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F69AE167CA5113FE2264E86ED76DE4E /* NSValue+Expecta.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - EE9616B201A313798F3A40D9A636750B /* SDImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BE56A866D956C48B3A07A077AA30E6F /* SDImageLoadersManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EEB28E940F407DDAF928EC1B73155FF7 /* OCMFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = D4575EADBF96D18BF9DFAA46148F03C4 /* OCMFunctions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EEC88630DC3F804E03AF715DF8BF8422 /* Pods-BitriseATV-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0737FD1FACF633D70616CB317F2EC64C /* Pods-BitriseATV-dummy.m */; }; - EED21AA66F01F2F9CFAEABCFC395ECDF /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 708030192838B80AB5E0460B6E687194 /* NSButton+WebCache.m */; }; - EED4D51267517F2D304C74540B6B0489 /* ExpectaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = AE3615FE3C25BC5BFED9475620B18427 /* ExpectaSupport.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EEFEC2C69577425D1446AFB526329E32 /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2716E4B1649A8833BD6F9C1D271B8FF /* CacheSerializer.swift */; }; - EF07E681556BC7689CCED3B38434F00E /* EXPMatchers+haveCountOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 717AAB42E5B837F0CD5E8614F92BE548 /* EXPMatchers+haveCountOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - EFAD14B398A5DED6FC6D2976DC6EC00B /* SDAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 56899FE50A2A99881362A35F2005FEED /* SDAnimatedImageView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F013FB79B0CCB3AC9763954DF0B3A21A /* MixpanelPeoplePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = D1EB4E17FB5EAD0DC2A47732102AED43 /* MixpanelPeoplePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F06C8BBEA053E4DE6E46C24D530284D4 /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EA37B59FEEFC4126008D4438093882D /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F1D80A220E664E462AE9A21692370382 /* EKMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8CE8F303F0D4706A0082068622A245 /* EKMapper.m */; }; - F26E607263D806EB08FB2BE976DD5719 /* UIImage+MemoryCacheCost.m in Sources */ = {isa = PBXBuildFile; fileRef = 19CD256D264D78BEB3371940A41DBACA /* UIImage+MemoryCacheCost.m */; }; - F27DA7709F41E43F0BB47C6A0D3E4CD7 /* UIColor+HexString.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F645E945F39049D018050DE34D1761 /* UIColor+HexString.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F311ABF57205796290AAC4C9E70A57AF /* EKManagedObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = DF94BD6EDCCFD2443825163FB8B65A38 /* EKManagedObjectMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F3AA9FF5270EFC40E8D1BD1B4D05055A /* OCMRealObjectForwarder.m in Sources */ = {isa = PBXBuildFile; fileRef = 53DA50CB5C5309A4A85E7F9584687889 /* OCMRealObjectForwarder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - F3D79EE95A53DC322C2F93551780FCC4 /* ExpectaObject.h in Headers */ = {isa = PBXBuildFile; fileRef = CEAD97C29EFAB8BEAC263DB3B303A5E4 /* ExpectaObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F3E5BEE29D657DF6E9058D7FCACC4287 /* SDWebImageDownloaderConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DEF35F27ACDB14F4FFBB034E4AA2831 /* SDWebImageDownloaderConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F4701D4CE3C2B0A14695164D5E582DF2 /* NSTextAttachment+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D884EC3FBCA256B592A7BF175DB4A590 /* NSTextAttachment+Kingfisher.swift */; }; - F64A0D949FB29390A4F2604446C9C965 /* OCMReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = DC92E918B3166C9B4C4BDB94D6E2FB81 /* OCMReturnValueProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - F6F27633B32DE9FB4C636810ADA4F9A9 /* EKManagedObjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CF995B7342B40A45E27459B69A702C2 /* EKManagedObjectModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F74BF06DBC15BB2A17E66943831132C2 /* EXPMatchers+beSupersetOf.m in Sources */ = {isa = PBXBuildFile; fileRef = BE6767C8ABFABDC3AD0FF966CE31C70E /* EXPMatchers+beSupersetOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - F7A9F53A68FF24600778D518BCD448F1 /* EXPMatchers+beFalsy.h in Headers */ = {isa = PBXBuildFile; fileRef = D09347008ADF9857FE17C7C03E5FD631 /* EXPMatchers+beFalsy.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F7B19B68FAB73CB0732744B6A096D791 /* EXPDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 841BB69169E16B75648566DC54E4D405 /* EXPDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F836088040A893CDC77FE27CC4FF1128 /* SDImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2247CF28BF90D35DD24088EB9F8425 /* SDImageLoadersManager.m */; }; - F9F0296BB4A501C75884F81457F6793A /* EKRelationshipMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = E40BB8DAF48D8157DA1CF09C26A8A2BB /* EKRelationshipMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FA5C886F0154733309AFFF0C41C9D62C /* SDImageCacheConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = AD1C8BD7DEB42F687DDF5D0C5BAF26A0 /* SDImageCacheConfig.m */; }; - FBA580E5E82E288FF4E0633FD686FD8D /* SDMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = F4BC3BB600D3B7C15CE82551B31038F4 /* SDMemoryCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FC03EE048F70F1E14A2F78836CA26D49 /* EXPMatchers+raiseWithReason.m in Sources */ = {isa = PBXBuildFile; fileRef = 341D4E70DB49D4DCD350DA4D9ED20A0A /* EXPMatchers+raiseWithReason.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - FC218F96DB09A48D9D13774F9CA178BF /* MixpanelPeople.m in Sources */ = {isa = PBXBuildFile; fileRef = BAED2AAE5E9EA784319F20AD830C8A32 /* MixpanelPeople.m */; }; - FD568DDA288E91778CDC445CB72E8F6E /* NSValue+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = C4AD47EAF619C857BEC113A2047709F2 /* NSValue+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FFF7A088B3B6F9795C85FE880C29F9E7 /* UIImage+Metadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 48E34B5E54DDDCE905E3AEA8359FA621 /* UIImage+Metadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 00301FABA708E07673968C6E9F9685EE /* SDImageAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BB20062D0FA5FA812F3E4061BB7427CB /* SDImageAssetManager.m */; }; + 0033350F9C449649F2B63AD620B68BEC /* SentryEnvelopeRateLimit.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C3715BC9F903D97400016275A722B9 /* SentryEnvelopeRateLimit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0076745D50ACBF53F8CAFD0A43C99848 /* SentryCurrentDate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6028B0CECC6A8136E220A86E8C686B05 /* SentryCurrentDate.m */; }; + 007C778C9961B07D41E4CF1C92B1FCA6 /* EKMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F5B2D858E5616537CDD4EA800C5173 /* EKMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 00F873799DDD0CF0ECCFD7B5EF38364C /* SentryCrashC.c in Sources */ = {isa = PBXBuildFile; fileRef = 310F43800A6087EA88D2D109C93895D5 /* SentryCrashC.c */; }; + 0114FB20C311C29C8494010970C7E44E /* UIColor+HexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 85CEE7611CA747051932DE9C7ADA24E4 /* UIColor+HexString.m */; }; + 02025BF71C9F2C50DFAAE14236584E10 /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = A8673ECA3B5E894D0AD1F258CFFFB9C9 /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 02157386A058474A315E1A290585944D /* SDImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 571073AB176AFE9D5425295A0BEB0C02 /* SDImageLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 021CB55D395846970B94FAFCCAA5DC1B /* SentryCrashCPU_x86_32.c in Sources */ = {isa = PBXBuildFile; fileRef = 76CD924DD05728AB3BF84E8D93885369 /* SentryCrashCPU_x86_32.c */; }; + 0229A6C32A076719C11ABB418B7CEF0C /* SentryDispatchQueueWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 283CF93D0E24384373D3F11E6A1D612E /* SentryDispatchQueueWrapper.m */; }; + 022CC0766440E05D2F84E24EA9F53A5C /* SentryRateLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F3224D9568E6D6B837E95D55B0F917 /* SentryRateLimits.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 027F3E9665A51CB5972FE41A5569A066 /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 10BFBB8F051AEE483FAA09C828C9ADE1 /* SDmetamacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 028B09647AC4074230DB89C08982BC38 /* SentrySerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 442B5088AAD4A7635F001BBC8DA25200 /* SentrySerialization.m */; }; + 02AB7FD6E971C0E6E3EFC2953296850F /* SentryCrashDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A1732A4F71AA53446C68DDCB89BC9A1 /* SentryCrashDebug.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 02C261C3E5A39ACC64244A8F380FBCAB /* SentryCrashAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FDBE617EF1EA76B9219DC475DFE0B4D /* SentryCrashAdapter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0303374046837710F3D28C3B0B4CD039 /* SentrySpanId.h in Headers */ = {isa = PBXBuildFile; fileRef = 08B901DA30F9297F9B7E39C00791CAE4 /* SentrySpanId.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 032E5388FE0C4113337FECBDA12FEEFE /* SentrySessionCrashedHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DAA072773DE54BFAA4917530A95F092 /* SentrySessionCrashedHandler.m */; }; + 03430978B7D0D125FC3F6D3C9D64BFD5 /* SentryOutOfMemoryTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 88DBEA1A6DF2FC4DE59CCC2CAE2B4235 /* SentryOutOfMemoryTrackingIntegration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 03BDE0470F8061C9F55D6839E534A465 /* SentrySpanId.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8FC0B52735277BF7A7F2DBB43DBB93 /* SentrySpanId.m */; }; + 03C321596EC119A1F8EF4E988752270B /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9A6AB7B0D89F2EABE8504652874196B /* Deprecated.swift */; }; + 03F5CFCBF0C1033ABC8951B2B406ADB4 /* SentryAutoBreadcrumbTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1A06E37E387E8DFDB3FAC7C71EADA3 /* SentryAutoBreadcrumbTrackingIntegration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 040D38DE5CCF1E753AE9E01F499B9995 /* SentryCrashMonitor_User.h in Headers */ = {isa = PBXBuildFile; fileRef = 05A5DAC0EC5EF59D6C15397258A939C9 /* SentryCrashMonitor_User.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 04B9D3BB21C760E8993AF3EE5EEEF93F /* SentrySpanProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 78AFD32C679BA0512CD29B01C52FD8E0 /* SentrySpanProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 04DDC981AAD7F73EFDFD96393C227827 /* EXPUnsupportedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 639DB5F3F4526DD4E2091E18B340C3C6 /* EXPUnsupportedObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 04E724A97339965ACA4E5D60226DA001 /* EXPMatchers+beIdenticalTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FA942C52C785545E4D4C42A7EAC6893 /* EXPMatchers+beIdenticalTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 0514C2AC6F2ABF04CFBEB20EDDDA2C50 /* OCMRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 00C44F2BE6F0FFAADFDB233517EF0AF4 /* OCMRecorder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 051D4B5709A6257B6F79D54D9139E812 /* EXPMatchers+beGreaterThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 060A4FAD62F94BC224E0223323FCB29A /* EXPMatchers+beGreaterThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 0580739B35F3E13E331EF1D4C6EC5AAC /* SentryCrashMonitor_System.m in Sources */ = {isa = PBXBuildFile; fileRef = 977EB770ABF48ED5105390B227CF1057 /* SentryCrashMonitor_System.m */; }; + 06395D1A27A40E21AAB0A02DF8BFFA5E /* SentryCrashInstallation+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 707B03E715E22776FCC31962771A7E2D /* SentryCrashInstallation+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 06AFBDB6BF3B72745AB6F83BABE60C84 /* NSString+SentryUnsignedLongLongValue.m in Sources */ = {isa = PBXBuildFile; fileRef = CB32A5329227AA32586B5F39F8AC262F /* NSString+SentryUnsignedLongLongValue.m */; }; + 071608B620AAA9AD806BEC14D6721DE3 /* NSData+ImageContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = E2A90A5DEB09F21EA190C89343DE0462 /* NSData+ImageContentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 07193DD81439174D4B8DDA86835AB0CD /* SentryCrashMonitorType.h in Headers */ = {isa = PBXBuildFile; fileRef = 10F5894E3DCDD857C93D93387290D1C5 /* SentryCrashMonitorType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0726A08EB130C4FCCE7A8B14C8F35A02 /* EasyMapping-tvOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C3A060C3967F3342A7DCC03CFA813D6 /* EasyMapping-tvOS-dummy.m */; }; + 07968CFA4E57CEBC4DF23D2A15DE388E /* Mixpanel-tvOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FB28F864B2530B901ECC2199761359A /* Mixpanel-tvOS-dummy.m */; }; + 07E5854E45B4F185DAE8FDC36C94EECE /* EXPMatchers+beLessThanOrEqualTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF03F0C7762E903D6D62F462E93BE35 /* EXPMatchers+beLessThanOrEqualTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 085F3A44FF0EB115121C2AB43D72F001 /* SentryCrashDefaultBinaryImageProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = C190ED49B8AF2D2705779E1DD6001A3F /* SentryCrashDefaultBinaryImageProvider.m */; }; + 08972BEC745F3895C5FE98732BB0E646 /* EXPMatcherHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8C060574C7D88BA3788F238D7F2FF8 /* EXPMatcherHelpers.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 08FDBF25279270022964AA3CCBF6633C /* SentrySessionTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 205390348AA79A216C5E4236AF4C090A /* SentrySessionTracker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 09993F0619B95EFC4E4E62BF50022D2E /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79AD15A04248C56802F9B6C75D3019A1 /* Delegate.swift */; }; + 0A268D01D23A774FAFAC6C9C35594A43 /* SentrySampleDecision.h in Headers */ = {isa = PBXBuildFile; fileRef = 58976039A170F01993918E5B37032F00 /* SentrySampleDecision.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0A79813D171A8D87C2D2E9E6B005C18A /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2B96990033B4F418F03E42E8155FFE /* ImageDownloader.swift */; }; + 0B21FA5871B6F62512CC91D4AF3F1646 /* SentryCrashReportConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = C1E333E813AEA3E1D1114D3717C7022B /* SentryCrashReportConverter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0B285E0008F37AEA783281D73964CB74 /* SentryCrashStackEntryMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = F8678DC07C3A0A61B18287BFACB10934 /* SentryCrashStackEntryMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0B6134267A0EEE08E4546B8A97A24599 /* SentryCrashLogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A983085F3DFDC173B710B3C170F3368 /* SentryCrashLogger.c */; }; + 0B87D9B83388B5AEC1D63BEB0E468CD6 /* SentryAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 912295245C4EFAE6597BD5624C6D29CE /* SentryAttachment.m */; }; + 0B96707E793EFD952A2B721150F3D645 /* SentryCrashStackCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FF9C78A3E1CB9EF63637883B8EB32A9D /* SentryCrashStackCursor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0B9729009B52B1F83A03B398B43D2AB8 /* SDAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F41EB095A01EDA99B2B497F53C1F0E /* SDAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0BE6A4F2147AF27E1F426CB73618739B /* Container+SentryDeepSearch.h in Headers */ = {isa = PBXBuildFile; fileRef = 1754A6ED4900E0794C9F85E0D875BED1 /* Container+SentryDeepSearch.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0C278D28FBE5D9ABCAC2C28B87930AA3 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E59068B900E048C38B63AE64FFC855 /* fishhook.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0C6A47A81D7BB7EB3044BCECB58EA76F /* SentryCrashC.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AC17A06B2CD1137FBA04236CCCD1715 /* SentryCrashC.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0C91143C982032738F7EB25775DA3B6F /* SentrySamplingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 9400F8F8837DB55A86F586A9609B2117 /* SentrySamplingContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0CB9B55735A73E69F337D6925C1D67CD /* SentrySwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E52820D73978A25A8C1B784E898C377 /* SentrySwizzle.m */; }; + 0D4AA798F6D543876B4184B6A08E716B /* SentryCrashObjCApple.h in Headers */ = {isa = PBXBuildFile; fileRef = C5E2A317B34E97C0BC9E7D8A5432134F /* SentryCrashObjCApple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0DB4433111B4ED4C8F2F9C32888A9F27 /* GIFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F714842293BA367D0CABC101D6E183F2 /* GIFAnimatedImage.swift */; }; + 0E0BDAD6524C03845FFA300E7FCF550B /* SentrySpanContext.m in Sources */ = {isa = PBXBuildFile; fileRef = CAAE2845DDE3787AE62AC63FD77B83AE /* SentrySpanContext.m */; }; + 0E635614142E32FD9F8C01EDB69B1625 /* SentryInternalNotificationNames.h in Headers */ = {isa = PBXBuildFile; fileRef = D1CFE48E766C5DA9E609AC5092AAF2E7 /* SentryInternalNotificationNames.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0E66A0F36DD725E82041A51F593EA534 /* EXPMatchers+conformTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 1863F1E2E1E6A795639A75A3C001F893 /* EXPMatchers+conformTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0EA31AE23591C4AEE8C9CB6632ACDBCB /* SentryCrashMonitorContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A1ED785B7119EA303867FB77D23DC691 /* SentryCrashMonitorContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0F0E966DCF3F4695681B9D66EF334E76 /* SentryOutOfMemoryLogic.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D55DD2E8B9C505A780231B6FA0855C7 /* SentryOutOfMemoryLogic.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0F1E156138AA4165ED144E0EABC9A887 /* SentryDefaultRateLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = FF14B9E54E4823DBAA00FF762A1568CE /* SentryDefaultRateLimits.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0F32EB10487FD4E1AFB085354A2F4642 /* SentryCrashMonitor_Zombie.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F6115F119202A304EEF57D5B2954F18 /* SentryCrashMonitor_Zombie.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0F4705701AAD5ED85AA7DBB042A4712F /* Sentry-tvOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CFCECE13EE1E489D7FE9331B3E9AA5A5 /* Sentry-tvOS-dummy.m */; }; + 0F5E1D54200B7ABEC45030D6BB49E2BC /* SentrySampleDecision.h in Headers */ = {isa = PBXBuildFile; fileRef = 58976039A170F01993918E5B37032F00 /* SentrySampleDecision.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0F72B24EF424B11E17F35B5E63DF856A /* NSPopover+MISSINGBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4480333F342523BA7314F31E49980C8A /* NSPopover+MISSINGBackgroundView.m */; }; + 0F791D68F15E4822C7832B3FEB63375D /* NSDictionary+SentrySanitize.m in Sources */ = {isa = PBXBuildFile; fileRef = 7899C1894601F14A332E8A700E2B043C /* NSDictionary+SentrySanitize.m */; }; + 0F8D3E5A1F385A27C17AC3FBAF77D7B9 /* SentryCrashStackCursor_Backtrace.h in Headers */ = {isa = PBXBuildFile; fileRef = AE44188648C57CDADB4BBBC4CC62CC3A /* SentryCrashStackCursor_Backtrace.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0FE351CF21E5FB05948FCA25DA714E20 /* OCMBlockCaller.h in Headers */ = {isa = PBXBuildFile; fileRef = 0565FE21AB63AFEF67A9CA59773523DE /* OCMBlockCaller.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1012286B28D43DAAFC7BF5AECD94DDA3 /* EasyMapping-macOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A1A3F63E2060CABB0E5098F6A5ED0E8 /* EasyMapping-macOS-dummy.m */; }; + 103616B200DAE8A3AA9EC3AF8A1A0DBD /* SDDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F04A6A52D80B51E2844EAB7D7922D07 /* SDDiskCache.m */; }; + 10982A735A92B1781B7D0319A0B89D4C /* SentryMechanism.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E4DF4622B9F51C96D13D365CC3101A5 /* SentryMechanism.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 10DE4447065F7B39B0213549E5291746 /* SentryException.m in Sources */ = {isa = PBXBuildFile; fileRef = BBAB57A64E6C4CD076398499D4EFB432 /* SentryException.m */; }; + 1192C87EE0EDF2562FB83CDBECD9FCFD /* SentryDateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E61FB7499176B62067C34B234D8526A /* SentryDateUtil.m */; }; + 1219102F3ACBEB268E978460516FFDA4 /* SentryException.h in Headers */ = {isa = PBXBuildFile; fileRef = 539A29AA5C82086D87D861EF794BE53A /* SentryException.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1222560B913CB9C9C0D14221D02C8306 /* EXPMatchers+beTruthy.m in Sources */ = {isa = PBXBuildFile; fileRef = A11A7A73E2BA6DE77E94D1B9080AFD49 /* EXPMatchers+beTruthy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 124B5CDCE1A2C1CC04D40D0A096A4149 /* SentryEnvelopeItemType.h in Headers */ = {isa = PBXBuildFile; fileRef = FC629D7EE5D4E3D25A8DC71977FB9A70 /* SentryEnvelopeItemType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1305E3E5FE7BBCA238F58E82FF3CB112 /* SentryCrashMonitor_NSException.h in Headers */ = {isa = PBXBuildFile; fileRef = A55A5E501307CDABEECE7608B972AA18 /* SentryCrashMonitor_NSException.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 130DD540BB6A30E2A78896396C4EFBB3 /* SentryCrashThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 71699EDEB34DA036C4C91F1111D82BC0 /* SentryCrashThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 14122D6356629DE6958BF7E2D2F10328 /* OCMInvocationStub.m in Sources */ = {isa = PBXBuildFile; fileRef = BE880AB1DB81B927C0BC664948EAC229 /* OCMInvocationStub.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 14726DFA1A1C8CD6D90D482A44DDF487 /* UIImage+MultiFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 7078F92F031EADAB7617667F38967D79 /* UIImage+MultiFormat.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 14C7625735FDF34CB497D8AA8DEFFD4D /* OCMStubRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 353D6F3694A36EA3F9994B9E30E9C7D2 /* OCMStubRecorder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 159F81DC613185E5D038DECF196C9352 /* ImageDataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A394BD3445668D99A5E87488474235A3 /* ImageDataProcessor.swift */; }; + 15A345758D8182D5622A75B1009514FB /* SentryLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F317A88BF3EC0E25B9D3EEEE2368BF99 /* SentryLog.m */; }; + 15D2A19DB46A147228619855051D29BE /* NSArray+SentrySanitize.m in Sources */ = {isa = PBXBuildFile; fileRef = C071660C8956DB87DA658081A5D78D83 /* NSArray+SentrySanitize.m */; }; + 15F113A6B9C45658AFC05D44CEB1141D /* SentryCrashMonitor_Zombie.c in Sources */ = {isa = PBXBuildFile; fileRef = 8118BBD07F06D9B65E67B6C0CAA7BAD5 /* SentryCrashMonitor_Zombie.c */; }; + 163CA6B366B2EEB01CB5F00D1759BF8C /* NSMethodSignature+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = A09C87640D6D2DC5D6EB71A57E7E67BB /* NSMethodSignature+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1655589080B07484CFC0959B2CC2689B /* OCMPassByRefSetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D5DE687FE4F1B67174712D0C059309B /* OCMPassByRefSetter.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 16995CDC4E1A838D97993D629400A3B1 /* SentryCrashJSONCodecObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = AC14140BA60C11A89D4E5C625E6C09F8 /* SentryCrashJSONCodecObjC.m */; }; + 16D119900A2EFF37CC7D5737A761290D /* EKObjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D94575F97C3B97906EA0DF45F8B3665F /* EKObjectModel.m */; }; + 17B47C54800CAD288E8A16767F283101 /* OCClassMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = B93A61CED72D42D90093A6C9AE0216A4 /* OCClassMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 17D16CC85A55F7893378226320FDDEEA /* SentryLevelMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CA4FF39ED0B887747BAB6C80C3A034E /* SentryLevelMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1815CB239F54F1DBB6D094492FA67935 /* SentryCrashCachedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 73FBF880D819F3A37A47DF758F95393E /* SentryCrashCachedData.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 18A81E582E9A975270C6E32EA47EB8DE /* EKManagedObjectMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = F2C7A6B01B0431E52F0426FFA9FA836E /* EKManagedObjectMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 195A249E1689E50752E0BCC1BF9014AB /* SentryUserFeedback.m in Sources */ = {isa = PBXBuildFile; fileRef = D31491006FD74023E72260AE10EAB3EA /* SentryUserFeedback.m */; }; + 195C16A090EB57E09CF7DC44C5C16206 /* SentryFrameInAppLogic.m in Sources */ = {isa = PBXBuildFile; fileRef = F2F27DBEE78FB424F0C52D196487096B /* SentryFrameInAppLogic.m */; }; + 19B029DC65FAE863E6B0136CE5DAAE3F /* SentryCrashSymbolicator.h in Headers */ = {isa = PBXBuildFile; fileRef = C09407241B2BDC8483771D6D0859B8D2 /* SentryCrashSymbolicator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 19B8A147AE34E2B5E59F104313720636 /* MixpanelGroupPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6710CF323F6003446FA076D00037B1B7 /* MixpanelGroupPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 19D56BAFFB87CE38FEC9E4866CC9DB34 /* SentrySpanStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 258332C878F6E9B127D8D8CDC15ABBBB /* SentrySpanStatus.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1A2C3447836599F5FB5220C32241D0E5 /* SentryScope+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D117F3A6C5BAE303986E03C59EAD73E /* SentryScope+Private.m */; }; + 1A39A8AA098EDD950FCD1C5C7490C53E /* Mixpanel-macOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B871ADB422CB46B0A68EFB7C06F829F5 /* Mixpanel-macOS-dummy.m */; }; + 1ABA6AB04474E83F6F40C5337D2D2C4F /* SentryInstallation.h in Headers */ = {isa = PBXBuildFile; fileRef = 216232C7E3B491836F7FE4829869B5D7 /* SentryInstallation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1CE288226DA4D5164FDE93288F20616B /* EXPMatchers+beNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AAB0857570A8D45394C82F74F2306E /* EXPMatchers+beNil.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 1CE803860576BC6FA2F369A0EB19D015 /* SentryCrashMonitor_System.m in Sources */ = {isa = PBXBuildFile; fileRef = 977EB770ABF48ED5105390B227CF1057 /* SentryCrashMonitor_System.m */; }; + 1D287EFBD7E47AAC1F2E7EBA359EAC94 /* NSPopover+MISSINGBackgroundView.h in Headers */ = {isa = PBXBuildFile; fileRef = F7799C05177DB8BEF9236E1AF5D9AA12 /* NSPopover+MISSINGBackgroundView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1DC14E6955C085C49A36A11EC77E5709 /* Pods-BitBotTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB85262F5F33A0C16F18E0EB8E0C8CF /* Pods-BitBotTests-dummy.m */; }; + 1DD728FE53DADBA98A838C0F260E89EE /* OCMIndirectReturnValueProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = C14C6D61A8BD9081A41C40D24192DE44 /* OCMIndirectReturnValueProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1DF5ECB76476BA3197B6C803B7F9A588 /* AuthenticationChallengeResponsable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7692F573D1E2DC63616021DF3412CD78 /* AuthenticationChallengeResponsable.swift */; }; + 1DF756CE0E40EB5671264AEA58B2B231 /* SentryOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 98FC521CFE4B7F822E15B95D82BF96FF /* SentryOptions.m */; }; + 1E0138011438F599DD914AF8FA9D75B0 /* MixpanelGroupPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6710CF323F6003446FA076D00037B1B7 /* MixpanelGroupPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1E13E59EAB5B4BBF1C9EACB6A6F103FC /* SentryAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D10EBA641A0E8165BB44E4DE84E910B2 /* SentryAttachment.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1E3042F668BEAF92BEB9422C8E13A263 /* SentryCurrentDateProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = B55607C0615FFE6430F17A69A880EB12 /* SentryCurrentDateProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1E58E12AEF469FD04EE76BA0CF146635 /* EKManagedObjectMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DBBDC9C6D38AE230697D019D427B5D5 /* EKManagedObjectMapper.m */; }; + 1EBDD2B28C8B1BDF757769E92E8E80BA /* SentryCrashMach.c in Sources */ = {isa = PBXBuildFile; fileRef = 864951E1419140446120DB8592F5D890 /* SentryCrashMach.c */; }; + 1F250882122AB915F3FD7B0CF2F5EB9B /* SDImageGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = B524FC3A2CD1BCD9A80259FC8CE87C5F /* SDImageGraphics.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1F3315414DEC5158097B9B9A54ECE5E0 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5DA7F5301E11295B7E5A404917A412 /* Box.swift */; }; + 2010039F5D1F5F4AB05D0C106D527D5D /* EKObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = A73048B0940DC44FBE9BC89CC02BAD9C /* EKObjectMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 20B2F87DE97F1A2661A5A268DEBABA00 /* SentryOutOfMemoryTrackingIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = D63CDF6E2D49F7055CDF917E715932E8 /* SentryOutOfMemoryTrackingIntegration.m */; }; + 20C469D06B05527A1CDA62407159871B /* SentryId.m in Sources */ = {isa = PBXBuildFile; fileRef = 157863084A17F4A1D73C4C2C4237CF48 /* SentryId.m */; }; + 20C529D50C75C371E15BCDFFE0A15F98 /* SentryCrashReportSink.h in Headers */ = {isa = PBXBuildFile; fileRef = 085DF157C909A8A4111A1513A172F832 /* SentryCrashReportSink.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 211A21A6B25A968B0632C27A984C273E /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37036428688A5CFD9A0E8390B2C3836D /* UIButton+Kingfisher.swift */; }; + 213C095EF87C2009F3EAEA96C0B72A97 /* SentrySwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E52820D73978A25A8C1B784E898C377 /* SentrySwizzle.m */; }; + 21B6AE69441E82E2E5716EF3231492A9 /* SentryHook.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C261258984F7E4A236711D1EA29A49 /* SentryHook.c */; }; + 21D97B29CD24881CDB275150FFACB46C /* EXPMatchers+raiseWithReason.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC039A57E303FB78B1A337C34F6D1D1 /* EXPMatchers+raiseWithReason.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2252C975D5E36FEB868A0FBC10D3E173 /* SentryRetryAfterHeaderParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 97ED53DEEF94C51589000FDDBDD245FC /* SentryRetryAfterHeaderParser.m */; }; + 225460728C5092E4E08968652684DD94 /* OCObserverMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = EFA3E94236148B21C103665DBDE36A19 /* OCObserverMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 22DDBBE17C9149D396F4913460A6C2D5 /* SentryTransactionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B10146712CA2C75052E427FF98FEE76 /* SentryTransactionContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 22ECA059E65D73DA50BDB13FCCCF3286 /* EKManagedObjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D19CFB58A52BB6ECB5EAB0DAF6B03C2 /* EKManagedObjectModel.m */; }; + 22F13A37E9DEBC541FA2DDFFC69F9446 /* SentryHttpDateParser.h in Headers */ = {isa = PBXBuildFile; fileRef = C885E0C6872E0DD37AE7F83D152E4CC8 /* SentryHttpDateParser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 235BB46399C919E853BD78A4DB20FAE8 /* SDWebImageDownloaderConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C1E4494082CC0E21EBD915E0B5B25F8 /* SDWebImageDownloaderConfig.m */; }; + 235E6007FB481FCAF9ACE09DBA49CD73 /* SentryCrashDefaultMachineContextWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = E313C6D74AB03A8A9C0A213DFF159F90 /* SentryCrashDefaultMachineContextWrapper.m */; }; + 23910BE384DC89AD2F8F011EF9847609 /* MixpanelPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D213DC3D25A75835B758B314D291EB4 /* MixpanelPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 23FF3738AF42DAA97EDC406C88BFBF94 /* SentryFileManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 017B91A7D74324D087DE3D13046EC99E /* SentryFileManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 24037CD96B3797AC808840774B5A1B3D /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CFD317BCE11392832E42B3F7239B444 /* ImageModifier.swift */; }; + 246BAB24CF6BFE7344492720C2B3B118 /* SDImageCacheDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D606D5FCFC2B24362878D144E408FB4 /* SDImageCacheDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 24DCA3772E4FA6F77D08880B8E47904F /* SentryClient+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = AD6D919B73E1764BE2EA183589BCD2A2 /* SentryClient+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2575E63759688B01F29224EE5CE0D567 /* SentryHub.m in Sources */ = {isa = PBXBuildFile; fileRef = 051572966812B4346D5D43CB731AF26F /* SentryHub.m */; }; + 25AA61B3AFA6BA2174C68BCEC65EFD44 /* NSDate+SentryExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = EE988064E682B9A56B6A0555F5C13ADF /* NSDate+SentryExtras.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2612A3ED4E1D25EF47797B1CE18E69C2 /* OCMArg.h in Headers */ = {isa = PBXBuildFile; fileRef = 249A6E6554241E9A2E70500432FE1E9B /* OCMArg.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 26247F0051223C088BCBAC226FA84A0E /* SentryCrashDefaultMachineContextWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = E313C6D74AB03A8A9C0A213DFF159F90 /* SentryCrashDefaultMachineContextWrapper.m */; }; + 26340C119D8DC11C5D0A66D471895277 /* NSDateFormatter+EasyMappingAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B9746E334F7B96E4F782D91BECC052AB /* NSDateFormatter+EasyMappingAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 263CB8C21A0D8B4917D73251A016719F /* SentrySpanId.h in Headers */ = {isa = PBXBuildFile; fileRef = 08B901DA30F9297F9B7E39C00791CAE4 /* SentrySpanId.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 26656B2A7E2D85C40761063B8E8B13F3 /* EKRelationshipMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0311EFB6DC50C64A6FA83FA56E458E77 /* EKRelationshipMapping.m */; }; + 26D1A2F917DAD31D34EB0245FE6253F0 /* SentryCrashDefaultBinaryImageProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = D611C4E992B69008A1A656939508A290 /* SentryCrashDefaultBinaryImageProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 26DE4140E14E294975042563DAF50F36 /* SentrySamplingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 9400F8F8837DB55A86F586A9609B2117 /* SentrySamplingContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 26E33CBCA823C72C51357582994E746C /* EXPMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EB0E1EE3862BD69F6E01020B2BDE08E /* EXPMatcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2700518F3FDFB549DA3A258448FA4198 /* SDAnimatedImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 86690CFE527A596F3B6AA8038D199EA2 /* SDAnimatedImageRep.m */; }; + 2726C0617CCB2E7829158A457641D4A4 /* SentryAppState.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D3339DEF95FA636F126C2080A088321 /* SentryAppState.m */; }; + 27795A61A33C0A1A0EE7BC1099284DA5 /* SDImageCacheDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = C3D92E3100FDE0A02B9E624C29649659 /* SDImageCacheDefine.m */; }; + 27A742BBA9FBC26A6E6CD59939F7C4D0 /* SentryCrashThread.c in Sources */ = {isa = PBXBuildFile; fileRef = DC3A1C125FE9A2938808FC9189B98F86 /* SentryCrashThread.c */; }; + 27FF6FF7A140CAB98827EA6F68F90D7D /* SentryUserFeedback.m in Sources */ = {isa = PBXBuildFile; fileRef = D31491006FD74023E72260AE10EAB3EA /* SentryUserFeedback.m */; }; + 28886A3C19965402C2DBDAEBF7E6D0EB /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23EF580A0426C81F2EA1FBA4B7DE4D86 /* ImageTransition.swift */; }; + 28A5F2DCB9AA922830068A1224805A96 /* SentryCrashSignalInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 74410FD9A799F3F268BFA760FFFE0B0F /* SentryCrashSignalInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 28AD902BEAB65883967CCC67EC8B8A82 /* SentryCrashCachedData.c in Sources */ = {isa = PBXBuildFile; fileRef = 100CF4E00773DF746C10C45D5F9A6A88 /* SentryCrashCachedData.c */; }; + 28C5305E54BEE838C2417164F7FD6DC8 /* SentryCrashMonitor_MachException.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A825AE1B597340584246AA8758C978F /* SentryCrashMonitor_MachException.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 29070F37FD7A660E573815EEBCEB47B9 /* SentryCrashSignalInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 5E10825BF1E02BA77AD12B4EFCB737B7 /* SentryCrashSignalInfo.c */; }; + 293358E44E368F842BD4203919EBDFB7 /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE114970A6D97164E402E9B61139AA6 /* MemoryStorage.swift */; }; + 295E07FCB2E9A427323FE2A0D404EF7C /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42B31391B2FAC25C05285540C1CF6F6 /* KingfisherOptionsInfo.swift */; }; + 29FDD7D64DD97DC7C341E1450BED0BB0 /* MixpanelPeople.m in Sources */ = {isa = PBXBuildFile; fileRef = F3864646ED479BF8F6292472141DE6C4 /* MixpanelPeople.m */; }; + 2A83F376A90E8DAA9A28D2AEA8E1CC87 /* EKObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = A73048B0940DC44FBE9BC89CC02BAD9C /* EKObjectMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2B16EA7802DB6BAB1B388CCFCB29ACA9 /* SentryCrashInstallationReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 87B8D862925C1E3D10970596A63C2CEC /* SentryCrashInstallationReporter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2B1F867E090435A7F8A6B65678467E7C /* SentryCrashString.h in Headers */ = {isa = PBXBuildFile; fileRef = 8522E68E0FED7627A746EDFD9DDD0700 /* SentryCrashString.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2B28795761CA8E052BC46D60C69DF0F0 /* MixpanelPeople.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C0A1B0E54182F7303BF9551261EC6D3 /* MixpanelPeople.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2B48CF877B00FA2F8B00C1A069B2D662 /* SentryAutoSessionTrackingIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = EC93C90F2B5676049CC384D0AB9C6972 /* SentryAutoSessionTrackingIntegration.m */; }; + 2B8DBBD0B12779D9C62B30D8D30BA557 /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 223B6A8C24D4E6A3F09A2E454C53B4C3 /* SDImageCache.m */; }; + 2BBF47486443C99FE5519B2C27EAF1A6 /* SentryCrashStackCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = 422EB5E0CBDCA3F2BC8CD610045F4AC6 /* SentryCrashStackCursor.c */; }; + 2BDEDB0CFA0B2BC566A697B3D47FA60C /* SDWebImageError.h in Headers */ = {isa = PBXBuildFile; fileRef = 04DE6B370E3EE3FE5D61EECEE498400B /* SDWebImageError.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2CA22754CA1D08462ACBE3F9F3726D95 /* NSArray+SentrySanitize.m in Sources */ = {isa = PBXBuildFile; fileRef = C071660C8956DB87DA658081A5D78D83 /* NSArray+SentrySanitize.m */; }; + 2CB3EA10753C3BE4CB7774CB28971D8D /* SentryRateLimitParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC646924C2D2C93556CA6232316B400 /* SentryRateLimitParser.m */; }; + 2CFC6B18F22665A941B9DA0C1C3FEB82 /* SentryCrash.m in Sources */ = {isa = PBXBuildFile; fileRef = E637A1CA51A72009B436C19799A1EB1A /* SentryCrash.m */; }; + 2D566410B96E56D417C8BB7542C67A91 /* SentrySpan.h in Headers */ = {isa = PBXBuildFile; fileRef = EE4528E0DF692080615D4E109A960DBD /* SentrySpan.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2D5858A78F99A1196B5416C63B18F8AA /* EXPMatchers+haveCountOf.h in Headers */ = {isa = PBXBuildFile; fileRef = D01CF0850D3D4C872590CBFBDC03EB5A /* EXPMatchers+haveCountOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2E7E23F3948479C7324DEBEF52AC88C9 /* OCMExceptionReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A29DCD4677EEB50CC5E79F957801968 /* OCMExceptionReturnValueProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 2ECD0E4C2802CEC73D5FF007581194FA /* SentryTracer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AABDDA011743888BE5370D828CE8324 /* SentryTracer.m */; }; + 2EE6DC6F9610EE4F4C947170DC4D194E /* SDImageGIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF3E89497AE3160C90222810494D9F3 /* SDImageGIFCoder.m */; }; + 2EFDAE49DE30F6F1219FAFFAA4917E26 /* SentrySDK.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A164679F41D45A5932DAA29D61891C2 /* SentrySDK.m */; }; + 2F004A303B65F61BF5955637C1D0348A /* SDAsyncBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AE56FFEC107368C3977D88E534EB6929 /* SDAsyncBlockOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2F17B8F399F7CA46935ED1D46E657325 /* SentryCrashIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 131891EA60BFD2C10D365038115CC8C2 /* SentryCrashIntegration.m */; }; + 2F197C91E76D2335F5FED44C3DFEFAAC /* OCMObserverRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = D22AF5F63AD1761496D54AE9764983A6 /* OCMObserverRecorder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2F2B73383C4EB46C4A2568304CC40A8F /* SentryCrashJSONCodecObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = A256F1C1E08340F2EEA91E8F3B75F656 /* SentryCrashJSONCodecObjC.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2F747801DA2AFDF9E1069ACCC4AAB343 /* OCProtocolMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = A27A3F985112C5E7105FF757855141B3 /* OCProtocolMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 2FA1093AF879015B0B01BD1AE304D9BE /* SentryMeta.m in Sources */ = {isa = PBXBuildFile; fileRef = D11372170552F442945E0B5B17587894 /* SentryMeta.m */; }; + 2FE1E99E3D73775B86C84EECBA5FA1D9 /* SentryCrashReportStore.h in Headers */ = {isa = PBXBuildFile; fileRef = E772C6FC8CD4F5F3153C1AD785CA8BB4 /* SentryCrashReportStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2FEC1C3CEE441535210ECFDECB448F93 /* EKManagedObjectMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DBBDC9C6D38AE230697D019D427B5D5 /* EKManagedObjectMapper.m */; }; + 3010F2355B89399CD23D206AA0618EE5 /* OCMConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = EE73BC7E6B9CE2CE444F233D3BD368DA /* OCMConstraint.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3015CA46040CF18E0F71602202C29338 /* SDImageCachesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EC1A9E5F4BFAB7EC1F350C715A897657 /* SDImageCachesManager.m */; }; + 306CE82B21363D3A2BE5791B0441F22C /* EXPMatchers+beKindOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BA44563517EF05D49C2288AC8068CE /* EXPMatchers+beKindOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 309B84784D7DBFFE4D99D7854FE7B115 /* SentryCrashCPU_arm.c in Sources */ = {isa = PBXBuildFile; fileRef = 8AF6BB3EE258D3AC2AA0C205519F518D /* SentryCrashCPU_arm.c */; }; + 30FB698D984E3201F70BC6809D5DA022 /* OCProtocolMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = CB51C6354F85DBE35F75A892B2A35813 /* OCProtocolMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 310F4B5D204D4775A758F8B778E52B8D /* SentryDefaultCurrentDateProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = DA34AA796C52BB44C0BD196FB3DFF6F8 /* SentryDefaultCurrentDateProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3170D006F584356009EC14D9AEBD6227 /* EKObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = CF5EAFB93582013A51B76C904CC6049D /* EKObjectMapping.m */; }; + 31E32A4CB736BDDFD999D5C2B5853A54 /* SentryCrashExceptionApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DFFECBC682FD9C906742F24B35A3F1C /* SentryCrashExceptionApplication.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 31F103D325335CB0DF660BBA17444855 /* SentryDsn.h in Headers */ = {isa = PBXBuildFile; fileRef = CD4A38B44E188BC0AE09430BFEDA430A /* SentryDsn.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3253A1DE32096BAB15AC7D2DEB5DF435 /* SentryThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 89B11BFCB1A668E910E7D78C6959D8B2 /* SentryThread.m */; }; + 329727CC5B87F69BAF0886DC846F57EE /* SentryAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D10EBA641A0E8165BB44E4DE84E910B2 /* SentryAttachment.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 32BA8E1007096A8E8D09AB22CFC54EDB /* UIImage+Metadata.m in Sources */ = {isa = PBXBuildFile; fileRef = DDF3E3AFB8E2DB0B1288BA44784E32C1 /* UIImage+Metadata.m */; }; + 332EDD4B52609D9E2FAB74C157DABA76 /* SentryCrashAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FDBE617EF1EA76B9219DC475DFE0B4D /* SentryCrashAdapter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 332F71C7E4732A9E1865EBF987DC1E79 /* SentryCrashMonitorContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A1ED785B7119EA303867FB77D23DC691 /* SentryCrashMonitorContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 332F7401BFB8CA9CF20EDA92B99E4554 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF122E9704C7DFBCE5DFE35410F55E32 /* Placeholder.swift */; }; + 3392D2E960D7DC25FC7654AE46D88826 /* SentryCrashDefaultBinaryImageProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = D611C4E992B69008A1A656939508A290 /* SentryCrashDefaultBinaryImageProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 33D272880DFB19B6207525CA74B37084 /* SentryCrashStackCursor_MachineContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A339574BDAC6852EC8CD47F1A626B26E /* SentryCrashStackCursor_MachineContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 33DF0A3CD48108AEA7B20F04837298F4 /* SentryCrash.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D34CB3DFF8BF5C1EAC6DDE6A5A0F132 /* SentryCrash.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 343FEF7BBB93D1BB48BB25E4F6E128DA /* SentryClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BEE132FA31AD0DE7FE890AA026022DE /* SentryClient.m */; }; + 346B0A9DA79A7C913D04703A59139DA9 /* SentryLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C35F9CE61D977267F2235041B820E03 /* SentryLog.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 349490565ABEE6D73096D9F5C17B4B7F /* SentryLogOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 60FA170C048C44881C44223DA22C1A34 /* SentryLogOutput.m */; }; + 34B24EC9EF1F355F35873412EB34BEE8 /* SentryCrashFileUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = CDE4D9299F0AF2CF5B0B8F25A0A284BE /* SentryCrashFileUtils.c */; }; + 34E54E4279F1798CD2967306D23D9D4D /* SentryRequestManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1861C909B39B2D38DFFDE22EABE4EA12 /* SentryRequestManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3544268F1900FEA515469308E34B5843 /* NSNotificationCenter+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D15A2DBE72CBB3651486C29CE7CFA7C /* NSNotificationCenter+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 35C45AC728A83DE07326B4F8ADB08A72 /* SentryCrashStackCursor_MachineContext.c in Sources */ = {isa = PBXBuildFile; fileRef = 7DDB6D70780CEE79091CB18DC8FFCA26 /* SentryCrashStackCursor_MachineContext.c */; }; + 35F323C91106C14A77D1ED71480C31BB /* SentryDebugMeta.m in Sources */ = {isa = PBXBuildFile; fileRef = D4E58AC687FF6638E95247AC8D47481E /* SentryDebugMeta.m */; }; + 36694278FBCC39D9A25D3713E6D90485 /* SentryCrashStackCursor_MachineContext.c in Sources */ = {isa = PBXBuildFile; fileRef = 7DDB6D70780CEE79091CB18DC8FFCA26 /* SentryCrashStackCursor_MachineContext.c */; }; + 368AC5FD67E926ACA2C7E206F8F4FA59 /* SentryCrashReportFilterBasic.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C0D06F888A372154BF1F8BA0B428CC3 /* SentryCrashReportFilterBasic.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3726CD36BF4080EE1145EC822AA6BF4C /* EXPMatchers+match.h in Headers */ = {isa = PBXBuildFile; fileRef = 5122E3FCDD75BB5EAA1489400AFCB5FD /* EXPMatchers+match.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 376B34322C3C942845B6A48214F2D45A /* SentryOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = F7D074B3F94A6FA8E0911B6B79FCE292 /* SentryOptions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 376F295FE52F25B45BE3C81F5F158818 /* SentryLogOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 60FA170C048C44881C44223DA22C1A34 /* SentryLogOutput.m */; }; + 382C9C3A0F41581340331A194F3672E6 /* SentryBreadcrumbTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 729F7AFE262AF22B1D2157AE03081029 /* SentryBreadcrumbTracker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 384D6A5F12F43434A7E43AEFE93E9147 /* SentryCrashCPU_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B535A4FC57286211DE40388C054BDAC /* SentryCrashCPU_x86_64.c */; }; + 386925CC6164F7530A7CD706170498DF /* SentrySpanId.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8FC0B52735277BF7A7F2DBB43DBB93 /* SentrySpanId.m */; }; + 3883614D0C16437A09C006BDB41B0E37 /* SentryCrashDefaultMachineContextWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 67C4AF11F6139DA148872B8D9BAE44BC /* SentryCrashDefaultMachineContextWrapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 38D46DB9704C8E2658ADCC67FF846440 /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F73D52AE3C01661DE55ACA0D0E98D50 /* SDWebImageCompat.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 38F31B524B46F859887154AAB4E659AB /* NSPopover+MISSINGBackgroundView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD6179D6616CC83F0EBC88FEB40E3F2 /* NSPopover+MISSINGBackgroundView-dummy.m */; }; + 3923D7BFA8E5EB8D7153F94931556FAC /* OCMInvocationMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = F8E6838B2952D27DD32D3B00DF7C1B66 /* OCMInvocationMatcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 3933A57238E726E8FB97C695F18B8B0D /* OCMArg.m in Sources */ = {isa = PBXBuildFile; fileRef = 99FF117BFA025DA2B85FF183B445BBF2 /* OCMArg.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 39540AB3BF2C0D0AC47D97AB9036F71E /* SentryRateLimitCategoryMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E01B96E9D6EEE758CC6F000CB4F7ED0 /* SentryRateLimitCategoryMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 39CDE5B1AA525EEFEFF30B9538B8A7FB /* SentrySpanProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 78AFD32C679BA0512CD29B01C52FD8E0 /* SentrySpanProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 39DE503905BDCF4F110A16EEDB54F1AC /* SentryLogOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD6FF53E585D37C0030DD7DDB732653 /* SentryLogOutput.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 39DEE11CF63642BF01433A0CEA2D0070 /* OCPartialMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 6139A0A10B75059FF153ECA3DE15D1AB /* OCPartialMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3A20B0B018A3ACBD288A530E01CCA61A /* NSMethodSignature+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D1DC52144056CD5535375140BBE4CB3B /* NSMethodSignature+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 3A5EC68C9C94AF6767B9DE70F70F765D /* SentryAutoBreadcrumbTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1A06E37E387E8DFDB3FAC7C71EADA3 /* SentryAutoBreadcrumbTrackingIntegration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3A73912B0BE0281F3DD177F3D361DCA2 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9980BF60F7882669ADCC6EACBE8B4B67 /* UIButton+WebCache.m */; }; + 3A90B8CAC14516118DD2B9F045FAD7D7 /* EKSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 80F38BDE157D18A99DE165F15628E9D8 /* EKSerializer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3AC2A7F58EB378F6B9493E38019591CC /* OCMMacroState.h in Headers */ = {isa = PBXBuildFile; fileRef = D937487D98CF1317A50F757709136421 /* OCMMacroState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3B5F00F3E5996A8910F60C3C0D7FB45B /* SDImageCoderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E3C41018B6941535465C50E902AC4F40 /* SDImageCoderHelper.m */; }; + 3B8DA4EF7CBB3EDF7045DF2232786261 /* SentryEnvelope.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED89C1427E6BA14DF252DAAE9BBC9F5 /* SentryEnvelope.m */; }; + 3B91CCA46476F9085E8D56D81ADC6437 /* SentryCrashIsAppImage.h in Headers */ = {isa = PBXBuildFile; fileRef = CD43EB3DB8F1A13F4F230EB3F12BD14D /* SentryCrashIsAppImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3BC722FA65856E8F66EDC14D13738212 /* SentryEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84148C4BBC5639650E918B7D1AE9FCA8 /* SentryEvent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3BCE4893063AC34B03686EDB4327204E /* Kingfisher.h in Headers */ = {isa = PBXBuildFile; fileRef = CFF959F28BA7ACD5D882BBA3D1C58893 /* Kingfisher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3C2A6844C54198CB7CF7AD0FA63358E7 /* MixpanelGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 327F432D938896DE00325DA3BCAC1A8E /* MixpanelGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3C5178CDD33187B18E01DF7B336950A0 /* SentryMechanismMeta.h in Headers */ = {isa = PBXBuildFile; fileRef = F1EEA3D5D4E1598D0CBCE3D4DDBF2997 /* SentryMechanismMeta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3C8C22FD31AB056456134B4727C6CAE5 /* SentrySpan.h in Headers */ = {isa = PBXBuildFile; fileRef = EE4528E0DF692080615D4E109A960DBD /* SentrySpan.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3CAF2A050912D6E9F376201660C8251D /* MixpanelType.h in Headers */ = {isa = PBXBuildFile; fileRef = DB9FF4A48AF84AF31680A56E61A2BF84 /* MixpanelType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3D382E499B8BCAF8A1B0B32C227B41A1 /* SentryClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1693B04CD7105542A4995D7B1860CB4C /* SentryClient.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3D6085CD92FFD56CA7DC96F005C53502 /* SDWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D2F0B54A0E96CE375161189B18840A5 /* SDWeakProxy.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3D6384561F570C0C678EF055B88E4F23 /* SentryRetryAfterHeaderParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DECCD676C555CF5BA3C512220A939A6 /* SentryRetryAfterHeaderParser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3D7AF741C5E7EB2D3EAF8B1B36581701 /* OCMPassByRefSetter.h in Headers */ = {isa = PBXBuildFile; fileRef = 943A6DC32F2A12EA051DDB9E22D150E3 /* OCMPassByRefSetter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3DD573909A68DB21A9E8B66F24EDB1A7 /* SentryEnvelope.h in Headers */ = {isa = PBXBuildFile; fileRef = E06EC8CDC64B1745C9173D810AF762B5 /* SentryEnvelope.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3E05CEFCFE31C9A066BBF5976601333B /* SentryScope.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F57830DA0361A1D478D6FD1206B5C8C /* SentryScope.m */; }; + 3F199CE43433677AE6B4874DCB4762D6 /* SDMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 33DA7E311D382D1E2A185A8363040779 /* SDMemoryCache.m */; }; + 3F431010BAE68FB8C5879FAD53A7B01F /* SDWebImageIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D1A435A8F0243D5863B9B7E1A343AD4 /* SDWebImageIndicator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3F47B2EAE92B0E2623C18FA59EF28A90 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 143C0131251CC3EC130B715BA6A780CD /* SDImageGraphics.m */; }; + 3F6E67C32D7BED098DF9740C1A5A0877 /* SentryCrashDate.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6C5ADDBAA1A94B1A204F0A2616531 /* SentryCrashDate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3FA9FCD25576E9BC1EF36B8AAE9D3654 /* SentryFileManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 017B91A7D74324D087DE3D13046EC99E /* SentryFileManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3FB675C0E73B6F8058EA1467E1A33C16 /* EXPMatchers+conformTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 70122D147B4CFCF6BD5F06A6D048B8EB /* EXPMatchers+conformTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 3FDB128F4EAD763A8F37183E70F2C8F6 /* SDWebImagePrefetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C4A9EB2EB2E18572F51BBB3635C4566 /* SDWebImagePrefetcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3FF1F325FEEAF8CD6EB331DB94FBA56F /* SentryMechanismMeta.h in Headers */ = {isa = PBXBuildFile; fileRef = F1EEA3D5D4E1598D0CBCE3D4DDBF2997 /* SentryMechanismMeta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 40CD9DDB04FE5E72D8B56512EBDA6EAB /* EasyMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = B074CAB984CC58579CF9DF157C294F9C /* EasyMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 40CF419E980658251FC55B629C1C85AF /* SentryConcurrentRateLimitsDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = EF55C9584F47C438713DC40D4B95320A /* SentryConcurrentRateLimitsDictionary.m */; }; + 40F9B5C5A2DBA02C1AD3F1D71C7B468D /* SentryMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AAE60C4B38EA9E0AAAACD0701EA5D4 /* SentryMessage.m */; }; + 410AF8F3097D212405D3876B99371DB6 /* EKMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F5B2D858E5616537CDD4EA800C5173 /* EKMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 416522372FF901287AD5829BE288865D /* Mixpanel.m in Sources */ = {isa = PBXBuildFile; fileRef = 918C1E8E18681194571CC7CC409D810F /* Mixpanel.m */; }; + 4205F8923996C784064E36B57266AC03 /* SDImageIOCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F1A254848526B7085E6D816DBA83162 /* SDImageIOCoder.m */; }; + 4237B1CD76E9152BA664855BF6CC6202 /* SentryNSError.m in Sources */ = {isa = PBXBuildFile; fileRef = 11570D4A1B52E97A9FA97C20AA7920A1 /* SentryNSError.m */; }; + 4249C373DF03DB91A9578953A77E5294 /* OCMRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E416F122F76468EAD9E8E52289FD699 /* OCMRecorder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 429A8916BCB6A4DBF540EE74DF598BC0 /* SentryTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F77AE7AF85B51FDC734F0B9716C1B11 /* SentryTransaction.m */; }; + 43163FF5C47E1BAAC12E171C188302E1 /* EXPExpect.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5C2078B50FD676339A2FEE36C2439C /* EXPExpect.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 433A302BAED3761EDB444D894B914CAC /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9612BF50019AFAE4BFFBC23DE2E36FB /* Result.swift */; }; + 433DA65CBD4E6720A0F5FE8F37FEEEBD /* SentryOutOfMemoryTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 88DBEA1A6DF2FC4DE59CCC2CAE2B4235 /* SentryOutOfMemoryTrackingIntegration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 43A18C37EE1C1C6D06A302F8641F9FFC /* SentrySdkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BFEDAD83AB355F5DA2420B3CA6B2A99 /* SentrySdkInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 44177ECC2FA1171A09F071042D42C2E3 /* SentryEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E6AD007B410E94A2BBD08C73803082 /* SentryEvent.m */; }; + 441820200996CE7A1B2BA6704C0F6D2C /* SentryFrameInAppLogic.h in Headers */ = {isa = PBXBuildFile; fileRef = 33FE9136D837600FD6367096AD17FEEB /* SentryFrameInAppLogic.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 44188681506D134274D1626284F91312 /* SentryGlobalEventProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = B7B0452CB83EB470B9D578159CD4EC40 /* SentryGlobalEventProcessor.m */; }; + 4423078F86C2E7B54145D76885A13888 /* SentryHook.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C261258984F7E4A236711D1EA29A49 /* SentryHook.c */; }; + 45A54480B743ECC3DE568B170DB0B8D1 /* SentryEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E6AD007B410E94A2BBD08C73803082 /* SentryEvent.m */; }; + 45F2317E23C1AD3DA0B4FF4706A82FC6 /* SessionMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A2DA9F20E042F158279FE9D1897627 /* SessionMetadata.m */; }; + 464B6F049C941AF8720487C77948EC74 /* EKObjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D94575F97C3B97906EA0DF45F8B3665F /* EKObjectModel.m */; }; + 46662E1A6DCBA8F8F0BF54DB050B85F6 /* SentryCrashC.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AC17A06B2CD1137FBA04236CCCD1715 /* SentryCrashC.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46886563296F6F5DEAE5CABFC1A5AF0D /* SentryCrash.m in Sources */ = {isa = PBXBuildFile; fileRef = E637A1CA51A72009B436C19799A1EB1A /* SentryCrash.m */; }; + 476B11C84AE969E07A4CAD5E8BB79277 /* SDAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 73EAEF93218258282F3A5E40521101B2 /* SDAnimatedImage.m */; }; + 476F20500C2C3F50C35E23390D1E003C /* SentryHttpTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = 58390617A0187652449D42C311506573 /* SentryHttpTransport.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 477C77170BBEBE5DA4591B9C45A375B4 /* EXPMatchers+postNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 71D17FB9AD23896A66494244B436948B /* EXPMatchers+postNotification.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 47D455560D66ACA017BB920AF7BB356C /* MPFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = D8728A92B3768750BE8C034BB8A6C225 /* MPFoundation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 47F6C508CFBB0667B100157CAB4AF4A7 /* SentryClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BEE132FA31AD0DE7FE890AA026022DE /* SentryClient.m */; }; + 47FE0CB05A96A5894033A8B83225F6BC /* SentryCrashMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 77E6411FB561EA85553780EA72EC7EDB /* SentryCrashMemory.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4826CB79FAB8E2AE560D9924A300270B /* SentrySpanContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 01C8C1525E5E47B587B3B1805005ABEE /* SentrySpanContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 482815DD16475606993475C0878895E0 /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72E56A84AF11E5CA2CC24F859B6B60B1 /* Source.swift */; }; + 4905496C02DBD3900AFCFD193E891C08 /* UIImage+ForceDecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 96DB10A52721644F3864476CAF337A2C /* UIImage+ForceDecode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 49122F1AAFCC4C67F9FC08F06C9476E3 /* SentryCrashStackEntryMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 098D18C816918B0625F2EFAC46124416 /* SentryCrashStackEntryMapper.m */; }; + 494A8450E53A2F638171049E31106D57 /* SentryCrashCPU_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B535A4FC57286211DE40388C054BDAC /* SentryCrashCPU_x86_64.c */; }; + 4954A385199A818B177E146777CF37D6 /* EXPMatchers+beGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = FD09A0A8C776D6C7C89CC9A450B4C376 /* EXPMatchers+beGreaterThan.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4963DE75332B884EA58EA2DEE9C9EED5 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 37BD8D3AB94FFA0798CB394794BCBAD9 /* fishhook.c */; }; + 498A6B8E37EC169EA181D0AA9F7E402D /* SDImageCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = BD89E69E85081CB3BFA0DA50E6BD729C /* SDImageCoder.m */; }; + 498E5A14A3BAD36D01F3C817BAC822DF /* SentryMigrateSessionInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0963B2E3E97A0722C7CBBDDB36B76860 /* SentryMigrateSessionInit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4A2A2ECD9B7D18856D088C5EC2D15418 /* SentrySDK.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A164679F41D45A5932DAA29D61891C2 /* SentrySDK.m */; }; + 4A2D9307A43FBFC4899C02144F46D403 /* SentryCrashMonitor_CPPException.h in Headers */ = {isa = PBXBuildFile; fileRef = E5772F49F24A961F4D2A7CC2EF2C22D7 /* SentryCrashMonitor_CPPException.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4A646460F7E6DD2AD4970FCFEBEC2EE1 /* SentryConcurrentRateLimitsDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = A07387E3FEA32D2AC879F4FBE79D7CF2 /* SentryConcurrentRateLimitsDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4AA81A4B215994DB285F4F536CB447DC /* SentrySession.h in Headers */ = {isa = PBXBuildFile; fileRef = BFE1C8C5066FDEED8D3A06A903580C81 /* SentrySession.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4AC19F9738754BBD6A5153269565556A /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AC2EE6A36100366A5ACE15D447ED6CB /* Resource.swift */; }; + 4B83DA974BBFBCDF4A52EE13FB629C23 /* SentryTransportFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 249A621C3105048EAC1AAFF00A061841 /* SentryTransportFactory.m */; }; + 4B89E5B5DB9661FEF250097B68406DBF /* SentryMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AAE60C4B38EA9E0AAAACD0701EA5D4 /* SentryMessage.m */; }; + 4BAD3027F3A6591BB8958FA35CB29CAE /* ImageBinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66ECB3B7DF926F46DB3E2A027346DEC9 /* ImageBinder.swift */; }; + 4C1A04A84B22F36975D2918553B1F42D /* SentryCrashMonitor_Signal.h in Headers */ = {isa = PBXBuildFile; fileRef = B7E43F64E96E0C3A23315AD8FDD875B5 /* SentryCrashMonitor_Signal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4C70358EE6DFC36C1A723019F0ED86FF /* SentryCrashStackCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = 422EB5E0CBDCA3F2BC8CD610045F4AC6 /* SentryCrashStackCursor.c */; }; + 4C9FAA6D05D6ED82480FCCB04F9A6BBA /* SentryCrashReportSink.m in Sources */ = {isa = PBXBuildFile; fileRef = 26D65938F613F4DCAC1F063D925D9C8B /* SentryCrashReportSink.m */; }; + 4CD1C2912781807CB5322849038088EF /* SentrySessionCrashedHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DAA072773DE54BFAA4917530A95F092 /* SentrySessionCrashedHandler.m */; }; + 4D6915E7C20FFFFA995E5C9FDDA64C78 /* SentryMechanism.m in Sources */ = {isa = PBXBuildFile; fileRef = 35DF544F231298A2C3983E204103A328 /* SentryMechanism.m */; }; + 4DEC4FC7A759ED6E40C6706E5E500543 /* EXPMatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = C5884F3C5EDA3C444E34EAEFA5496AB2 /* EXPMatchers.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4EB9BDDBBCD6A403D4A7D96618AA63D2 /* SentryCrashThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 71699EDEB34DA036C4C91F1111D82BC0 /* SentryCrashThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4EDF0F8A5BB1BBF3F72F87FBF9D4887D /* SentryThreadInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 6885FD677F329175EFEA133271225111 /* SentryThreadInspector.m */; }; + 4F2A0FE52C169B30779382C75D251BE8 /* SentryCrashMonitor_AppState.c in Sources */ = {isa = PBXBuildFile; fileRef = 17D19B09C84E2416E96D186E823E81E8 /* SentryCrashMonitor_AppState.c */; }; + 4F92BEA5A066C3FB1A18E12C73B7D92D /* SentryCrashString.c in Sources */ = {isa = PBXBuildFile; fileRef = 0691D3E0BDC9CD8351C20F1978A97E1F /* SentryCrashString.c */; }; + 4FA6C0019A7A03D5FB351D7A615205E8 /* OCMFunctionsPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F26D1CBB432719C60FC75BFF2DD1E67 /* OCMFunctionsPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4FFB458AB69D654B292BB9D95B88149D /* SessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CC1924BC66C4930A9848851D49802FB /* SessionMetadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 50232D2B692E825625A3AD2600732F3C /* SentryRequestManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1861C909B39B2D38DFFDE22EABE4EA12 /* SentryRequestManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 507BAAB8A950EAEF74FEADE94D3805F1 /* SentryLevelMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CA4FF39ED0B887747BAB6C80C3A034E /* SentryLevelMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 51377BF4356F8692EB7BBC4109C44702 /* MPNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FBACCD33706E0D6F5EE7CD78059B44 /* MPNetwork.m */; }; + 517362AF8B4FD68DE2F6FD2B66EF79F4 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E08B03BCD7615E02B7D315BB800CD90 /* ImageFormat.swift */; }; + 51BAF9D7D861DD3F4F9F283CCEDDE16F /* SentryId.m in Sources */ = {isa = PBXBuildFile; fileRef = 157863084A17F4A1D73C4C2C4237CF48 /* SentryId.m */; }; + 51E04F1081F50758FEC19131B9E5D1E0 /* SentryException.m in Sources */ = {isa = PBXBuildFile; fileRef = BBAB57A64E6C4CD076398499D4EFB432 /* SentryException.m */; }; + 51E38CC17B40B0DBEA0811D622A0C1F0 /* SentryNSURLRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = D27C49F3B33A9DC4BA1676033B188637 /* SentryNSURLRequest.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5203CD8079771375D574EDBD84DDABAB /* OCMArgAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 76C875F37828366270A19D86E3E42D6C /* OCMArgAction.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 52575DC3F9AA6A335B83F9DDEE23CA48 /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = B0629066F58B4A33514A6AF0F03BDDD5 /* UIView+WebCacheOperation.m */; }; + 527A1FD6FD79117C535D19213B9011D1 /* EXPMatcherHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 02DC83D5E00FE99440BD62AF984711A2 /* EXPMatcherHelpers.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 52C26A7F0403CDD87ACEBE4EE446F8BA /* SessionMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A2DA9F20E042F158279FE9D1897627 /* SessionMetadata.m */; }; + 52E483485002A85C047D787E31073223 /* SDWebImageDownloaderRequestModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AF45A5DF93EB934D1C9A9A778501710 /* SDWebImageDownloaderRequestModifier.m */; }; + 52EFF2F07728CEDF82364F4272365EE0 /* SentryCrashDefaultMachineContextWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 67C4AF11F6139DA148872B8D9BAE44BC /* SentryCrashDefaultMachineContextWrapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 530AF873B64BEE3AF9373FC9FECC6F03 /* EKManagedObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D08DE0D01595536B14C06E957A81A17 /* EKManagedObjectMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5334639B9FFD9F04E02BE4E9F91499C2 /* SentryRequestOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFA50A50F6E5469D4E4F53B09FAAFF11 /* SentryRequestOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 538035ACBF1CEF83E939B0450AE2642A /* NSDateFormatter+EasyMappingAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B9746E334F7B96E4F782D91BECC052AB /* NSDateFormatter+EasyMappingAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 54662FF12326414D001D5672DFF9C1EF /* SentryCrashUUIDConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D346136A47A1485152ECFBB337DF36 /* SentryCrashUUIDConversion.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 549BDD1035830AA7FB7B2903B2F7220E /* SentryCrashVarArgs.h in Headers */ = {isa = PBXBuildFile; fileRef = 021507B63C15C6275FA1614AA26D56C7 /* SentryCrashVarArgs.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 54C326EF57C7E16518F74581C09DC09B /* SentryBreadcrumb.m in Sources */ = {isa = PBXBuildFile; fileRef = 11A50C52679A85C930D61E41E25F0A15 /* SentryBreadcrumb.m */; }; + 54D82C0542CED2FE83F2350B5DF89707 /* SentryOutOfMemoryTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 4995871A89A4C5222BE0FBF47A7FB17A /* SentryOutOfMemoryTracker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 54E3A61D1BD1F996442AFDA0018BA2AB /* EKManagedObjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF7F0C7B39D9162359E52B189FE8F21 /* EKManagedObjectModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 55202EA582A7BEDFDACA6D85B01868F5 /* MPNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = D86F21A61B42BA1F53F84900700F92A6 /* MPNetwork.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5583A8B7B1712E13D8A18CE1998BD17B /* SentryMechanism.m in Sources */ = {isa = PBXBuildFile; fileRef = 35DF544F231298A2C3983E204103A328 /* SentryMechanism.m */; }; + 5599DB34088E6C5B4139B7026425B826 /* EKObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = CF5EAFB93582013A51B76C904CC6049D /* EKObjectMapping.m */; }; + 55BBA612AF1D05409029A7DA39F45906 /* OCMMacroState.m in Sources */ = {isa = PBXBuildFile; fileRef = B352E3B766B7B86A89E0481FEEFCA38C /* OCMMacroState.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 55E5FF4DC5EEEC6B400A0D87E3193890 /* EXPMatchers+beInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E111C8A9A247EDA742310038540721 /* EXPMatchers+beInstanceOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 560AD3C0BED5BEBDD79B407F8889B536 /* SDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7069DDCC3D9FD25F2944D0A9C7BD3812 /* SDWeakProxy.m */; }; + 56F641AFBA9F63851BF88F1F8A7504EE /* SentryCrashAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D39586091AD5DC73D4742E3DF9BBEE /* SentryCrashAdapter.m */; }; + 570CB48E1424192AEA23FCD7F4FDA23F /* NSDictionary+SentrySanitize.h in Headers */ = {isa = PBXBuildFile; fileRef = 76D9E7F762492B8E9172AB546A66189B /* NSDictionary+SentrySanitize.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 57119A5FDC2E82134E056FB0BF0AD593 /* TracesSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46AB541CCB0ABA088F628178E27D63A8 /* TracesSampler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5759BFCCCC8BC50A3DDB156CA486F98A /* SDImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 297F53EBDB02A11F591EC8C9D9F3F878 /* SDImageLoader.m */; }; + 57BA46DFE2F32F04F308289610F73EDD /* EXPMatchers+equal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF711190956F6B15EBCFD0EDA1345DF /* EXPMatchers+equal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 57DDE2FCBF802264158E6D33F5649EE6 /* ImageDownloaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B696723444D17E2C081123ABAC3C0EE7 /* ImageDownloaderDelegate.swift */; }; + 58227EE0228AD65F67824364F3F00008 /* SentryDsn.h in Headers */ = {isa = PBXBuildFile; fileRef = CD4A38B44E188BC0AE09430BFEDA430A /* SentryDsn.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 58A87B73F1B7F00D3B235B2AABB5DF54 /* SentryCrashInstallationReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 03B0EEABA146653D4D0D5E83C4159A4F /* SentryCrashInstallationReporter.m */; }; + 59112B54182E65582F65FF4B8E771918 /* OCMVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 66C034548AF4F3B544F25A2A0632AAFF /* OCMVerifier.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5947B0CBF56733EEABEDDF47FF4ED82E /* SentrySystemEventsBreadcrumbs.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF78BEA53B328FF4AC085F3142F1197 /* SentrySystemEventsBreadcrumbs.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5A2341AA325EBF1CD740D22651775746 /* SentryHttpTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = 58390617A0187652449D42C311506573 /* SentryHttpTransport.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5A251C978AB6ADB201CD3EA58FF1545A /* SentryCrashReportConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = C1E333E813AEA3E1D1114D3717C7022B /* SentryCrashReportConverter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5A2CCC68530C7040F1777EC4D2F1551F /* SentryCrashStackEntryMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = F8678DC07C3A0A61B18287BFACB10934 /* SentryCrashStackEntryMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5A43305F185AD6B24558485ACBAC13D3 /* EXPMatchers+beInstanceOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CC2DE11D8B53AA2809C93B3DF96B78 /* EXPMatchers+beInstanceOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 5A478B7929BA7487BC065F93AF68C319 /* NSString+SentryUnsignedLongLongValue.h in Headers */ = {isa = PBXBuildFile; fileRef = CDB702BF91B1964D255A4A5C424C327E /* NSString+SentryUnsignedLongLongValue.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5ADD752DC119365A2AA9345A38BDB5AB /* SentryOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 98FC521CFE4B7F822E15B95D82BF96FF /* SentryOptions.m */; }; + 5AF3539D5B4FD0E9BA7ED3648BE2E7F4 /* SentryCrashInstallation.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F88FA256932D4EFA23E52859A5ED9BD /* SentryCrashInstallation.m */; }; + 5B1BD40A04E368A003BEFF0FAEEFD59D /* SentryCrashMonitor_CPPException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 216E33880C75DB02F09EBC7E6442708D /* SentryCrashMonitor_CPPException.cpp */; }; + 5B4D6F932A6FA06910BB47BC43843683 /* SentryOutOfMemoryLogic.m in Sources */ = {isa = PBXBuildFile; fileRef = 6752AE45A10AE01FB384A64DA9F7E3A4 /* SentryOutOfMemoryLogic.m */; }; + 5B654328900B9B578AAD634B921C4332 /* SentrySamplingContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E5B9EB4F70C9724CEC101658BE9A22 /* SentrySamplingContext.m */; }; + 5C3F77A130703D262FC147E1ABEF98AC /* SentryMigrateSessionInit.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CCB6752988681478753D8ECC5D8F288 /* SentryMigrateSessionInit.m */; }; + 5C6E15752F48AEFE649D5F15B8462A45 /* SentrySpan.m in Sources */ = {isa = PBXBuildFile; fileRef = 5169589B116558FFAAB8BE33DD6CFF16 /* SentrySpan.m */; }; + 5C85782CEC7616BA354A317B7536DC8E /* SentryCrashSignalInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 74410FD9A799F3F268BFA760FFFE0B0F /* SentryCrashSignalInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5CEA958400E5BD28FEE35EB2CB170B05 /* EKPropertyHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = FEDE59956F01BAB8149B4FE239EBD53A /* EKPropertyHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5D9A2A4AED9115CD67B89FE161666920 /* SDImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DCDDE6A99DD91D67C0528308889B8C9 /* SDImageFrame.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5DBCFA008E75D73ADFFEF24C210E6CB5 /* UIButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = F3258D01C395815147B1578AF9AFD710 /* UIButton+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5E12BCB2A3CC2DD19A7DDE775EBFA878 /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CAD47560D17493EDE1906F5E071CE326 /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5E6233C210A6AF47C79AC729CE57536E /* Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = E7E2786467AFA14CB5DA07F30C390C8E /* Expecta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5E7B816536368B9FD5ED26E2F24C0CD8 /* SentryDebugMeta.m in Sources */ = {isa = PBXBuildFile; fileRef = D4E58AC687FF6638E95247AC8D47481E /* SentryDebugMeta.m */; }; + 5E843800864DE1218AA446BB6142B8E7 /* SentryCrashMonitor.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B6F60DE19BDBE6C64EBB8CF63D6EEE1 /* SentryCrashMonitor.c */; }; + 5F093700A2F831DEDB72E6B79A78BD92 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E59068B900E048C38B63AE64FFC855 /* fishhook.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5F18E6BC35A41A9B0BF224F3FD74653A /* SentryCrashInstallation.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F88FA256932D4EFA23E52859A5ED9BD /* SentryCrashInstallation.m */; }; + 5F314721A1272DEBCF5175CCCDD84486 /* SentryCrashReportWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 06D304B144FA7C586C57986E3612227B /* SentryCrashReportWriter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5F7DD505806A3BDCD84050AC6A2382DF /* SentryGlobalEventProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = D60913A7573D0C51BD7A2D9982EA74E4 /* SentryGlobalEventProcessor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5FA5F9D87EBC05469A0D34F5CF820715 /* SentryRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = E482E15A51417B629DB9DA89BFC13FB6 /* SentryRandom.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5FB300212268804AE44612C65A4C1C31 /* EKCoreDataImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC68AE22AB019032DD1A0EA782C4614 /* EKCoreDataImporter.m */; }; + 604313AB7820FCE93E4F572AC2BC9242 /* OCMNotificationPoster.m in Sources */ = {isa = PBXBuildFile; fileRef = 35AB175A6910B81B03372F043897023B /* OCMNotificationPoster.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 60CA1324A2DECD22D0DFD2B86BFB166F /* SDImageGIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 119E9DE2FE8F50178BC215E54D111A7E /* SDImageGIFCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6153DC71AA743CCC08CE7F3A614F7CC8 /* SentryCrashMonitor_CPPException.h in Headers */ = {isa = PBXBuildFile; fileRef = E5772F49F24A961F4D2A7CC2EF2C22D7 /* SentryCrashMonitor_CPPException.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 615AE5B2C412C6521AC9ADE3634DB859 /* SentryAutoSessionTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D9816E9BA0E9C1D408810DF06B24A0B /* SentryAutoSessionTrackingIntegration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 615D536041DDBBEEADE84CBF41513838 /* SentryCrashReportVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C776FAE04FB29E201583DFAC74FE9F /* SentryCrashReportVersion.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 61B3038A5DD13EDCC32F709956ECCA64 /* NSArray+SentrySanitize.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F7AACCA9011988D5EA92395F682A784 /* NSArray+SentrySanitize.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 61C0D893E3B2DAD5ADC53BD84FA920C1 /* SentryThread.h in Headers */ = {isa = PBXBuildFile; fileRef = BBC0FD88956CF8F23259FCE3D7B5E7C9 /* SentryThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 61F0FD43504B408AE0A1C0B74EF76871 /* SentryThreadInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 6885FD677F329175EFEA133271225111 /* SentryThreadInspector.m */; }; + 62139DE96318240FD52A1DE99EF984ED /* MPNetworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AC9CB050C910E77C9B12CB287704992 /* MPNetworkPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6214814A6B4ED5038353C2DE0F71DE04 /* EXPMatchers+beKindOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A861715DA3C27C1CEC0B5149E88DE65 /* EXPMatchers+beKindOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 621D184BFA75881116AF407ECBE236DD /* SentryHttpDateParser.m in Sources */ = {isa = PBXBuildFile; fileRef = E4C37732B893111733DF0A4585B21DFD /* SentryHttpDateParser.m */; }; + 622F767AC051109722554A4BEDB28970 /* NSArray+FlattenArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 158A69E47F44FC87022EB7B284DB6CED /* NSArray+FlattenArray.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 624F4C5F3039A454392C2150A801171D /* SentryCrashBinaryImageProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 87CD89D239B8AD49C9E6A7B041C940CC /* SentryCrashBinaryImageProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 62611DD528701129520532D66E9A5781 /* SDWebImageDownloaderRequestModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B4ACCDC92441FA388B90ED4B3F3E349 /* SDWebImageDownloaderRequestModifier.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 62652BB410F8BED2B0F2906158B458AA /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C3109EA3A2A5C9AD325830B1B6C99F9 /* String+MD5.swift */; }; + 626AF15E28B5B47357F8EFF24D8168C2 /* SentryCrashMemory.c in Sources */ = {isa = PBXBuildFile; fileRef = 794F16D3AAB9F5CF04D4FDAB7BC7EC48 /* SentryCrashMemory.c */; }; + 62DC6E15DDA7806F8EAED5653ACF07F5 /* SentryHub.m in Sources */ = {isa = PBXBuildFile; fileRef = 051572966812B4346D5D43CB731AF26F /* SentryHub.m */; }; + 632F2CF8BAFDCFB7E46DBF992FFBCA9D /* OCMInvocationExpectation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE7F630B356E6F9F3E9B043676AEAAD /* OCMInvocationExpectation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 63418C3CB4D94D127C02E7FE00232B26 /* SentryCrashReportFilterBasic.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C0D06F888A372154BF1F8BA0B428CC3 /* SentryCrashReportFilterBasic.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6344EAFAA20DD33EDF1D34CA754571BC /* SentryRateLimitCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 979EDE57A39CEF533C37EC090F0D5821 /* SentryRateLimitCategory.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 635A6105DE7E61EB7B657250BEE397EF /* Sentry.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC877162AAD2CD71819994ABEB546C0 /* Sentry.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 63D65A705F4B4C3E464A78E7F16C275D /* SentryCrashMonitor_Signal.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A79920CFA1BDBD9E75FB348D29B205 /* SentryCrashMonitor_Signal.c */; }; + 6419B1751F19550BC6C5035C3AEE3E02 /* SentryDefaultCurrentDateProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ABC382AC330CC67B3C949FB87775132 /* SentryDefaultCurrentDateProvider.m */; }; + 64AD9E0AAF2CC323FDD4BCB5C1784B10 /* SentryCrashReportConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CB00895C3B8D81E78B53D91E9A3ED2F /* SentryCrashReportConverter.m */; }; + 6519FB4DA2CEEAED9D69014D004A62B1 /* SentryCrashInstallation.h in Headers */ = {isa = PBXBuildFile; fileRef = A183B8C88C10AE3947EC7E662488F951 /* SentryCrashInstallation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 655F9B3E71080105163364275A80F6EE /* SDImageCodersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 639B0100D981E73C7785C98B61DB4A2C /* SDImageCodersManager.m */; }; + 6564DDC2D24997D5B15457DCDE8744F0 /* SentryMeta.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E00FC8189AAAB1B80CCE473B6C8AF52 /* SentryMeta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 65966C9F6D9F555A0B4FE2A59AB2F87E /* SentryCrashObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 28F30BDB100EE20988EF30AF46D98AE9 /* SentryCrashObjC.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6613C1B05B8CB97CF3255CE665F50898 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 974630185E5A0C273B1868FF0A45382C /* SDWebImageCompat.m */; }; + 661BF6CBE08556C7569DC807BB861219 /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = EB76A04ABD9F9A9253A632D1D64AFC25 /* SDWebImageDownloader.m */; }; + 661C9CDABDE0692A04AE80032B927C34 /* SentryCrashFileUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = CDE4D9299F0AF2CF5B0B8F25A0A284BE /* SentryCrashFileUtils.c */; }; + 667490CD7ED2AF0A7D30F4674B8048E5 /* MPNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FBACCD33706E0D6F5EE7CD78059B44 /* MPNetwork.m */; }; + 6696CBE4654AD391C63CD4E85ACF2C97 /* EXPMatchers+beLessThan.h in Headers */ = {isa = PBXBuildFile; fileRef = E1874710A7496BA57237D6BDA6C21AC3 /* EXPMatchers+beLessThan.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 67596C213D1304AFA32F996B6E8F62F3 /* SentryCrashMonitor_Deadlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B8940A8DA7525FD7DD22402B5A63D /* SentryCrashMonitor_Deadlock.m */; }; + 679BC695B4EF085AF72BF1A570150ED5 /* SentryRateLimitParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F56E39159CAE9BE998C994876ED8E9D /* SentryRateLimitParser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 679EB6C977D909B92783A2F62B16521F /* SentryFileContents.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9FFACA5FE82A9DE4CB2228561AEAED /* SentryFileContents.m */; }; + 67B9250508EF1FBDB01B02BD6CEFD873 /* SentryCrashMach.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA0261A606C77F7BFED637CC3557677 /* SentryCrashMach.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 67EEEF94B813BA4B16BB9D86AEC0D791 /* SentryTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = E7A20D0EF6CC27822F5F673A4C0CE300 /* SentryTransaction.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 67F5852AF2E03411C6A46ED316366865 /* EKMappingBlocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 20FDCB67501389A381C2608C683D619B /* EKMappingBlocks.m */; }; + 685A65378327C1F6C51FBD7BB138764B /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4EA5E277EE2AC8B664CD9FC2A9ED44 /* SessionDelegate.swift */; }; + 685AA6CF713D63B325787424C7DD6279 /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F608D42A6E990A153F1AB8E208946B /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6869CCB933286B8A3D3F5991783E0921 /* SentryCrashMonitor.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B6F60DE19BDBE6C64EBB8CF63D6EEE1 /* SentryCrashMonitor.c */; }; + 68C225A6C4301799D596A2A96F652640 /* OCMStubRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = A4F20D84DBC0E8F03B43766CD57B6C5B /* OCMStubRecorder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 69349BECD39FBA209D2ECA0AFE6550AE /* EXPMatchers+endWith.m in Sources */ = {isa = PBXBuildFile; fileRef = 3643E758C072AA39C0B4AA42EC9A2589 /* EXPMatchers+endWith.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 69614D3B0ACC2D4C956A6E489FF0C333 /* SentrySwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = AFE14AC670BBDE68888F91AD1EAD112D /* SentrySwizzle.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 69A46C5860D341060EA3A5B2B35BC9FB /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 37BD8D3AB94FFA0798CB394794BCBAD9 /* fishhook.c */; }; + 6A977385E9AD0106433204C53EF1332F /* UIImage+MemoryCacheCost.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C76FF267314E0DA402A592F00DDAE6D /* UIImage+MemoryCacheCost.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6AB635E53472AFA729AD959EB18363B1 /* EXPMatchers+beFalsy.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD60C8C2D829AF89945E853ED1CA1F3 /* EXPMatchers+beFalsy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 6B10EDF8693EEC2BDB03124725098505 /* SentryCrashInstallationReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 03B0EEABA146653D4D0D5E83C4159A4F /* SentryCrashInstallationReporter.m */; }; + 6B2003806D88FB4BEA846EA5179B13E2 /* SentryHook.h in Headers */ = {isa = PBXBuildFile; fileRef = 6792D215AB742EF73C6E5D637C93536C /* SentryHook.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6B4C8C7378DD51AB86A2CFDFE5B63ECE /* SDImageAssetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 058E44E46F03F2A6AB8936F8843AE72A /* SDImageAssetManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6B6C1C4E6311F21507FCE7DB7090AB87 /* SentryTransportFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FB87107341CDBA82C7CEB2B131A51B3 /* SentryTransportFactory.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6B88B156844760908D535DDB2E59A0B9 /* SentryCrashJSONCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE92C9C62C1580212860559CDCDB61 /* SentryCrashJSONCodec.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6B8EBB605F20A9C7866EB19ADF49DE37 /* SentryFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = C324EB3A7AC0090B4AAEA7B08A40BE78 /* SentryFrame.m */; }; + 6BD5D41D0FD19C27AAD3536B0484671F /* OCMock.h in Headers */ = {isa = PBXBuildFile; fileRef = ABEEA66650DAFED36AC0A7B67BDC27BD /* OCMock.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6C15F811A1380F7A7ABAC575E40D505E /* SDWebImageIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B1D742BA9A979DF92459A477916420 /* SDWebImageIndicator.m */; }; + 6C2B1FA8BDF3452AD5C6E640AE95AA6C /* EXPDoubleTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 5413522E2E83F53BB8740D2CFB917577 /* EXPDoubleTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 6D311E7FBE67BFDE9E812885324764C3 /* EXPFloatTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = A58E63C8196E979642B5A41F2AA5F26A /* EXPFloatTuple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6DBEFA84693305F4EFC8EC490833C890 /* SizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E030A61F17D17FD81E63D627666FECDB /* SizeExtensions.swift */; }; + 6E14D0FD44BFC002E827AAB8A17262D4 /* SentryAppState.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D3339DEF95FA636F126C2080A088321 /* SentryAppState.m */; }; + 6E168BB4333A8951E277B8454E15A4C7 /* SentryRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B6F73B31552AA6B9946DE3D01FABFE1 /* SentryRequestOperation.m */; }; + 6E4181C1011A7D01C5E2CFAFDBE05282 /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 702074EA12749CFCFBDF2CDA24573ED5 /* KingfisherManager.swift */; }; + 6E4BC11268613D03E0F8462E9D2A2F34 /* NSError+SentrySimpleConstructor.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CB6B2ED6DFCB782ACC85B2D4C2B7F22 /* NSError+SentrySimpleConstructor.m */; }; + 6E84C445C8AA0A251B93F40C2479FB4B /* SDWebImageCacheSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = E6429B66FC50FB2E00DE7EBBD2B39441 /* SDWebImageCacheSerializer.m */; }; + 6E891DCCC0B5B58C59E6925437E24B5F /* SentryCrashExceptionApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DFFECBC682FD9C906742F24B35A3F1C /* SentryCrashExceptionApplication.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6FADB33F5F1305B1DEF22D8C2DB60DFB /* NSObject+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = F7D9640F4FF58EE0BFA4681BD8524652 /* NSObject+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 6FCB1A72E475707BE1EC1862E0B01AFD /* SentryCrashMonitor_NSException.m in Sources */ = {isa = PBXBuildFile; fileRef = F8651300AE05A68F5000B0FEDFB83E6E /* SentryCrashMonitor_NSException.m */; }; + 7004415DCED00085428458F405D8EC33 /* NSDate+SentryExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = A6197DD8D086D74EC7BFCCE051FD5F31 /* NSDate+SentryExtras.m */; }; + 7021D3AF25EC280F69E49EC9FBE59484 /* EXPMatchers+contain.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0181CAABD875283907391EB7A5F605 /* EXPMatchers+contain.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7036A3887A246B05E8CF15D86FEC6DAA /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95EC668E798CC7757D2A7FAE411066D4 /* KFImage.swift */; }; + 70384A05DD64D46FE1E31969F1C4F88D /* EXPMatchers+beGreaterThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 251C6FF39FE45D49E74742E54367D150 /* EXPMatchers+beGreaterThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 70CFEF39BE41BB3FD25F511B8997BCA0 /* EKPropertyMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = F39921B3FB050F3374B5EC60FC1119BE /* EKPropertyMapping.m */; }; + 70DC6E4A54FD93C0AF97BCE150DDCEDE /* MixpanelExceptionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B651AA679368297876836D632672329 /* MixpanelExceptionHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 71246DF7E5A02CA452078BB762FCDE3E /* SentryCrashReportFields.h in Headers */ = {isa = PBXBuildFile; fileRef = C7FE1EF9F428C6334E0F097B069FC11C /* SentryCrashReportFields.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 712C6A45D1129E62850CB79D5ACD340F /* Pods-BitBot-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B84BCB752C7801A42B7566DCD7F888B /* Pods-BitBot-dummy.m */; }; + 71452DB3DB742B4035096C41B1A00261 /* SDAsyncBlockOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EE249DEE7BB07E67055EB8B9D87F3F5 /* SDAsyncBlockOperation.m */; }; + 718B9E93210A8AF5B8EB02F07073FCBD /* NSDictionary+SentrySanitize.h in Headers */ = {isa = PBXBuildFile; fileRef = 76D9E7F762492B8E9172AB546A66189B /* NSDictionary+SentrySanitize.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 71954657A5F0B37B52770DBBC8D5D445 /* SentryCrashMonitor_NSException.m in Sources */ = {isa = PBXBuildFile; fileRef = F8651300AE05A68F5000B0FEDFB83E6E /* SentryCrashMonitor_NSException.m */; }; + 71F17CC4A600EEE9EB9B371C531A39F5 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F51174B10209840F57501FA9C81C780 /* Storage.swift */; }; + 71F6061C24B4C1B6A766F9ADD5C44D58 /* EKPropertyMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = B0F73FEAAFEBB7A8FB01FAB8C7D9136A /* EKPropertyMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7204E0104BAE2059158C15A8ABAF164A /* SDImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F77BFB3507FA24ADF2D491C22BDA2118 /* SDImageCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 729FA3889610818FD32181DE049486D5 /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 382B6780F0FBF48423885E733831C75C /* RequestModifier.swift */; }; + 73325E46BC27E70CA40360B7A2D50C2F /* SentryDateUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = CD9E7F9949C74A81F649A55858744F7D /* SentryDateUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7385647AF22E08DA35FEB3BE0346F783 /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 951C5CBA2B0F0DBF578D98D52943E388 /* SDWebImageDownloader.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 738B88E8018D3400546022C0A2641846 /* EXPMatchers+beNil.h in Headers */ = {isa = PBXBuildFile; fileRef = 557D34A7742B007287FCA4734299A008 /* EXPMatchers+beNil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 73F6F988D5F232F32F108A406FC4114F /* SentryIntegrationProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 65A8A898D3B71BB42B900D8CAEF6FB3A /* SentryIntegrationProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 741CA1BF0828521988A5B6CA703D1186 /* SentryDebugMetaBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = D9BC90810FA98ED7665170917F955CB8 /* SentryDebugMetaBuilder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7435A798ACDD217B72A81934709A9322 /* SentryCrashLogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A983085F3DFDC173B710B3C170F3368 /* SentryCrashLogger.c */; }; + 745CD20F091C1079A7E4741A2CC524FB /* EKMappingBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = C16CDA7D12CE2887C6C67BA402461988 /* EKMappingBlocks.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 745EAB9B11A2CDA962198A0BDE269394 /* SentryStacktrace.m in Sources */ = {isa = PBXBuildFile; fileRef = 41B0A65DF6211BF2861ABE6E500D3B7E /* SentryStacktrace.m */; }; + 746E6DD4C3E469E15DE3BA3E3F39857A /* EKRelationshipMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E480A4679A415C223FF40639884AF28 /* EKRelationshipMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 74BD5C0BC281CBD516E17FF2C7E93277 /* EKManagedObjectMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = F2C7A6B01B0431E52F0426FFA9FA836E /* EKManagedObjectMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 75056239E3EC9B8A86168309EBE50E43 /* SentryRateLimitCategoryMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E01B96E9D6EEE758CC6F000CB4F7ED0 /* SentryRateLimitCategoryMapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 756508F66332DF225107FD25BDF0EB09 /* SDWebImage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 656179F2734A46FE73D7EAFE5EF0DD3D /* SDWebImage-dummy.m */; }; + 75E1E8967716404B6E4A8AFFBC46E88E /* SDImageCachesManagerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3F0CF22C5A4DA1A8DA024DAD3E614 /* SDImageCachesManagerOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 760EA6582D011C79E40B3547614BE51B /* SentryHexAddressFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E2C83FDCC2689D4A0B69747EF511C0 /* SentryHexAddressFormatter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 76BF29D0C90B3EEF57A4885BFEEC365C /* ImageDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 928F1C804CA779C74BBAD7277B516830 /* ImageDrawing.swift */; }; + 76C84E41EF308B3492D1D0C7E8EF79DF /* SentryAutoSessionTrackingIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = EC93C90F2B5676049CC384D0AB9C6972 /* SentryAutoSessionTrackingIntegration.m */; }; + 771B768E46483AF4B29811AAA06AEFDA /* SentryCrashMach.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA0261A606C77F7BFED637CC3557677 /* SentryCrashMach.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 771BD7A0914FA4CD9E181CD54D5F48B1 /* SentryGlobalEventProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = B7B0452CB83EB470B9D578159CD4EC40 /* SentryGlobalEventProcessor.m */; }; + 7756CDA1D1906D164DB8FB1DDC6DF102 /* EKManagedObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 4083F4A45B92B9A4CDA43A2E616B20D5 /* EKManagedObjectMapping.m */; }; + 77CB3489AE0B02B5995F1DB1CC9C13C1 /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D88D09A9D5B23D66D2E3164E233965A /* SDWebImageDownloaderOperation.m */; }; + 783B759B1E57DC7A2E883D8031A0281D /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE40BA3D3BBB6AC28E2B587F77AD04F3 /* Kingfisher.swift */; }; + 783BE48835B54903BDC6226708B41AA7 /* SDImageAPNGCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 13D79AE204DDA50C7C3F4E8E04D32276 /* SDImageAPNGCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 78779DACEACE53197EE58B4BC72302C0 /* NSImage+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BCD39F27356B900115C3AB0529AFDD5 /* NSImage+Compatibility.m */; }; + 78BC790FC7EDA25CA786A67152CBF264 /* EKMappingBlocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 20FDCB67501389A381C2608C683D619B /* EKMappingBlocks.m */; }; + 78EA884E98093B5FC97DD7710FD70779 /* SentryCrashSysCtl.h in Headers */ = {isa = PBXBuildFile; fileRef = C932E34914D61B118DFFB14264E4F46F /* SentryCrashSysCtl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 793BBCBCD78226E4F2845B64AD10AB86 /* SentryUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C1EC470E15CDC0A396B6A75163FD54 /* SentryUser.m */; }; + 79A75320E54F09C2F7E8C8E6F5F10D8E /* SentrySession.h in Headers */ = {isa = PBXBuildFile; fileRef = BFE1C8C5066FDEED8D3A06A903580C81 /* SentrySession.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 79D6B35393FF7B46CDFF85FDE6ACE8A7 /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 7868BA38D167639FC1B3A1A064F98CAA /* UIImage+MultiFormat.m */; }; + 79FD8117A6E29FD70CC62236B2A20E07 /* SentryCrashSignalInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 5E10825BF1E02BA77AD12B4EFCB737B7 /* SentryCrashSignalInfo.c */; }; + 7A1E8A59D9CA4B52C4672688EC481FB5 /* SentryMigrateSessionInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0963B2E3E97A0722C7CBBDDB36B76860 /* SentryMigrateSessionInit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7A27F29E5AEEEDDD7404CAD1B52069DE /* SDImageFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B891BFE89B9952888C4A187D6D6181D /* SDImageFrame.m */; }; + 7AD1876CCEDCFC178AE50A92FB354C46 /* SentryFileContents.h in Headers */ = {isa = PBXBuildFile; fileRef = 643054DB8DBCF6B6727687DF0F36411F /* SentryFileContents.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7B816F3A0D2D0E23A4AC290F4A4C0148 /* SentryInternalNotificationNames.h in Headers */ = {isa = PBXBuildFile; fileRef = D1CFE48E766C5DA9E609AC5092AAF2E7 /* SentryInternalNotificationNames.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7BF6CB8A03E9EE464778CF4ACBAC80E2 /* SentryCrashIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F0F3D31B52CB059E34ADCD8A40B4082 /* SentryCrashIntegration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7C1632A83B80B163FAC5297F8E9576D1 /* EXPMatchers+beIdenticalTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C23419431442D582D63E8ABBE30C470 /* EXPMatchers+beIdenticalTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7C477CF08C23CB76868B185DAAE8AFF0 /* SDImageCodersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A37B1F725D56C8C4BCE30AB4B450E10 /* SDImageCodersManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7C4E62B83E124848E307238125176B9D /* SentrySessionTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CA26FD9028DA58D96FBF18B6DBCD422 /* SentrySessionTracker.m */; }; + 7C5AB855327E04A23448FD9EBBB04D93 /* OCMInvocationExpectation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0CA3D813A44762422977B90EA44465 /* OCMInvocationExpectation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 7C60688F5BE4D20029112A2A88665036 /* SDAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7533734215B52194CC28854B3989C0B9 /* SDAnimatedImageView+WebCache.m */; }; + 7C98299820092A85E03BE0AA7D50544E /* SentryEnvelopeItemType.h in Headers */ = {isa = PBXBuildFile; fileRef = FC629D7EE5D4E3D25A8DC71977FB9A70 /* SentryEnvelopeItemType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7CE32DF6E2711D45C5D8E729C54A4AE1 /* SentryError.h in Headers */ = {isa = PBXBuildFile; fileRef = E5D86D1F25D9DEDAABC2D4BF04C13638 /* SentryError.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7D147924B4DE3C80D96C1A68BC0ECBFE /* SentryCrashReport.c in Sources */ = {isa = PBXBuildFile; fileRef = E9A6894E165A917A3864A338D7E718A9 /* SentryCrashReport.c */; }; + 7D4250439096E28950B8756D4376218E /* SentryRateLimitCategoryMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A52A6F3E00C33219FCD44F31FAD48FB /* SentryRateLimitCategoryMapper.m */; }; + 7D4A97B89E96F7C217B98B82CBCA591C /* SentrySDK+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2702815AF26E4C9FE035C2A0484F78AB /* SentrySDK+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7D98220C51E00B83BFC8F8D1839BE934 /* SentryNSURLRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = D27C49F3B33A9DC4BA1676033B188637 /* SentryNSURLRequest.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7DABAAF600D1305912C1B4B889A2FA30 /* OCMBlockCaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F184392A295DE2E19C93D0C8B7143C7 /* OCMBlockCaller.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 7DD9E43AA2CA169E95FF9EC27909FFD5 /* SentrySerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 893F74730AB7653048453181D4060B4E /* SentrySerialization.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7DDF7F2CB636B216C8763FB6C3C08005 /* SentryHub+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = F4C3B484D92B78C21F5D450A1F3A5B12 /* SentryHub+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7E571DCF762EE26E3829FA6120EC7C14 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = B25FFE571A338D87EDF909EC906499E0 /* Image.swift */; }; + 7E5DF1232CC16AC178FADB8447DA222E /* SentryError.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A65932F3946AFE7DE35B76CF74D0911 /* SentryError.m */; }; + 7E7E5DDA00EFB9CAE1711863C6DFED43 /* SentryCrashStackCursor_MachineContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A339574BDAC6852EC8CD47F1A626B26E /* SentryCrashStackCursor_MachineContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7E8F3B346FBFF1B578F470376D94FABE /* Mixpanel.h in Headers */ = {isa = PBXBuildFile; fileRef = BB20C65D91E6BA3A93FCE00CC0AEE9FB /* Mixpanel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7E9548ABBA08444FF57D3BB9E89CF89B /* SentryCrashJSONCodecObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = A256F1C1E08340F2EEA91E8F3B75F656 /* SentryCrashJSONCodecObjC.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7EC7E5CC084FC6A07AA4E71F0F377BB8 /* SDWebImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AEA160530D3540C9520D2C636449E6B3 /* SDWebImageOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7EE7E487A3FA00050BF84EDE48E06476 /* SentrySessionTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CA26FD9028DA58D96FBF18B6DBCD422 /* SentrySessionTracker.m */; }; + 7F07D7FB69CA93077F46B714739AE7C7 /* NSButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB9836C3922D9280D5ECB5E16654E761 /* NSButton+Kingfisher.swift */; }; + 7F2FCA4A64914994B1149350E45C2B8F /* SentryCrashSysCtl.c in Sources */ = {isa = PBXBuildFile; fileRef = E7D07B95AE09FB5092665CB55709027B /* SentryCrashSysCtl.c */; }; + 7F72D00FC206707FB310CA57D371D9EC /* SentryCrashIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F0F3D31B52CB059E34ADCD8A40B4082 /* SentryCrashIntegration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7F8A9A8BA27DB615A23982C18288990E /* SentryRequestOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFA50A50F6E5469D4E4F53B09FAAFF11 /* SentryRequestOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7FD25AE74C165D37BB9909EF2026746C /* EXPMatchers+beginWith.m in Sources */ = {isa = PBXBuildFile; fileRef = 73EFA1A2808B11E38E10524558CCC4BA /* EXPMatchers+beginWith.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 801F4A028FAE7D5798927FF6CD74EADB /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F98F21A3A4AF3F01F89B2CF4C1CA0A /* Kingfisher-dummy.m */; }; + 802CFE26A7F695D6DDBADAD2623BFB28 /* SentryUser.h in Headers */ = {isa = PBXBuildFile; fileRef = C35F4308293B135C7155C0CA4BD07558 /* SentryUser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 80529F3D8C05C5746E805CE7D3721416 /* SentryAsynchronousOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FD7012E4F272E888FCB789C2A861DD6 /* SentryAsynchronousOperation.m */; }; + 80612C4104A4DE34DF86B6D030C9E358 /* OCMFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D3A4B1DBA7E15E533F1C21B73BD47EB /* OCMFunctions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 8085654A7283CBE196F3AB934C2E3E47 /* SentrySDK.h in Headers */ = {isa = PBXBuildFile; fileRef = 72683F357F02D5EDA048DC6F23D4092D /* SentrySDK.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 80BF14D9BB67EDA3DB5AA61E0B56CDC4 /* SentryRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B6F73B31552AA6B9946DE3D01FABFE1 /* SentryRequestOperation.m */; }; + 80DA2EA015D0BB48D62E6B423532FE2C /* UIImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = D9762FEC996DD0B9D2CB88F3325CEE40 /* UIImageView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 80E371FE77A34E12BA35EE5C7EEC092C /* EXPMatchers+beLessThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0619CDE980999D5C59E9F15C006149DF /* EXPMatchers+beLessThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 80E594CD0EC375F13CD7310167173DA1 /* SentryRateLimitParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC646924C2D2C93556CA6232316B400 /* SentryRateLimitParser.m */; }; + 8121DE3E632E3DDF585BBD663D632609 /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 82CABB27D18CEA8BFA0E6F9422B6FA84 /* UIImageView+HighlightedWebCache.m */; }; + 81BE7BE25048573093CABE94BC9A8FA3 /* NSBezierPath+RoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = B6DAA8E43339786802C0F8CC809AC768 /* NSBezierPath+RoundedCorners.m */; }; + 81C743D1A490A6A0AA25F871822B5A68 /* OCMArgAction.m in Sources */ = {isa = PBXBuildFile; fileRef = AAD1A4DFC439E32BC55F333A85B0D6B7 /* OCMArgAction.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 8278FE30343E81033150AB284ECC98D8 /* OCMBlockArgCaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 69132E45666D517B599B0E045DE67502 /* OCMBlockArgCaller.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 82CC384514F38830F5724C59278B2414 /* EKManagedObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 4083F4A45B92B9A4CDA43A2E616B20D5 /* EKManagedObjectMapping.m */; }; + 833ACF674B6B23FE6A1430E23AC875D3 /* SentryEnvelope.h in Headers */ = {isa = PBXBuildFile; fileRef = E06EC8CDC64B1745C9173D810AF762B5 /* SentryEnvelope.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 83F31D6D135422CA0C1FE0CAE40CF492 /* SentryCrashSymbolicator.c in Sources */ = {isa = PBXBuildFile; fileRef = B890219F03689D886CBA4020B1CD7B14 /* SentryCrashSymbolicator.c */; }; + 83FA5A3892B988C55601B32E470F2919 /* EKPropertyHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = D5139F1EF9D079FC16A2A8568E1BCA1F /* EKPropertyHelper.m */; }; + 84A174D550C67B2EAA26D32E4C309755 /* OCMExpectationRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8085360E3336A58D8C1F511F7DBE7D78 /* OCMExpectationRecorder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 84A35BECD5CBE4F0042B3B740C779539 /* SDAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = DF94D725DA123E1FA30C9D95416E1258 /* SDAnimatedImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 852148C44AD655794A071ACAA389F48C /* SentryCrashMonitor_CPPException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 216E33880C75DB02F09EBC7E6442708D /* SentryCrashMonitor_CPPException.cpp */; }; + 855DC8BDD9380B4B88E39500031037AC /* SentrySession+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CADE90E5E97059DA721F894B29C72DBC /* SentrySession+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 858025A6AD1BEC27F2D46242D7C459CF /* EKObjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 56D5464E1A54D9ADA7C36F10D96C010C /* EKObjectModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 85BE28A0CABD9D6EF1960009050D8520 /* NSString+SentryUnsignedLongLongValue.m in Sources */ = {isa = PBXBuildFile; fileRef = CB32A5329227AA32586B5F39F8AC262F /* NSString+SentryUnsignedLongLongValue.m */; }; + 85DB8C763AEC85C2609506000A94E295 /* SentryEnvelopeRateLimit.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC994083E6028E0A5B0CB8C7F894C1 /* SentryEnvelopeRateLimit.m */; }; + 85F1E88FEEBF9B0337821E05C048AC39 /* EXPDoubleTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = 32EE06144281D6F9D2433552BFE5F506 /* EXPDoubleTuple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 866D5D586F49531EEA423588B41AB08B /* SentryCrashMonitor_MachException.c in Sources */ = {isa = PBXBuildFile; fileRef = AF11E02E80C577B2B41594595DBFA01E /* SentryCrashMonitor_MachException.c */; }; + 86BC1E8283EC3D4A4108C17FD2482DFE /* SentryTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F77AE7AF85B51FDC734F0B9716C1B11 /* SentryTransaction.m */; }; + 86F0DB19CBDCA60F4582EDFEB4D9A1D0 /* SDImageTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1302D0CB32C03B303DEC187E3830CF72 /* SDImageTransformer.m */; }; + 8723D39A8D99C3B96431EF99BF42DF25 /* OCMVerifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B5C408964654E9EFD65EF335BD11CA5 /* OCMVerifier.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 87A149568A9FFB275ABA463F08C4F4D0 /* SentryDefaultRateLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = FF14B9E54E4823DBAA00FF762A1568CE /* SentryDefaultRateLimits.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 87F7881EBD28763D12C01D5E581D5F3F /* SentrySpanContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 01C8C1525E5E47B587B3B1805005ABEE /* SentrySpanContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 88410B62B8DE587A46FC7585ED83D331 /* SentryClient+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = AD6D919B73E1764BE2EA183589BCD2A2 /* SentryClient+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 88599A80B45E050AA4D5961445F67AB7 /* SentryCrashReportFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = EBF50F815E871FC102F8AA6473815C6C /* SentryCrashReportFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8873174683E2EE234F3A3EB7A9B4F15D /* ExpectaSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F3707783B7E17EBAC2B40048C2B638B /* ExpectaSupport.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 88869CED8C3936032A81468A19686E55 /* SentryCrashSymbolicator.c in Sources */ = {isa = PBXBuildFile; fileRef = B890219F03689D886CBA4020B1CD7B14 /* SentryCrashSymbolicator.c */; }; + 891E6FBFF27D16F0454DB3503DFD112A /* SentryCrashMachineContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F0FFBDBC22ED035FD2A99177FA77B13 /* SentryCrashMachineContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 892AB9E1F334AB05954703FB547DB06B /* SentryStacktraceBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D11B4BDEC059D18FA4E0388AD0D8785 /* SentryStacktraceBuilder.m */; }; + 893111B6205B7FE5EB13264511A6697C /* SentryCrashLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA0F2519E0F70EF0D35210ADB5F9D21 /* SentryCrashLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 895D03A412632626D6F0B85833F2BA2E /* SentryCrashDynamicLinker.c in Sources */ = {isa = PBXBuildFile; fileRef = 02FE69406B0C2F87D52C67EBB5E19FCE /* SentryCrashDynamicLinker.c */; }; + 896FECD7595629ABE8B25034A2A13163 /* MixpanelGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 327F432D938896DE00325DA3BCAC1A8E /* MixpanelGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 89788A6CD0B5D2C2FD98CD74F7BF0D10 /* SentryInstallation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EBC1AF6E820A7A363E11B50E41E5DA1 /* SentryInstallation.m */; }; + 89EBA8DBE12DC4404793C89F509D8CE9 /* SentryRetryAfterHeaderParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DECCD676C555CF5BA3C512220A939A6 /* SentryRetryAfterHeaderParser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 89FB2A1B7F24A11BC8F6905ADA195FB5 /* NSNotificationCenter+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D7C8972FA1895EECCF701E7E43D21BD0 /* NSNotificationCenter+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 8A12D80BDE28291F4B892EC9AC16A7F5 /* SentryTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = DF5D8291C1A5901C39977D7EC0026FDB /* SentryTransport.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8A424AADCE5CCA866E98F9C6DB5A4E47 /* SDInternalMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ECE59D4410E525D049CBF05D59E2720 /* SDInternalMacros.m */; }; + 8A590AC6ADAC4DA97B2EFBE1D37EB17D /* SentryCrashObjCApple.h in Headers */ = {isa = PBXBuildFile; fileRef = C5E2A317B34E97C0BC9E7D8A5432134F /* SentryCrashObjCApple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8A7ADB85ED8400CB25372625B2911BC7 /* MixpanelExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FB17A41E13C12B1D2AA71FAF3E004C2 /* MixpanelExceptionHandler.m */; }; + 8B353BCA87165AFF3FCD922D0E1CF291 /* OCMLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 03DB632D03C3927CA1825C545CACA388 /* OCMLocation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 8B44F94C4180A18C6D5863A149DEE715 /* SentrySDK+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2702815AF26E4C9FE035C2A0484F78AB /* SentrySDK+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8BB9EEED678887D3E12AFE3B32A961F4 /* SentryDebugMeta.h in Headers */ = {isa = PBXBuildFile; fileRef = 28C04358E6A2DC7343F90687D9DB0E7F /* SentryDebugMeta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8BC2BA168054057AF362766F99E3F191 /* SentryFrameRemover.h in Headers */ = {isa = PBXBuildFile; fileRef = E018C8C2D434DF9416FE294E909F30D8 /* SentryFrameRemover.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8BE513058B1421AA8F5AA44689B2E65A /* SentryCrashThread.c in Sources */ = {isa = PBXBuildFile; fileRef = DC3A1C125FE9A2938808FC9189B98F86 /* SentryCrashThread.c */; }; + 8BE5F8AFD9599FB4D542FEEA1E61299B /* SentryCrashMachineContext_Apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D48E9E19EDCAF24050949D06D6DD6E2 /* SentryCrashMachineContext_Apple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8BEE89715D6281CD53F462F0E2BBA599 /* SentryCrashSystemCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 733EB9949216F382705773FC086855B6 /* SentryCrashSystemCapabilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8C3B6032548EF72F9E3C1BF7EEE2BA76 /* MixpanelPeople.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C0A1B0E54182F7303BF9551261EC6D3 /* MixpanelPeople.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8C51FD9693D6F334A594DE8C39D1533E /* SentryCrashDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A1732A4F71AA53446C68DDCB89BC9A1 /* SentryCrashDebug.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8CAB3898BB17F34D23346496CE0E0A67 /* SentryCrashMachineContextWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 668A94876717C5D861AE21C2D9206219 /* SentryCrashMachineContextWrapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8CFF71693CA5B723B7D6CA98CF3B210E /* SentryDispatchQueueWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 283CF93D0E24384373D3F11E6A1D612E /* SentryDispatchQueueWrapper.m */; }; + 8D391AE0D74C488F594AB16A59C02C8C /* SDImageCachesManagerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 459D974EAA55D2D6B05023A91ADD1E1A /* SDImageCachesManagerOperation.m */; }; + 8D3CF898A1AED34C26AF862E7E3EB71C /* SentryUser.h in Headers */ = {isa = PBXBuildFile; fileRef = C35F4308293B135C7155C0CA4BD07558 /* SentryUser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8D3FB5D2661E03576E9A1F25C000D895 /* SentryFileContents.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9FFACA5FE82A9DE4CB2228561AEAED /* SentryFileContents.m */; }; + 8D6B3DEFA9CBF0F82DFAA713A4AC014C /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C42085705C144EED1AC95F520556B2D /* Filter.swift */; }; + 8E088D678DE289C2E34825D26F391E2F /* EKObjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 56D5464E1A54D9ADA7C36F10D96C010C /* EKObjectModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8E0BA9176D8C95E9F1436C2E7F95D421 /* SentryIntegrationProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 65A8A898D3B71BB42B900D8CAEF6FB3A /* SentryIntegrationProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8E205C644854D0686EA55BD2B7A564F4 /* SentryCrashID.h in Headers */ = {isa = PBXBuildFile; fileRef = CF16C145406DA3D8215F2D031636900B /* SentryCrashID.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8E971E2458163B8D717523B8D8BC892D /* EXPMatchers+match.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C100DF887E309856C0A3752A56C2EE /* EXPMatchers+match.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 8EB5BB5E22A7E21ED79A0B1A8D0DAE50 /* MixpanelPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D213DC3D25A75835B758B314D291EB4 /* MixpanelPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8F155838723CB6DF9EA0055DD0DB8709 /* SentryRetryAfterHeaderParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 97ED53DEEF94C51589000FDDBDD245FC /* SentryRetryAfterHeaderParser.m */; }; + 8F192AF8E29E7B0796977E14C60C12A1 /* SentryCrashMonitorType.c in Sources */ = {isa = PBXBuildFile; fileRef = 2756ECD1BE253C72B9421EB065BC47A9 /* SentryCrashMonitorType.c */; }; + 8F5B10D2E6BD453C535653D36FFFE4BB /* NSObject+Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = F3E5EA14068E6E74A749A04470626998 /* NSObject+Expecta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8FCA295ED2D88E35A9C91DA0ADA5E63A /* SentryOutOfMemoryTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 4995871A89A4C5222BE0FBF47A7FB17A /* SentryOutOfMemoryTracker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 900483F018B375B428D1E32F3DB919BE /* SentrySession+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CADE90E5E97059DA721F894B29C72DBC /* SentrySession+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9024F577BCA603F64895B5436E882A31 /* SentryCrashStackCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FF9C78A3E1CB9EF63637883B8EB32A9D /* SentryCrashStackCursor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 909179C22A3DF2C07DC45F86FB02083F /* SentryHub.h in Headers */ = {isa = PBXBuildFile; fileRef = ADCBFFF10E2E79248CA56AECC1AB9EDB /* SentryHub.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 90C43317EED4C897B75945B5AFBF2327 /* EKMappingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0542808674F5A10FF9784DA1864F8CBC /* EKMappingProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 90FF09F84EC1A0A92A39666604FD54CD /* TracesSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 46AB541CCB0ABA088F628178E27D63A8 /* TracesSampler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 911EC9AFFFF296275D29DAC4A64491DF /* SentryLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C35F9CE61D977267F2235041B820E03 /* SentryLog.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9150E0D884F547968001FEA0DD1ADE07 /* SentryCrashCachedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 73FBF880D819F3A37A47DF758F95393E /* SentryCrashCachedData.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9195DDF9B870700CF68EE05472DAE884 /* OCMInvocationStub.h in Headers */ = {isa = PBXBuildFile; fileRef = 2156CED034416F787C882CDFFADC6829 /* OCMInvocationStub.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 919E9BB52F6A9A369C54A8844E6B9D51 /* EKPropertyMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = F39921B3FB050F3374B5EC60FC1119BE /* EKPropertyMapping.m */; }; + 9226C7A923AA1CE7A87F1372C673CD47 /* SentryCrashDoctor.h in Headers */ = {isa = PBXBuildFile; fileRef = 8466E48F03D70CA17AC83C7B881AE446 /* SentryCrashDoctor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 923E97A02255B4F84AAAE4DD6AC6C6E4 /* SentrySDK.h in Headers */ = {isa = PBXBuildFile; fileRef = 72683F357F02D5EDA048DC6F23D4092D /* SentrySDK.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 92765930E3B94F317E132E9356D88FAC /* SentryDefaultCurrentDateProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ABC382AC330CC67B3C949FB87775132 /* SentryDefaultCurrentDateProvider.m */; }; + 92BCD6A5BE8CA77A76752EB429B1B3EF /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D8478733C770AD8B5E60B4BFFF6C7BFB /* SDAnimatedImageView.m */; }; + 92CE0D8352F847E3FB4F88388A9835DC /* OCMExpectationRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 21463A3730433C3AA2E07A0BA53A08B9 /* OCMExpectationRecorder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 93095F594EB27EB7D64B75CDB1A0CBE9 /* SentryCrashReportFixer.c in Sources */ = {isa = PBXBuildFile; fileRef = F97C641D4A8FFBE3CBDB534ACFE13EBA /* SentryCrashReportFixer.c */; }; + 9311CFD012D1CDC16E9719C9087A640E /* SentryCrashMonitor_NSException.h in Headers */ = {isa = PBXBuildFile; fileRef = A55A5E501307CDABEECE7608B972AA18 /* SentryCrashMonitor_NSException.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9347C0404D47A3B1FCC09D8DF592F0B4 /* SentryStacktraceBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = EC1EEE25B6064557720CF2B1812DF2FD /* SentryStacktraceBuilder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9351ED3AB561718C306EA994867C7A79 /* SentryCrashIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 131891EA60BFD2C10D365038115CC8C2 /* SentryCrashIntegration.m */; }; + 938E70A81407D700DD36CB557E17CE42 /* SDImageCacheConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = F5F2B1490B6DD7BB39A64E8C982E68A6 /* SDImageCacheConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 93D5BBA4B364F5312887A675E25388AC /* SentryCrashMonitor_MachException.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A825AE1B597340584246AA8758C978F /* SentryCrashMonitor_MachException.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 93EB0B8CE0AE7FFC996562B4DB55CE24 /* SDImageCachesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 668302F463985196E28640C57429DA13 /* SDImageCachesManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 940F21B9A3A36EF8ED734718FC13FDC5 /* SentrySystemEventsBreadcrumbs.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF78BEA53B328FF4AC085F3142F1197 /* SentrySystemEventsBreadcrumbs.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9477444E5C1483D09FE487575F31FC1D /* SentryThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 89B11BFCB1A668E910E7D78C6959D8B2 /* SentryThread.m */; }; + 9494B8B6DA4552D1A006F5ECBF9673FF /* MixpanelPeoplePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AD8082B1558E9CD4FE81D97AA7EFBB9 /* MixpanelPeoplePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 94A899454728A627B3A09E219D11F90B /* NSValue+Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A0B6EC88D0EFA74FC3FB8F0BBCCEC0F /* NSValue+Expecta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 94B6DAFE2FD3A0309F25E7EAAC53DA34 /* SentryMechanism.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E4DF4622B9F51C96D13D365CC3101A5 /* SentryMechanism.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 94BD694E8B0DA875351BCB512772B1E0 /* RetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F03E9E2CCBA2497C85A620AD66646FF /* RetryStrategy.swift */; }; + 94C2D2CAA567894E9CD228DEDCF66044 /* SentryAutoBreadcrumbTrackingIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FF6CBBFF458151EFC2056A73D7092CE /* SentryAutoBreadcrumbTrackingIntegration.m */; }; + 95EDE12789CC1195FDAF5E5CB86112AD /* EKSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 80F38BDE157D18A99DE165F15628E9D8 /* EKSerializer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9652E46AC6C2B8C6579C903EADB667A2 /* MixpanelType.m in Sources */ = {isa = PBXBuildFile; fileRef = 41A323BD55CEF8F8697370A91DF02F88 /* MixpanelType.m */; }; + 971B4C9BAB43DFD9C22A3BCAD962B882 /* SentryCrashJSONCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE92C9C62C1580212860559CDCDB61 /* SentryCrashJSONCodec.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 972D0C8F72933F21B9E2468F683C20F0 /* SentryCrashDebug.c in Sources */ = {isa = PBXBuildFile; fileRef = C02A9CF89AD5F57E5E1DC0F438331741 /* SentryCrashDebug.c */; }; + 9736BF32F948068A322BF8E06B6ABE58 /* OCMBoxedReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C94CDAF70A626A6557896E3013D3F6 /* OCMBoxedReturnValueProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 977A269A6DD9969DB827B44E70EF4000 /* SentryScope.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F57830DA0361A1D478D6FD1206B5C8C /* SentryScope.m */; }; + 97A9132C49185CF94832897F6AD9628A /* SentryCrashDefaultBinaryImageProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = C190ED49B8AF2D2705779E1DD6001A3F /* SentryCrashDefaultBinaryImageProvider.m */; }; + 97DD26AE2DBAD80F87679FCA6732BC5A /* NSData+SentryCompression.m in Sources */ = {isa = PBXBuildFile; fileRef = 3298B34DB4E92B8B598D382D9EFE204A /* NSData+SentryCompression.m */; }; + 9807A78A9140DBC2E065BBC0B55E3685 /* UIImageView+HighlightedWebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A50596FAFF371E0C7E67A7CA37C794AD /* UIImageView+HighlightedWebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 981EF60CF03CC56C4FDE66DD95072934 /* SentryHttpDateParser.m in Sources */ = {isa = PBXBuildFile; fileRef = E4C37732B893111733DF0A4585B21DFD /* SentryHttpDateParser.m */; }; + 98B330E41CE45CED9AC0C426F192F000 /* SentryRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = E482E15A51417B629DB9DA89BFC13FB6 /* SentryRandom.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9912B758EFE345DB72EE03DB4ED86630 /* SDImageGIFCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 59325D1A1541A07E74163513B6C7AF55 /* SDImageGIFCoderInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9934E1DEC10D877E5E59AE57C318ECFD /* SDImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F4D52F3B627B332A01C5715F76C62D8 /* SDImageCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 997852819F690AE3E059573B84BE10A2 /* NSError+SentrySimpleConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 20A2C767F5807D413097F6C204719CA6 /* NSError+SentrySimpleConstructor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 99B83DAC578920B3E2BD4736533E57A9 /* SentryDefaultRateLimits.m in Sources */ = {isa = PBXBuildFile; fileRef = F80977F97FF7554E700DD6D4126D3A7F /* SentryDefaultRateLimits.m */; }; + 99C5D4C03DC0C21BCE641165479FA71A /* SentryCrashMonitor_User.c in Sources */ = {isa = PBXBuildFile; fileRef = 24AF02D97FDECA148365DA4E0103FF00 /* SentryCrashMonitor_User.c */; }; + 99ECAD246F5A6D4B1484C48D09A81D21 /* EasyMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = B074CAB984CC58579CF9DF157C294F9C /* EasyMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 99FA053F5CAB636FD11312F40EBBF0CC /* SentryCrashMonitor_Deadlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 3ED720BAD2544EC968D1F33773CF08EB /* SentryCrashMonitor_Deadlock.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9A14041987B17C1D70C8E93B78DC1415 /* SentryCrashReportStore.h in Headers */ = {isa = PBXBuildFile; fileRef = E772C6FC8CD4F5F3153C1AD785CA8BB4 /* SentryCrashReportStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9A1D2DAB700D2F165A7631E5BD9F2790 /* SentryCrash.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D34CB3DFF8BF5C1EAC6DDE6A5A0F132 /* SentryCrash.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9A3DCF423259DA1AC1A0F0851FFACEEB /* SentryCrashReportFixer.h in Headers */ = {isa = PBXBuildFile; fileRef = CA279AE3C2EB34F9499A2B45631985DE /* SentryCrashReportFixer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9A68B49491E89F69DDDFFD78A3D99061 /* SDWebImageCacheKeyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 231648EF993E94C012C047EDB0A87DD7 /* SDWebImageCacheKeyFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9AC2BFADBB45D261140975D95CDDF6C2 /* EKCoreDataImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC68AE22AB019032DD1A0EA782C4614 /* EKCoreDataImporter.m */; }; + 9BA4EDC40FABB96AE639CE795D3F3D8A /* SentryCrashReportFixer.h in Headers */ = {isa = PBXBuildFile; fileRef = CA279AE3C2EB34F9499A2B45631985DE /* SentryCrashReportFixer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9BB39052C25415D9EDCFC3CF7F930AB9 /* SentryDebugMetaBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = D7BC83D8B30962F7F9482DEAB81BF427 /* SentryDebugMetaBuilder.m */; }; + 9C25C59B12F769D4309BDC960DFD81D5 /* SentryDateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E61FB7499176B62067C34B234D8526A /* SentryDateUtil.m */; }; + 9C2CDCF43CFFCE702DC78698C0B0C5F3 /* Container+SentryDeepSearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A2CBF658B1028843343F4D084C7F808 /* Container+SentryDeepSearch.m */; }; + 9C335E0C75EF070C6D4A83AEC64FBF01 /* SentryTransactionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B10146712CA2C75052E427FF98FEE76 /* SentryTransactionContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9C6BF74B2BB020EDF3390BAEF20F9C91 /* OCClassMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E586A05DDB15DCAAD49489B0632C0DA /* OCClassMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9CD2BCD7072F93A5FC9FF9E340437E21 /* OCMConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 427528E5351360795A2FC716F0A61A43 /* OCMConstraint.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9D856D3CF2508C51A92D7F4B0CD53F59 /* NSInvocation+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DE6AFAD4DA89E40DCBFF481259AAE455 /* NSInvocation+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9D96E887F3AF3FCB896F40F6167D03AF /* ExpectaObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 45787E0AEDF8AD16DDEA9AA886A226C0 /* ExpectaObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9E1B8E2CB017BC7545F2DE5EFDCF7B74 /* SentryTracer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AABDDA011743888BE5370D828CE8324 /* SentryTracer.m */; }; + 9E2AE23F44E947FB14BCBEECBF1F41B4 /* Mixpanel.m in Sources */ = {isa = PBXBuildFile; fileRef = 918C1E8E18681194571CC7CC409D810F /* Mixpanel.m */; }; + 9E7C7FAE7DB2991CAEC21B9A38CB3700 /* SentryFrameInAppLogic.m in Sources */ = {isa = PBXBuildFile; fileRef = F2F27DBEE78FB424F0C52D196487096B /* SentryFrameInAppLogic.m */; }; + 9F6E2AA5B19A49BAFBBA3D17CDA34036 /* SentryBreadcrumb.h in Headers */ = {isa = PBXBuildFile; fileRef = 10C33D949E0F21DC36A9644F03202279 /* SentryBreadcrumb.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9FB1648CE2E58896B4CE11FFDDF42604 /* SentryConcurrentRateLimitsDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = EF55C9584F47C438713DC40D4B95320A /* SentryConcurrentRateLimitsDictionary.m */; }; + 9FDE4F42EC733A5EBE03577A1B0BD616 /* SentryFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 910A5EA3CAC3C38415BB28F6CF628F83 /* SentryFrame.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A01199D4151D6DEFF98D292E794581A9 /* SentryScope+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = AF59753534C973EC2CA684E58AA58706 /* SentryScope+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A039049BD1ACE347793D15694312ED48 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = B111E844834CEDC91CDE3BE38BD67D55 /* SDWebImagePrefetcher.m */; }; + A05EC45CE67973AFF41D00EBF1BACC2B /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B4728D9253591A76583B4851D369268 /* SDWebImageTransition.m */; }; + A12CFB59F38100C987161083B914187D /* EXPMatchers+beSubclassOf.h in Headers */ = {isa = PBXBuildFile; fileRef = F2D31996EC48D78A198DBE8858B6151B /* EXPMatchers+beSubclassOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A15945657307EC5A623B2A8F0EF06F6E /* Mixpanel.h in Headers */ = {isa = PBXBuildFile; fileRef = BB20C65D91E6BA3A93FCE00CC0AEE9FB /* Mixpanel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A181A081D11DA62F39C1A1EC420F2DF3 /* AVAssetImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4ACE71B7BF8F77EA48BC5C6B292247F /* AVAssetImageDataProvider.swift */; }; + A194DE7323C4BD30401CD361961E5F74 /* SDAnimatedImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 094D47CB9ED66B51D0B71F70E8BE1EF5 /* SDAnimatedImageRep.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A196AE57DF39127949AB29665E18F251 /* SentryFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 00A6995B33F3B7F8D6D346392CE2FAB1 /* SentryFileManager.m */; }; + A1BEFAC9339924AEB6B79413211D05A5 /* SentryAsynchronousOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FD7012E4F272E888FCB789C2A861DD6 /* SentryAsynchronousOperation.m */; }; + A1C36CC845958977873951337FC4C3BE /* SentryCrashInstallation.h in Headers */ = {isa = PBXBuildFile; fileRef = A183B8C88C10AE3947EC7E662488F951 /* SentryCrashInstallation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A1D4BF93966F679CA1158691ECADAFD2 /* SentryCrashReport.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F0537A8A90D413531F5A9EA15E6D7FD /* SentryCrashReport.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A26ADE1931856B9F72370EB470D145D7 /* EXPMatchers+beTruthy.h in Headers */ = {isa = PBXBuildFile; fileRef = A60658B35C750AD8DE167E3A43FF0C23 /* EXPMatchers+beTruthy.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A26C4EB868D918E726F5887BD4145D8F /* SentryCrashMonitor_Deadlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B8940A8DA7525FD7DD22402B5A63D /* SentryCrashMonitor_Deadlock.m */; }; + A29A7313B9C82077B6DE4D83D2AC3ECE /* TracesSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = D88D303335E70DB46B148AF73F042D6E /* TracesSampler.m */; }; + A327DFEF86D8B57F7C0091B904B8D876 /* SentryCrashMonitor_Deadlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 3ED720BAD2544EC968D1F33773CF08EB /* SentryCrashMonitor_Deadlock.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A36930E3A99533EF350A99423B9CE2B9 /* SentryMigrateSessionInit.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CCB6752988681478753D8ECC5D8F288 /* SentryMigrateSessionInit.m */; }; + A36A02BE4A44F7BA5F2B0FC110B6CCE6 /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 96FC816744C2BCCA51CED048731F0C91 /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A370F8BBD13111FDFCFA7A10577C35EF /* SentryQueueableRequestManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 77037A26EFAA75844B4E6E8757662060 /* SentryQueueableRequestManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A39292434983FA18E0545CD074BAA88F /* SentryHook.h in Headers */ = {isa = PBXBuildFile; fileRef = 6792D215AB742EF73C6E5D637C93536C /* SentryHook.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A3E9D8D3FCC116B9977B4D9D15931763 /* EXPMatchers+beInTheRangeOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ED45AE327842259B4C32E6BCB45FAEF /* EXPMatchers+beInTheRangeOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + A442B55E72B9E343A34C6185EF5BEE51 /* SentryTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = E7A20D0EF6CC27822F5F673A4C0CE300 /* SentryTransaction.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A454AF3F4AF742B2E9E118F5446E9FB3 /* OCMLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 358E2C8396B00E243809000DFC3F9F46 /* OCMLocation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A45E62E1B3CD8100D1980D99279488CC /* SentryCrashUUIDConversion.c in Sources */ = {isa = PBXBuildFile; fileRef = 09F7FF971894B9A06B4ECBF1B884BCEE /* SentryCrashUUIDConversion.c */; }; + A474EEA7620B4B70761B02343CF79040 /* SentryCrashReportSink.m in Sources */ = {isa = PBXBuildFile; fileRef = 26D65938F613F4DCAC1F063D925D9C8B /* SentryCrashReportSink.m */; }; + A48FAEBA4B6D5975A2A4CF8EC37E9A3D /* SentryDsn.m in Sources */ = {isa = PBXBuildFile; fileRef = 0995BB77768EED5B1928D052E061FED9 /* SentryDsn.m */; }; + A495437891EBB7938E7068677FB64F68 /* SentryRateLimitParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F56E39159CAE9BE998C994876ED8E9D /* SentryRateLimitParser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A514279639E922DD686A2C17BD238BEC /* SentryOutOfMemoryTrackingIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = D63CDF6E2D49F7055CDF917E715932E8 /* SentryOutOfMemoryTrackingIntegration.m */; }; + A51F7ECF32728036C3977EA073A559AD /* EXPBlockDefinedMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = EE191BC83E04210BBFF33CDC23B799B5 /* EXPBlockDefinedMatcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A5752F690CF82DAD517E95D985B786F1 /* SentryRandom.m in Sources */ = {isa = PBXBuildFile; fileRef = 2685949B966DFD911386610465982AFF /* SentryRandom.m */; }; + A589DDECC7AD32CA25386B92F3D9C278 /* SentryCrashDate.c in Sources */ = {isa = PBXBuildFile; fileRef = 98B74495E6501725B2A5B7348E1C93AE /* SentryCrashDate.c */; }; + A5C6DFA12D0A2BA2B82620C5EE9D351D /* Sentry-macOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C4A6679DBB5BEDCF84D9F0F1B2E6204D /* Sentry-macOS-dummy.m */; }; + A5C99AC00D6E07276A05C23CFF9CE496 /* SentryAsynchronousOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5724B0A9796694E79E16B52BE58B5C79 /* SentryAsynchronousOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A5D55782524E9DA98FB2CF6C28E84110 /* EXPMatchers+respondTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8177EB82FABE600FA5B880534D57C6 /* EXPMatchers+respondTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A5DAC4AA05505E57069CB3192FB88517 /* SentryAppState.h in Headers */ = {isa = PBXBuildFile; fileRef = CEDD3F9A418E86363FCB41C14161DC01 /* SentryAppState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A5F1DCB17662413E75F50B57E3DC4E5F /* SentryCrashCachedData.c in Sources */ = {isa = PBXBuildFile; fileRef = 100CF4E00773DF746C10C45D5F9A6A88 /* SentryCrashCachedData.c */; }; + A5F6EE5AE62E7FC137C84315CB651395 /* MixpanelType.m in Sources */ = {isa = PBXBuildFile; fileRef = 41A323BD55CEF8F8697370A91DF02F88 /* MixpanelType.m */; }; + A5F8B9CA051B11573C979B2AF9499A3B /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69D2E3393AB08042B490CCC899D7E965 /* FormatIndicatedCacheSerializer.swift */; }; + A60283C3AF52B127660FD68951CF8D27 /* SentryTransportFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 249A621C3105048EAC1AAFF00A061841 /* SentryTransportFactory.m */; }; + A641B211305122B6B0930D3AE1DF9E0C /* SentryMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4921086B7457B240615C849B4A4DE4A7 /* SentryMessage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A65F2AEE7FB68576B6E1BC8C7184DFAA /* SentryStacktrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 707760BF81A4C4F1570470CC648600BC /* SentryStacktrace.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A6627DDCBAC5902427F06406C17FBD90 /* SentryCrashBinaryImageProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 87CD89D239B8AD49C9E6A7B041C940CC /* SentryCrashBinaryImageProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A6A1ED7188FCA275C31A024E93A6D4A0 /* NSImage+Compatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 37E0C1DAB986269E65DF3BF1A45C66D1 /* NSImage+Compatibility.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A6A77EA563BBBEFD3FF877C6A4182750 /* SentryException.h in Headers */ = {isa = PBXBuildFile; fileRef = 539A29AA5C82086D87D861EF794BE53A /* SentryException.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A6DFD379AD92DA495E880DA2AF2EA845 /* EKManagedObjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D19CFB58A52BB6ECB5EAB0DAF6B03C2 /* EKManagedObjectModel.m */; }; + A71370F4935778355DF49316C4130053 /* SentryCrashMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B7B262830FE791A2992275F9570DE8C /* SentryCrashMonitor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A731311E14FA86A1B4802C3C114AE6F8 /* SentryCrashReportFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = EBF50F815E871FC102F8AA6473815C6C /* SentryCrashReportFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A75CD5CB8D97034FC5B7903E111E4BC1 /* MixpanelGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 4801355A25E5488A0DF0A051F6ADB977 /* MixpanelGroup.m */; }; + A7AFF805552754168FE472102902BEE8 /* EXPExpect.h in Headers */ = {isa = PBXBuildFile; fileRef = A202CEF8C27DDD9E0C7DBA2D5E025C07 /* EXPExpect.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A7B2109E598125ED8B51B8F03559E45B /* OCMObserverRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = F0B2CB9BEC64D0147EDC960E67516CE5 /* OCMObserverRecorder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + A7C9F3D124E5E6BC56306580B4BBF12F /* SDWebImageDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 970D9F8EDEB3B80C1218D90CD500232C /* SDWebImageDefine.m */; }; + A7CE151D48A5DD876ED10486B9C4FBB4 /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 33B716A52A3BD31594FA249C2ED9CBA5 /* UIImageView+WebCache.m */; }; + A7EA36DC1811C699D2C4C0831FB9EADC /* SentryNSError.h in Headers */ = {isa = PBXBuildFile; fileRef = ABF82152AE21904F7720320408CF90EC /* SentryNSError.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A7EEA4CAAD20EB07A0F0A19B45035CA9 /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16ABE2EA48367A888D50B0F067C45957 /* DiskStorage.swift */; }; + A810535B1D3418C355D09AFC9AAE45F4 /* SentryLevelMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = EAC198E0EA2F49AA7D4D66A51EE2F528 /* SentryLevelMapper.m */; }; + A81926638FF550204E63D7D76C419C02 /* NSValue+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 656E06E6545A067AF16918EE5E3123DD /* NSValue+OCMAdditions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + A81D9CD8A55BDCF4776392B3426F0AEA /* SentryFrameRemover.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8FE91A1ADA4F3ED0E95C05F4EFD64F /* SentryFrameRemover.m */; }; + A8258677EF0DCD40B4E937D946ADEF4A /* NSError+SentrySimpleConstructor.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CB6B2ED6DFCB782ACC85B2D4C2B7F22 /* NSError+SentrySimpleConstructor.m */; }; + A848463EEC33CA28BE553CA42A747EA2 /* SentryCrashMonitor_Signal.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A79920CFA1BDBD9E75FB348D29B205 /* SentryCrashMonitor_Signal.c */; }; + A85951B63AE13857A9454593CFE075D2 /* SentryCrashExceptionApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A08B9374BA62246F90A56F8B705B234 /* SentryCrashExceptionApplication.m */; }; + A88F704CBD4D82BB5D02AEECCB5D6436 /* SDImageIOCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 91A9040BA97087B23F51E478BA701A6F /* SDImageIOCoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A899FC847C293004CDDE2082820097F6 /* NSArray+FlattenArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DE263CCD7DE182693CA38B30F831375 /* NSArray+FlattenArray.m */; }; + A8E1E6D13E9C202131DBEB99E17CA82F /* SentryCrashStackCursor_Backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 479F6C5B2AD83CECCF85A2F820906395 /* SentryCrashStackCursor_Backtrace.c */; }; + A9059641712404E39B1370D94DFC5CED /* SentryCrashReportConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CB00895C3B8D81E78B53D91E9A3ED2F /* SentryCrashReportConverter.m */; }; + A95E3534D0F0F3D77D95DFD16D7ABC77 /* OCMExceptionReturnValueProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = C0D2656F2A875ECFE893BF18B2E16492 /* OCMExceptionReturnValueProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A9B06F5E33552A9640D0E4D2A5159786 /* SentryTransportFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FB87107341CDBA82C7CEB2B131A51B3 /* SentryTransportFactory.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A9F97A22BB3B6CE7148194717E4E415F /* SentryCrashMachineContext_Apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D48E9E19EDCAF24050949D06D6DD6E2 /* SentryCrashMachineContext_Apple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A9FF3EBA5BE9A7E842FDA570134BA848 /* SentryCurrentDate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6028B0CECC6A8136E220A86E8C686B05 /* SentryCurrentDate.m */; }; + AA4B15DEBAB34C1E23C8797FAF8FB9FD /* MPNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = D86F21A61B42BA1F53F84900700F92A6 /* MPNetwork.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AA9E92FFF1588E9B0489222BED552DA0 /* TracesSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = D88D303335E70DB46B148AF73F042D6E /* TracesSampler.m */; }; + AAA15CF17FF4F4FA07ECE64351789D5A /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = B436EC62C08B574E6FEA12C19BE5C8C3 /* UIView+WebCache.m */; }; + ABC57616D491AD6705C6B5B40C9DAF85 /* SentryCrashMachineContext.c in Sources */ = {isa = PBXBuildFile; fileRef = 31BD2E6667910A3319B47B6397FB7A7D /* SentryCrashMachineContext.c */; }; + AD220444D975F808498256F647D8EABC /* SentryFrameRemover.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8FE91A1ADA4F3ED0E95C05F4EFD64F /* SentryFrameRemover.m */; }; + AD2CF66258C344DB8B748A7D7325059E /* EXPMatchers+endWith.h in Headers */ = {isa = PBXBuildFile; fileRef = A2E6C9BD4CA6F7A05DFD31BEB92AD59D /* EXPMatchers+endWith.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AD5E020DE6D6894A6DE52ED3425E7E3D /* SentryFileContents.h in Headers */ = {isa = PBXBuildFile; fileRef = 643054DB8DBCF6B6727687DF0F36411F /* SentryFileContents.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ADB269445976EB1535E532F7E853E83F /* SDImageAPNGCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9387616F36BC353A71CA06624B067969 /* SDImageAPNGCoderInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ADCBEB3BBFB482CEFCAFE5585FAB6D7F /* SentryMeta.m in Sources */ = {isa = PBXBuildFile; fileRef = D11372170552F442945E0B5B17587894 /* SentryMeta.m */; }; + AE344EC3B051D94E99753BA9A18D1E45 /* SentryStacktrace.m in Sources */ = {isa = PBXBuildFile; fileRef = 41B0A65DF6211BF2861ABE6E500D3B7E /* SentryStacktrace.m */; }; + AF1CE89AB242EE3E79A62A11D1DB45BA /* SentryFrameInAppLogic.h in Headers */ = {isa = PBXBuildFile; fileRef = 33FE9136D837600FD6367096AD17FEEB /* SentryFrameInAppLogic.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AF4EEDDC8B4D37D4105C7AC3A571A6B3 /* EXPMatchers+postNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = A7042E946A278D6275B3C37E519799F4 /* EXPMatchers+postNotification.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AF61EE2DB798B07B41DE57B88148C5F8 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D759D1EF7CB9A6791C8A65C27143C696 /* Indicator.swift */; }; + AF8F7B4506188565F09AD4D19A80EFE0 /* SentryLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F317A88BF3EC0E25B9D3EEEE2368BF99 /* SentryLog.m */; }; + AF9EF75D319BC6E2B0931FCF66671E51 /* SentryCrashStackCursor_Backtrace.h in Headers */ = {isa = PBXBuildFile; fileRef = AE44188648C57CDADB4BBBC4CC62CC3A /* SentryCrashStackCursor_Backtrace.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AFB32B60015F518A3836ED5665ACDE1F /* SentryThread.h in Headers */ = {isa = PBXBuildFile; fileRef = BBC0FD88956CF8F23259FCE3D7B5E7C9 /* SentryThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B0010BBE7F27AA63239F8B31D4AB4366 /* EXPMatchers+beSupersetOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E9FC117741B956A49CA4281D1D1444F /* EXPMatchers+beSupersetOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B01939CFE9617A00F0F4308B6FBAF370 /* SentryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = EF4162342FE010A64DF41F62EFFE32FC /* SentryScope.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B02325814394E4F3606C1F8EDC5E9367 /* SentryCrashVarArgs.h in Headers */ = {isa = PBXBuildFile; fileRef = 021507B63C15C6275FA1614AA26D56C7 /* SentryCrashVarArgs.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B037286C4815742A15E134466A379DBE /* EKCoreDataImporter.h in Headers */ = {isa = PBXBuildFile; fileRef = FB4D53C11D7F99FD3BC21C897B80C49B /* EKCoreDataImporter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B03B0C90097E42CE81DB8A43E8DAF504 /* SentryQueueableRequestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BBCCBA0D6DE3EFC7812C64133351C711 /* SentryQueueableRequestManager.m */; }; + B05EF0263571719D669495825B89200D /* OCMInvocationMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = F1EDFC2372A9C734629885AC1A91E4AE /* OCMInvocationMatcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B07538E7C6D99FB5BAC78A3C8DBB42E1 /* SentryCrashCString.h in Headers */ = {isa = PBXBuildFile; fileRef = 438F5D72C80C54963277C3109A0652B0 /* SentryCrashCString.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B089A167D7843D388D7257B183119170 /* SentryCrashCPU_Apple.h in Headers */ = {isa = PBXBuildFile; fileRef = B96ED94280EE507E42A646706D56CE1C /* SentryCrashCPU_Apple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B0BBCE4814FD7D6927440AE418591B2E /* SentryEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84148C4BBC5639650E918B7D1AE9FCA8 /* SentryEvent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B0EBEC7D8D557110409295660CCD3F7A /* SentryNSURLRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 472F88C1AE184846E3C92E70773C562C /* SentryNSURLRequest.m */; }; + B14FAEB37710ABF8E15D138A4B2AC02E /* OCMRealObjectForwarder.h in Headers */ = {isa = PBXBuildFile; fileRef = AD43111F7D7D4B981C14C7A679582A32 /* OCMRealObjectForwarder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B19B0811B8D0A22FFA5936396666C55E /* SentryRateLimitCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 979EDE57A39CEF533C37EC090F0D5821 /* SentryRateLimitCategory.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B2152DBDF58C09D82AE8E9697E15C092 /* SentryId.h in Headers */ = {isa = PBXBuildFile; fileRef = ABE2CA9730DCE620663640615D743BB0 /* SentryId.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B2D1AA2A21989FFBE36B49993FA51B1C /* SentryCrashUUIDConversion.c in Sources */ = {isa = PBXBuildFile; fileRef = 09F7FF971894B9A06B4ECBF1B884BCEE /* SentryCrashUUIDConversion.c */; }; + B348C492A2322F68A812B67B6B85F1A3 /* SentryCrashSystemCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 733EB9949216F382705773FC086855B6 /* SentryCrashSystemCapabilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B353DEE0F707A17093B0D8A5F53894D9 /* Expecta-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A0ADA459399E5006B57CF039E0BFF87E /* Expecta-dummy.m */; }; + B37091C335BA5DB4EAD19B61DFB7883A /* SentryCrashCPU_Apple.h in Headers */ = {isa = PBXBuildFile; fileRef = B96ED94280EE507E42A646706D56CE1C /* SentryCrashCPU_Apple.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B38B31930E04412FF4390F40B506868F /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = D786DB1ACA3291F506237438289B40BA /* UIImage+GIF.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B42F53A5373F6DBD58A3753377F11A3F /* SentryCrashReportFields.h in Headers */ = {isa = PBXBuildFile; fileRef = C7FE1EF9F428C6334E0F097B069FC11C /* SentryCrashReportFields.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B43AC1BF85A55FE20FE10925797906AE /* SentrySessionCrashedHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A0628EA6AE627462153793C03272C2CE /* SentrySessionCrashedHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B4414D2644F388ADC0C39DC930324A90 /* SentryCrashReportSink.h in Headers */ = {isa = PBXBuildFile; fileRef = 085DF157C909A8A4111A1513A172F832 /* SentryCrashReportSink.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B44FC2AB5B47F10C09A1C458049CF21A /* SentryCurrentDate.h in Headers */ = {isa = PBXBuildFile; fileRef = 52ED80A99741A76F678B412BF5FC91DA /* SentryCurrentDate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B458BC2D677BFE2781CA179888E41364 /* EXPMatchers+beInTheRangeOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D87B40410B52B9EF1864370A90442B8 /* EXPMatchers+beInTheRangeOf.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B4596B592E540A4887A76F8367BB64D2 /* SentryCrashMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 77E6411FB561EA85553780EA72EC7EDB /* SentryCrashMemory.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B49614695970F83CFEE68B8A61EBEA1C /* SentryCrashMachineContextWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 668A94876717C5D861AE21C2D9206219 /* SentryCrashMachineContextWrapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B4AE70BB3B7544E6E79FC96E60E6BA1F /* SDWebImageDownloaderOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = CD2B67146BB65F60C7F9AA52A0242BB2 /* SDWebImageDownloaderOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B5308E889740F697E0432FFFC05971F6 /* MixpanelType.h in Headers */ = {isa = PBXBuildFile; fileRef = DB9FF4A48AF84AF31680A56E61A2BF84 /* MixpanelType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B587FF3B640203FF67D0AAC3E7A9580B /* SentryCrashReportWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 06D304B144FA7C586C57986E3612227B /* SentryCrashReportWriter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B5C28A763C4100F75703229CB27148BB /* SentryFrameRemover.h in Headers */ = {isa = PBXBuildFile; fileRef = E018C8C2D434DF9416FE294E909F30D8 /* SentryFrameRemover.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B5D629B65A97D9E8EF4D5BAA4F40C0FC /* EXPMatchers+beSubclassOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 11925E02843BE5EF8939078EB45BAFA5 /* EXPMatchers+beSubclassOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + B5E7B7574A67181C856E0C677ABFBBAE /* NSString+SentryUnsignedLongLongValue.h in Headers */ = {isa = PBXBuildFile; fileRef = CDB702BF91B1964D255A4A5C424C327E /* NSString+SentryUnsignedLongLongValue.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B60B6F7F6F6DDB622761C08B097868E7 /* SentryCrashCString.m in Sources */ = {isa = PBXBuildFile; fileRef = F0B701C1D482E92F4504D38FE92A930F /* SentryCrashCString.m */; }; + B67DB68BFDA7EE795AC74CB0AC45001A /* SentryCrashString.h in Headers */ = {isa = PBXBuildFile; fileRef = 8522E68E0FED7627A746EDFD9DDD0700 /* SentryCrashString.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B6954F38C15CA4FD0B251EF76865606B /* SentryScope+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = AF59753534C973EC2CA684E58AA58706 /* SentryScope+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B6CBC14845016BC0387EE16974AD5121 /* SentryCrashReportStore.c in Sources */ = {isa = PBXBuildFile; fileRef = B67294EB0F7BE16140AA5419E527DE10 /* SentryCrashReportStore.c */; }; + B6D28D12D9F9B9D61C988129EA6D1919 /* NSData+SentryCompression.h in Headers */ = {isa = PBXBuildFile; fileRef = BA6674821E44BAAADC77D5FB4CD7671F /* NSData+SentryCompression.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B6EE74F7C6A89BB6B351FE8E7FB922B3 /* SDWebImageCacheKeyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = B69653CC54B8A80021F43EC587AB9266 /* SDWebImageCacheKeyFilter.m */; }; + B7049B8112BB72962F49E3DA3280A41F /* SentrySerializable.h in Headers */ = {isa = PBXBuildFile; fileRef = E73AE987835897A07BBC6DCC00651DCE /* SentrySerializable.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B712F3D7BB3F77A62982F72BB96E3AFF /* SentryEnvelope.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED89C1427E6BA14DF252DAAE9BBC9F5 /* SentryEnvelope.m */; }; + B7603387DF30944EE2AF64E8AFD9B996 /* EXPMatchers+beCloseTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 2721B1D673A34DA349D3468D5EB061F5 /* EXPMatchers+beCloseTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + B7A75A336ECD93F3B97B3C3E6D74AB98 /* UIImage+ForceDecode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C103D4E297EFF00119BCB966FCB8FA6 /* UIImage+ForceDecode.m */; }; + B7D699155A8B5E76B2DA483A3E96F862 /* NSDictionary+SentrySanitize.m in Sources */ = {isa = PBXBuildFile; fileRef = 7899C1894601F14A332E8A700E2B043C /* NSDictionary+SentrySanitize.m */; }; + B814EB568E6FC783F451588AF8D3C426 /* SentryCrashMonitor_Zombie.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F6115F119202A304EEF57D5B2954F18 /* SentryCrashMonitor_Zombie.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B82BBBCFE5BED28B1276BE76A577FB08 /* SentryAutoBreadcrumbTrackingIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FF6CBBFF458151EFC2056A73D7092CE /* SentryAutoBreadcrumbTrackingIntegration.m */; }; + B87E1E284805A1F6AB2AB20F873CAE1D /* NSDate+SentryExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = A6197DD8D086D74EC7BFCCE051FD5F31 /* NSDate+SentryExtras.m */; }; + B8C924F7983360C20BCC019E89DF874C /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EE01D24380B370BF657B7428A0587C7 /* ImagePrefetcher.swift */; }; + B8D415D848D08F942B73D5168C0F114A /* SentryCrashDynamicLinker.c in Sources */ = {isa = PBXBuildFile; fileRef = 02FE69406B0C2F87D52C67EBB5E19FCE /* SentryCrashDynamicLinker.c */; }; + B91BD03920E3C188E391B90EA0BF1A4E /* SentryOutOfMemoryLogic.m in Sources */ = {isa = PBXBuildFile; fileRef = 6752AE45A10AE01FB384A64DA9F7E3A4 /* SentryOutOfMemoryLogic.m */; }; + B91E5F7AF68E8B24E40FF9B2C80A648D /* ImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627A23129220606C34D687C6A9E1E86 /* ImageDataProvider.swift */; }; + B95AED6298F5C65D4C3F8709A6E4F12D /* SentryDateUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = CD9E7F9949C74A81F649A55858744F7D /* SentryDateUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B98D09E680FD5AD6C240EEA05BF673EC /* SentrySamplingContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E5B9EB4F70C9724CEC101658BE9A22 /* SentrySamplingContext.m */; }; + B996D4516F1B0CC3D1EDF8D26977EFB0 /* EKSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1884FAF2A8FA6485B812BC2FF3A2D02F /* EKSerializer.m */; }; + B9C9E6FDAE332F9A7BCEDEE21FA33A0B /* SentrySdkInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F3523459F8BDE81CDD88934EA8F73B0 /* SentrySdkInfo.m */; }; + BA2B72C5C0861493B8E9294F56D25DEB /* SentryError.h in Headers */ = {isa = PBXBuildFile; fileRef = E5D86D1F25D9DEDAABC2D4BF04C13638 /* SentryError.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BA3411323C165C1133911719BDF696E3 /* UIImage+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = A033ED022000B891E90E46281AE3C84C /* UIImage+Transform.m */; }; + BA50B2813238B73794AA166ACC10D0EB /* SDImageCoderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = FBE1E2A79F4BFD1C2ED9B7F27661C283 /* SDImageCoderHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BB35FC9133C0FBCFFE9E86876DF26218 /* SentryCrashDoctor.m in Sources */ = {isa = PBXBuildFile; fileRef = D5DE137007B263FBF5F21EC0F26AF27A /* SentryCrashDoctor.m */; }; + BB6A366F78C059717E395840E9906792 /* MPFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = D8728A92B3768750BE8C034BB8A6C225 /* MPFoundation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BB73937DFA779CE341839F29F767FC96 /* SentryHexAddressFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E2C83FDCC2689D4A0B69747EF511C0 /* SentryHexAddressFormatter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BB8AB85AB145BF1FE8770FFECE80675F /* SentryMeta.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E00FC8189AAAB1B80CCE473B6C8AF52 /* SentryMeta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BBCC9987EE8E58C698E6AAD5FA838798 /* NSBezierPath+RoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = DEBA5D47513477CC60EDE11609A69A63 /* NSBezierPath+RoundedCorners.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BBE7DF9CF894DFD35F04F8E3626E7821 /* SentryDsn.m in Sources */ = {isa = PBXBuildFile; fileRef = 0995BB77768EED5B1928D052E061FED9 /* SentryDsn.m */; }; + BC3EC5377F513E07E873442F925E82BB /* SentryCrashID.c in Sources */ = {isa = PBXBuildFile; fileRef = 50C09C43E38AC5954BD87B5EE7401748 /* SentryCrashID.c */; }; + BC7E14094D5830551C418F2B4BB0F799 /* SentryNSError.h in Headers */ = {isa = PBXBuildFile; fileRef = ABF82152AE21904F7720320408CF90EC /* SentryNSError.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BC860116C8605FFF88ACC3520C231D76 /* SDWebImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F9B7BC7DE91FC476DE62B33FF2103B1 /* SDWebImageManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BCCC03AB3BEC74DAD5170A8441D9BBEC /* EXPFloatTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = ECAA70483A39BCA0C0C7E356FB322F42 /* EXPFloatTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + BD285C4B8AA93E741611DD1556DE4069 /* SentryConcurrentRateLimitsDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = A07387E3FEA32D2AC879F4FBE79D7CF2 /* SentryConcurrentRateLimitsDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BD769EA7F521A62B01BA7C52FBFE218B /* EXPMatchers+equal.m in Sources */ = {isa = PBXBuildFile; fileRef = A33AA886DE0330C68ABC7B568A11AEEA /* EXPMatchers+equal.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + BDFF7A69B6B203BC4DB6ADBF3EC42CAC /* SentryCrashCPU.h in Headers */ = {isa = PBXBuildFile; fileRef = B8AF8D7DF499D5D21A642832F339131F /* SentryCrashCPU.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BE0AAA2A08954EA36461820A3F4157BD /* MixpanelGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 4801355A25E5488A0DF0A051F6ADB977 /* MixpanelGroup.m */; }; + BE8130356652C7F976E9B4263C3AE820 /* SentryTransactionContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CD9DCB3C79818BF4DC9700BE32E0785 /* SentryTransactionContext.m */; }; + BE8A5B2559FBE02B1005CBE2223A1E02 /* SentryCrashString.c in Sources */ = {isa = PBXBuildFile; fileRef = 0691D3E0BDC9CD8351C20F1978A97E1F /* SentryCrashString.c */; }; + BEC07B848EB8497572F6C76FF78EE3C9 /* SentryLogOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD6FF53E585D37C0030DD7DDB732653 /* SentryLogOutput.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BED27B3404A4315E4BCCB1358AECCDC6 /* SentryId.h in Headers */ = {isa = PBXBuildFile; fileRef = ABE2CA9730DCE620663640615D743BB0 /* SentryId.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BED84F19DDD265A8DC03B3F4DFFEA254 /* EXPMatchers+beginWith.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B3ABCB4EFCA6459E64585F4A9691AE1 /* EXPMatchers+beginWith.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BF0E9FC2F301F77F02220AA076BE6443 /* EXPMatchers+beCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A49E743371CDA3384FFE238BF4B61D3 /* EXPMatchers+beCloseTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BF353A7249397BFA345229E3DE348AFD /* OCObserverMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = B25757E02D53C1DF22036581F36AC94A /* OCObserverMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BF60AD1CBB20952ADA29421BDA01B37D /* SDWebImageDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = E50C0637D8244791201E8A2D80B8B6DB /* SDWebImageDefine.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BF76B135520EAF1E074BA691AEB3811C /* SentryCrashObjC.c in Sources */ = {isa = PBXBuildFile; fileRef = 8473F3DC171840EAC0BDA09D6FA0E4A0 /* SentryCrashObjC.c */; }; + BF9E3937CCFD78E7DBE3EF757C4B9093 /* EXPMatchers+beGreaterThanOrEqualTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CE4111130816741BE64DB8AA9AF25EE /* EXPMatchers+beGreaterThanOrEqualTo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BFC529FCE9A65F74DDAD7E762A7CACAE /* SentryCrashSymbolicator.h in Headers */ = {isa = PBXBuildFile; fileRef = C09407241B2BDC8483771D6D0859B8D2 /* SentryCrashSymbolicator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BFEA3D2CED9609B4C44CCF34B903F3BC /* OCMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D3669E97FB5BC347CDC0D1D98051F84 /* OCMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C035140AB4EE01C891E20BBFF8D6796E /* SentryCrashID.h in Headers */ = {isa = PBXBuildFile; fileRef = CF16C145406DA3D8215F2D031636900B /* SentryCrashID.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C04B253BED4BD526528573F487619765 /* SentrySerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 893F74730AB7653048453181D4060B4E /* SentrySerialization.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C11A2ACA77C6BF8D6821D2DB9C28E096 /* SentryUserFeedback.h in Headers */ = {isa = PBXBuildFile; fileRef = 61B13957C17E507A36360EEC6762EEB2 /* SentryUserFeedback.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C11B9DC682963BE29B7EE76E6838D9AF /* SentryCrashMonitor_User.c in Sources */ = {isa = PBXBuildFile; fileRef = 24AF02D97FDECA148365DA4E0103FF00 /* SentryCrashMonitor_User.c */; }; + C1667BC4C33118E0CDB9185A6EBC4F71 /* EKCoreDataImporter.h in Headers */ = {isa = PBXBuildFile; fileRef = FB4D53C11D7F99FD3BC21C897B80C49B /* EKCoreDataImporter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C2EC7A9CB370F4E283C430C290734AE4 /* SentryAppState.h in Headers */ = {isa = PBXBuildFile; fileRef = CEDD3F9A418E86363FCB41C14161DC01 /* SentryAppState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C32BD5CC8E760ABAC14D0FA5C4ECE841 /* SentryCrashMemory.c in Sources */ = {isa = PBXBuildFile; fileRef = 794F16D3AAB9F5CF04D4FDAB7BC7EC48 /* SentryCrashMemory.c */; }; + C32D97BF144988C4F1BFFBCDDBF3EB84 /* SentryDebugMeta.h in Headers */ = {isa = PBXBuildFile; fileRef = 28C04358E6A2DC7343F90687D9DB0E7F /* SentryDebugMeta.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C3AF5195A000CF02EB5F0A0FF2A6EC28 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 846A6C09F2ABC29168D385CAA2D58969 /* SDWebImageError.m */; }; + C3D4CDC2CF942B1742CC609DC94612F1 /* SentryCrashStackCursor_Backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 479F6C5B2AD83CECCF85A2F820906395 /* SentryCrashStackCursor_Backtrace.c */; }; + C4265AE0D54889CE2EC8E1188D7537AC /* OCMBlockArgCaller.h in Headers */ = {isa = PBXBuildFile; fileRef = 437EAEDD38DB97E2357378A28B74AF85 /* OCMBlockArgCaller.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C43CD2D29B91567CE7495F83ED9B5D4C /* SentryTransactionContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CD9DCB3C79818BF4DC9700BE32E0785 /* SentryTransactionContext.m */; }; + C4985A1BD4CEC211AD8E2B3998A6C601 /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AA0F981BE89DFC51FBDA98DD87025D9 /* NSData+ImageContentType.m */; }; + C4D05730886A2DD720E67068E81556A1 /* KingfisherError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89AF6C11A3C19706E7C785D56D93D67C /* KingfisherError.swift */; }; + C5704F541D472183ECD228FCA6FA4AF8 /* SentryCrashDoctor.m in Sources */ = {isa = PBXBuildFile; fileRef = D5DE137007B263FBF5F21EC0F26AF27A /* SentryCrashDoctor.m */; }; + C5ABCAD032D262081CC9D9A46F2315E4 /* EXPUnsupportedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = B1BAE2DAE9706E2DCF18FDA63A2EE109 /* EXPUnsupportedObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C5B32C4394CCEDB572459394BDB3FC60 /* SentryRateLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F3224D9568E6D6B837E95D55B0F917 /* SentryRateLimits.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C5CF2EF707C0069DDB121980C937253E /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = A73B1AB046609EA753474A7985924C8C /* ImageCache.swift */; }; + C5D677C161E34D4601D39E703062F674 /* NSError+SentrySimpleConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 20A2C767F5807D413097F6C204719CA6 /* NSError+SentrySimpleConstructor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C5E3E4FF82E3E5EF903C7C3BA4AF5B24 /* SentryCrashInstallationReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 87B8D862925C1E3D10970596A63C2CEC /* SentryCrashInstallationReporter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C60568B491B9DC158DED56407047852A /* Pods-BitBotATV-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B724904092136FEEDB93380DA4070C0 /* Pods-BitBotATV-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C6090CD48338384D778BF641E5F3A0BF /* SentryDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D679F841A6E4E79B5D1E35CA2A4D7CE /* SentryDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C61B8F138CBC985B7A4D0477D6FB013F /* SentryCrashMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B7B262830FE791A2992275F9570DE8C /* SentryCrashMonitor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C677BDC98B12FF3C78C5E3C8420A80A6 /* ExtensionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = C209DBD35687683B0353434E2C4ED4BA /* ExtensionHelpers.swift */; }; + C678D9267C3C16D92EDDD7A1125FBED0 /* SentryCrashMonitor_AppState.h in Headers */ = {isa = PBXBuildFile; fileRef = 01CF90EEF3339577C8BEECE383A29D05 /* SentryCrashMonitor_AppState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C6BC24640D2B9B336247D9EA26C59E9B /* SentryDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D679F841A6E4E79B5D1E35CA2A4D7CE /* SentryDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C6FA4FE61B5E13962BC1418D10A41951 /* OCPartialMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 97957EFCC33E464C409C5390DF5D48D2 /* OCPartialMockObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C725C2700A842B1555ADD982ACAF618A /* SentryCrashStackCursor_SelfThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 433A671CB2FACC218F4EFC5EA60169C7 /* SentryCrashStackCursor_SelfThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C7504B7D8EAB7A0036BBCD418A8CFD1B /* SentryCrashCPU_arm.c in Sources */ = {isa = PBXBuildFile; fileRef = 8AF6BB3EE258D3AC2AA0C205519F518D /* SentryCrashCPU_arm.c */; }; + C7C6B1961A79784E2959E58DF6D14733 /* SentryTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = DF5D8291C1A5901C39977D7EC0026FDB /* SentryTransport.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C7C6C69274B596C67FF19D6CAC2857C5 /* MixpanelExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FB17A41E13C12B1D2AA71FAF3E004C2 /* MixpanelExceptionHandler.m */; }; + C80EB621E26F3A5701927765966B4CB7 /* SentryUserFeedback.h in Headers */ = {isa = PBXBuildFile; fileRef = 61B13957C17E507A36360EEC6762EEB2 /* SentryUserFeedback.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C82581DE2C0A93D72CA2FB8500058889 /* SentryCrashJSONCodec.c in Sources */ = {isa = PBXBuildFile; fileRef = A84049969AB25295B25C07B265E0573A /* SentryCrashJSONCodec.c */; }; + C8CBA5E819C92018016880FC72F72550 /* SentryQueueableRequestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BBCCBA0D6DE3EFC7812C64133351C711 /* SentryQueueableRequestManager.m */; }; + C8CF588D582C12C62CC76685B66B6518 /* Pods-BitBotATV-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B8B4F5B5F48C2BEC0FE0781579AF143 /* Pods-BitBotATV-dummy.m */; }; + C8EA44C7497A9E85036BB910258DE166 /* SentryBreadcrumbTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F01D2FB88692CCA07D12D161B9B3ABC /* SentryBreadcrumbTracker.m */; }; + C94614DC549748A43D25911D3FABA1BB /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44D2D0E6F4C6EF2EE76172E3124101F /* RedirectHandler.swift */; }; + C998AC42B31D27D637E71C147B6DF9DC /* Sentry.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC877162AAD2CD71819994ABEB546C0 /* Sentry.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C99D1B26354103BA0B0099F014182E4D /* EKMappingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0542808674F5A10FF9784DA1864F8CBC /* EKMappingProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C9FFFDB86316A0ECA4373D2F31D4EBFD /* SentryCrashFileUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D487B3797BA0C1BE5BA1380E70BF1D8 /* SentryCrashFileUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CA5A9C560B039EB6C0E64E3B1D5CF665 /* EKMappingBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = C16CDA7D12CE2887C6C67BA402461988 /* EKMappingBlocks.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CA66064D1C2C0469323961DB9B8F3AE0 /* CallbackQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FC7A323C502BBC6AEDE47DEC7EC501D /* CallbackQueue.swift */; }; + CA6A3D4528883BD431B92ECE28AACCCA /* EKMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 36737DC870746AD789DBCD3EC70812EE /* EKMapper.m */; }; + CAE8D9E60604DD9EEC6F00A0E01E0C4F /* EXPMatchers+contain.m in Sources */ = {isa = PBXBuildFile; fileRef = F1EA89C71E01F52BE17CFAEEE8951B4E /* EXPMatchers+contain.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CAE9158CFE1E16FCF2671C86F94F9896 /* ImageProgressive.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2255F2139506AB4C73A65EB517AFE79 /* ImageProgressive.swift */; }; + CB3B359D511D88BA92FBE3611ED9BE62 /* SentryQueueableRequestManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 77037A26EFAA75844B4E6E8757662060 /* SentryQueueableRequestManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CB45D40EE97B85586D2492895D4F675D /* SentryHub.h in Headers */ = {isa = PBXBuildFile; fileRef = ADCBFFF10E2E79248CA56AECC1AB9EDB /* SentryHub.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CBADF46CE902738535173A40F8CDCB18 /* SentryCurrentDate.h in Headers */ = {isa = PBXBuildFile; fileRef = 52ED80A99741A76F678B412BF5FC91DA /* SentryCurrentDate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CBFCBAB70247D43B34732B30B02289F3 /* SentryCrashDoctor.h in Headers */ = {isa = PBXBuildFile; fileRef = 8466E48F03D70CA17AC83C7B881AE446 /* SentryCrashDoctor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CC4D8A8E836D1D85C55998DF01F1D381 /* SentryStacktrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 707760BF81A4C4F1570470CC648600BC /* SentryStacktrace.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CC7B01EF0F57A09A5BA86CD7F719C811 /* SentrySpanStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 258332C878F6E9B127D8D8CDC15ABBBB /* SentrySpanStatus.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CCA0672CF48281CC9A2033E1CDBC32A8 /* SentryDefaultRateLimits.m in Sources */ = {isa = PBXBuildFile; fileRef = F80977F97FF7554E700DD6D4126D3A7F /* SentryDefaultRateLimits.m */; }; + CCA4DDC7D3E05B419041A5DF596B2FFD /* SentryCrashMonitorType.c in Sources */ = {isa = PBXBuildFile; fileRef = 2756ECD1BE253C72B9421EB065BC47A9 /* SentryCrashMonitorType.c */; }; + CD6EB00C1A5FAFEAE9DF50F30619FFF6 /* UIImage+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = FA8333751F570A5824ED5639096D2900 /* UIImage+Transform.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CD705D455A111FACD53E87EC3FA174E3 /* SentryCrashMonitor_AppState.c in Sources */ = {isa = PBXBuildFile; fileRef = 17D19B09C84E2416E96D186E823E81E8 /* SentryCrashMonitor_AppState.c */; }; + CD9FF47BE5185B042B632E8D0C0E1479 /* SentryDebugMetaBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = D7BC83D8B30962F7F9482DEAB81BF427 /* SentryDebugMetaBuilder.m */; }; + CDADC0A1DE193095622BBF32AA2BAC80 /* SentryOutOfMemoryTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 5408BDB36266B7615E01E688550651A4 /* SentryOutOfMemoryTracker.m */; }; + CDBF888FAAEB4A9761E5383285135E84 /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475E42A215A0DAE591C36514C111C296 /* Runtime.swift */; }; + CE060F39A2CC9263A33E91C9A87968C2 /* SentryCrashStackCursor_SelfThread.c in Sources */ = {isa = PBXBuildFile; fileRef = 9107D3E7F68DC7DB538D9EFB06A196E2 /* SentryCrashStackCursor_SelfThread.c */; }; + CE1C625D67497149BAC2B217ED583B4A /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = DF6CA6E602B6EA673C00D2C1246FD365 /* SDWebImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CE7F92241F7F1F212EFE404C89B75622 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B278697392A010FC841BA550A3EBD53F /* ImageView+Kingfisher.swift */; }; + CE8E6348397F931435D960E6B9434C2D /* OCMBoxedReturnValueProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 915D25D749AA3B4EC0FB0BAA6674D9C8 /* OCMBoxedReturnValueProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CF03DE4B17880C53755AA5483A33A701 /* EKRelationshipMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0311EFB6DC50C64A6FA83FA56E458E77 /* EKRelationshipMapping.m */; }; + CF2B46DA0C8D824B1BA270A06F2DE0AE /* UIView+WebCacheOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 861E4C71E1A5734D8A890EC87DDBB518 /* UIView+WebCacheOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CFB7776438921226B9BFA7F30F057AA0 /* SentryCrashAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D39586091AD5DC73D4742E3DF9BBEE /* SentryCrashAdapter.m */; }; + D0706D9C488551E4233E22E5B276DD47 /* SentryCrashCPU.c in Sources */ = {isa = PBXBuildFile; fileRef = 8D05EB46779D7C5A818D73B62F77753B /* SentryCrashCPU.c */; }; + D0C823A67ADEEE4E9F61DE3BD3BF1A40 /* SentrySystemEventsBreadcrumbs.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D21CAAD0ADD11B944B272D58532943B /* SentrySystemEventsBreadcrumbs.m */; }; + D1025678CE5CA89A7D52795E91E5A3CD /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C61D629079DD747B52BE9B257FF97536 /* AnimatedImageView.swift */; }; + D10C2AE0012DF7F4CFD9E309BE12F3C6 /* OCMIndirectReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 20BBA88BD1BC2C4981789AC0163EA2C8 /* OCMIndirectReturnValueProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + D1B44FF4003BA2096A4F9D5560E93318 /* SentryNSError.m in Sources */ = {isa = PBXBuildFile; fileRef = 11570D4A1B52E97A9FA97C20AA7920A1 /* SentryNSError.m */; }; + D1BF0D14765A5F2B82A53A58E7912DF5 /* EXPMatchers+respondTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC8E6210696D094872766EB0C6A7733 /* EXPMatchers+respondTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + D1C07ADBB8066A91EF931BF54F8033D2 /* SentryCrashReportStore.c in Sources */ = {isa = PBXBuildFile; fileRef = B67294EB0F7BE16140AA5419E527DE10 /* SentryCrashReportStore.c */; }; + D1E9BBF25DF848728F82B7AC88E2744C /* SentryBreadcrumb.h in Headers */ = {isa = PBXBuildFile; fileRef = 10C33D949E0F21DC36A9644F03202279 /* SentryBreadcrumb.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D20371540B07C552220E2CE0629F02AF /* SentryError.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A65932F3946AFE7DE35B76CF74D0911 /* SentryError.m */; }; + D220F073B1BBC9D6C8740FE14B20194E /* SentryCrashMonitor_User.h in Headers */ = {isa = PBXBuildFile; fileRef = 05A5DAC0EC5EF59D6C15397258A939C9 /* SentryCrashMonitor_User.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D2A945CADDDBE837C69ABF57DEC53050 /* Container+SentryDeepSearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A2CBF658B1028843343F4D084C7F808 /* Container+SentryDeepSearch.m */; }; + D33081A99EF7C3EF8FEF87979943D427 /* SentrySwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = AFE14AC670BBDE68888F91AD1EAD112D /* SentrySwizzle.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D33C600E6B5E582C65F3EF397CAD3338 /* EXPMatchers+raise.m in Sources */ = {isa = PBXBuildFile; fileRef = C43F69BAD51BED8B5077272C9934AE97 /* EXPMatchers+raise.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + D3429C53587B3AACD6152043D5AEE6B2 /* SentryCrashUUIDConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D346136A47A1485152ECFBB337DF36 /* SentryCrashUUIDConversion.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D379C5760B3D23B41E33D545A0780174 /* SentryCrashReportFilterBasic.m in Sources */ = {isa = PBXBuildFile; fileRef = 149E0F5BB4F3EAB50454D198D95531E3 /* SentryCrashReportFilterBasic.m */; }; + D3E7E2B9DE3E35E462B074F9D8CA2D8A /* SentryCrashC.c in Sources */ = {isa = PBXBuildFile; fileRef = 310F43800A6087EA88D2D109C93895D5 /* SentryCrashC.c */; }; + D3ED628D907EC5A5812F6282B1865B35 /* SentryDebugMetaBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = D9BC90810FA98ED7665170917F955CB8 /* SentryDebugMetaBuilder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D43E2D8252B250C938F3C06A5C5A4E8B /* SentryMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4921086B7457B240615C849B4A4DE4A7 /* SentryMessage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D44E1C13840064E02442E7E3DBEC3A89 /* SentryThreadInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EE44E030124FB9FEF6EEA1B78AC4F09 /* SentryThreadInspector.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D461A4857C4768E0B6600988641B76A5 /* SentryCrashDynamicLinker.h in Headers */ = {isa = PBXBuildFile; fileRef = 36CE61210416761404325FA95F4B0B13 /* SentryCrashDynamicLinker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D4B33820AB9FF17E1E0FE9530ED39E1C /* SentryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = EF4162342FE010A64DF41F62EFFE32FC /* SentryScope.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D4D9F57DC6C5FB4B2A01201DA81A5A8E /* SentryCrashStackCursor_SelfThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 433A671CB2FACC218F4EFC5EA60169C7 /* SentryCrashStackCursor_SelfThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D5BEB27AAC6AB430F127D8BD0CC6F0CB /* SentryCrashInstallation+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 707B03E715E22776FCC31962771A7E2D /* SentryCrashInstallation+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D5F038BE87A55128BD2AADFF1B2BCC66 /* SentryCrashDynamicLinker.h in Headers */ = {isa = PBXBuildFile; fileRef = 36CE61210416761404325FA95F4B0B13 /* SentryCrashDynamicLinker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D6A40A9E58A4D053EAFC59EA5A1D3510 /* SentryDispatchQueueWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = A03FCA222D59471B84B0261382857F95 /* SentryDispatchQueueWrapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D6B66398722F5CCDDB3F403BF69BB89A /* SentryCrashStackCursor_SelfThread.c in Sources */ = {isa = PBXBuildFile; fileRef = 9107D3E7F68DC7DB538D9EFB06A196E2 /* SentryCrashStackCursor_SelfThread.c */; }; + D6F6AD5F0E32B5E8AB6BF2E7C098A05A /* SentryOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = F7D074B3F94A6FA8E0911B6B79FCE292 /* SentryOptions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D7085F72FF2D1C4C93B114D39C880216 /* SentryOutOfMemoryLogic.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D55DD2E8B9C505A780231B6FA0855C7 /* SentryOutOfMemoryLogic.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D754CAF796FC5A962BAE1D97A4C57B2A /* SentryCrashSysCtl.c in Sources */ = {isa = PBXBuildFile; fileRef = E7D07B95AE09FB5092665CB55709027B /* SentryCrashSysCtl.c */; }; + D774878A421998994EB39DCAA8A1C49A /* SentryCrashReportVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C776FAE04FB29E201583DFAC74FE9F /* SentryCrashReportVersion.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D8CEADFE74807E34CDCFBF3C4730CA8C /* EKSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1884FAF2A8FA6485B812BC2FF3A2D02F /* EKSerializer.m */; }; + D901CE4658B14AD9AC9D87ACD0F8938F /* SentryUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C1EC470E15CDC0A396B6A75163FD54 /* SentryUser.m */; }; + D90DF2DC3D1C9A3AA4339CABEAE770EF /* SentryDefaultCurrentDateProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = DA34AA796C52BB44C0BD196FB3DFF6F8 /* SentryDefaultCurrentDateProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D91A995950BE8D4006C46F49418118E4 /* OCMNotificationPoster.h in Headers */ = {isa = PBXBuildFile; fileRef = AD04F4E2AF56D7FBACEDB0A518996D17 /* OCMNotificationPoster.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D99F4EBB23AB24DDC6FA644C1E33B45B /* SentryCrashReport.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F0537A8A90D413531F5A9EA15E6D7FD /* SentryCrashReport.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D9A5D0337898B020B76567375DAB6055 /* MPLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 301E1022D63C63981FEEEE645954B1C3 /* MPLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D9EE52832C1F335A45446FCA91745985 /* SentryCrashCPU.c in Sources */ = {isa = PBXBuildFile; fileRef = 8D05EB46779D7C5A818D73B62F77753B /* SentryCrashCPU.c */; }; + DA3775C2C80E037A7D623C59A5378A94 /* MixpanelExceptionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B651AA679368297876836D632672329 /* MixpanelExceptionHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DA3822D5C69C9017CBB78978E24A248B /* NSInvocation+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 2537FB4C8CB0778DD625F206CF385CA8 /* NSInvocation+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DA7B989AFE2B409E9EF6BF04120B8C13 /* EXPBlockDefinedMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 504C881F5EF6D0E2B49BBA35F1FE88E7 /* EXPBlockDefinedMatcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + DBB8E5610A5A5166183574ADAB57FA53 /* SentryScope+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D117F3A6C5BAE303986E03C59EAD73E /* SentryScope+Private.m */; }; + DCAA497864C4E51B0DE87A8471A89CD5 /* SentryRandom.m in Sources */ = {isa = PBXBuildFile; fileRef = 2685949B966DFD911386610465982AFF /* SentryRandom.m */; }; + DCAAB0FA1F0B7A3F26FEAC67F8FD832B /* EKPropertyMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = B0F73FEAAFEBB7A8FB01FAB8C7D9136A /* EKPropertyMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DCE86B34B441CCAEC489D1130513A967 /* OCMReturnValueProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = FD1BA966CD9EDA0D91BE150F4DDEFEAD /* OCMReturnValueProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DD1276257A6B652303591E341BB03CAD /* WKInterfaceImage+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C335C90B0893B78D0E77022821932C64 /* WKInterfaceImage+Kingfisher.swift */; }; + DD1467164E14367DA250DEE821A80907 /* SDImageTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BD7D6166DAB82CE8BE016B0182FCC1 /* SDImageTransformer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DDC6384AD423F30771D505780BCA7786 /* SDWebImageCacheSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 55DC328A5DFB6F98942A41EA53199E96 /* SDWebImageCacheSerializer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DDDB8810D4060879C45257F86768D8C6 /* SentryCrashExceptionApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A08B9374BA62246F90A56F8B705B234 /* SentryCrashExceptionApplication.m */; }; + DE13883D559603ACC417F69DE5A92E05 /* EKPropertyHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = D5139F1EF9D079FC16A2A8568E1BCA1F /* EKPropertyHelper.m */; }; + DE44B2D3B46369E0B4DE0FA4CDC52025 /* SentryInstallation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EBC1AF6E820A7A363E11B50E41E5DA1 /* SentryInstallation.m */; }; + DE8C5CA9E2CCE05776810E280BFD8EEB /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 126910B9AFE2B293DE3439F8733DBEF0 /* SDWebImageManager.m */; }; + DEC7CC434258CA15D2A02AB3290DFB1E /* SentryHub+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = F4C3B484D92B78C21F5D450A1F3A5B12 /* SentryHub+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DEE0373521A4CF2B19982E6D5D0BC349 /* SentryCrashMonitor_MachException.c in Sources */ = {isa = PBXBuildFile; fileRef = AF11E02E80C577B2B41594595DBFA01E /* SentryCrashMonitor_MachException.c */; }; + DF5C758538361B44620EA8A4E5872C43 /* SentryCrashJSONCodec.c in Sources */ = {isa = PBXBuildFile; fileRef = A84049969AB25295B25C07B265E0573A /* SentryCrashJSONCodec.c */; }; + DFEEB75EA1B2172C382FA8594ADA0241 /* EXPMatchers+beLessThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4071362B52F086A16600C4AF635940 /* EXPMatchers+beLessThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + E001752B149F4E972A5880981FFE9E8B /* OCMock-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 91098A929162682414A487BF62B0C51E /* OCMock-dummy.m */; }; + E00A0A877F8E4BE010DD342DFDAEB18A /* OCMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF331BB4BA9B2DC12487F3DBD970080 /* OCMockObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E024EBCB7B48EE1543EA135EF10321A9 /* SentryEnvelopeRateLimit.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC994083E6028E0A5B0CB8C7F894C1 /* SentryEnvelopeRateLimit.m */; }; + E02F2060665C40B704ECA410BE4504FC /* SentryCrashCPU.h in Headers */ = {isa = PBXBuildFile; fileRef = B8AF8D7DF499D5D21A642832F339131F /* SentryCrashCPU.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E0E6B540426A4C5F5A7EB4774410C42A /* SessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CC1924BC66C4930A9848851D49802FB /* SessionMetadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E1CD0533CE2A3DB5684304BA1019B542 /* SDDiskCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0E39861C5E3259ECA3D9D2E49DAFD /* SDDiskCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E1E0CF18E339AD1DE62A57BB5617A073 /* SentryCrashMonitor_Zombie.c in Sources */ = {isa = PBXBuildFile; fileRef = 8118BBD07F06D9B65E67B6C0CAA7BAD5 /* SentryCrashMonitor_Zombie.c */; }; + E2188A86DF2633379C99FBA18C8E55C3 /* NSObject+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 558CF21D6FBBA3B07A824C9121767409 /* NSObject+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E30AC13C618EE16EF2D4DED21B229B8B /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 88368478BD964F0C78E7C27C1D7E9A38 /* UIImage+GIF.m */; }; + E3215503404E4C075EDC9E1EA2B87611 /* SentryCrashReportFilterBasic.m in Sources */ = {isa = PBXBuildFile; fileRef = 149E0F5BB4F3EAB50454D198D95531E3 /* SentryCrashReportFilterBasic.m */; }; + E37564826AE0CDBE4D990D3ABF81886D /* SentryHttpTransport.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D480BEB3C3B1A576E713DB1B6413CD2 /* SentryHttpTransport.m */; }; + E49674D8BE2B14B254D787410495D4BE /* SentryCrashMonitor_Signal.h in Headers */ = {isa = PBXBuildFile; fileRef = B7E43F64E96E0C3A23315AD8FDD875B5 /* SentryCrashMonitor_Signal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E4B3DBA8AE6557EBE579E89ABBAACFD3 /* SentryCrashMonitor_System.h in Headers */ = {isa = PBXBuildFile; fileRef = C871A5023CDCEF1BAB6E6FD1DEE58644 /* SentryCrashMonitor_System.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E4BB882234A977C7AA36C1839E70D113 /* SessionDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEAA547EB86BF0690AF84A817A3EE1B1 /* SessionDataTask.swift */; }; + E5574067990DA712969838F8A332D594 /* SentrySpanContext.m in Sources */ = {isa = PBXBuildFile; fileRef = CAAE2845DDE3787AE62AC63FD77B83AE /* SentrySpanContext.m */; }; + E574DFE0C6E91C79181C033CAB99842D /* NSArray+SentrySanitize.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F7AACCA9011988D5EA92395F682A784 /* NSArray+SentrySanitize.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E57EE5D6EF2562B002AB69429AD0B7F4 /* SentrySerializable.h in Headers */ = {isa = PBXBuildFile; fileRef = E73AE987835897A07BBC6DCC00651DCE /* SentrySerializable.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E68D16336B2C434E08A5B4CD88EEA461 /* SentryMechanismMeta.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EDDD7D1E2FDD44649448745A77ABAC /* SentryMechanismMeta.m */; }; + E69FAAB07BA64EFA282DD6533749448D /* SentryCurrentDateProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = B55607C0615FFE6430F17A69A880EB12 /* SentryCurrentDateProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E6F1A2BA1620552CA15C02996D717800 /* MPLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 301E1022D63C63981FEEEE645954B1C3 /* MPLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E71A0D1EF31C210971C5049BE82F9EFC /* SentryCrashCPU_arm64.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D70F821154E7BBE09D9B7BEDB0361E2 /* SentryCrashCPU_arm64.c */; }; + E7BE4B4599818EC03B8BECE5B8408717 /* SentryCrashMachineContext.c in Sources */ = {isa = PBXBuildFile; fileRef = 31BD2E6667910A3319B47B6397FB7A7D /* SentryCrashMachineContext.c */; }; + E7EC0E343BB0B34F48C6A260AD493B22 /* SentryCrashDebug.c in Sources */ = {isa = PBXBuildFile; fileRef = C02A9CF89AD5F57E5E1DC0F438331741 /* SentryCrashDebug.c */; }; + E80589588CC157119F1FB96A03B30BF5 /* NSArray+FlattenArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DE263CCD7DE182693CA38B30F831375 /* NSArray+FlattenArray.m */; }; + E85244D0F4D0AC8555C380CB0F9D57DF /* SentryBreadcrumbTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 729F7AFE262AF22B1D2157AE03081029 /* SentryBreadcrumbTracker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E8B9E1BFBAF7D8C1BAE2A45B815A5CAC /* SentryMechanismMeta.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EDDD7D1E2FDD44649448745A77ABAC /* SentryMechanismMeta.m */; }; + E8D29FE759687DF80EF8CFA23CD1EFA4 /* SentryCrashStackEntryMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 098D18C816918B0625F2EFAC46124416 /* SentryCrashStackEntryMapper.m */; }; + E912C8C2D42BCD36D1449E7E6CC5B3F2 /* SentryCrashReport.c in Sources */ = {isa = PBXBuildFile; fileRef = E9A6894E165A917A3864A338D7E718A9 /* SentryCrashReport.c */; }; + E9D14ECAFF22E8A41399D2A863A239AF /* SentryInstallation.h in Headers */ = {isa = PBXBuildFile; fileRef = 216232C7E3B491836F7FE4829869B5D7 /* SentryInstallation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EA7CCE29307048D044A60D1F8D63D87A /* EXPMatchers+raise.h in Headers */ = {isa = PBXBuildFile; fileRef = 180BA2E6B8B202B199C3249C471B57A1 /* EXPMatchers+raise.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EADF972AB8FB2C89321CE3F8FCE0D70D /* EKPropertyHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = FEDE59956F01BAB8149B4FE239EBD53A /* EKPropertyHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EBBFA7EB42BA30826988AAADAC95CEA8 /* SentryBreadcrumbTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F01D2FB88692CCA07D12D161B9B3ABC /* SentryBreadcrumbTracker.m */; }; + EC720B96E61C5F88F94DED9088653DE7 /* NSArray+FlattenArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 158A69E47F44FC87022EB7B284DB6CED /* NSArray+FlattenArray.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ED65D8FBF27E9C32762C6954B6A734FB /* SentryCrashCPU_arm64.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D70F821154E7BBE09D9B7BEDB0361E2 /* SentryCrashCPU_arm64.c */; }; + ED7200380D9FCD751F09B5EF1C4612BE /* SentryTracer.h in Headers */ = {isa = PBXBuildFile; fileRef = 745E8932DD0AB64C1A0DB120B425D892 /* SentryTracer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ED75521511EB41296F116A15159AD7AE /* SentryCrashReportFixer.c in Sources */ = {isa = PBXBuildFile; fileRef = F97C641D4A8FFBE3CBDB534ACFE13EBA /* SentryCrashReportFixer.c */; }; + EDC19D69387F113F3C4FE1F0B3A60F9E /* SDImageAPNGCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = D17B64FED552F0A53E4F9A17E1256AB7 /* SDImageAPNGCoder.m */; }; + EDC6D94569FE806DC0BB7477131B78D0 /* MPNetworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AC9CB050C910E77C9B12CB287704992 /* MPNetworkPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EDDC5F0F11F9259AFF050359E79DB57E /* SentryEnvelopeRateLimit.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C3715BC9F903D97400016275A722B9 /* SentryEnvelopeRateLimit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EDE754E56B7360B384477BFEA2843424 /* SentrySdkInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F3523459F8BDE81CDD88934EA8F73B0 /* SentrySdkInfo.m */; }; + EDF666FA20CB8D6D89A8F0E36EC21CF9 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D7893BCF8FC30708A78AA396189D1B3 /* ImageProcessor.swift */; }; + EE3B38AAF28EC96D14AD7FAA38D3ABB2 /* NSData+SentryCompression.h in Headers */ = {isa = PBXBuildFile; fileRef = BA6674821E44BAAADC77D5FB4CD7671F /* NSData+SentryCompression.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EE5C24CB39E9430C35331506D899ED28 /* SentryStacktraceBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = EC1EEE25B6064557720CF2B1812DF2FD /* SentryStacktraceBuilder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EE62D51B4F4A55731CCD546D25BA1064 /* NSValue+Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = D7FF1BC66B772F592CC4BB58F4662E01 /* NSValue+Expecta.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + EE6D8FAA3554E12D373196359FDFC70A /* SentryCrashID.c in Sources */ = {isa = PBXBuildFile; fileRef = 50C09C43E38AC5954BD87B5EE7401748 /* SentryCrashID.c */; }; + EE7561DADC01EC301AB898348FC979FA /* SentryLevelMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = EAC198E0EA2F49AA7D4D66A51EE2F528 /* SentryLevelMapper.m */; }; + EE9616B201A313798F3A40D9A636750B /* SDImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 03B5D1CBA2A3F931626E0F1CEF40E95D /* SDImageLoadersManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EEB28E940F407DDAF928EC1B73155FF7 /* OCMFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 47B69B903C4DE4A0125C0FFF10DD800F /* OCMFunctions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EED21AA66F01F2F9CFAEABCFC395ECDF /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = D281AC19FFB91D8781E163939DDB432A /* NSButton+WebCache.m */; }; + EED4D51267517F2D304C74540B6B0489 /* ExpectaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = E7498EE2465516ED35F4F3252FDF30A4 /* ExpectaSupport.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EEFEC2C69577425D1446AFB526329E32 /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B229986A8D850A78635DA668400B9541 /* CacheSerializer.swift */; }; + EF07E681556BC7689CCED3B38434F00E /* EXPMatchers+haveCountOf.m in Sources */ = {isa = PBXBuildFile; fileRef = F4AEF7C2E260CF1EAEC434B6350410F7 /* EXPMatchers+haveCountOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + EF2C974E1FC14FC9BA4B3C0A8A489B98 /* SentrySessionTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 205390348AA79A216C5E4236AF4C090A /* SentrySessionTracker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EF3E4E23B0E99E5E5BE8C2366E21173E /* SentryDispatchQueueWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = A03FCA222D59471B84B0261382857F95 /* SentryDispatchQueueWrapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EFAD14B398A5DED6FC6D2976DC6EC00B /* SDAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B2A47368F861EA82DD76288F964703F /* SDAnimatedImageView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EFE13FDCCE755F3CC51B529A445A03F9 /* SentryNSURLRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 472F88C1AE184846E3C92E70773C562C /* SentryNSURLRequest.m */; }; + EFEC3B834850107DF18A4E6573924F4F /* SentryFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = C324EB3A7AC0090B4AAEA7B08A40BE78 /* SentryFrame.m */; }; + F013FB79B0CCB3AC9763954DF0B3A21A /* MixpanelPeoplePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AD8082B1558E9CD4FE81D97AA7EFBB9 /* MixpanelPeoplePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F02D1477C4F448BAB10E3E23A2948EBD /* SentrySerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 442B5088AAD4A7635F001BBC8DA25200 /* SentrySerialization.m */; }; + F06C8BBEA053E4DE6E46C24D530284D4 /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 468F25D684EB369BC80024F1557AE98E /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F131FBD0A4730878E5B7AF2E7469FEBD /* SentryStacktraceBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D11B4BDEC059D18FA4E0388AD0D8785 /* SentryStacktraceBuilder.m */; }; + F13B85AEC0704EC5A948CBFB93E78F6E /* SentryAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 912295245C4EFAE6597BD5624C6D29CE /* SentryAttachment.m */; }; + F1D80A220E664E462AE9A21692370382 /* EKMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 36737DC870746AD789DBCD3EC70812EE /* EKMapper.m */; }; + F1FDD232C9658A5AF7D0DC6DE2D79CC4 /* SentryCrashJSONCodecObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = AC14140BA60C11A89D4E5C625E6C09F8 /* SentryCrashJSONCodecObjC.m */; }; + F2282BCB06ED4241E1DA9AA02C18452F /* SentryCrashCString.h in Headers */ = {isa = PBXBuildFile; fileRef = 438F5D72C80C54963277C3109A0652B0 /* SentryCrashCString.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F26E607263D806EB08FB2BE976DD5719 /* UIImage+MemoryCacheCost.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323FE2B3DEDEFC6B6B60BBBEA74D18E /* UIImage+MemoryCacheCost.m */; }; + F27DA7709F41E43F0BB47C6A0D3E4CD7 /* UIColor+HexString.h in Headers */ = {isa = PBXBuildFile; fileRef = DC78BE6918A6EB0A9A1BB56F9F6F0F2F /* UIColor+HexString.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F292104E173BC8CD5140919937BC8369 /* SentrySession.m in Sources */ = {isa = PBXBuildFile; fileRef = 23CF50EB90747454BA5721ACEE41D52B /* SentrySession.m */; }; + F29867510A722B452658DDB7DBA68B6B /* SentryFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 00A6995B33F3B7F8D6D346392CE2FAB1 /* SentryFileManager.m */; }; + F2D916718D2E7D7E0610969A627E93FD /* SentryCrashLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA0F2519E0F70EF0D35210ADB5F9D21 /* SentryCrashLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F311ABF57205796290AAC4C9E70A57AF /* EKManagedObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D08DE0D01595536B14C06E957A81A17 /* EKManagedObjectMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F31B3B28D61829979B9811837CD06A59 /* SentryCrashFileUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D487B3797BA0C1BE5BA1380E70BF1D8 /* SentryCrashFileUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F3AA9FF5270EFC40E8D1BD1B4D05055A /* OCMRealObjectForwarder.m in Sources */ = {isa = PBXBuildFile; fileRef = 970C3CABE864F4EBDD5E4EDF8AB861F8 /* OCMRealObjectForwarder.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + F3D79EE95A53DC322C2F93551780FCC4 /* ExpectaObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AD1847DA1E09CA4FF64EBDDCE9E89BBD /* ExpectaObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F3E5BEE29D657DF6E9058D7FCACC4287 /* SDWebImageDownloaderConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C32FAAC06813A2BAB1ED4111D5695E4 /* SDWebImageDownloaderConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F3F17BC2AE9E98FE68B5DF1435F8DDC7 /* SentrySessionCrashedHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A0628EA6AE627462153793C03272C2CE /* SentrySessionCrashedHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F43821994B65DA151E605E370C9623BF /* SentryCrashCString.m in Sources */ = {isa = PBXBuildFile; fileRef = F0B701C1D482E92F4504D38FE92A930F /* SentryCrashCString.m */; }; + F45DC3D227892AECA7091CFA5783DE9C /* SentryCrashMonitor_AppState.h in Headers */ = {isa = PBXBuildFile; fileRef = 01CF90EEF3339577C8BEECE383A29D05 /* SentryCrashMonitor_AppState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F46A1C326588B04A3D0092FAC2D9F92E /* SentryAsynchronousOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5724B0A9796694E79E16B52BE58B5C79 /* SentryAsynchronousOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F4701D4CE3C2B0A14695164D5E582DF2 /* NSTextAttachment+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78926F9F16D6B661CB5C56915AB11082 /* NSTextAttachment+Kingfisher.swift */; }; + F4CFA29E646297ADEA02FE0D2AB9F89C /* SentryGlobalEventProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = D60913A7573D0C51BD7A2D9982EA74E4 /* SentryGlobalEventProcessor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F4E756CB7F54C54379983FE68B61693C /* SentrySession.m in Sources */ = {isa = PBXBuildFile; fileRef = 23CF50EB90747454BA5721ACEE41D52B /* SentrySession.m */; }; + F52F60C7410EFCA45AA9BBDF421C69B7 /* SentryTracer.h in Headers */ = {isa = PBXBuildFile; fileRef = 745E8932DD0AB64C1A0DB120B425D892 /* SentryTracer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F64A0D949FB29390A4F2604446C9C965 /* OCMReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CCE329FFD1284B959ACC03EA2F58404 /* OCMReturnValueProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + F655B1CEDC459E321B19A5D24BED6B90 /* SentryBreadcrumb.m in Sources */ = {isa = PBXBuildFile; fileRef = 11A50C52679A85C930D61E41E25F0A15 /* SentryBreadcrumb.m */; }; + F6F27633B32DE9FB4C636810ADA4F9A9 /* EKManagedObjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF7F0C7B39D9162359E52B189FE8F21 /* EKManagedObjectModel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F702374985354DA721560D79EC608FE9 /* SentrySystemEventsBreadcrumbs.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D21CAAD0ADD11B944B272D58532943B /* SentrySystemEventsBreadcrumbs.m */; }; + F70FFCE7CD088CF1051BE01852B7DED5 /* SentrySdkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BFEDAD83AB355F5DA2420B3CA6B2A99 /* SentrySdkInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F7152A7109DC2A6E38B386B924771ED0 /* SentryCrashDate.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6C5ADDBAA1A94B1A204F0A2616531 /* SentryCrashDate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F74BF06DBC15BB2A17E66943831132C2 /* EXPMatchers+beSupersetOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D3FBFA74344F4FF521DCE28F5DF4976 /* EXPMatchers+beSupersetOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + F76ADB72D5BB24A5A59F9FA06C9B3D9D /* SentryHttpDateParser.h in Headers */ = {isa = PBXBuildFile; fileRef = C885E0C6872E0DD37AE7F83D152E4CC8 /* SentryHttpDateParser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F76BBA5C5563ABBB3B5F31D39607DC86 /* SentryCrashObjC.c in Sources */ = {isa = PBXBuildFile; fileRef = 8473F3DC171840EAC0BDA09D6FA0E4A0 /* SentryCrashObjC.c */; }; + F78114247A88B45FB1793C1B91EF4239 /* Container+SentryDeepSearch.h in Headers */ = {isa = PBXBuildFile; fileRef = 1754A6ED4900E0794C9F85E0D875BED1 /* Container+SentryDeepSearch.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F7A9F53A68FF24600778D518BCD448F1 /* EXPMatchers+beFalsy.h in Headers */ = {isa = PBXBuildFile; fileRef = A31FB9F387655224851D83FFE7738B1E /* EXPMatchers+beFalsy.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F7B19B68FAB73CB0732744B6A096D791 /* EXPDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D3EE8F9270FE0BB85BFFCE0EEF64D69 /* EXPDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F7ED9EAD3805A6C58C1466646CE20A82 /* SentryThreadInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EE44E030124FB9FEF6EEA1B78AC4F09 /* SentryThreadInspector.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F82B1826A74659DF7FCAB6AC03AF559E /* SentryCrashMonitor_System.h in Headers */ = {isa = PBXBuildFile; fileRef = C871A5023CDCEF1BAB6E6FD1DEE58644 /* SentryCrashMonitor_System.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F836088040A893CDC77FE27CC4FF1128 /* SDImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F0A2594C9B5A62A6BFE259F3838B7420 /* SDImageLoadersManager.m */; }; + F887644D7436B365A7F46E37F91932CA /* SentryCrashDate.c in Sources */ = {isa = PBXBuildFile; fileRef = 98B74495E6501725B2A5B7348E1C93AE /* SentryCrashDate.c */; }; + F9977D025D4848E253BB040AD7F0A0D2 /* NSDate+SentryExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = EE988064E682B9A56B6A0555F5C13ADF /* NSDate+SentryExtras.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F9B6CD3150A237B72B34F88D3018C20D /* SentryCrashObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 28F30BDB100EE20988EF30AF46D98AE9 /* SentryCrashObjC.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F9CEFE5A097E1CE7ECB2E4DCB3ADF385 /* SentryOutOfMemoryTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 5408BDB36266B7615E01E688550651A4 /* SentryOutOfMemoryTracker.m */; }; + F9F0296BB4A501C75884F81457F6793A /* EKRelationshipMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E480A4679A415C223FF40639884AF28 /* EKRelationshipMapping.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FA5C886F0154733309AFFF0C41C9D62C /* SDImageCacheConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD68E665E1E63202CCC33440DEE5688 /* SDImageCacheConfig.m */; }; + FB70BFE525506DF077F57FC93C4FCCFB /* SentryCrashSysCtl.h in Headers */ = {isa = PBXBuildFile; fileRef = C932E34914D61B118DFFB14264E4F46F /* SentryCrashSysCtl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FBA580E5E82E288FF4E0633FD686FD8D /* SDMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5286CE54B4C0709E1A5746B083322665 /* SDMemoryCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FBF07C1C9AB7CD1D8F80419FAE4A07E5 /* NSData+SentryCompression.m in Sources */ = {isa = PBXBuildFile; fileRef = 3298B34DB4E92B8B598D382D9EFE204A /* NSData+SentryCompression.m */; }; + FBF300F7DD65088A9B5EE1282366227F /* SentryRateLimitCategoryMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A52A6F3E00C33219FCD44F31FAD48FB /* SentryRateLimitCategoryMapper.m */; }; + FC03EE048F70F1E14A2F78836CA26D49 /* EXPMatchers+raiseWithReason.m in Sources */ = {isa = PBXBuildFile; fileRef = 697E0B998BB4B99DC155F08BE3EFCC6C /* EXPMatchers+raiseWithReason.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + FC218F96DB09A48D9D13774F9CA178BF /* MixpanelPeople.m in Sources */ = {isa = PBXBuildFile; fileRef = F3864646ED479BF8F6292472141DE6C4 /* MixpanelPeople.m */; }; + FD3C3E6900DB90A452B87AAD7B449E58 /* SentryCrashCPU_x86_32.c in Sources */ = {isa = PBXBuildFile; fileRef = 76CD924DD05728AB3BF84E8D93885369 /* SentryCrashCPU_x86_32.c */; }; + FD568DDA288E91778CDC445CB72E8F6E /* NSValue+OCMAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = A91922616AFB9EA146BD8FBEF311BEAC /* NSValue+OCMAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FD97D8B642908F34B8B8BA157C3201FD /* SentrySpan.m in Sources */ = {isa = PBXBuildFile; fileRef = 5169589B116558FFAAB8BE33DD6CFF16 /* SentrySpan.m */; }; + FE02EFB4C22E56F997DD6019B06D38D7 /* SentryCrashMachineContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F0FFBDBC22ED035FD2A99177FA77B13 /* SentryCrashMachineContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FE4F9B8C36D3B69A06CA5B8C01449F7D /* SentryCrashMach.c in Sources */ = {isa = PBXBuildFile; fileRef = 864951E1419140446120DB8592F5D890 /* SentryCrashMach.c */; }; + FE65C2D61F4C878F71AA42B73712713A /* SentryHttpTransport.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D480BEB3C3B1A576E713DB1B6413CD2 /* SentryHttpTransport.m */; }; + FEA4F45A367766F9BE6388400546169B /* SentryFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 910A5EA3CAC3C38415BB28F6CF628F83 /* SentryFrame.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FEF34113D2C3F5CB5DABDB5E60726650 /* SentryClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1693B04CD7105542A4995D7B1860CB4C /* SentryClient.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FEF54D75494F24857B6C60CA6B9C31BD /* SentryCrashIsAppImage.h in Headers */ = {isa = PBXBuildFile; fileRef = CD43EB3DB8F1A13F4F230EB3F12BD14D /* SentryCrashIsAppImage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FEF8707835935AC79B6D2B5D976963ED /* SentryAutoSessionTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D9816E9BA0E9C1D408810DF06B24A0B /* SentryAutoSessionTrackingIntegration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FF5D013AA6280083C7EC16BE7E6273A1 /* SentryCrashMonitorType.h in Headers */ = {isa = PBXBuildFile; fileRef = 10F5894E3DCDD857C93D93387290D1C5 /* SentryCrashMonitorType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FFF7A088B3B6F9795C85FE880C29F9E7 /* UIImage+Metadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C686F67FB022C1485E7B62E2841750A /* UIImage+Metadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 04C9088432689A38DA79B08BFB3A949F /* PBXContainerItemProxy */ = { + 0CF6F1759A8CD7D79985829219F186EE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = DBD5E5EA15DC8E29C6771390FFF80639; - remoteInfo = "Mixpanel-tvOS"; + remoteGlobalIDString = DC371B7477C88184274EC6710690F97C; + remoteInfo = Expecta; + }; + 1AE05166B989BC2CF1ACCF236D3EC544 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E8022D22FAA6690B5E1C379C1BCE1491; + remoteInfo = Kingfisher; }; - 29FE6F6A34AFE952E2A50FEC2B75B9EF /* PBXContainerItemProxy */ = { + 1CC5AD975176C539F11396BFAE88B22D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = C260B5A26D3CD54F215E5E39371483B6; remoteInfo = OCMock; }; - 2B39365175D1273474422C3CE9DC4302 /* PBXContainerItemProxy */ = { + 1FA47FCCCC1D40E782349AFD330D6DDC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E64F498650CA1EED2135C3BEA452F3FD; - remoteInfo = "NSPopover+MISSINGBackgroundView"; + remoteGlobalIDString = EF68D578CA0C3D7CEDE4A31C9014F26F; + remoteInfo = "Pods-BitBot"; + }; + 4965B6FC2CB5165C16835D1F7B86323D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DBD5E5EA15DC8E29C6771390FFF80639; + remoteInfo = "Mixpanel-tvOS"; }; - 3DFC3AD45B68FDD68130A30B67DCCB2F /* PBXContainerItemProxy */ = { + 51E799C0C44219F9ECCF37169173711B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 3847153A6E5EEFB86565BA840768F429; remoteInfo = SDWebImage; }; - 7687F4F24F52C9FE25608AF8A2DC5F2C /* PBXContainerItemProxy */ = { + 59523D5EF63DEAEB8A81836F110D0B6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC371B7477C88184274EC6710690F97C; - remoteInfo = Expecta; + remoteGlobalIDString = E64F498650CA1EED2135C3BEA452F3FD; + remoteInfo = "NSPopover+MISSINGBackgroundView"; }; - 793E5E4E79FE365625F2200313175089 /* PBXContainerItemProxy */ = { + 636620EDFC8FCA2B6E6179AB44140931 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = EF68D578CA0C3D7CEDE4A31C9014F26F; - remoteInfo = "Pods-BitBot"; + remoteGlobalIDString = 61C08C8B4FDF80F2237C00557D267969; + remoteInfo = "EasyMapping-macOS"; }; - 82CCD1B3AFED5DE20DF7E7ECE5D2D3B0 /* PBXContainerItemProxy */ = { + 8CC4C52963C396ABA46B9008938897FC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E8022D22FAA6690B5E1C379C1BCE1491; - remoteInfo = Kingfisher; + remoteGlobalIDString = 8E2EC09E06710CFBAD6AF578E2A14F7C; + remoteInfo = "Mixpanel-macOS"; }; - C8B92276696C6B5A2C7E2EE3E1DDFC61 /* PBXContainerItemProxy */ = { + C41FEF88C256678BA5687E5FFAA9104C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 74A6508FB061133A1E28C2850A437667; remoteInfo = "EasyMapping-tvOS"; }; - C934252033DEBEE9562CD435915B6006 /* PBXContainerItemProxy */ = { + C4A8C00BCE5EB35E1CAC96F2A06F18EB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 8E2EC09E06710CFBAD6AF578E2A14F7C; - remoteInfo = "Mixpanel-macOS"; + remoteGlobalIDString = DDC5B143847B1E75AB9687D42E6EF6B8; + remoteInfo = "Sentry-tvOS"; }; - F1BD7307B4B464D2BDE817FDE6E2C066 /* PBXContainerItemProxy */ = { + E0223640F20B5760574822FD5DBD6F57 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 61C08C8B4FDF80F2237C00557D267969; - remoteInfo = "EasyMapping-macOS"; + remoteGlobalIDString = 9AA8A98273205387E6FF9B148A006F31; + remoteInfo = "Sentry-macOS"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 034943133D11EBBBF83DA60CEFA92DE2 /* OCMExpectationRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMExpectationRecorder.h; path = Source/OCMock/OCMExpectationRecorder.h; sourceTree = ""; }; - 0426F8771A05633CAB423C142380FDAF /* NSValue+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSValue+OCMAdditions.m"; path = "Source/OCMock/NSValue+OCMAdditions.m"; sourceTree = ""; }; - 044181C5DB4A0D04183ABE8F9B246D79 /* Pods-BitriseATV-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-BitriseATV-acknowledgements.plist"; sourceTree = ""; }; - 047081A3E965601782291A1E4B25BEF0 /* OCMBlockCaller.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMBlockCaller.m; path = Source/OCMock/OCMBlockCaller.m; sourceTree = ""; }; - 04A3FDEAC8848912398C906327E13BA3 /* Source.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Source.swift; path = Sources/General/ImageSource/Source.swift; sourceTree = ""; }; - 04C89116FD3CAABF943C05E0EECAB17B /* Pods-BitBot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBot.release.xcconfig"; sourceTree = ""; }; - 053A44FACD30EF6E275D6704FBE18CCE /* OCMInvocationExpectation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMInvocationExpectation.m; path = Source/OCMock/OCMInvocationExpectation.m; sourceTree = ""; }; - 05AFD55F4788466522B9FA8D8BA16EAE /* SDWebImageDownloaderOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderOperation.h; path = SDWebImage/SDWebImageDownloaderOperation.h; sourceTree = ""; }; - 06603B8AC9B141505673852488A83DE1 /* EKManagedObjectMapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKManagedObjectMapper.h; path = Sources/EasyMapping/EKManagedObjectMapper.h; sourceTree = ""; }; - 0672A0F9DA8817B2A4DA4AE2F34F966F /* OCMFunctionsPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMFunctionsPrivate.h; path = Source/OCMock/OCMFunctionsPrivate.h; sourceTree = ""; }; - 0737FD1FACF633D70616CB317F2EC64C /* Pods-BitriseATV-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-BitriseATV-dummy.m"; sourceTree = ""; }; + 001C309BA5BC26FE8099864DCB397F9B /* Mixpanel-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Mixpanel-tvOS.debug.xcconfig"; path = "../Mixpanel-tvOS/Mixpanel-tvOS.debug.xcconfig"; sourceTree = ""; }; + 00A6995B33F3B7F8D6D346392CE2FAB1 /* SentryFileManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryFileManager.m; path = Sources/Sentry/SentryFileManager.m; sourceTree = ""; }; + 00BA44563517EF05D49C2288AC8068CE /* EXPMatchers+beKindOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beKindOf.h"; path = "Expecta/Matchers/EXPMatchers+beKindOf.h"; sourceTree = ""; }; + 00C44F2BE6F0FFAADFDB233517EF0AF4 /* OCMRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMRecorder.m; path = Source/OCMock/OCMRecorder.m; sourceTree = ""; }; + 017B91A7D74324D087DE3D13046EC99E /* SentryFileManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryFileManager.h; path = Sources/Sentry/include/SentryFileManager.h; sourceTree = ""; }; + 01C8C1525E5E47B587B3B1805005ABEE /* SentrySpanContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySpanContext.h; path = Sources/Sentry/Public/SentrySpanContext.h; sourceTree = ""; }; + 01CF90EEF3339577C8BEECE383A29D05 /* SentryCrashMonitor_AppState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_AppState.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.h; sourceTree = ""; }; + 021507B63C15C6275FA1614AA26D56C7 /* SentryCrashVarArgs.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashVarArgs.h; path = Sources/SentryCrash/Reporting/Filters/Tools/SentryCrashVarArgs.h; sourceTree = ""; }; + 02DC83D5E00FE99440BD62AF984711A2 /* EXPMatcherHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatcherHelpers.h; path = Expecta/Matchers/EXPMatcherHelpers.h; sourceTree = ""; }; + 02FE69406B0C2F87D52C67EBB5E19FCE /* SentryCrashDynamicLinker.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashDynamicLinker.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.c; sourceTree = ""; }; + 0311EFB6DC50C64A6FA83FA56E458E77 /* EKRelationshipMapping.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKRelationshipMapping.m; path = Sources/EasyMapping/EKRelationshipMapping.m; sourceTree = ""; }; + 03B0EEABA146653D4D0D5E83C4159A4F /* SentryCrashInstallationReporter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashInstallationReporter.m; path = Sources/Sentry/SentryCrashInstallationReporter.m; sourceTree = ""; }; + 03B5D1CBA2A3F931626E0F1CEF40E95D /* SDImageLoadersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageLoadersManager.h; path = SDWebImage/SDImageLoadersManager.h; sourceTree = ""; }; + 03DB632D03C3927CA1825C545CACA388 /* OCMLocation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMLocation.m; path = Source/OCMock/OCMLocation.m; sourceTree = ""; }; + 04DE6B370E3EE3FE5D61EECEE498400B /* SDWebImageError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageError.h; path = SDWebImage/SDWebImageError.h; sourceTree = ""; }; + 04FBACCD33706E0D6F5EE7CD78059B44 /* MPNetwork.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MPNetwork.m; path = Mixpanel/MPNetwork.m; sourceTree = ""; }; + 051572966812B4346D5D43CB731AF26F /* SentryHub.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryHub.m; path = Sources/Sentry/SentryHub.m; sourceTree = ""; }; + 053C481FDFE0573C79EB67973EAB3864 /* Mixpanel-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Mixpanel-macOS.release.xcconfig"; sourceTree = ""; }; + 0542808674F5A10FF9784DA1864F8CBC /* EKMappingProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKMappingProtocol.h; path = Sources/EasyMapping/EKMappingProtocol.h; sourceTree = ""; }; + 0565FE21AB63AFEF67A9CA59773523DE /* OCMBlockCaller.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMBlockCaller.h; path = Source/OCMock/OCMBlockCaller.h; sourceTree = ""; }; + 058E44E46F03F2A6AB8936F8843AE72A /* SDImageAssetManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAssetManager.h; path = SDWebImage/Private/SDImageAssetManager.h; sourceTree = ""; }; + 05A5DAC0EC5EF59D6C15397258A939C9 /* SentryCrashMonitor_User.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_User.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.h; sourceTree = ""; }; + 05F5B2D858E5616537CDD4EA800C5173 /* EKMapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKMapper.h; path = Sources/EasyMapping/EKMapper.h; sourceTree = ""; }; + 060A4FAD62F94BC224E0223323FCB29A /* EXPMatchers+beGreaterThanOrEqualTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beGreaterThanOrEqualTo.m"; path = "Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.m"; sourceTree = ""; }; + 0619CDE980999D5C59E9F15C006149DF /* EXPMatchers+beLessThanOrEqualTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beLessThanOrEqualTo.m"; path = "Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.m"; sourceTree = ""; }; + 0691D3E0BDC9CD8351C20F1978A97E1F /* SentryCrashString.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashString.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashString.c; sourceTree = ""; }; + 06D304B144FA7C586C57986E3612227B /* SentryCrashReportWriter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportWriter.h; path = Sources/SentryCrash/Recording/SentryCrashReportWriter.h; sourceTree = ""; }; + 07D346136A47A1485152ECFBB337DF36 /* SentryCrashUUIDConversion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashUUIDConversion.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.h; sourceTree = ""; }; + 085DF157C909A8A4111A1513A172F832 /* SentryCrashReportSink.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportSink.h; path = Sources/Sentry/include/SentryCrashReportSink.h; sourceTree = ""; }; + 08B901DA30F9297F9B7E39C00791CAE4 /* SentrySpanId.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySpanId.h; path = Sources/Sentry/Public/SentrySpanId.h; sourceTree = ""; }; 08F7F0770B4878B9883B87DCD8569CB4 /* libExpecta.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libExpecta.a; path = libExpecta.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 09B515D14713BF4D5C47A28E2BF5C779 /* DiskStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DiskStorage.swift; path = Sources/Cache/DiskStorage.swift; sourceTree = ""; }; - 09C7E99EBC284F25C7F8ADED9BFDCB12 /* SDImageGraphics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGraphics.h; path = SDWebImage/SDImageGraphics.h; sourceTree = ""; }; - 0A45A1DA22EEDF7CB3E3C2FBF2C94C67 /* EXPMatchers+beLessThanOrEqualTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beLessThanOrEqualTo.h"; path = "Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.h"; sourceTree = ""; }; - 0BB323D9D7D7016C8AD08C2E3E150D08 /* UIColor+HexString.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIColor+HexString.m"; path = "SDWebImage/Private/UIColor+HexString.m"; sourceTree = ""; }; - 0BF93FF0D3C987DFC760391725FE25CA /* OCMIndirectReturnValueProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMIndirectReturnValueProvider.m; path = Source/OCMock/OCMIndirectReturnValueProvider.m; sourceTree = ""; }; - 0C3CBC28B037AB6A9DBB7C58473725CF /* EKMapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKMapper.h; path = Sources/EasyMapping/EKMapper.h; sourceTree = ""; }; - 0C8DDBE02D435933578C3D9CF9DB3219 /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/General/Kingfisher.swift; sourceTree = ""; }; - 0DEF35F27ACDB14F4FFBB034E4AA2831 /* SDWebImageDownloaderConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderConfig.h; path = SDWebImage/SDWebImageDownloaderConfig.h; sourceTree = ""; }; - 0E44BF2888ADFDF6796D186A5C321643 /* NSPopover+MISSINGBackgroundView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "NSPopover+MISSINGBackgroundView.debug.xcconfig"; sourceTree = ""; }; - 0E5FFCEAE0562BAE4C8E1775E814D99E /* OCMock-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "OCMock-prefix.pch"; sourceTree = ""; }; - 0F69AE167CA5113FE2264E86ED76DE4E /* NSValue+Expecta.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSValue+Expecta.m"; path = "Expecta/NSValue+Expecta.m"; sourceTree = ""; }; - 0FB84539B3D19B7FFC818161CE30CFF9 /* EasyMapping-tvOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EasyMapping-tvOS-dummy.m"; path = "../EasyMapping-tvOS/EasyMapping-tvOS-dummy.m"; sourceTree = ""; }; - 104C5B6C851601D859293E092AC36D08 /* UIImageView+HighlightedWebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+HighlightedWebCache.m"; path = "SDWebImage/UIImageView+HighlightedWebCache.m"; sourceTree = ""; }; - 130BFADFF57F3645DF20CCE614833C47 /* Pods-BitBot-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-BitBot-dummy.m"; sourceTree = ""; }; - 140022B9A102D37A032DBA6B152CA4E5 /* UIImageView+HighlightedWebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImageView+HighlightedWebCache.h"; path = "SDWebImage/UIImageView+HighlightedWebCache.h"; sourceTree = ""; }; - 14A88043724A1C2FF5276F579A74A83A /* SDDiskCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDDiskCache.m; path = SDWebImage/SDDiskCache.m; sourceTree = ""; }; - 14BF7FAE70B1B4B7DAA59DBCEB9CF9B8 /* SDWebImage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SDWebImage-dummy.m"; sourceTree = ""; }; - 14C0DCDD5D84614288FC9861FADD8501 /* OCMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMockObject.h; path = Source/OCMock/OCMockObject.h; sourceTree = ""; }; - 14F645E945F39049D018050DE34D1761 /* UIColor+HexString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIColor+HexString.h"; path = "SDWebImage/Private/UIColor+HexString.h"; sourceTree = ""; }; - 1565092550B223C4AA495868EA9ACCAE /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/General/ImageSource/Resource.swift; sourceTree = ""; }; - 166E5AA4004AA292F3940708D09686C0 /* Pods-BitriseATV-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-BitriseATV-acknowledgements.markdown"; sourceTree = ""; }; - 186F2A0989590D228E0BEE7E95FD3268 /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/Utility/String+MD5.swift"; sourceTree = ""; }; - 189145CF4A26929B148653BA2D875C0D /* EKCoreDataImporter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKCoreDataImporter.m; path = Sources/EasyMapping/EKCoreDataImporter.m; sourceTree = ""; }; - 19A77DFF172A3A9B3729D9A8DDA0481D /* ImageModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageModifier.swift; path = Sources/Networking/ImageModifier.swift; sourceTree = ""; }; - 19CD256D264D78BEB3371940A41DBACA /* UIImage+MemoryCacheCost.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+MemoryCacheCost.m"; path = "SDWebImage/UIImage+MemoryCacheCost.m"; sourceTree = ""; }; - 1A0B00C0866927A55EB7CF92B97DBEA1 /* OCMObserverRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMObserverRecorder.h; path = Source/OCMock/OCMObserverRecorder.h; sourceTree = ""; }; - 1A2EC3E9C1B6EA6971044D90C040768F /* OCMExceptionReturnValueProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMExceptionReturnValueProvider.m; path = Source/OCMock/OCMExceptionReturnValueProvider.m; sourceTree = ""; }; - 1A5502588214C14362D4206E958AB4DC /* NSObject+Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+Expecta.h"; path = "Expecta/NSObject+Expecta.h"; sourceTree = ""; }; - 1AD3CE5E6A7204EFCF0A94875B0F200C /* SDImageIOCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageIOCoder.m; path = SDWebImage/SDImageIOCoder.m; sourceTree = ""; }; - 1B53664E19E87DE3381B734459ABCFC4 /* EXPBlockDefinedMatcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPBlockDefinedMatcher.m; path = Expecta/EXPBlockDefinedMatcher.m; sourceTree = ""; }; - 1DA71E408B0A6D56446C2E5779AD7559 /* NSInvocation+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSInvocation+OCMAdditions.m"; path = "Source/OCMock/NSInvocation+OCMAdditions.m"; sourceTree = ""; }; - 1DBA344177BE60B9FC857B007F7899D1 /* CallbackQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallbackQueue.swift; path = Sources/Utility/CallbackQueue.swift; sourceTree = ""; }; - 1EE7E1C448B38B420808CC8605F8256B /* SDWebImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImage.h; path = WebImage/SDWebImage.h; sourceTree = ""; }; - 1F0E14AADA908BBB95E09797A0968416 /* EXPMatchers+match.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+match.h"; path = "Expecta/Matchers/EXPMatchers+match.h"; sourceTree = ""; }; - 1F8C9B0F00CA5E3B955DBC8BA1B1BBB2 /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; - 1FBDC4AD70DE3D06B76913290ED7B449 /* OCMArgAction.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMArgAction.m; path = Source/OCMock/OCMArgAction.m; sourceTree = ""; }; - 2067A7813FC3405752095AB40D062988 /* UIButton+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIButton+WebCache.h"; path = "SDWebImage/UIButton+WebCache.h"; sourceTree = ""; }; - 22B9F0B59BE15B06B82FFF9A49E8EC66 /* OCMLocation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMLocation.h; path = Source/OCMock/OCMLocation.h; sourceTree = ""; }; - 22D2D345016F9C053B3D1566570DA5EC /* SDAsyncBlockOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAsyncBlockOperation.h; path = SDWebImage/Private/SDAsyncBlockOperation.h; sourceTree = ""; }; - 230B187CA6AF6024F2B0036E0D164D04 /* SDWebImageDownloaderRequestModifier.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderRequestModifier.m; path = SDWebImage/SDWebImageDownloaderRequestModifier.m; sourceTree = ""; }; - 246A0C87B8EFEDCCF03667CE8BE5FD36 /* Mixpanel-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Mixpanel-tvOS.debug.xcconfig"; path = "../Mixpanel-tvOS/Mixpanel-tvOS.debug.xcconfig"; sourceTree = ""; }; - 247A6911F6FD4DACEE1AEF5DF4F49FAD /* SDImageCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCoder.m; path = SDWebImage/SDImageCoder.m; sourceTree = ""; }; - 249B7DEFAAD79ED621BF410C85E4E76A /* EKManagedObjectModel.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKManagedObjectModel.m; path = Sources/EasyMapping/EKManagedObjectModel.m; sourceTree = ""; }; - 26BED9F59C1EC352A91517BE7ED5DA93 /* EXPUnsupportedObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPUnsupportedObject.m; path = Expecta/EXPUnsupportedObject.m; sourceTree = ""; }; - 27D77C7ACC32A1A1AD494E09082CAD36 /* SDWebImageDefine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDefine.m; path = SDWebImage/SDWebImageDefine.m; sourceTree = ""; }; - 29266D803785F362E1AB4EEACA447597 /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Utility/Box.swift; sourceTree = ""; }; - 293AD8FB310917B27312010B015B0E5B /* OCMArgAction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMArgAction.h; path = Source/OCMock/OCMArgAction.h; sourceTree = ""; }; - 2A9D899A31143DE07964B6EBB4EE2084 /* SDAnimatedImageView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SDAnimatedImageView+WebCache.h"; path = "SDWebImage/SDAnimatedImageView+WebCache.h"; sourceTree = ""; }; - 2AE081BC4555FD7F02A0623282541F09 /* OCClassMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCClassMockObject.h; path = Source/OCMock/OCClassMockObject.h; sourceTree = ""; }; - 2C28179F76171CCE9AEBC4B5827CF3E9 /* ImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProvider.swift; path = Sources/General/ImageSource/ImageDataProvider.swift; sourceTree = ""; }; - 2D929F40722EA1C8DDAA7A14BE7CF771 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image/Image.swift; sourceTree = ""; }; - 2F2AE65500BCABFDFD85D713147C54F4 /* NSPopover+MISSINGBackgroundView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "NSPopover+MISSINGBackgroundView.release.xcconfig"; sourceTree = ""; }; - 318683794EA84AA46B81F67D9B6A5C41 /* EXPMatchers+beNil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beNil.m"; path = "Expecta/Matchers/EXPMatchers+beNil.m"; sourceTree = ""; }; - 31AC3F6479D957A7F4E7816F61098F4A /* EXPMatchers+raiseWithReason.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+raiseWithReason.h"; path = "Expecta/Matchers/EXPMatchers+raiseWithReason.h"; sourceTree = ""; }; - 31AF941F182276F2B40F2B726E75143E /* NSInvocation+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSInvocation+OCMAdditions.h"; path = "Source/OCMock/NSInvocation+OCMAdditions.h"; sourceTree = ""; }; - 32370B87A6CE0AA519B6CEDF99F910BF /* OCMPassByRefSetter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMPassByRefSetter.h; path = Source/OCMock/OCMPassByRefSetter.h; sourceTree = ""; }; - 33C60B7348A877E265B19BBA7EE57AFF /* UIView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIView+WebCache.m"; path = "SDWebImage/UIView+WebCache.m"; sourceTree = ""; }; - 341D4E70DB49D4DCD350DA4D9ED20A0A /* EXPMatchers+raiseWithReason.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+raiseWithReason.m"; path = "Expecta/Matchers/EXPMatchers+raiseWithReason.m"; sourceTree = ""; }; - 3494C85ECF06448B0147FD86227506AA /* EKSerializer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKSerializer.m; path = Sources/EasyMapping/EKSerializer.m; sourceTree = ""; }; - 350AB591550DC8BE6E78A18724372109 /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Views/Indicator.swift; sourceTree = ""; }; - 351E1639156085007A4F6BA6D161F9F3 /* EXPMatchers+endWith.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+endWith.h"; path = "Expecta/Matchers/EXPMatchers+endWith.h"; sourceTree = ""; }; - 355A7BC4978D41B9A315D86124F632C4 /* EKPropertyHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKPropertyHelper.m; path = Sources/EasyMapping/EKPropertyHelper.m; sourceTree = ""; }; - 360B43EA2822638B014CA70237DF74A3 /* NSNotificationCenter+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSNotificationCenter+OCMAdditions.m"; path = "Source/OCMock/NSNotificationCenter+OCMAdditions.m"; sourceTree = ""; }; - 37A99D4A2DF1C02DCA3946CF86D88A1B /* EXPMatchers+beInstanceOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beInstanceOf.m"; path = "Expecta/Matchers/EXPMatchers+beInstanceOf.m"; sourceTree = ""; }; - 38C45A85D39A9B8B7ABE3423AF6C7262 /* EXPMatchers+conformTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+conformTo.h"; path = "Expecta/Matchers/EXPMatchers+conformTo.h"; sourceTree = ""; }; - 38F1E72982CFDB8599746F32A1F0AE2B /* NSPopover+MISSINGBackgroundView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSPopover+MISSINGBackgroundView.m"; path = "Pod/Classes/NSPopover+MISSINGBackgroundView.m"; sourceTree = ""; }; - 39819557A29A9D29DD6D53EB13C399F4 /* EKMappingBlocks.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKMappingBlocks.m; path = Sources/EasyMapping/EKMappingBlocks.m; sourceTree = ""; }; - 3B555045479DF24DFFDE23E9DBFADB5E /* Pods-BitriseATV.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitriseATV.debug.xcconfig"; sourceTree = ""; }; - 3BC2E0DACFEAD5F5379C305F858D25B6 /* EXPMatchers+beSubclassOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beSubclassOf.h"; path = "Expecta/Matchers/EXPMatchers+beSubclassOf.h"; sourceTree = ""; }; - 3BF364F43D01D31692287DD1152F310C /* KingfisherError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherError.swift; path = Sources/General/KingfisherError.swift; sourceTree = ""; }; - 3C2868DF29A9449DC2CB6512DC6F2458 /* OCProtocolMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCProtocolMockObject.m; path = Source/OCMock/OCProtocolMockObject.m; sourceTree = ""; }; - 3C3D9EAFFF76FF6E8C46C08845C3FBA8 /* Pods-BitBotTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-BitBotTests-acknowledgements.plist"; sourceTree = ""; }; + 094D47CB9ED66B51D0B71F70E8BE1EF5 /* SDAnimatedImageRep.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImageRep.h; path = SDWebImage/SDAnimatedImageRep.h; sourceTree = ""; }; + 0963B2E3E97A0722C7CBBDDB36B76860 /* SentryMigrateSessionInit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryMigrateSessionInit.h; path = Sources/Sentry/include/SentryMigrateSessionInit.h; sourceTree = ""; }; + 098D18C816918B0625F2EFAC46124416 /* SentryCrashStackEntryMapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashStackEntryMapper.m; path = Sources/Sentry/SentryCrashStackEntryMapper.m; sourceTree = ""; }; + 0995BB77768EED5B1928D052E061FED9 /* SentryDsn.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryDsn.m; path = Sources/Sentry/SentryDsn.m; sourceTree = ""; }; + 09A3F0CF22C5A4DA1A8DA024DAD3E614 /* SDImageCachesManagerOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCachesManagerOperation.h; path = SDWebImage/Private/SDImageCachesManagerOperation.h; sourceTree = ""; }; + 09F7FF971894B9A06B4ECBF1B884BCEE /* SentryCrashUUIDConversion.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashUUIDConversion.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.c; sourceTree = ""; }; + 0A52A6F3E00C33219FCD44F31FAD48FB /* SentryRateLimitCategoryMapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryRateLimitCategoryMapper.m; path = Sources/Sentry/SentryRateLimitCategoryMapper.m; sourceTree = ""; }; + 0ABC382AC330CC67B3C949FB87775132 /* SentryDefaultCurrentDateProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryDefaultCurrentDateProvider.m; path = Sources/Sentry/SentryDefaultCurrentDateProvider.m; sourceTree = ""; }; + 0B5C408964654E9EFD65EF335BD11CA5 /* OCMVerifier.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMVerifier.m; path = Source/OCMock/OCMVerifier.m; sourceTree = ""; }; + 0B84BCB752C7801A42B7566DCD7F888B /* Pods-BitBot-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-BitBot-dummy.m"; sourceTree = ""; }; + 0C103D4E297EFF00119BCB966FCB8FA6 /* UIImage+ForceDecode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+ForceDecode.m"; path = "SDWebImage/UIImage+ForceDecode.m"; sourceTree = ""; }; + 0C3109EA3A2A5C9AD325830B1B6C99F9 /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/Utility/String+MD5.swift"; sourceTree = ""; }; + 0C686F67FB022C1485E7B62E2841750A /* UIImage+Metadata.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Metadata.h"; path = "SDWebImage/UIImage+Metadata.h"; sourceTree = ""; }; + 0CE7F630B356E6F9F3E9B043676AEAAD /* OCMInvocationExpectation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMInvocationExpectation.h; path = Source/OCMock/OCMInvocationExpectation.h; sourceTree = ""; }; + 0CF3E89497AE3160C90222810494D9F3 /* SDImageGIFCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageGIFCoder.m; path = SDWebImage/SDImageGIFCoder.m; sourceTree = ""; }; + 0D11B4BDEC059D18FA4E0388AD0D8785 /* SentryStacktraceBuilder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryStacktraceBuilder.m; path = Sources/Sentry/SentryStacktraceBuilder.m; sourceTree = ""; }; + 0D1A435A8F0243D5863B9B7E1A343AD4 /* SDWebImageIndicator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageIndicator.h; path = SDWebImage/SDWebImageIndicator.h; sourceTree = ""; }; + 0D34CB3DFF8BF5C1EAC6DDE6A5A0F132 /* SentryCrash.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrash.h; path = Sources/SentryCrash/Recording/SentryCrash.h; sourceTree = ""; }; + 0D55DD2E8B9C505A780231B6FA0855C7 /* SentryOutOfMemoryLogic.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryOutOfMemoryLogic.h; path = Sources/Sentry/include/SentryOutOfMemoryLogic.h; sourceTree = ""; }; + 0D606D5FCFC2B24362878D144E408FB4 /* SDImageCacheDefine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCacheDefine.h; path = SDWebImage/SDImageCacheDefine.h; sourceTree = ""; }; + 0E416F122F76468EAD9E8E52289FD699 /* OCMRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMRecorder.h; path = Source/OCMock/OCMRecorder.h; sourceTree = ""; }; + 0E4EA5E277EE2AC8B664CD9FC2A9ED44 /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Sources/Networking/SessionDelegate.swift; sourceTree = ""; }; + 0ED45AE327842259B4C32E6BCB45FAEF /* EXPMatchers+beInTheRangeOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beInTheRangeOf.m"; path = "Expecta/Matchers/EXPMatchers+beInTheRangeOf.m"; sourceTree = ""; }; + 0EE44E030124FB9FEF6EEA1B78AC4F09 /* SentryThreadInspector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryThreadInspector.h; path = Sources/Sentry/include/SentryThreadInspector.h; sourceTree = ""; }; + 0F77AE7AF85B51FDC734F0B9716C1B11 /* SentryTransaction.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryTransaction.m; path = Sources/Sentry/SentryTransaction.m; sourceTree = ""; }; + 0FE0E39861C5E3259ECA3D9D2E49DAFD /* SDDiskCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDDiskCache.h; path = SDWebImage/SDDiskCache.h; sourceTree = ""; }; + 100CF4E00773DF746C10C45D5F9A6A88 /* SentryCrashCachedData.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashCachedData.c; path = Sources/SentryCrash/Recording/SentryCrashCachedData.c; sourceTree = ""; }; + 10BFBB8F051AEE483FAA09C828C9ADE1 /* SDmetamacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDmetamacros.h; path = SDWebImage/Private/SDmetamacros.h; sourceTree = ""; }; + 10C33D949E0F21DC36A9644F03202279 /* SentryBreadcrumb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryBreadcrumb.h; path = Sources/Sentry/Public/SentryBreadcrumb.h; sourceTree = ""; }; + 10F5894E3DCDD857C93D93387290D1C5 /* SentryCrashMonitorType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitorType.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h; sourceTree = ""; }; + 11570D4A1B52E97A9FA97C20AA7920A1 /* SentryNSError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryNSError.m; path = Sources/Sentry/SentryNSError.m; sourceTree = ""; }; + 11925E02843BE5EF8939078EB45BAFA5 /* EXPMatchers+beSubclassOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beSubclassOf.m"; path = "Expecta/Matchers/EXPMatchers+beSubclassOf.m"; sourceTree = ""; }; + 119E9DE2FE8F50178BC215E54D111A7E /* SDImageGIFCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGIFCoder.h; path = SDWebImage/SDImageGIFCoder.h; sourceTree = ""; }; + 11A50C52679A85C930D61E41E25F0A15 /* SentryBreadcrumb.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryBreadcrumb.m; path = Sources/Sentry/SentryBreadcrumb.m; sourceTree = ""; }; + 126910B9AFE2B293DE3439F8733DBEF0 /* SDWebImageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageManager.m; path = SDWebImage/SDWebImageManager.m; sourceTree = ""; }; + 12975D01A5CEFC84922A28BC64869E48 /* Sentry-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Sentry-tvOS.release.xcconfig"; path = "../Sentry-tvOS/Sentry-tvOS.release.xcconfig"; sourceTree = ""; }; + 1302D0CB32C03B303DEC187E3830CF72 /* SDImageTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageTransformer.m; path = SDWebImage/SDImageTransformer.m; sourceTree = ""; }; + 131891EA60BFD2C10D365038115CC8C2 /* SentryCrashIntegration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashIntegration.m; path = Sources/Sentry/SentryCrashIntegration.m; sourceTree = ""; }; + 13B1D742BA9A979DF92459A477916420 /* SDWebImageIndicator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageIndicator.m; path = SDWebImage/SDWebImageIndicator.m; sourceTree = ""; }; + 13D79AE204DDA50C7C3F4E8E04D32276 /* SDImageAPNGCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAPNGCoder.h; path = SDWebImage/SDImageAPNGCoder.h; sourceTree = ""; }; + 13DE92C9C62C1580212860559CDCDB61 /* SentryCrashJSONCodec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashJSONCodec.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h; sourceTree = ""; }; + 143C0131251CC3EC130B715BA6A780CD /* SDImageGraphics.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageGraphics.m; path = SDWebImage/SDImageGraphics.m; sourceTree = ""; }; + 149E0F5BB4F3EAB50454D198D95531E3 /* SentryCrashReportFilterBasic.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashReportFilterBasic.m; path = Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.m; sourceTree = ""; }; + 14A5388595A1D1C81EF01AB89A8478D4 /* Pods-BitBot-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-BitBot-acknowledgements.markdown"; sourceTree = ""; }; + 152CDD8BC8FA40BCB765CC2A15B6444A /* EasyMapping-macOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "EasyMapping-macOS-prefix.pch"; sourceTree = ""; }; + 157863084A17F4A1D73C4C2C4237CF48 /* SentryId.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryId.m; path = Sources/Sentry/SentryId.m; sourceTree = ""; }; + 158A69E47F44FC87022EB7B284DB6CED /* NSArray+FlattenArray.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSArray+FlattenArray.h"; path = "Sources/EasyMapping/NSArray+FlattenArray.h"; sourceTree = ""; }; + 1693B04CD7105542A4995D7B1860CB4C /* SentryClient.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryClient.h; path = Sources/Sentry/Public/SentryClient.h; sourceTree = ""; }; + 16ABE2EA48367A888D50B0F067C45957 /* DiskStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DiskStorage.swift; path = Sources/Cache/DiskStorage.swift; sourceTree = ""; }; + 16C3715BC9F903D97400016275A722B9 /* SentryEnvelopeRateLimit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryEnvelopeRateLimit.h; path = Sources/Sentry/include/SentryEnvelopeRateLimit.h; sourceTree = ""; }; + 1754A6ED4900E0794C9F85E0D875BED1 /* Container+SentryDeepSearch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "Container+SentryDeepSearch.h"; path = "Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.h"; sourceTree = ""; }; + 17A69362E1FC166F5C2F8F3C55D67E3F /* Pods-BitBotTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBotTests.debug.xcconfig"; sourceTree = ""; }; + 17C1EC470E15CDC0A396B6A75163FD54 /* SentryUser.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryUser.m; path = Sources/Sentry/SentryUser.m; sourceTree = ""; }; + 17C94CDAF70A626A6557896E3013D3F6 /* OCMBoxedReturnValueProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMBoxedReturnValueProvider.m; path = Source/OCMock/OCMBoxedReturnValueProvider.m; sourceTree = ""; }; + 17D19B09C84E2416E96D186E823E81E8 /* SentryCrashMonitor_AppState.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMonitor_AppState.c; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.c; sourceTree = ""; }; + 180BA2E6B8B202B199C3249C471B57A1 /* EXPMatchers+raise.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+raise.h"; path = "Expecta/Matchers/EXPMatchers+raise.h"; sourceTree = ""; }; + 1861C909B39B2D38DFFDE22EABE4EA12 /* SentryRequestManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryRequestManager.h; path = Sources/Sentry/include/SentryRequestManager.h; sourceTree = ""; }; + 1863F1E2E1E6A795639A75A3C001F893 /* EXPMatchers+conformTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+conformTo.h"; path = "Expecta/Matchers/EXPMatchers+conformTo.h"; sourceTree = ""; }; + 1884FAF2A8FA6485B812BC2FF3A2D02F /* EKSerializer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKSerializer.m; path = Sources/EasyMapping/EKSerializer.m; sourceTree = ""; }; + 1A164679F41D45A5932DAA29D61891C2 /* SentrySDK.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySDK.m; path = Sources/Sentry/SentrySDK.m; sourceTree = ""; }; + 1A29DCD4677EEB50CC5E79F957801968 /* OCMExceptionReturnValueProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMExceptionReturnValueProvider.m; path = Source/OCMock/OCMExceptionReturnValueProvider.m; sourceTree = ""; }; + 1A63360C057BAF9E95C3C6ED480FF8E1 /* Expecta-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Expecta-prefix.pch"; sourceTree = ""; }; + 1A9FFACA5FE82A9DE4CB2228561AEAED /* SentryFileContents.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryFileContents.m; path = Sources/Sentry/SentryFileContents.m; sourceTree = ""; }; + 1B7B262830FE791A2992275F9570DE8C /* SentryCrashMonitor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.h; sourceTree = ""; }; + 1B891BFE89B9952888C4A187D6D6181D /* SDImageFrame.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageFrame.m; path = SDWebImage/SDImageFrame.m; sourceTree = ""; }; + 1BEE132FA31AD0DE7FE890AA026022DE /* SentryClient.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryClient.m; path = Sources/Sentry/SentryClient.m; sourceTree = ""; }; + 1C3A060C3967F3342A7DCC03CFA813D6 /* EasyMapping-tvOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EasyMapping-tvOS-dummy.m"; path = "../EasyMapping-tvOS/EasyMapping-tvOS-dummy.m"; sourceTree = ""; }; + 1CD9DCB3C79818BF4DC9700BE32E0785 /* SentryTransactionContext.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryTransactionContext.m; path = Sources/Sentry/SentryTransactionContext.m; sourceTree = ""; }; + 1CFD317BCE11392832E42B3F7239B444 /* ImageModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageModifier.swift; path = Sources/Networking/ImageModifier.swift; sourceTree = ""; }; + 1D3EE8F9270FE0BB85BFFCE0EEF64D69 /* EXPDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPDefines.h; path = Expecta/EXPDefines.h; sourceTree = ""; }; + 1D5DE687FE4F1B67174712D0C059309B /* OCMPassByRefSetter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMPassByRefSetter.m; path = Source/OCMock/OCMPassByRefSetter.m; sourceTree = ""; }; + 1D679F841A6E4E79B5D1E35CA2A4D7CE /* SentryDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryDefines.h; path = Sources/Sentry/Public/SentryDefines.h; sourceTree = ""; }; + 1D9816E9BA0E9C1D408810DF06B24A0B /* SentryAutoSessionTrackingIntegration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryAutoSessionTrackingIntegration.h; path = Sources/Sentry/include/SentryAutoSessionTrackingIntegration.h; sourceTree = ""; }; + 1DBBDC9C6D38AE230697D019D427B5D5 /* EKManagedObjectMapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKManagedObjectMapper.m; path = Sources/EasyMapping/EKManagedObjectMapper.m; sourceTree = ""; }; + 1DE114970A6D97164E402E9B61139AA6 /* MemoryStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MemoryStorage.swift; path = Sources/Cache/MemoryStorage.swift; sourceTree = ""; }; + 1DECCD676C555CF5BA3C512220A939A6 /* SentryRetryAfterHeaderParser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryRetryAfterHeaderParser.h; path = Sources/Sentry/include/SentryRetryAfterHeaderParser.h; sourceTree = ""; }; + 1E480A4679A415C223FF40639884AF28 /* EKRelationshipMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKRelationshipMapping.h; path = Sources/EasyMapping/EKRelationshipMapping.h; sourceTree = ""; }; + 1E4DF4622B9F51C96D13D365CC3101A5 /* SentryMechanism.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryMechanism.h; path = Sources/Sentry/Public/SentryMechanism.h; sourceTree = ""; }; + 1EE01D24380B370BF657B7428A0587C7 /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/Networking/ImagePrefetcher.swift; sourceTree = ""; }; + 1F04A6A52D80B51E2844EAB7D7922D07 /* SDDiskCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDDiskCache.m; path = SDWebImage/SDDiskCache.m; sourceTree = ""; }; + 1F184392A295DE2E19C93D0C8B7143C7 /* OCMBlockCaller.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMBlockCaller.m; path = Source/OCMock/OCMBlockCaller.m; sourceTree = ""; }; + 1F1A254848526B7085E6D816DBA83162 /* SDImageIOCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageIOCoder.m; path = SDWebImage/SDImageIOCoder.m; sourceTree = ""; }; + 1F4071362B52F086A16600C4AF635940 /* EXPMatchers+beLessThan.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beLessThan.m"; path = "Expecta/Matchers/EXPMatchers+beLessThan.m"; sourceTree = ""; }; + 1F6115F119202A304EEF57D5B2954F18 /* SentryCrashMonitor_Zombie.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_Zombie.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h; sourceTree = ""; }; + 1F88FA256932D4EFA23E52859A5ED9BD /* SentryCrashInstallation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashInstallation.m; path = Sources/SentryCrash/Installations/SentryCrashInstallation.m; sourceTree = ""; }; + 205390348AA79A216C5E4236AF4C090A /* SentrySessionTracker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySessionTracker.h; path = Sources/Sentry/include/SentrySessionTracker.h; sourceTree = ""; }; + 20A2C767F5807D413097F6C204719CA6 /* NSError+SentrySimpleConstructor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSError+SentrySimpleConstructor.h"; path = "Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.h"; sourceTree = ""; }; + 20BBA88BD1BC2C4981789AC0163EA2C8 /* OCMIndirectReturnValueProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMIndirectReturnValueProvider.m; path = Source/OCMock/OCMIndirectReturnValueProvider.m; sourceTree = ""; }; + 20FDCB67501389A381C2608C683D619B /* EKMappingBlocks.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKMappingBlocks.m; path = Sources/EasyMapping/EKMappingBlocks.m; sourceTree = ""; }; + 21463A3730433C3AA2E07A0BA53A08B9 /* OCMExpectationRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMExpectationRecorder.m; path = Source/OCMock/OCMExpectationRecorder.m; sourceTree = ""; }; + 2156CED034416F787C882CDFFADC6829 /* OCMInvocationStub.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMInvocationStub.h; path = Source/OCMock/OCMInvocationStub.h; sourceTree = ""; }; + 216232C7E3B491836F7FE4829869B5D7 /* SentryInstallation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryInstallation.h; path = Sources/Sentry/include/SentryInstallation.h; sourceTree = ""; }; + 216E33880C75DB02F09EBC7E6442708D /* SentryCrashMonitor_CPPException.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = SentryCrashMonitor_CPPException.cpp; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.cpp; sourceTree = ""; }; + 21C7B5AF640DAF194C58F14F0E88A87D /* Pods-BitBotATV-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-BitBotATV-acknowledgements.plist"; sourceTree = ""; }; + 223B6A8C24D4E6A3F09A2E454C53B4C3 /* SDImageCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCache.m; path = SDWebImage/SDImageCache.m; sourceTree = ""; }; + 231648EF993E94C012C047EDB0A87DD7 /* SDWebImageCacheKeyFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCacheKeyFilter.h; path = SDWebImage/SDWebImageCacheKeyFilter.h; sourceTree = ""; }; + 23CF50EB90747454BA5721ACEE41D52B /* SentrySession.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySession.m; path = Sources/Sentry/SentrySession.m; sourceTree = ""; }; + 23EF580A0426C81F2EA1FBA4B7DE4D86 /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/Image/ImageTransition.swift; sourceTree = ""; }; + 23FA33D338D06AE28C6AC2CADC005ED6 /* NSPopover+MISSINGBackgroundView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "NSPopover+MISSINGBackgroundView.debug.xcconfig"; sourceTree = ""; }; + 249A621C3105048EAC1AAFF00A061841 /* SentryTransportFactory.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryTransportFactory.m; path = Sources/Sentry/SentryTransportFactory.m; sourceTree = ""; }; + 249A6E6554241E9A2E70500432FE1E9B /* OCMArg.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMArg.h; path = Source/OCMock/OCMArg.h; sourceTree = ""; }; + 24AF02D97FDECA148365DA4E0103FF00 /* SentryCrashMonitor_User.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMonitor_User.c; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.c; sourceTree = ""; }; + 251C6FF39FE45D49E74742E54367D150 /* EXPMatchers+beGreaterThan.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beGreaterThan.m"; path = "Expecta/Matchers/EXPMatchers+beGreaterThan.m"; sourceTree = ""; }; + 2537FB4C8CB0778DD625F206CF385CA8 /* NSInvocation+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSInvocation+OCMAdditions.h"; path = "Source/OCMock/NSInvocation+OCMAdditions.h"; sourceTree = ""; }; + 256EE003D93BB1CAD0C8CAA7F1CFF85A /* NSPopover+MISSINGBackgroundView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "NSPopover+MISSINGBackgroundView.release.xcconfig"; sourceTree = ""; }; + 258332C878F6E9B127D8D8CDC15ABBBB /* SentrySpanStatus.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySpanStatus.h; path = Sources/Sentry/Public/SentrySpanStatus.h; sourceTree = ""; }; + 25E111C8A9A247EDA742310038540721 /* EXPMatchers+beInstanceOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beInstanceOf.h"; path = "Expecta/Matchers/EXPMatchers+beInstanceOf.h"; sourceTree = ""; }; + 25EDDD7D1E2FDD44649448745A77ABAC /* SentryMechanismMeta.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryMechanismMeta.m; path = Sources/Sentry/SentryMechanismMeta.m; sourceTree = ""; }; + 2685949B966DFD911386610465982AFF /* SentryRandom.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryRandom.m; path = Sources/Sentry/SentryRandom.m; sourceTree = ""; }; + 26D65938F613F4DCAC1F063D925D9C8B /* SentryCrashReportSink.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashReportSink.m; path = Sources/Sentry/SentryCrashReportSink.m; sourceTree = ""; }; + 2702815AF26E4C9FE035C2A0484F78AB /* SentrySDK+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SentrySDK+Private.h"; path = "Sources/Sentry/include/SentrySDK+Private.h"; sourceTree = ""; }; + 2721B1D673A34DA349D3468D5EB061F5 /* EXPMatchers+beCloseTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beCloseTo.m"; path = "Expecta/Matchers/EXPMatchers+beCloseTo.m"; sourceTree = ""; }; + 2756ECD1BE253C72B9421EB065BC47A9 /* SentryCrashMonitorType.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMonitorType.c; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c; sourceTree = ""; }; + 27BA44A4FAB2F26DB7AD3821A298F697 /* OCMock.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = OCMock.debug.xcconfig; sourceTree = ""; }; + 283CF93D0E24384373D3F11E6A1D612E /* SentryDispatchQueueWrapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryDispatchQueueWrapper.m; path = Sources/Sentry/SentryDispatchQueueWrapper.m; sourceTree = ""; }; + 28C04358E6A2DC7343F90687D9DB0E7F /* SentryDebugMeta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryDebugMeta.h; path = Sources/Sentry/Public/SentryDebugMeta.h; sourceTree = ""; }; + 28F30BDB100EE20988EF30AF46D98AE9 /* SentryCrashObjC.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashObjC.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashObjC.h; sourceTree = ""; }; + 297F53EBDB02A11F591EC8C9D9F3F878 /* SDImageLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageLoader.m; path = SDWebImage/SDImageLoader.m; sourceTree = ""; }; + 298DE2A21DD8DFBCCC013ED8A37AFD59 /* Pods-BitBotATV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBotATV.release.xcconfig"; sourceTree = ""; }; + 29C750494B2288788DB4B51460D5DEE6 /* EasyMapping-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "EasyMapping-macOS.debug.xcconfig"; sourceTree = ""; }; + 2A983085F3DFDC173B710B3C170F3368 /* SentryCrashLogger.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashLogger.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashLogger.c; sourceTree = ""; }; + 2AD68E665E1E63202CCC33440DEE5688 /* SDImageCacheConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCacheConfig.m; path = SDWebImage/SDImageCacheConfig.m; sourceTree = ""; }; + 2AD6FF53E585D37C0030DD7DDB732653 /* SentryLogOutput.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryLogOutput.h; path = Sources/Sentry/include/SentryLogOutput.h; sourceTree = ""; }; + 2AF331BB4BA9B2DC12487F3DBD970080 /* OCMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMockObject.h; path = Source/OCMock/OCMockObject.h; sourceTree = ""; }; + 2B5C2078B50FD676339A2FEE36C2439C /* EXPExpect.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPExpect.m; path = Expecta/EXPExpect.m; sourceTree = ""; }; + 2B8B4F5B5F48C2BEC0FE0781579AF143 /* Pods-BitBotATV-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-BitBotATV-dummy.m"; sourceTree = ""; }; + 2BFEDAD83AB355F5DA2420B3CA6B2A99 /* SentrySdkInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySdkInfo.h; path = Sources/Sentry/Public/SentrySdkInfo.h; sourceTree = ""; }; + 2CA4FF39ED0B887747BAB6C80C3A034E /* SentryLevelMapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryLevelMapper.h; path = Sources/Sentry/include/SentryLevelMapper.h; sourceTree = ""; }; + 2CB00895C3B8D81E78B53D91E9A3ED2F /* SentryCrashReportConverter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashReportConverter.m; path = Sources/Sentry/SentryCrashReportConverter.m; sourceTree = ""; }; + 2CC1924BC66C4930A9848851D49802FB /* SessionMetadata.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SessionMetadata.h; path = Mixpanel/SessionMetadata.h; sourceTree = ""; }; + 2CDC994083E6028E0A5B0CB8C7F894C1 /* SentryEnvelopeRateLimit.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryEnvelopeRateLimit.m; path = Sources/Sentry/SentryEnvelopeRateLimit.m; sourceTree = ""; }; + 2D213DC3D25A75835B758B314D291EB4 /* MixpanelPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelPrivate.h; path = Mixpanel/MixpanelPrivate.h; sourceTree = ""; }; + 2D70F821154E7BBE09D9B7BEDB0361E2 /* SentryCrashCPU_arm64.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashCPU_arm64.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashCPU_arm64.c; sourceTree = ""; }; + 2DB85262F5F33A0C16F18E0EB8E0C8CF /* Pods-BitBotTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-BitBotTests-dummy.m"; sourceTree = ""; }; + 2F01D2FB88692CCA07D12D161B9B3ABC /* SentryBreadcrumbTracker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryBreadcrumbTracker.m; path = Sources/Sentry/SentryBreadcrumbTracker.m; sourceTree = ""; }; + 2F57830DA0361A1D478D6FD1206B5C8C /* SentryScope.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryScope.m; path = Sources/Sentry/SentryScope.m; sourceTree = ""; }; + 301E1022D63C63981FEEEE645954B1C3 /* MPLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MPLogger.h; path = Mixpanel/MPLogger.h; sourceTree = ""; }; + 304D7AE95A8997C86DF9D893909AE6FD /* libPods-BitBotATV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-BitBotATV.a"; path = "libPods-BitBotATV.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 310F43800A6087EA88D2D109C93895D5 /* SentryCrashC.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashC.c; path = Sources/SentryCrash/Recording/SentryCrashC.c; sourceTree = ""; }; + 31BD2E6667910A3319B47B6397FB7A7D /* SentryCrashMachineContext.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMachineContext.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c; sourceTree = ""; }; + 327F432D938896DE00325DA3BCAC1A8E /* MixpanelGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelGroup.h; path = Mixpanel/MixpanelGroup.h; sourceTree = ""; }; + 3298B34DB4E92B8B598D382D9EFE204A /* NSData+SentryCompression.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+SentryCompression.m"; path = "Sources/Sentry/NSData+SentryCompression.m"; sourceTree = ""; }; + 32EE06144281D6F9D2433552BFE5F506 /* EXPDoubleTuple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPDoubleTuple.h; path = Expecta/EXPDoubleTuple.h; sourceTree = ""; }; + 33B716A52A3BD31594FA249C2ED9CBA5 /* UIImageView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+WebCache.m"; path = "SDWebImage/UIImageView+WebCache.m"; sourceTree = ""; }; + 33DA7E311D382D1E2A185A8363040779 /* SDMemoryCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDMemoryCache.m; path = SDWebImage/SDMemoryCache.m; sourceTree = ""; }; + 33FE9136D837600FD6367096AD17FEEB /* SentryFrameInAppLogic.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryFrameInAppLogic.h; path = Sources/Sentry/include/SentryFrameInAppLogic.h; sourceTree = ""; }; + 34F08715426C01748685B152C7ADCAFA /* Mixpanel-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Mixpanel-tvOS.release.xcconfig"; path = "../Mixpanel-tvOS/Mixpanel-tvOS.release.xcconfig"; sourceTree = ""; }; + 353D6F3694A36EA3F9994B9E30E9C7D2 /* OCMStubRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMStubRecorder.h; path = Source/OCMock/OCMStubRecorder.h; sourceTree = ""; }; + 358E2C8396B00E243809000DFC3F9F46 /* OCMLocation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMLocation.h; path = Source/OCMock/OCMLocation.h; sourceTree = ""; }; + 35AB175A6910B81B03372F043897023B /* OCMNotificationPoster.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMNotificationPoster.m; path = Source/OCMock/OCMNotificationPoster.m; sourceTree = ""; }; + 35DF544F231298A2C3983E204103A328 /* SentryMechanism.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryMechanism.m; path = Sources/Sentry/SentryMechanism.m; sourceTree = ""; }; + 3643E758C072AA39C0B4AA42EC9A2589 /* EXPMatchers+endWith.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+endWith.m"; path = "Expecta/Matchers/EXPMatchers+endWith.m"; sourceTree = ""; }; + 36737DC870746AD789DBCD3EC70812EE /* EKMapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKMapper.m; path = Sources/EasyMapping/EKMapper.m; sourceTree = ""; }; + 36CE61210416761404325FA95F4B0B13 /* SentryCrashDynamicLinker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashDynamicLinker.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.h; sourceTree = ""; }; + 37036428688A5CFD9A0E8390B2C3836D /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/Extensions/UIButton+Kingfisher.swift"; sourceTree = ""; }; + 37BD8D3AB94FFA0798CB394794BCBAD9 /* fishhook.c */ = {isa = PBXFileReference; includeInIndex = 1; name = fishhook.c; path = Sources/SentryCrash/Recording/Tools/fishhook.c; sourceTree = ""; }; + 37CFFB37B0F2EA6788D515BD2C299784 /* Sentry-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Sentry-macOS.debug.xcconfig"; sourceTree = ""; }; + 37E0C1DAB986269E65DF3BF1A45C66D1 /* NSImage+Compatibility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSImage+Compatibility.h"; path = "SDWebImage/NSImage+Compatibility.h"; sourceTree = ""; }; + 381477C01B8DA099AEF2076D35832CB9 /* NSPopover+MISSINGBackgroundView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSPopover+MISSINGBackgroundView-prefix.pch"; sourceTree = ""; }; + 382B6780F0FBF48423885E733831C75C /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/Networking/RequestModifier.swift; sourceTree = ""; }; + 393E830D1A859C819F8DDFFC69C8727E /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; + 3A0B6EC88D0EFA74FC3FB8F0BBCCEC0F /* NSValue+Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSValue+Expecta.h"; path = "Expecta/NSValue+Expecta.h"; sourceTree = ""; }; + 3A2CBF658B1028843343F4D084C7F808 /* Container+SentryDeepSearch.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "Container+SentryDeepSearch.m"; path = "Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.m"; sourceTree = ""; }; + 3A37B1F725D56C8C4BCE30AB4B450E10 /* SDImageCodersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCodersManager.h; path = SDWebImage/SDImageCodersManager.h; sourceTree = ""; }; + 3AC17A06B2CD1137FBA04236CCCD1715 /* SentryCrashC.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashC.h; path = Sources/SentryCrash/Recording/SentryCrashC.h; sourceTree = ""; }; + 3B724904092136FEEDB93380DA4070C0 /* Pods-BitBotATV-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-BitBotATV-umbrella.h"; sourceTree = ""; }; + 3BF03F0C7762E903D6D62F462E93BE35 /* EXPMatchers+beLessThanOrEqualTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beLessThanOrEqualTo.h"; path = "Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.h"; sourceTree = ""; }; + 3BF711190956F6B15EBCFD0EDA1345DF /* EXPMatchers+equal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+equal.h"; path = "Expecta/Matchers/EXPMatchers+equal.h"; sourceTree = ""; }; + 3C0D06F888A372154BF1F8BA0B428CC3 /* SentryCrashReportFilterBasic.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportFilterBasic.h; path = Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.h; sourceTree = ""; }; 3CA25617ED43F9B28F37E0C51D1B5047 /* libMixpanel-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libMixpanel-tvOS.a"; path = "libMixpanel-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3CF287C63E99637D48551E625B228C5D /* SDAsyncBlockOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAsyncBlockOperation.m; path = SDWebImage/Private/SDAsyncBlockOperation.m; sourceTree = ""; }; - 3F62CF50DC8FA9E8FA9A41282444BAB3 /* Pods-BitBot-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-BitBot-acknowledgements.plist"; sourceTree = ""; }; - 3F6312424838238EECCB0C1BA1002684 /* OCMMacroState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMMacroState.h; path = Source/OCMock/OCMMacroState.h; sourceTree = ""; }; - 405CE14212D8D81B57A9E972895A31D7 /* Pods-BitBot.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBot.debug.xcconfig"; sourceTree = ""; }; - 4072B0EAE2E33D5AB029517D512D41C4 /* OCMock.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = OCMock.debug.xcconfig; sourceTree = ""; }; - 43338F28496A583931F32BF4E684495B /* OCMInvocationStub.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMInvocationStub.m; path = Source/OCMock/OCMInvocationStub.m; sourceTree = ""; }; - 451058C9822FCCFCFA0769D8F9C0EF8D /* Pods-BitBot-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-BitBot-acknowledgements.markdown"; sourceTree = ""; }; - 45967075B8CB5A601521BEDEDDDF70B6 /* SDAnimatedImageView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "SDAnimatedImageView+WebCache.m"; path = "SDWebImage/SDAnimatedImageView+WebCache.m"; sourceTree = ""; }; - 460A2613309D6A90A54CEB827940AF8C /* SDWebImageDefine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDefine.h; path = SDWebImage/SDWebImageDefine.h; sourceTree = ""; }; - 46209163AE3F1146C82075ECDBD3EC77 /* OCMExceptionReturnValueProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMExceptionReturnValueProvider.h; path = Source/OCMock/OCMExceptionReturnValueProvider.h; sourceTree = ""; }; + 3CA26FD9028DA58D96FBF18B6DBCD422 /* SentrySessionTracker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySessionTracker.m; path = Sources/Sentry/SentrySessionTracker.m; sourceTree = ""; }; + 3CB6B2ED6DFCB782ACC85B2D4C2B7F22 /* NSError+SentrySimpleConstructor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSError+SentrySimpleConstructor.m"; path = "Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.m"; sourceTree = ""; }; + 3CD47642CEB2A2790CA703FAD8DF55D4 /* EasyMapping-tvOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EasyMapping-tvOS-prefix.pch"; path = "../EasyMapping-tvOS/EasyMapping-tvOS-prefix.pch"; sourceTree = ""; }; + 3D08DE0D01595536B14C06E957A81A17 /* EKManagedObjectMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKManagedObjectMapping.h; path = Sources/EasyMapping/EKManagedObjectMapping.h; sourceTree = ""; }; + 3D3669E97FB5BC347CDC0D1D98051F84 /* OCMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMockObject.m; path = Source/OCMock/OCMockObject.m; sourceTree = ""; }; + 3D88D09A9D5B23D66D2E3164E233965A /* SDWebImageDownloaderOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderOperation.m; path = SDWebImage/SDWebImageDownloaderOperation.m; sourceTree = ""; }; + 3DC68AE22AB019032DD1A0EA782C4614 /* EKCoreDataImporter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKCoreDataImporter.m; path = Sources/EasyMapping/EKCoreDataImporter.m; sourceTree = ""; }; + 3DCDDE6A99DD91D67C0528308889B8C9 /* SDImageFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageFrame.h; path = SDWebImage/SDImageFrame.h; sourceTree = ""; }; + 3E01B96E9D6EEE758CC6F000CB4F7ED0 /* SentryRateLimitCategoryMapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryRateLimitCategoryMapper.h; path = Sources/Sentry/include/SentryRateLimitCategoryMapper.h; sourceTree = ""; }; + 3ED720BAD2544EC968D1F33773CF08EB /* SentryCrashMonitor_Deadlock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_Deadlock.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.h; sourceTree = ""; }; + 3EE249DEE7BB07E67055EB8B9D87F3F5 /* SDAsyncBlockOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAsyncBlockOperation.m; path = SDWebImage/Private/SDAsyncBlockOperation.m; sourceTree = ""; }; + 3F3523459F8BDE81CDD88934EA8F73B0 /* SentrySdkInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySdkInfo.m; path = Sources/Sentry/SentrySdkInfo.m; sourceTree = ""; }; + 3F51174B10209840F57501FA9C81C780 /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = Sources/Cache/Storage.swift; sourceTree = ""; }; + 3FC7D392594228556B4C17B83C67DA94 /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; + 4083F4A45B92B9A4CDA43A2E616B20D5 /* EKManagedObjectMapping.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKManagedObjectMapping.m; path = Sources/EasyMapping/EKManagedObjectMapping.m; sourceTree = ""; }; + 41A323BD55CEF8F8697370A91DF02F88 /* MixpanelType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MixpanelType.m; path = Mixpanel/MixpanelType.m; sourceTree = ""; }; + 41B0A65DF6211BF2861ABE6E500D3B7E /* SentryStacktrace.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryStacktrace.m; path = Sources/Sentry/SentryStacktrace.m; sourceTree = ""; }; + 422EB5E0CBDCA3F2BC8CD610045F4AC6 /* SentryCrashStackCursor.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashStackCursor.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.c; sourceTree = ""; }; + 427528E5351360795A2FC716F0A61A43 /* OCMConstraint.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMConstraint.m; path = Source/OCMock/OCMConstraint.m; sourceTree = ""; }; + 433A671CB2FACC218F4EFC5EA60169C7 /* SentryCrashStackCursor_SelfThread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashStackCursor_SelfThread.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h; sourceTree = ""; }; + 437EAEDD38DB97E2357378A28B74AF85 /* OCMBlockArgCaller.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMBlockArgCaller.h; path = Source/OCMock/OCMBlockArgCaller.h; sourceTree = ""; }; + 438F5D72C80C54963277C3109A0652B0 /* SentryCrashCString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashCString.h; path = Sources/SentryCrash/Reporting/Tools/SentryCrashCString.h; sourceTree = ""; }; + 43CC2DE11D8B53AA2809C93B3DF96B78 /* EXPMatchers+beInstanceOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beInstanceOf.m"; path = "Expecta/Matchers/EXPMatchers+beInstanceOf.m"; sourceTree = ""; }; + 442B5088AAD4A7635F001BBC8DA25200 /* SentrySerialization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySerialization.m; path = Sources/Sentry/SentrySerialization.m; sourceTree = ""; }; + 4480333F342523BA7314F31E49980C8A /* NSPopover+MISSINGBackgroundView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSPopover+MISSINGBackgroundView.m"; path = "Pod/Classes/NSPopover+MISSINGBackgroundView.m"; sourceTree = ""; }; + 456AD22FE7425CEF9CCB07B74D2628F0 /* Pods-BitBotTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-BitBotTests-acknowledgements.plist"; sourceTree = ""; }; + 45787E0AEDF8AD16DDEA9AA886A226C0 /* ExpectaObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ExpectaObject.m; path = Expecta/ExpectaObject.m; sourceTree = ""; }; + 459D974EAA55D2D6B05023A91ADD1E1A /* SDImageCachesManagerOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCachesManagerOperation.m; path = SDWebImage/Private/SDImageCachesManagerOperation.m; sourceTree = ""; }; + 468F25D684EB369BC80024F1557AE98E /* UIView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+WebCache.h"; path = "SDWebImage/UIView+WebCache.h"; sourceTree = ""; }; + 46AB541CCB0ABA088F628178E27D63A8 /* TracesSampler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = TracesSampler.h; path = Sources/Sentry/include/TracesSampler.h; sourceTree = ""; }; 46F4F400E88483A3268939ED4F54B477 /* libPods-BitBot.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-BitBot.a"; path = "libPods-BitBot.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 473387FDA75A441BDCAD6FD610A4E523 /* OCMBlockArgCaller.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMBlockArgCaller.m; path = Source/OCMock/OCMBlockArgCaller.m; sourceTree = ""; }; - 474825B5D9CD57231E0863576494A2A1 /* OCMRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMRecorder.h; path = Source/OCMock/OCMRecorder.h; sourceTree = ""; }; - 475B134AC1BCAE5FB01505BBA2261DE5 /* OCClassMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCClassMockObject.m; path = Source/OCMock/OCClassMockObject.m; sourceTree = ""; }; - 48A8FADBD7E4D999799E8CC0E67046CA /* Mixpanel-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Mixpanel-macOS.release.xcconfig"; sourceTree = ""; }; - 48E34B5E54DDDCE905E3AEA8359FA621 /* UIImage+Metadata.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Metadata.h"; path = "SDWebImage/UIImage+Metadata.h"; sourceTree = ""; }; - 49022F133FF236AA7B02EBB4B4827D07 /* EXPMatchers+respondTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+respondTo.h"; path = "Expecta/Matchers/EXPMatchers+respondTo.h"; sourceTree = ""; }; - 49424D224EA68C64A3D1A8ED64880769 /* NSPopover+MISSINGBackgroundView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "NSPopover+MISSINGBackgroundView-dummy.m"; sourceTree = ""; }; - 4B6A690A9A6C6A1F35D533D71672AE8D /* SDWebImageError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageError.m; path = SDWebImage/SDWebImageError.m; sourceTree = ""; }; - 4BFF7D460EC190F4EF6ED180A3017FC0 /* EKRelationshipMapping.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKRelationshipMapping.m; path = Sources/EasyMapping/EKRelationshipMapping.m; sourceTree = ""; }; - 4C0C745CE85F9303B8FFDAC722E056D0 /* EXPMatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatcher.h; path = Expecta/EXPMatcher.h; sourceTree = ""; }; - 4C54643A14053405BDB4037BC6923EEB /* Mixpanel-tvOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "Mixpanel-tvOS-dummy.m"; path = "../Mixpanel-tvOS/Mixpanel-tvOS-dummy.m"; sourceTree = ""; }; - 4C5CEDC685B0DAF949C106E84D43A94C /* MixpanelPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelPrivate.h; path = Mixpanel/MixpanelPrivate.h; sourceTree = ""; }; - 4C7771685DCCEB9E674423E98EFC435C /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Image/Placeholder.swift; sourceTree = ""; }; - 4CDEE8194B56CF2FED272F0BF55F6583 /* EXPMatchers+beSubclassOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beSubclassOf.m"; path = "Expecta/Matchers/EXPMatchers+beSubclassOf.m"; sourceTree = ""; }; - 4D0D4DA41BE5383DA49503DAFA6F1445 /* Mixpanel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Mixpanel.h; path = Mixpanel/Mixpanel.h; sourceTree = ""; }; - 4D4CAD6A25521E9242F03EE13302FB7A /* UIButton+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIButton+WebCache.m"; path = "SDWebImage/UIButton+WebCache.m"; sourceTree = ""; }; - 4D823CF7CA5CAC63795CA9BBD5473A44 /* SDImageGIFCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageGIFCoder.m; path = SDWebImage/SDImageGIFCoder.m; sourceTree = ""; }; - 4E8CE8F303F0D4706A0082068622A245 /* EKMapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKMapper.m; path = Sources/EasyMapping/EKMapper.m; sourceTree = ""; }; - 4EA37B59FEEFC4126008D4438093882D /* UIView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+WebCache.h"; path = "SDWebImage/UIView+WebCache.h"; sourceTree = ""; }; - 4EA6B926575B4BFD799AB7AB428D480C /* SessionMetadata.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SessionMetadata.m; path = Mixpanel/SessionMetadata.m; sourceTree = ""; }; - 508C1A1C5A4AFFB6E7B04F71FE0E0F71 /* SDImageCachesManagerOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCachesManagerOperation.h; path = SDWebImage/Private/SDImageCachesManagerOperation.h; sourceTree = ""; }; - 50C87AB4B61D62461E9958E2BF8D9EA3 /* EXPBlockDefinedMatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPBlockDefinedMatcher.h; path = Expecta/EXPBlockDefinedMatcher.h; sourceTree = ""; }; - 512768F8B3FF93AED6AA35F6FB770F30 /* MPNetworkPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MPNetworkPrivate.h; path = Mixpanel/MPNetworkPrivate.h; sourceTree = ""; }; - 51944D9571F5EFD1BED19D1CFCBF2FF7 /* Runtime.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Runtime.swift; path = Sources/Utility/Runtime.swift; sourceTree = ""; }; - 524F0C8BF02AF437472F424326751775 /* NSImage+Compatibility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSImage+Compatibility.h"; path = "SDWebImage/NSImage+Compatibility.h"; sourceTree = ""; }; - 528A49D37E1026AEB96C97C085C90019 /* ImageDrawing.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDrawing.swift; path = Sources/Image/ImageDrawing.swift; sourceTree = ""; }; - 53DA50CB5C5309A4A85E7F9584687889 /* OCMRealObjectForwarder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMRealObjectForwarder.m; path = Source/OCMock/OCMRealObjectForwarder.m; sourceTree = ""; }; - 5611299158585069B560CAC196D9809F /* Expecta.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Expecta.debug.xcconfig; sourceTree = ""; }; - 5657918E85BD137F9793730413845AE0 /* GIFAnimatedImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GIFAnimatedImage.swift; path = Sources/Image/GIFAnimatedImage.swift; sourceTree = ""; }; - 56899FE50A2A99881362A35F2005FEED /* SDAnimatedImageView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImageView.h; path = SDWebImage/SDAnimatedImageView.h; sourceTree = ""; }; + 472F88C1AE184846E3C92E70773C562C /* SentryNSURLRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryNSURLRequest.m; path = Sources/Sentry/SentryNSURLRequest.m; sourceTree = ""; }; + 4753CFE0EA0A4BF9BBB242C45FBBDA64 /* SDWebImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.debug.xcconfig; sourceTree = ""; }; + 475E42A215A0DAE591C36514C111C296 /* Runtime.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Runtime.swift; path = Sources/Utility/Runtime.swift; sourceTree = ""; }; + 479F6C5B2AD83CECCF85A2F820906395 /* SentryCrashStackCursor_Backtrace.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashStackCursor_Backtrace.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.c; sourceTree = ""; }; + 47B69B903C4DE4A0125C0FFF10DD800F /* OCMFunctions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMFunctions.h; path = Source/OCMock/OCMFunctions.h; sourceTree = ""; }; + 4801355A25E5488A0DF0A051F6ADB977 /* MixpanelGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MixpanelGroup.m; path = Mixpanel/MixpanelGroup.m; sourceTree = ""; }; + 489798041B2405CC8A490AB0B42C55D7 /* Sentry-tvOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "Sentry-tvOS-prefix.pch"; path = "../Sentry-tvOS/Sentry-tvOS-prefix.pch"; sourceTree = ""; }; + 4921086B7457B240615C849B4A4DE4A7 /* SentryMessage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryMessage.h; path = Sources/Sentry/Public/SentryMessage.h; sourceTree = ""; }; + 4995871A89A4C5222BE0FBF47A7FB17A /* SentryOutOfMemoryTracker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryOutOfMemoryTracker.h; path = Sources/Sentry/include/SentryOutOfMemoryTracker.h; sourceTree = ""; }; + 49BD7D6166DAB82CE8BE016B0182FCC1 /* SDImageTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageTransformer.h; path = SDWebImage/SDImageTransformer.h; sourceTree = ""; }; + 4AC9CB050C910E77C9B12CB287704992 /* MPNetworkPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MPNetworkPrivate.h; path = Mixpanel/MPNetworkPrivate.h; sourceTree = ""; }; + 4B10146712CA2C75052E427FF98FEE76 /* SentryTransactionContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryTransactionContext.h; path = Sources/Sentry/Public/SentryTransactionContext.h; sourceTree = ""; }; + 4B4728D9253591A76583B4851D369268 /* SDWebImageTransition.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageTransition.m; path = SDWebImage/SDWebImageTransition.m; sourceTree = ""; }; + 4B8128A487CD674959BF7DC3296CA01D /* Pods-BitBotATV-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-BitBotATV-acknowledgements.markdown"; sourceTree = ""; }; + 4BA0261A606C77F7BFED637CC3557677 /* SentryCrashMach.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMach.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashMach.h; sourceTree = ""; }; + 4C8177EB82FABE600FA5B880534D57C6 /* EXPMatchers+respondTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+respondTo.h"; path = "Expecta/Matchers/EXPMatchers+respondTo.h"; sourceTree = ""; }; + 4CC646924C2D2C93556CA6232316B400 /* SentryRateLimitParser.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryRateLimitParser.m; path = Sources/Sentry/SentryRateLimitParser.m; sourceTree = ""; }; + 4CCB6752988681478753D8ECC5D8F288 /* SentryMigrateSessionInit.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryMigrateSessionInit.m; path = Sources/Sentry/SentryMigrateSessionInit.m; sourceTree = ""; }; + 4D19CFB58A52BB6ECB5EAB0DAF6B03C2 /* EKManagedObjectModel.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKManagedObjectModel.m; path = Sources/EasyMapping/EKManagedObjectModel.m; sourceTree = ""; }; + 4D3FBFA74344F4FF521DCE28F5DF4976 /* EXPMatchers+beSupersetOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beSupersetOf.m"; path = "Expecta/Matchers/EXPMatchers+beSupersetOf.m"; sourceTree = ""; }; + 4D48E9E19EDCAF24050949D06D6DD6E2 /* SentryCrashMachineContext_Apple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMachineContext_Apple.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext_Apple.h; sourceTree = ""; }; + 4DAA072773DE54BFAA4917530A95F092 /* SentrySessionCrashedHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySessionCrashedHandler.m; path = Sources/Sentry/SentrySessionCrashedHandler.m; sourceTree = ""; }; + 4DB313DA821938D69711108885AC28DC /* Mixpanel-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Mixpanel-macOS.debug.xcconfig"; sourceTree = ""; }; + 4E52820D73978A25A8C1B784E898C377 /* SentrySwizzle.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySwizzle.m; path = Sources/Sentry/SentrySwizzle.m; sourceTree = ""; }; + 4E61FB7499176B62067C34B234D8526A /* SentryDateUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryDateUtil.m; path = Sources/Sentry/SentryDateUtil.m; sourceTree = ""; }; + 4F03E9E2CCBA2497C85A620AD66646FF /* RetryStrategy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryStrategy.swift; path = Sources/Networking/RetryStrategy.swift; sourceTree = ""; }; + 4F56E39159CAE9BE998C994876ED8E9D /* SentryRateLimitParser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryRateLimitParser.h; path = Sources/Sentry/include/SentryRateLimitParser.h; sourceTree = ""; }; + 4F73D52AE3C01661DE55ACA0D0E98D50 /* SDWebImageCompat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCompat.h; path = SDWebImage/SDWebImageCompat.h; sourceTree = ""; }; + 4F7AACCA9011988D5EA92395F682A784 /* NSArray+SentrySanitize.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSArray+SentrySanitize.h"; path = "Sources/Sentry/include/NSArray+SentrySanitize.h"; sourceTree = ""; }; + 4FD1228EA2E85C9985EC483AD3EEC37E /* Pods-BitBot.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBot.debug.xcconfig"; sourceTree = ""; }; + 4FDBE617EF1EA76B9219DC475DFE0B4D /* SentryCrashAdapter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashAdapter.h; path = Sources/Sentry/include/SentryCrashAdapter.h; sourceTree = ""; }; + 504C881F5EF6D0E2B49BBA35F1FE88E7 /* EXPBlockDefinedMatcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPBlockDefinedMatcher.m; path = Expecta/EXPBlockDefinedMatcher.m; sourceTree = ""; }; + 50C09C43E38AC5954BD87B5EE7401748 /* SentryCrashID.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashID.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashID.c; sourceTree = ""; }; + 50C776FAE04FB29E201583DFAC74FE9F /* SentryCrashReportVersion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportVersion.h; path = Sources/SentryCrash/Recording/SentryCrashReportVersion.h; sourceTree = ""; }; + 50E59068B900E048C38B63AE64FFC855 /* fishhook.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = fishhook.h; path = Sources/SentryCrash/Recording/Tools/fishhook.h; sourceTree = ""; }; + 50F41EB095A01EDA99B2B497F53C1F0E /* SDAnimatedImageView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SDAnimatedImageView+WebCache.h"; path = "SDWebImage/SDAnimatedImageView+WebCache.h"; sourceTree = ""; }; + 5122E3FCDD75BB5EAA1489400AFCB5FD /* EXPMatchers+match.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+match.h"; path = "Expecta/Matchers/EXPMatchers+match.h"; sourceTree = ""; }; + 5169589B116558FFAAB8BE33DD6CFF16 /* SentrySpan.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySpan.m; path = Sources/Sentry/SentrySpan.m; sourceTree = ""; }; + 5286CE54B4C0709E1A5746B083322665 /* SDMemoryCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDMemoryCache.h; path = SDWebImage/SDMemoryCache.h; sourceTree = ""; }; + 52ED80A99741A76F678B412BF5FC91DA /* SentryCurrentDate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCurrentDate.h; path = Sources/Sentry/include/SentryCurrentDate.h; sourceTree = ""; }; + 539A29AA5C82086D87D861EF794BE53A /* SentryException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryException.h; path = Sources/Sentry/Public/SentryException.h; sourceTree = ""; }; + 5408BDB36266B7615E01E688550651A4 /* SentryOutOfMemoryTracker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryOutOfMemoryTracker.m; path = Sources/Sentry/SentryOutOfMemoryTracker.m; sourceTree = ""; }; + 5413522E2E83F53BB8740D2CFB917577 /* EXPDoubleTuple.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPDoubleTuple.m; path = Expecta/EXPDoubleTuple.m; sourceTree = ""; }; + 54D39586091AD5DC73D4742E3DF9BBEE /* SentryCrashAdapter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashAdapter.m; path = Sources/Sentry/SentryCrashAdapter.m; sourceTree = ""; }; + 557D34A7742B007287FCA4734299A008 /* EXPMatchers+beNil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beNil.h"; path = "Expecta/Matchers/EXPMatchers+beNil.h"; sourceTree = ""; }; + 558CF21D6FBBA3B07A824C9121767409 /* NSObject+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+OCMAdditions.h"; path = "Source/OCMock/NSObject+OCMAdditions.h"; sourceTree = ""; }; + 55DC328A5DFB6F98942A41EA53199E96 /* SDWebImageCacheSerializer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCacheSerializer.h; path = SDWebImage/SDWebImageCacheSerializer.h; sourceTree = ""; }; + 56D5464E1A54D9ADA7C36F10D96C010C /* EKObjectModel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKObjectModel.h; path = Sources/EasyMapping/EKObjectModel.h; sourceTree = ""; }; 56ED198D758A74DB68808B8975C6B6C3 /* libEasyMapping-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libEasyMapping-tvOS.a"; path = "libEasyMapping-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 570A465B0497E83886347A5D4E94102B /* SDWebImageTransition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageTransition.h; path = SDWebImage/SDWebImageTransition.h; sourceTree = ""; }; - 57148ECBF1DD36D149E773F13491AC48 /* NSArray+FlattenArray.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSArray+FlattenArray.m"; path = "Sources/EasyMapping/NSArray+FlattenArray.m"; sourceTree = ""; }; - 5765F80701F6F392447C2ABA53BCD83D /* EXPMatchers+haveCountOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+haveCountOf.h"; path = "Expecta/Matchers/EXPMatchers+haveCountOf.h"; sourceTree = ""; }; - 57EB895450DA2C40A1B05B17486D7202 /* SDWeakProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWeakProxy.h; path = SDWebImage/Private/SDWeakProxy.h; sourceTree = ""; }; - 583B47951CD7CBE1EA97C970D494BBC4 /* EasyMapping-macOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "EasyMapping-macOS-dummy.m"; sourceTree = ""; }; - 58AB2C510FC2C1A8E0B56D19E4967D17 /* SDImageAssetManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAssetManager.h; path = SDWebImage/Private/SDImageAssetManager.h; sourceTree = ""; }; - 5A0CF62073129C73345E453F1671A2E7 /* SDImageAPNGCoderInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAPNGCoderInternal.h; path = SDWebImage/Private/SDImageAPNGCoderInternal.h; sourceTree = ""; }; - 5B4DD3877C768331D8354899F3365C4F /* OCMock.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = OCMock.release.xcconfig; sourceTree = ""; }; - 5B960D4FD6AAA51C641D3555812B4072 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/General/KingfisherManager.swift; sourceTree = ""; }; - 5C141A466F16A0C707E292C28A7A0411 /* EKManagedObjectMapping.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKManagedObjectMapping.m; path = Sources/EasyMapping/EKManagedObjectMapping.m; sourceTree = ""; }; - 5C70B107A43E113F3F1055B97D5C64B2 /* SDImageAPNGCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAPNGCoder.m; path = SDWebImage/SDImageAPNGCoder.m; sourceTree = ""; }; - 5D00809841220351032F8DECD98C2663 /* SDWebImageCompat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCompat.h; path = SDWebImage/SDWebImageCompat.h; sourceTree = ""; }; - 5D24152DABCFDC9F1C6AB214D1B4287E /* AVAssetImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AVAssetImageDataProvider.swift; path = Sources/General/ImageSource/AVAssetImageDataProvider.swift; sourceTree = ""; }; - 5D4483DDBD04DB89E950F27F6C029DE7 /* OCMFunctions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMFunctions.m; path = Source/OCMock/OCMFunctions.m; sourceTree = ""; }; - 5DC2EB0F2557488F898BF21B5847CD85 /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/Cache/ImageCache.swift; sourceTree = ""; }; - 5DEFBD22C13412C0F8792B77A2536966 /* EasyMapping-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "EasyMapping-tvOS.release.xcconfig"; path = "../EasyMapping-tvOS/EasyMapping-tvOS.release.xcconfig"; sourceTree = ""; }; - 6081C8356E7ECFDEDE70DCC46FC0D70B /* OCMBoxedReturnValueProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMBoxedReturnValueProvider.m; path = Source/OCMock/OCMBoxedReturnValueProvider.m; sourceTree = ""; }; - 60C55B52DAF071CD4AE7F1521C437500 /* Pods-BitBotTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-BitBotTests-acknowledgements.markdown"; sourceTree = ""; }; - 61A13E39F8EC94CD85DD2643FE333FD7 /* OCMNotificationPoster.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMNotificationPoster.m; path = Source/OCMock/OCMNotificationPoster.m; sourceTree = ""; }; - 61FCFC3F530E4D72E86BE5E1C3002D95 /* SDWebImageTransition.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageTransition.m; path = SDWebImage/SDWebImageTransition.m; sourceTree = ""; }; - 64B05964124210B349236926810AC127 /* SDWebImageCacheKeyFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCacheKeyFilter.h; path = SDWebImage/SDWebImageCacheKeyFilter.h; sourceTree = ""; }; - 64B36E4A5223DC3E8BA26A6EEB6B2779 /* OCObserverMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCObserverMockObject.m; path = Source/OCMock/OCObserverMockObject.m; sourceTree = ""; }; - 64E775D257ACD72CBD411B058EA94408 /* SDWebImage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImage-prefix.pch"; sourceTree = ""; }; - 6551499803C2FE69FD6CA4FB03E5FEE6 /* OCMConstraint.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMConstraint.h; path = Source/OCMock/OCMConstraint.h; sourceTree = ""; }; - 65C68E58B21D695F281A118140FF2F4E /* MixpanelType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MixpanelType.m; path = Mixpanel/MixpanelType.m; sourceTree = ""; }; - 664A0614E5FE37713C8FCFFC25070016 /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; - 66C80F683A1878C39827AB1A8ADE2339 /* OCMInvocationStub.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMInvocationStub.h; path = Source/OCMock/OCMInvocationStub.h; sourceTree = ""; }; - 674EF19E7E47344921FFEA25FC8EAE0F /* EXPMatchers+equal.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+equal.m"; path = "Expecta/Matchers/EXPMatchers+equal.m"; sourceTree = ""; }; - 67DD828DE7647C11596D9C8075277B0B /* SDInternalMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDInternalMacros.h; path = SDWebImage/Private/SDInternalMacros.h; sourceTree = ""; }; - 68B65178DEB4E187ADC99E5892714533 /* SDWebImageDownloaderRequestModifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderRequestModifier.h; path = SDWebImage/SDWebImageDownloaderRequestModifier.h; sourceTree = ""; }; - 6904639B2FA8645216AE60AAC09C6246 /* EXPFloatTuple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPFloatTuple.h; path = Expecta/EXPFloatTuple.h; sourceTree = ""; }; - 69318348B3B55B4AC7307DBB4F4DAC01 /* SDWebImageIndicator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageIndicator.h; path = SDWebImage/SDWebImageIndicator.h; sourceTree = ""; }; - 697AF15476B4F23A75BDC507ED83ABB5 /* UIImage+MultiFormat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+MultiFormat.m"; path = "SDWebImage/UIImage+MultiFormat.m"; sourceTree = ""; }; - 69FB273327E44E351B5D4832E76556BF /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/Image/ImageTransition.swift; sourceTree = ""; }; - 6A33E007596522D13A845FC4E36F8249 /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/Cache/FormatIndicatedCacheSerializer.swift; sourceTree = ""; }; - 6AD3C6229239FD004ECDF3767CC55B62 /* OCMock-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "OCMock-dummy.m"; sourceTree = ""; }; - 6B20C9C2696FB4B6D8468F8C0CA32447 /* OCMArg.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMArg.h; path = Source/OCMock/OCMArg.h; sourceTree = ""; }; - 6C63BC121FDC54C77FBD9748ACCBC838 /* EXPMatchers+beTruthy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beTruthy.h"; path = "Expecta/Matchers/EXPMatchers+beTruthy.h"; sourceTree = ""; }; - 6CD77A9208BF0386967CD1A399611065 /* ExtensionHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionHelpers.swift; path = Sources/Utility/ExtensionHelpers.swift; sourceTree = ""; }; - 6D2D40E796780AAE41183B9F4680FA66 /* EXPMatchers+contain.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+contain.h"; path = "Expecta/Matchers/EXPMatchers+contain.h"; sourceTree = ""; }; - 6D39C95C6BA2F7ACA778BFE91D762354 /* Kingfisher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Kingfisher.h; path = Sources/Kingfisher.h; sourceTree = ""; }; - 6D5A6014B717BFC26FF621490622E081 /* NSMethodSignature+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSMethodSignature+OCMAdditions.h"; path = "Source/OCMock/NSMethodSignature+OCMAdditions.h"; sourceTree = ""; }; - 6DC77D01AD9862B5693CDB9BCB87267C /* EXPMatchers+beGreaterThanOrEqualTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beGreaterThanOrEqualTo.h"; path = "Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.h"; sourceTree = ""; }; - 6E042C755F61BFCB46472E73B468A7F8 /* EKSerializer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKSerializer.h; path = Sources/EasyMapping/EKSerializer.h; sourceTree = ""; }; - 6EBA2351A93813A05034F31E228E3098 /* SessionMetadata.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SessionMetadata.h; path = Mixpanel/SessionMetadata.h; sourceTree = ""; }; - 6F1DE796615553F706BC5482E0896830 /* Pods-BitriseATV.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-BitriseATV.modulemap"; sourceTree = ""; }; - 6F469FC4B15200F7960D4286CC2DD92D /* EXPFloatTuple.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPFloatTuple.m; path = Expecta/EXPFloatTuple.m; sourceTree = ""; }; - 704865349FC0AA93ABA47EC6250E2567 /* SDAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImage.h; path = SDWebImage/SDAnimatedImage.h; sourceTree = ""; }; - 7049926894FD903D522F31E5CBCA8396 /* EXPMatchers+beInstanceOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beInstanceOf.h"; path = "Expecta/Matchers/EXPMatchers+beInstanceOf.h"; sourceTree = ""; }; - 708030192838B80AB5E0460B6E687194 /* NSButton+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSButton+WebCache.m"; path = "SDWebImage/NSButton+WebCache.m"; sourceTree = ""; }; - 7088AC11AE8AF76D0ACEC401EF65AB5F /* OCMRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMRecorder.m; path = Source/OCMock/OCMRecorder.m; sourceTree = ""; }; - 708DE1D96C6A00BBDCE27C80AA4D2AA3 /* MixpanelType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelType.h; path = Mixpanel/MixpanelType.h; sourceTree = ""; }; - 708F9116E82E223F9775AA96F1EF8AB8 /* EXPMatchers+beGreaterThanOrEqualTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beGreaterThanOrEqualTo.m"; path = "Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.m"; sourceTree = ""; }; - 717A6A925F8110E257AE946485EDA856 /* UIImage+GIF.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+GIF.h"; path = "SDWebImage/UIImage+GIF.h"; sourceTree = ""; }; - 717AAB42E5B837F0CD5E8614F92BE548 /* EXPMatchers+haveCountOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+haveCountOf.m"; path = "Expecta/Matchers/EXPMatchers+haveCountOf.m"; sourceTree = ""; }; - 720EF1ED28AC3B688CE6F3FB9E438EBE /* OCMLocation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMLocation.m; path = Source/OCMock/OCMLocation.m; sourceTree = ""; }; - 7236B3230AD0889A724CF497043F01A6 /* EXPDoubleTuple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPDoubleTuple.h; path = Expecta/EXPDoubleTuple.h; sourceTree = ""; }; - 729E44DF9F35A91C782042717748FC55 /* OCMInvocationMatcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMInvocationMatcher.m; path = Source/OCMock/OCMInvocationMatcher.m; sourceTree = ""; }; - 72B0ED45761C3EADB29E9166055000A4 /* EKManagedObjectMapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKManagedObjectMapper.m; path = Sources/EasyMapping/EKManagedObjectMapper.m; sourceTree = ""; }; - 736FE3B1A3FD3F00512B7171439D130F /* MPFoundation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MPFoundation.h; path = Mixpanel/MPFoundation.h; sourceTree = ""; }; - 73CA4DF78364101A233A47EDD6EEA713 /* EKCoreDataImporter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKCoreDataImporter.h; path = Sources/EasyMapping/EKCoreDataImporter.h; sourceTree = ""; }; - 760EC8BECFAB5CE1F17ABEB898648C77 /* EXPMatchers+beCloseTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beCloseTo.m"; path = "Expecta/Matchers/EXPMatchers+beCloseTo.m"; sourceTree = ""; }; - 76BFB8CE05074AF39CC140752DEB82FE /* EXPMatchers+beNil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beNil.h"; path = "Expecta/Matchers/EXPMatchers+beNil.h"; sourceTree = ""; }; - 77D06687A5169837CF67DDCE96D0602B /* EasyMapping-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "EasyMapping-tvOS.debug.xcconfig"; path = "../EasyMapping-tvOS/EasyMapping-tvOS.debug.xcconfig"; sourceTree = ""; }; - 77F78C8F8B32756794A2F45D9AEABA88 /* Pods-BitBotTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBotTests.debug.xcconfig"; sourceTree = ""; }; - 78045319F740F63C57B362B9AB2A8748 /* NSObject+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+OCMAdditions.m"; path = "Source/OCMock/NSObject+OCMAdditions.m"; sourceTree = ""; }; - 7836184F3B8A75E0D19FAB2308E5024E /* Pods-BitriseATV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitriseATV.release.xcconfig"; sourceTree = ""; }; - 787B08443FD92595FA0DC41A0BC847C3 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/Image/ImageProcessor.swift; sourceTree = ""; }; - 797C915C816B98FD9BD12C5C555F9F81 /* NSButton+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSButton+WebCache.h"; path = "SDWebImage/NSButton+WebCache.h"; sourceTree = ""; }; - 7A37018142E46FB872419EF3966E8ECC /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/Networking/ImageDownloader.swift; sourceTree = ""; }; - 7AD872128EF47421633BDF1B46487FC4 /* Pods-BitBotTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-BitBotTests-dummy.m"; sourceTree = ""; }; - 7B82369BE8E0B9F11564DBC9E55086EC /* ExpectaSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ExpectaSupport.m; path = Expecta/ExpectaSupport.m; sourceTree = ""; }; - 7CB305224A079CA6B534CB5DA4136DC6 /* SDAnimatedImageRep.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageRep.m; path = SDWebImage/SDAnimatedImageRep.m; sourceTree = ""; }; - 7D2247CF28BF90D35DD24088EB9F8425 /* SDImageLoadersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageLoadersManager.m; path = SDWebImage/SDImageLoadersManager.m; sourceTree = ""; }; - 7D2C6CCA336F42607F337E1EFA0006F8 /* ImageDownloaderDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloaderDelegate.swift; path = Sources/Networking/ImageDownloaderDelegate.swift; sourceTree = ""; }; - 7D3DE9686C65C2AA5CCCAED5C15AB8CD /* SDImageGIFCoderInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGIFCoderInternal.h; path = SDWebImage/Private/SDImageGIFCoderInternal.h; sourceTree = ""; }; - 7D7624BD7181C0A641F064CB8136FF73 /* EXPDoubleTuple.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPDoubleTuple.m; path = Expecta/EXPDoubleTuple.m; sourceTree = ""; }; - 7E0252387946370A3D69E36D50D29E59 /* EasyMapping-tvOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EasyMapping-tvOS-prefix.pch"; path = "../EasyMapping-tvOS/EasyMapping-tvOS-prefix.pch"; sourceTree = ""; }; - 7F31796752F8CF5D9D0D58B025055067 /* EXPMatchers+beKindOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beKindOf.m"; path = "Expecta/Matchers/EXPMatchers+beKindOf.m"; sourceTree = ""; }; - 7F86E9C0BC3ADA6A7A59A633361DA940 /* Expecta-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Expecta-dummy.m"; sourceTree = ""; }; - 8205653621A0B670E7F3FDF4C5C36A58 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Image/Filter.swift; sourceTree = ""; }; - 827735D4D43CE0DDCD15D60859120C75 /* SDImageLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageLoader.m; path = SDWebImage/SDImageLoader.m; sourceTree = ""; }; - 8341906BAF78F592CBBECCA1690241F6 /* MixpanelGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MixpanelGroup.m; path = Mixpanel/MixpanelGroup.m; sourceTree = ""; }; - 83490DAFF67A0197CFB5F511B3FE126F /* EKObjectMapping.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKObjectMapping.m; path = Sources/EasyMapping/EKObjectMapping.m; sourceTree = ""; }; - 8398C38511B633C2B4E5C963995956D8 /* EasyMapping-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "EasyMapping-macOS.debug.xcconfig"; sourceTree = ""; }; - 841BB69169E16B75648566DC54E4D405 /* EXPDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPDefines.h; path = Expecta/EXPDefines.h; sourceTree = ""; }; - 855230599E967A05447F178A3D557046 /* EasyMapping-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "EasyMapping-macOS.release.xcconfig"; sourceTree = ""; }; - 85ECDF65524CC0F3870C9F005C733141 /* NSObject+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+OCMAdditions.h"; path = "Source/OCMock/NSObject+OCMAdditions.h"; sourceTree = ""; }; - 86BD8B43E38AFBC6B15B04EA3903A324 /* SDInternalMacros.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDInternalMacros.m; path = SDWebImage/Private/SDInternalMacros.m; sourceTree = ""; }; - 8734B79633EB68199F968AD242A66EC8 /* Pods-BitriseATV-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-BitriseATV-umbrella.h"; sourceTree = ""; }; - 8787EAF8E690F3E1FBAE6C743D84431F /* Mixpanel-macOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Mixpanel-macOS-prefix.pch"; sourceTree = ""; }; - 88B972C3230D9A90FF61B58C59DF04F5 /* SDImageCachesManagerOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCachesManagerOperation.m; path = SDWebImage/Private/SDImageCachesManagerOperation.m; sourceTree = ""; }; - 890A2F3CF1A55C6200A25E16CE6BAB19 /* UIImage+Transform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Transform.m"; path = "SDWebImage/UIImage+Transform.m"; sourceTree = ""; }; - 8959A8DF80C3F2AD13A28DF2D9F0AFAA /* SDWebImageCompat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCompat.m; path = SDWebImage/SDWebImageCompat.m; sourceTree = ""; }; - 89777E5F7D16F4D26949703CC7890AFB /* EXPMatchers+beCloseTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beCloseTo.h"; path = "Expecta/Matchers/EXPMatchers+beCloseTo.h"; sourceTree = ""; }; - 8A05896299BDD20F8E0B2FBC121EDD15 /* EXPMatchers+contain.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+contain.m"; path = "Expecta/Matchers/EXPMatchers+contain.m"; sourceTree = ""; }; - 8A0BBFFD2EA27DA6B09E2875385A2052 /* NSValue+Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSValue+Expecta.h"; path = "Expecta/NSValue+Expecta.h"; sourceTree = ""; }; - 8A2370785CF931AAD343E57522428185 /* SDImageCachesManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCachesManager.h; path = SDWebImage/SDImageCachesManager.h; sourceTree = ""; }; - 8B05FBC154203BB747B882B6E725E759 /* SDWebImagePrefetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImagePrefetcher.m; path = SDWebImage/SDWebImagePrefetcher.m; sourceTree = ""; }; - 8BE56A866D956C48B3A07A077AA30E6F /* SDImageLoadersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageLoadersManager.h; path = SDWebImage/SDImageLoadersManager.h; sourceTree = ""; }; - 8C299D6117A127858E519895CF940442 /* SDWebImageDownloaderOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderOperation.m; path = SDWebImage/SDWebImageDownloaderOperation.m; sourceTree = ""; }; - 8C6D94943ABA018F8FE56BDBE9FC1191 /* ImageBinder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageBinder.swift; path = Sources/SwiftUI/ImageBinder.swift; sourceTree = ""; }; - 8CF995B7342B40A45E27459B69A702C2 /* EKManagedObjectModel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKManagedObjectModel.h; path = Sources/EasyMapping/EKManagedObjectModel.h; sourceTree = ""; }; - 8D6A91E801016258D4C031AE91650396 /* EKMappingProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKMappingProtocol.h; path = Sources/EasyMapping/EKMappingProtocol.h; sourceTree = ""; }; - 8FF9B9E3CA15D993513213755D00B89B /* SizeExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SizeExtensions.swift; path = Sources/Utility/SizeExtensions.swift; sourceTree = ""; }; - 90D9077EE66C60A9B04C97F6FDD53C0C /* EXPMatchers+raise.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+raise.m"; path = "Expecta/Matchers/EXPMatchers+raise.m"; sourceTree = ""; }; - 91298D8445BED58F32A59F0D7442D7D1 /* Expecta-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Expecta-prefix.pch"; sourceTree = ""; }; - 913EBD22558950862D0830EE189B272F /* UIImage+ForceDecode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+ForceDecode.h"; path = "SDWebImage/UIImage+ForceDecode.h"; sourceTree = ""; }; - 914886C9DE73B54DB69A91E71C457CCF /* NSData+ImageContentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+ImageContentType.m"; path = "SDWebImage/NSData+ImageContentType.m"; sourceTree = ""; }; - 92C2004006AECCC51DCE4B55AD73B019 /* EKPropertyMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKPropertyMapping.h; path = Sources/EasyMapping/EKPropertyMapping.h; sourceTree = ""; }; - 9319667CC0041FDC3FC13F7C93E6E462 /* NSPopover+MISSINGBackgroundView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSPopover+MISSINGBackgroundView-prefix.pch"; sourceTree = ""; }; - 9446B364CFDB08ADB0802CC3DFCB3D16 /* OCMObserverRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMObserverRecorder.m; path = Source/OCMock/OCMObserverRecorder.m; sourceTree = ""; }; - 94DCC4C3FF9A74FFBEEB2AD03F66E76B /* OCMIndirectReturnValueProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMIndirectReturnValueProvider.h; path = Source/OCMock/OCMIndirectReturnValueProvider.h; sourceTree = ""; }; - 95563B1EA47DD86FC4817BE8339B6101 /* SDAnimatedImageRep.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImageRep.h; path = SDWebImage/SDAnimatedImageRep.h; sourceTree = ""; }; - 955CBA37DD5C01B043411285DB126CB0 /* EXPMatchers+endWith.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+endWith.m"; path = "Expecta/Matchers/EXPMatchers+endWith.m"; sourceTree = ""; }; - 95DD4922510FE102A4125D8B906D4721 /* UIImage+GIF.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+GIF.m"; path = "SDWebImage/UIImage+GIF.m"; sourceTree = ""; }; - 963F1099A35439CB4AC27D2E19814B39 /* OCObserverMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCObserverMockObject.h; path = Source/OCMock/OCObserverMockObject.h; sourceTree = ""; }; - 96C752DC496BB2334FBC711B6DDD2A5A /* OCMBlockCaller.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMBlockCaller.h; path = Source/OCMock/OCMBlockCaller.h; sourceTree = ""; }; - 97ABC7DE2E6E7D85D21D2C42E767EDC4 /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; - 97D86A9D76DC8AE9454534808B623C55 /* SDWebImageCacheSerializer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCacheSerializer.m; path = SDWebImage/SDWebImageCacheSerializer.m; sourceTree = ""; }; - 98F64D946D0D5EAA81CC1B0F9D334199 /* OCPartialMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCPartialMockObject.m; path = Source/OCMock/OCPartialMockObject.m; sourceTree = ""; }; - 992D60F0497E6F51CEAB91FF2C9FE24F /* ImageFormat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageFormat.swift; path = Sources/Image/ImageFormat.swift; sourceTree = ""; }; - 99D75CBB7C8193D992BF15A7EBAA9F4D /* SDWebImageCacheKeyFilter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCacheKeyFilter.m; path = SDWebImage/SDWebImageCacheKeyFilter.m; sourceTree = ""; }; - 99FFE72BA41D124C3E66032BEA09225D /* EXPMatchers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatchers.h; path = Expecta/Matchers/EXPMatchers.h; sourceTree = ""; }; - 9B0855654A0B2D8977CEEC37544E90A9 /* EXPMatchers+respondTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+respondTo.m"; path = "Expecta/Matchers/EXPMatchers+respondTo.m"; sourceTree = ""; }; - 9B71A33DA344B8FA3913B5CA3B8538FE /* EasyMapping-macOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "EasyMapping-macOS-prefix.pch"; sourceTree = ""; }; - 9BD2815D50FF77D25D8698E01B52BFC3 /* Kingfisher.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.release.xcconfig; sourceTree = ""; }; - 9C5FEDDA3B696F572A41CCB38C8E8A8B /* OCMBlockArgCaller.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMBlockArgCaller.h; path = Source/OCMock/OCMBlockArgCaller.h; sourceTree = ""; }; - 9D08CFD0ACE4C85B21B2BFE8F037E58E /* SDImageAssetManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAssetManager.m; path = SDWebImage/Private/SDImageAssetManager.m; sourceTree = ""; }; + 571073AB176AFE9D5425295A0BEB0C02 /* SDImageLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageLoader.h; path = SDWebImage/SDImageLoader.h; sourceTree = ""; }; + 5724B0A9796694E79E16B52BE58B5C79 /* SentryAsynchronousOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryAsynchronousOperation.h; path = Sources/Sentry/include/SentryAsynchronousOperation.h; sourceTree = ""; }; + 58390617A0187652449D42C311506573 /* SentryHttpTransport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryHttpTransport.h; path = Sources/Sentry/include/SentryHttpTransport.h; sourceTree = ""; }; + 58976039A170F01993918E5B37032F00 /* SentrySampleDecision.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySampleDecision.h; path = Sources/Sentry/Public/SentrySampleDecision.h; sourceTree = ""; }; + 59325D1A1541A07E74163513B6C7AF55 /* SDImageGIFCoderInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGIFCoderInternal.h; path = SDWebImage/Private/SDImageGIFCoderInternal.h; sourceTree = ""; }; + 599951F618E605ABAD714564410AC8E3 /* EasyMapping-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "EasyMapping-tvOS.release.xcconfig"; path = "../EasyMapping-tvOS/EasyMapping-tvOS.release.xcconfig"; sourceTree = ""; }; + 59E5B9EB4F70C9724CEC101658BE9A22 /* SentrySamplingContext.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySamplingContext.m; path = Sources/Sentry/SentrySamplingContext.m; sourceTree = ""; }; + 5A1A3F63E2060CABB0E5098F6A5ED0E8 /* EasyMapping-macOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "EasyMapping-macOS-dummy.m"; sourceTree = ""; }; + 5A861715DA3C27C1CEC0B5149E88DE65 /* EXPMatchers+beKindOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beKindOf.m"; path = "Expecta/Matchers/EXPMatchers+beKindOf.m"; sourceTree = ""; }; + 5B3ABCB4EFCA6459E64585F4A9691AE1 /* EXPMatchers+beginWith.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beginWith.h"; path = "Expecta/Matchers/EXPMatchers+beginWith.h"; sourceTree = ""; }; + 5C32FAAC06813A2BAB1ED4111D5695E4 /* SDWebImageDownloaderConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderConfig.h; path = SDWebImage/SDWebImageDownloaderConfig.h; sourceTree = ""; }; + 5C42085705C144EED1AC95F520556B2D /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Image/Filter.swift; sourceTree = ""; }; + 5D15A2DBE72CBB3651486C29CE7CFA7C /* NSNotificationCenter+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSNotificationCenter+OCMAdditions.h"; path = "Source/OCMock/NSNotificationCenter+OCMAdditions.h"; sourceTree = ""; }; + 5D480BEB3C3B1A576E713DB1B6413CD2 /* SentryHttpTransport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryHttpTransport.m; path = Sources/Sentry/SentryHttpTransport.m; sourceTree = ""; }; + 5D7893BCF8FC30708A78AA396189D1B3 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/Image/ImageProcessor.swift; sourceTree = ""; }; + 5DA0F2519E0F70EF0D35210ADB5F9D21 /* SentryCrashLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashLogger.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashLogger.h; sourceTree = ""; }; + 5E08B03BCD7615E02B7D315BB800CD90 /* ImageFormat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageFormat.swift; path = Sources/Image/ImageFormat.swift; sourceTree = ""; }; + 5E0CA3D813A44762422977B90EA44465 /* OCMInvocationExpectation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMInvocationExpectation.m; path = Source/OCMock/OCMInvocationExpectation.m; sourceTree = ""; }; + 5E10825BF1E02BA77AD12B4EFCB737B7 /* SentryCrashSignalInfo.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashSignalInfo.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.c; sourceTree = ""; }; + 5E586A05DDB15DCAAD49489B0632C0DA /* OCClassMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCClassMockObject.h; path = Source/OCMock/OCClassMockObject.h; sourceTree = ""; }; + 5EBC1AF6E820A7A363E11B50E41E5DA1 /* SentryInstallation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryInstallation.m; path = Sources/Sentry/SentryInstallation.m; sourceTree = ""; }; + 5F0F3D31B52CB059E34ADCD8A40B4082 /* SentryCrashIntegration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashIntegration.h; path = Sources/Sentry/include/SentryCrashIntegration.h; sourceTree = ""; }; + 5F8FC0B52735277BF7A7F2DBB43DBB93 /* SentrySpanId.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySpanId.m; path = Sources/Sentry/SentrySpanId.m; sourceTree = ""; }; + 6028B0CECC6A8136E220A86E8C686B05 /* SentryCurrentDate.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCurrentDate.m; path = Sources/Sentry/SentryCurrentDate.m; sourceTree = ""; }; + 60FA170C048C44881C44223DA22C1A34 /* SentryLogOutput.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryLogOutput.m; path = Sources/Sentry/SentryLogOutput.m; sourceTree = ""; }; + 6139A0A10B75059FF153ECA3DE15D1AB /* OCPartialMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCPartialMockObject.h; path = Source/OCMock/OCPartialMockObject.h; sourceTree = ""; }; + 618DA7F1FC6944A9A00D902E64D718B7 /* Pods-BitBotATV.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-BitBotATV.modulemap"; sourceTree = ""; }; + 61B13957C17E507A36360EEC6762EEB2 /* SentryUserFeedback.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryUserFeedback.h; path = Sources/Sentry/Public/SentryUserFeedback.h; sourceTree = ""; }; + 62754719072EA7728FFA28F8BA5B8676 /* libSentry-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libSentry-macOS.a"; path = "libSentry-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 639B0100D981E73C7785C98B61DB4A2C /* SDImageCodersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCodersManager.m; path = SDWebImage/SDImageCodersManager.m; sourceTree = ""; }; + 639DB5F3F4526DD4E2091E18B340C3C6 /* EXPUnsupportedObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPUnsupportedObject.h; path = Expecta/EXPUnsupportedObject.h; sourceTree = ""; }; + 643054DB8DBCF6B6727687DF0F36411F /* SentryFileContents.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryFileContents.h; path = Sources/Sentry/include/SentryFileContents.h; sourceTree = ""; }; + 656179F2734A46FE73D7EAFE5EF0DD3D /* SDWebImage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SDWebImage-dummy.m"; sourceTree = ""; }; + 656E06E6545A067AF16918EE5E3123DD /* NSValue+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSValue+OCMAdditions.m"; path = "Source/OCMock/NSValue+OCMAdditions.m"; sourceTree = ""; }; + 65A8A898D3B71BB42B900D8CAEF6FB3A /* SentryIntegrationProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryIntegrationProtocol.h; path = Sources/Sentry/Public/SentryIntegrationProtocol.h; sourceTree = ""; }; + 668302F463985196E28640C57429DA13 /* SDImageCachesManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCachesManager.h; path = SDWebImage/SDImageCachesManager.h; sourceTree = ""; }; + 668A94876717C5D861AE21C2D9206219 /* SentryCrashMachineContextWrapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMachineContextWrapper.h; path = Sources/Sentry/include/SentryCrashMachineContextWrapper.h; sourceTree = ""; }; + 66C034548AF4F3B544F25A2A0632AAFF /* OCMVerifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMVerifier.h; path = Source/OCMock/OCMVerifier.h; sourceTree = ""; }; + 66ECB3B7DF926F46DB3E2A027346DEC9 /* ImageBinder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageBinder.swift; path = Sources/SwiftUI/ImageBinder.swift; sourceTree = ""; }; + 6710CF323F6003446FA076D00037B1B7 /* MixpanelGroupPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelGroupPrivate.h; path = Mixpanel/MixpanelGroupPrivate.h; sourceTree = ""; }; + 6752AE45A10AE01FB384A64DA9F7E3A4 /* SentryOutOfMemoryLogic.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryOutOfMemoryLogic.m; path = Sources/Sentry/SentryOutOfMemoryLogic.m; sourceTree = ""; }; + 6792D215AB742EF73C6E5D637C93536C /* SentryHook.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryHook.h; path = Sources/SentryCrash/Recording/Tools/SentryHook.h; sourceTree = ""; }; + 67C4AF11F6139DA148872B8D9BAE44BC /* SentryCrashDefaultMachineContextWrapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashDefaultMachineContextWrapper.h; path = Sources/Sentry/include/SentryCrashDefaultMachineContextWrapper.h; sourceTree = ""; }; + 6885FD677F329175EFEA133271225111 /* SentryThreadInspector.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryThreadInspector.m; path = Sources/Sentry/SentryThreadInspector.m; sourceTree = ""; }; + 69132E45666D517B599B0E045DE67502 /* OCMBlockArgCaller.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMBlockArgCaller.m; path = Source/OCMock/OCMBlockArgCaller.m; sourceTree = ""; }; + 697E0B998BB4B99DC155F08BE3EFCC6C /* EXPMatchers+raiseWithReason.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+raiseWithReason.m"; path = "Expecta/Matchers/EXPMatchers+raiseWithReason.m"; sourceTree = ""; }; + 69D2E3393AB08042B490CCC899D7E965 /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/Cache/FormatIndicatedCacheSerializer.swift; sourceTree = ""; }; + 6A1732A4F71AA53446C68DDCB89BC9A1 /* SentryCrashDebug.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashDebug.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashDebug.h; sourceTree = ""; }; + 6AA0F981BE89DFC51FBDA98DD87025D9 /* NSData+ImageContentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+ImageContentType.m"; path = "SDWebImage/NSData+ImageContentType.m"; sourceTree = ""; }; + 6B2A47368F861EA82DD76288F964703F /* SDAnimatedImageView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImageView.h; path = SDWebImage/SDAnimatedImageView.h; sourceTree = ""; }; + 6BCD39F27356B900115C3AB0529AFDD5 /* NSImage+Compatibility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSImage+Compatibility.m"; path = "SDWebImage/NSImage+Compatibility.m"; sourceTree = ""; }; + 6C76FF267314E0DA402A592F00DDAE6D /* UIImage+MemoryCacheCost.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+MemoryCacheCost.h"; path = "SDWebImage/UIImage+MemoryCacheCost.h"; sourceTree = ""; }; + 6D2F0B54A0E96CE375161189B18840A5 /* SDWeakProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWeakProxy.h; path = SDWebImage/Private/SDWeakProxy.h; sourceTree = ""; }; + 6D36DF8121B4044216DF887F9A7EA8BD /* Pods-BitBot-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-BitBot-acknowledgements.plist"; sourceTree = ""; }; + 6D87B40410B52B9EF1864370A90442B8 /* EXPMatchers+beInTheRangeOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beInTheRangeOf.h"; path = "Expecta/Matchers/EXPMatchers+beInTheRangeOf.h"; sourceTree = ""; }; + 6DE263CCD7DE182693CA38B30F831375 /* NSArray+FlattenArray.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSArray+FlattenArray.m"; path = "Sources/EasyMapping/NSArray+FlattenArray.m"; sourceTree = ""; }; + 6E3B8940A8DA7525FD7DD22402B5A63D /* SentryCrashMonitor_Deadlock.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashMonitor_Deadlock.m; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.m; sourceTree = ""; }; + 6F0FFBDBC22ED035FD2A99177FA77B13 /* SentryCrashMachineContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMachineContext.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h; sourceTree = ""; }; + 6F26D1CBB432719C60FC75BFF2DD1E67 /* OCMFunctionsPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMFunctionsPrivate.h; path = Source/OCMock/OCMFunctionsPrivate.h; sourceTree = ""; }; + 6FB17A41E13C12B1D2AA71FAF3E004C2 /* MixpanelExceptionHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MixpanelExceptionHandler.m; path = Mixpanel/MixpanelExceptionHandler.m; sourceTree = ""; }; + 6FC7A323C502BBC6AEDE47DEC7EC501D /* CallbackQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallbackQueue.swift; path = Sources/Utility/CallbackQueue.swift; sourceTree = ""; }; + 6FD6179D6616CC83F0EBC88FEB40E3F2 /* NSPopover+MISSINGBackgroundView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "NSPopover+MISSINGBackgroundView-dummy.m"; sourceTree = ""; }; + 70122D147B4CFCF6BD5F06A6D048B8EB /* EXPMatchers+conformTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+conformTo.m"; path = "Expecta/Matchers/EXPMatchers+conformTo.m"; sourceTree = ""; }; + 702074EA12749CFCFBDF2CDA24573ED5 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/General/KingfisherManager.swift; sourceTree = ""; }; + 705CC9DAC8C56CAB1394F921EF7B3595 /* Kingfisher.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.release.xcconfig; sourceTree = ""; }; + 7069DDCC3D9FD25F2944D0A9C7BD3812 /* SDWeakProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWeakProxy.m; path = SDWebImage/Private/SDWeakProxy.m; sourceTree = ""; }; + 707760BF81A4C4F1570470CC648600BC /* SentryStacktrace.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryStacktrace.h; path = Sources/Sentry/Public/SentryStacktrace.h; sourceTree = ""; }; + 7078F92F031EADAB7617667F38967D79 /* UIImage+MultiFormat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+MultiFormat.h"; path = "SDWebImage/UIImage+MultiFormat.h"; sourceTree = ""; }; + 707B03E715E22776FCC31962771A7E2D /* SentryCrashInstallation+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SentryCrashInstallation+Private.h"; path = "Sources/SentryCrash/Installations/SentryCrashInstallation+Private.h"; sourceTree = ""; }; + 70B4ECF8EB965BEFCBC17F7120D404FA /* Pods-BitBotATV.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBotATV.debug.xcconfig"; sourceTree = ""; }; + 71699EDEB34DA036C4C91F1111D82BC0 /* SentryCrashThread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashThread.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashThread.h; sourceTree = ""; }; + 71D17FB9AD23896A66494244B436948B /* EXPMatchers+postNotification.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+postNotification.m"; path = "Expecta/Matchers/EXPMatchers+postNotification.m"; sourceTree = ""; }; + 72683F357F02D5EDA048DC6F23D4092D /* SentrySDK.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySDK.h; path = Sources/Sentry/Public/SentrySDK.h; sourceTree = ""; }; + 729F7AFE262AF22B1D2157AE03081029 /* SentryBreadcrumbTracker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryBreadcrumbTracker.h; path = Sources/Sentry/include/SentryBreadcrumbTracker.h; sourceTree = ""; }; + 72E56A84AF11E5CA2CC24F859B6B60B1 /* Source.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Source.swift; path = Sources/General/ImageSource/Source.swift; sourceTree = ""; }; + 733EB9949216F382705773FC086855B6 /* SentryCrashSystemCapabilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashSystemCapabilities.h; path = Sources/SentryCrash/Recording/SentryCrashSystemCapabilities.h; sourceTree = ""; }; + 73EAEF93218258282F3A5E40521101B2 /* SDAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImage.m; path = SDWebImage/SDAnimatedImage.m; sourceTree = ""; }; + 73EFA1A2808B11E38E10524558CCC4BA /* EXPMatchers+beginWith.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beginWith.m"; path = "Expecta/Matchers/EXPMatchers+beginWith.m"; sourceTree = ""; }; + 73FBF880D819F3A37A47DF758F95393E /* SentryCrashCachedData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashCachedData.h; path = Sources/SentryCrash/Recording/SentryCrashCachedData.h; sourceTree = ""; }; + 74410FD9A799F3F268BFA760FFFE0B0F /* SentryCrashSignalInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashSignalInfo.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.h; sourceTree = ""; }; + 745E8932DD0AB64C1A0DB120B425D892 /* SentryTracer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryTracer.h; path = Sources/Sentry/include/SentryTracer.h; sourceTree = ""; }; + 74966EDE9BC6FA94BEC3BE0444039F20 /* EasyMapping-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "EasyMapping-macOS.release.xcconfig"; sourceTree = ""; }; + 7533734215B52194CC28854B3989C0B9 /* SDAnimatedImageView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "SDAnimatedImageView+WebCache.m"; path = "SDWebImage/SDAnimatedImageView+WebCache.m"; sourceTree = ""; }; + 7692F573D1E2DC63616021DF3412CD78 /* AuthenticationChallengeResponsable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationChallengeResponsable.swift; path = Sources/Networking/AuthenticationChallengeResponsable.swift; sourceTree = ""; }; + 76C875F37828366270A19D86E3E42D6C /* OCMArgAction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMArgAction.h; path = Source/OCMock/OCMArgAction.h; sourceTree = ""; }; + 76CD924DD05728AB3BF84E8D93885369 /* SentryCrashCPU_x86_32.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashCPU_x86_32.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashCPU_x86_32.c; sourceTree = ""; }; + 76D9E7F762492B8E9172AB546A66189B /* NSDictionary+SentrySanitize.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+SentrySanitize.h"; path = "Sources/Sentry/include/NSDictionary+SentrySanitize.h"; sourceTree = ""; }; + 77037A26EFAA75844B4E6E8757662060 /* SentryQueueableRequestManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryQueueableRequestManager.h; path = Sources/Sentry/include/SentryQueueableRequestManager.h; sourceTree = ""; }; + 77E6411FB561EA85553780EA72EC7EDB /* SentryCrashMemory.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMemory.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashMemory.h; sourceTree = ""; }; + 7868BA38D167639FC1B3A1A064F98CAA /* UIImage+MultiFormat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+MultiFormat.m"; path = "SDWebImage/UIImage+MultiFormat.m"; sourceTree = ""; }; + 78926F9F16D6B661CB5C56915AB11082 /* NSTextAttachment+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextAttachment+Kingfisher.swift"; path = "Sources/Extensions/NSTextAttachment+Kingfisher.swift"; sourceTree = ""; }; + 7899C1894601F14A332E8A700E2B043C /* NSDictionary+SentrySanitize.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+SentrySanitize.m"; path = "Sources/Sentry/NSDictionary+SentrySanitize.m"; sourceTree = ""; }; + 78AFD32C679BA0512CD29B01C52FD8E0 /* SentrySpanProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySpanProtocol.h; path = Sources/Sentry/Public/SentrySpanProtocol.h; sourceTree = ""; }; + 794F16D3AAB9F5CF04D4FDAB7BC7EC48 /* SentryCrashMemory.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMemory.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashMemory.c; sourceTree = ""; }; + 79AD15A04248C56802F9B6C75D3019A1 /* Delegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delegate.swift; path = Sources/Utility/Delegate.swift; sourceTree = ""; }; + 7A08B9374BA62246F90A56F8B705B234 /* SentryCrashExceptionApplication.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashExceptionApplication.m; path = Sources/Sentry/SentryCrashExceptionApplication.m; sourceTree = ""; }; + 7A3C3A0A972837655DFEB8EFE38B16C9 /* SDWebImage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImage-prefix.pch"; sourceTree = ""; }; + 7A49E743371CDA3384FFE238BF4B61D3 /* EXPMatchers+beCloseTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beCloseTo.h"; path = "Expecta/Matchers/EXPMatchers+beCloseTo.h"; sourceTree = ""; }; + 7A65932F3946AFE7DE35B76CF74D0911 /* SentryError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryError.m; path = Sources/Sentry/SentryError.m; sourceTree = ""; }; + 7B4ACCDC92441FA388B90ED4B3F3E349 /* SDWebImageDownloaderRequestModifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderRequestModifier.h; path = SDWebImage/SDWebImageDownloaderRequestModifier.h; sourceTree = ""; }; + 7B651AA679368297876836D632672329 /* MixpanelExceptionHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelExceptionHandler.h; path = Mixpanel/MixpanelExceptionHandler.h; sourceTree = ""; }; + 7C1E4494082CC0E21EBD915E0B5B25F8 /* SDWebImageDownloaderConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderConfig.m; path = SDWebImage/SDWebImageDownloaderConfig.m; sourceTree = ""; }; + 7C35F9CE61D977267F2235041B820E03 /* SentryLog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryLog.h; path = Sources/Sentry/include/SentryLog.h; sourceTree = ""; }; + 7C4A9EB2EB2E18572F51BBB3635C4566 /* SDWebImagePrefetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImagePrefetcher.h; path = SDWebImage/SDWebImagePrefetcher.h; sourceTree = ""; }; + 7DDB6D70780CEE79091CB18DC8FFCA26 /* SentryCrashStackCursor_MachineContext.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashStackCursor_MachineContext.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.c; sourceTree = ""; }; + 7ECE59D4410E525D049CBF05D59E2720 /* SDInternalMacros.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDInternalMacros.m; path = SDWebImage/Private/SDInternalMacros.m; sourceTree = ""; }; + 7FB28F864B2530B901ECC2199761359A /* Mixpanel-tvOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "Mixpanel-tvOS-dummy.m"; path = "../Mixpanel-tvOS/Mixpanel-tvOS-dummy.m"; sourceTree = ""; }; + 7FC8E6210696D094872766EB0C6A7733 /* EXPMatchers+respondTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+respondTo.m"; path = "Expecta/Matchers/EXPMatchers+respondTo.m"; sourceTree = ""; }; + 7FD7012E4F272E888FCB789C2A861DD6 /* SentryAsynchronousOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryAsynchronousOperation.m; path = Sources/Sentry/SentryAsynchronousOperation.m; sourceTree = ""; }; + 8085360E3336A58D8C1F511F7DBE7D78 /* OCMExpectationRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMExpectationRecorder.h; path = Source/OCMock/OCMExpectationRecorder.h; sourceTree = ""; }; + 80F38BDE157D18A99DE165F15628E9D8 /* EKSerializer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKSerializer.h; path = Sources/EasyMapping/EKSerializer.h; sourceTree = ""; }; + 8118BBD07F06D9B65E67B6C0CAA7BAD5 /* SentryCrashMonitor_Zombie.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMonitor_Zombie.c; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c; sourceTree = ""; }; + 82CABB27D18CEA8BFA0E6F9422B6FA84 /* UIImageView+HighlightedWebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+HighlightedWebCache.m"; path = "SDWebImage/UIImageView+HighlightedWebCache.m"; sourceTree = ""; }; + 8323FE2B3DEDEFC6B6B60BBBEA74D18E /* UIImage+MemoryCacheCost.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+MemoryCacheCost.m"; path = "SDWebImage/UIImage+MemoryCacheCost.m"; sourceTree = ""; }; + 83B0A87BB96EDBECBD9BCB1443F6108A /* Sentry-macOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Sentry-macOS-prefix.pch"; sourceTree = ""; }; + 83C261258984F7E4A236711D1EA29A49 /* SentryHook.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryHook.c; path = Sources/SentryCrash/Recording/Tools/SentryHook.c; sourceTree = ""; }; + 84148C4BBC5639650E918B7D1AE9FCA8 /* SentryEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryEvent.h; path = Sources/Sentry/Public/SentryEvent.h; sourceTree = ""; }; + 8466E48F03D70CA17AC83C7B881AE446 /* SentryCrashDoctor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashDoctor.h; path = Sources/SentryCrash/Recording/SentryCrashDoctor.h; sourceTree = ""; }; + 846A6C09F2ABC29168D385CAA2D58969 /* SDWebImageError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageError.m; path = SDWebImage/SDWebImageError.m; sourceTree = ""; }; + 8473F3DC171840EAC0BDA09D6FA0E4A0 /* SentryCrashObjC.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashObjC.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashObjC.c; sourceTree = ""; }; + 8522E68E0FED7627A746EDFD9DDD0700 /* SentryCrashString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashString.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashString.h; sourceTree = ""; }; + 85CEE7611CA747051932DE9C7ADA24E4 /* UIColor+HexString.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIColor+HexString.m"; path = "SDWebImage/Private/UIColor+HexString.m"; sourceTree = ""; }; + 861E4C71E1A5734D8A890EC87DDBB518 /* UIView+WebCacheOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+WebCacheOperation.h"; path = "SDWebImage/UIView+WebCacheOperation.h"; sourceTree = ""; }; + 864951E1419140446120DB8592F5D890 /* SentryCrashMach.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMach.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashMach.c; sourceTree = ""; }; + 86690CFE527A596F3B6AA8038D199EA2 /* SDAnimatedImageRep.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageRep.m; path = SDWebImage/SDAnimatedImageRep.m; sourceTree = ""; }; + 87B8D862925C1E3D10970596A63C2CEC /* SentryCrashInstallationReporter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashInstallationReporter.h; path = Sources/Sentry/include/SentryCrashInstallationReporter.h; sourceTree = ""; }; + 87CD89D239B8AD49C9E6A7B041C940CC /* SentryCrashBinaryImageProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashBinaryImageProvider.h; path = Sources/Sentry/include/SentryCrashBinaryImageProvider.h; sourceTree = ""; }; + 88368478BD964F0C78E7C27C1D7E9A38 /* UIImage+GIF.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+GIF.m"; path = "SDWebImage/UIImage+GIF.m"; sourceTree = ""; }; + 88DBEA1A6DF2FC4DE59CCC2CAE2B4235 /* SentryOutOfMemoryTrackingIntegration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryOutOfMemoryTrackingIntegration.h; path = Sources/Sentry/include/SentryOutOfMemoryTrackingIntegration.h; sourceTree = ""; }; + 88F98F21A3A4AF3F01F89B2CF4C1CA0A /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; + 893F74730AB7653048453181D4060B4E /* SentrySerialization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySerialization.h; path = Sources/Sentry/include/SentrySerialization.h; sourceTree = ""; }; + 89AF6C11A3C19706E7C785D56D93D67C /* KingfisherError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherError.swift; path = Sources/General/KingfisherError.swift; sourceTree = ""; }; + 89B11BFCB1A668E910E7D78C6959D8B2 /* SentryThread.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryThread.m; path = Sources/Sentry/SentryThread.m; sourceTree = ""; }; + 8A825AE1B597340584246AA8758C978F /* SentryCrashMonitor_MachException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_MachException.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.h; sourceTree = ""; }; + 8AABDDA011743888BE5370D828CE8324 /* SentryTracer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryTracer.m; path = Sources/Sentry/SentryTracer.m; sourceTree = ""; }; + 8AC2EE6A36100366A5ACE15D447ED6CB /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/General/ImageSource/Resource.swift; sourceTree = ""; }; + 8AD8082B1558E9CD4FE81D97AA7EFBB9 /* MixpanelPeoplePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelPeoplePrivate.h; path = Mixpanel/MixpanelPeoplePrivate.h; sourceTree = ""; }; + 8AF45A5DF93EB934D1C9A9A778501710 /* SDWebImageDownloaderRequestModifier.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderRequestModifier.m; path = SDWebImage/SDWebImageDownloaderRequestModifier.m; sourceTree = ""; }; + 8AF6BB3EE258D3AC2AA0C205519F518D /* SentryCrashCPU_arm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashCPU_arm.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashCPU_arm.c; sourceTree = ""; }; + 8C23419431442D582D63E8ABBE30C470 /* EXPMatchers+beIdenticalTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beIdenticalTo.h"; path = "Expecta/Matchers/EXPMatchers+beIdenticalTo.h"; sourceTree = ""; }; + 8C26A4BB3B912B165DC20DB7D54CB0C8 /* Pods-BitBotTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-BitBotTests-acknowledgements.markdown"; sourceTree = ""; }; + 8C5412152A02375F97BCFA96C31002E2 /* Kingfisher.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.debug.xcconfig; sourceTree = ""; }; + 8CE4111130816741BE64DB8AA9AF25EE /* EXPMatchers+beGreaterThanOrEqualTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beGreaterThanOrEqualTo.h"; path = "Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.h"; sourceTree = ""; }; + 8D05EB46779D7C5A818D73B62F77753B /* SentryCrashCPU.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashCPU.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashCPU.c; sourceTree = ""; }; + 8D21CAAD0ADD11B944B272D58532943B /* SentrySystemEventsBreadcrumbs.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySystemEventsBreadcrumbs.m; path = Sources/Sentry/SentrySystemEventsBreadcrumbs.m; sourceTree = ""; }; + 8D3339DEF95FA636F126C2080A088321 /* SentryAppState.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryAppState.m; path = Sources/Sentry/SentryAppState.m; sourceTree = ""; }; + 8D3A4B1DBA7E15E533F1C21B73BD47EB /* OCMFunctions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMFunctions.m; path = Source/OCMock/OCMFunctions.m; sourceTree = ""; }; + 8E00FC8189AAAB1B80CCE473B6C8AF52 /* SentryMeta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryMeta.h; path = Sources/Sentry/include/SentryMeta.h; sourceTree = ""; }; + 8EB0E1EE3862BD69F6E01020B2BDE08E /* EXPMatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatcher.h; path = Expecta/EXPMatcher.h; sourceTree = ""; }; + 8ED89C1427E6BA14DF252DAAE9BBC9F5 /* SentryEnvelope.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryEnvelope.m; path = Sources/Sentry/SentryEnvelope.m; sourceTree = ""; }; + 8F0537A8A90D413531F5A9EA15E6D7FD /* SentryCrashReport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReport.h; path = Sources/SentryCrash/Recording/SentryCrashReport.h; sourceTree = ""; }; + 8F3707783B7E17EBAC2B40048C2B638B /* ExpectaSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ExpectaSupport.m; path = Expecta/ExpectaSupport.m; sourceTree = ""; }; + 8FA942C52C785545E4D4C42A7EAC6893 /* EXPMatchers+beIdenticalTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beIdenticalTo.m"; path = "Expecta/Matchers/EXPMatchers+beIdenticalTo.m"; sourceTree = ""; }; + 8FB87107341CDBA82C7CEB2B131A51B3 /* SentryTransportFactory.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryTransportFactory.h; path = Sources/Sentry/include/SentryTransportFactory.h; sourceTree = ""; }; + 9107D3E7F68DC7DB538D9EFB06A196E2 /* SentryCrashStackCursor_SelfThread.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashStackCursor_SelfThread.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.c; sourceTree = ""; }; + 91098A929162682414A487BF62B0C51E /* OCMock-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "OCMock-dummy.m"; sourceTree = ""; }; + 910A5EA3CAC3C38415BB28F6CF628F83 /* SentryFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryFrame.h; path = Sources/Sentry/Public/SentryFrame.h; sourceTree = ""; }; + 912295245C4EFAE6597BD5624C6D29CE /* SentryAttachment.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryAttachment.m; path = Sources/Sentry/SentryAttachment.m; sourceTree = ""; }; + 915D25D749AA3B4EC0FB0BAA6674D9C8 /* OCMBoxedReturnValueProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMBoxedReturnValueProvider.h; path = Source/OCMock/OCMBoxedReturnValueProvider.h; sourceTree = ""; }; + 918C1E8E18681194571CC7CC409D810F /* Mixpanel.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Mixpanel.m; path = Mixpanel/Mixpanel.m; sourceTree = ""; }; + 91A9040BA97087B23F51E478BA701A6F /* SDImageIOCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageIOCoder.h; path = SDWebImage/SDImageIOCoder.h; sourceTree = ""; }; + 928F1C804CA779C74BBAD7277B516830 /* ImageDrawing.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDrawing.swift; path = Sources/Image/ImageDrawing.swift; sourceTree = ""; }; + 9387616F36BC353A71CA06624B067969 /* SDImageAPNGCoderInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAPNGCoderInternal.h; path = SDWebImage/Private/SDImageAPNGCoderInternal.h; sourceTree = ""; }; + 9400F8F8837DB55A86F586A9609B2117 /* SentrySamplingContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySamplingContext.h; path = Sources/Sentry/Public/SentrySamplingContext.h; sourceTree = ""; }; + 943A6DC32F2A12EA051DDB9E22D150E3 /* OCMPassByRefSetter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMPassByRefSetter.h; path = Source/OCMock/OCMPassByRefSetter.h; sourceTree = ""; }; + 94AAB0857570A8D45394C82F74F2306E /* EXPMatchers+beNil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beNil.m"; path = "Expecta/Matchers/EXPMatchers+beNil.m"; sourceTree = ""; }; + 951C5CBA2B0F0DBF578D98D52943E388 /* SDWebImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloader.h; path = SDWebImage/SDWebImageDownloader.h; sourceTree = ""; }; + 95EC668E798CC7757D2A7FAE411066D4 /* KFImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImage.swift; path = Sources/SwiftUI/KFImage.swift; sourceTree = ""; }; + 96DB10A52721644F3864476CAF337A2C /* UIImage+ForceDecode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+ForceDecode.h"; path = "SDWebImage/UIImage+ForceDecode.h"; sourceTree = ""; }; + 96FC816744C2BCCA51CED048731F0C91 /* NSButton+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSButton+WebCache.h"; path = "SDWebImage/NSButton+WebCache.h"; sourceTree = ""; }; + 970C3CABE864F4EBDD5E4EDF8AB861F8 /* OCMRealObjectForwarder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMRealObjectForwarder.m; path = Source/OCMock/OCMRealObjectForwarder.m; sourceTree = ""; }; + 970D9F8EDEB3B80C1218D90CD500232C /* SDWebImageDefine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDefine.m; path = SDWebImage/SDWebImageDefine.m; sourceTree = ""; }; + 974630185E5A0C273B1868FF0A45382C /* SDWebImageCompat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCompat.m; path = SDWebImage/SDWebImageCompat.m; sourceTree = ""; }; + 977EB770ABF48ED5105390B227CF1057 /* SentryCrashMonitor_System.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashMonitor_System.m; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m; sourceTree = ""; }; + 97957EFCC33E464C409C5390DF5D48D2 /* OCPartialMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCPartialMockObject.m; path = Source/OCMock/OCPartialMockObject.m; sourceTree = ""; }; + 979EDE57A39CEF533C37EC090F0D5821 /* SentryRateLimitCategory.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryRateLimitCategory.h; path = Sources/Sentry/include/SentryRateLimitCategory.h; sourceTree = ""; }; + 97C100DF887E309856C0A3752A56C2EE /* EXPMatchers+match.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+match.m"; path = "Expecta/Matchers/EXPMatchers+match.m"; sourceTree = ""; }; + 97ED53DEEF94C51589000FDDBDD245FC /* SentryRetryAfterHeaderParser.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryRetryAfterHeaderParser.m; path = Sources/Sentry/SentryRetryAfterHeaderParser.m; sourceTree = ""; }; + 98B74495E6501725B2A5B7348E1C93AE /* SentryCrashDate.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashDate.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashDate.c; sourceTree = ""; }; + 98FC521CFE4B7F822E15B95D82BF96FF /* SentryOptions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryOptions.m; path = Sources/Sentry/SentryOptions.m; sourceTree = ""; }; + 9980BF60F7882669ADCC6EACBE8B4B67 /* UIButton+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIButton+WebCache.m"; path = "SDWebImage/UIButton+WebCache.m"; sourceTree = ""; }; + 99FF117BFA025DA2B85FF183B445BBF2 /* OCMArg.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMArg.m; path = Source/OCMock/OCMArg.m; sourceTree = ""; }; + 9B535A4FC57286211DE40388C054BDAC /* SentryCrashCPU_x86_64.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashCPU_x86_64.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashCPU_x86_64.c; sourceTree = ""; }; + 9B6F60DE19BDBE6C64EBB8CF63D6EEE1 /* SentryCrashMonitor.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMonitor.c; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c; sourceTree = ""; }; + 9B6F73B31552AA6B9946DE3D01FABFE1 /* SentryRequestOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryRequestOperation.m; path = Sources/Sentry/SentryRequestOperation.m; sourceTree = ""; }; + 9B8C060574C7D88BA3788F238D7F2FF8 /* EXPMatcherHelpers.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPMatcherHelpers.m; path = Expecta/Matchers/EXPMatcherHelpers.m; sourceTree = ""; }; + 9C0A1B0E54182F7303BF9551261EC6D3 /* MixpanelPeople.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelPeople.h; path = Mixpanel/MixpanelPeople.h; sourceTree = ""; }; + 9CCE329FFD1284B959ACC03EA2F58404 /* OCMReturnValueProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMReturnValueProvider.m; path = Source/OCMock/OCMReturnValueProvider.m; sourceTree = ""; }; + 9D117F3A6C5BAE303986E03C59EAD73E /* SentryScope+Private.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "SentryScope+Private.m"; path = "Sources/Sentry/SentryScope+Private.m"; sourceTree = ""; }; + 9D487B3797BA0C1BE5BA1380E70BF1D8 /* SentryCrashFileUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashFileUtils.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.h; sourceTree = ""; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 9DFE2561372FBEC8433424B1A3A78FAB /* AuthenticationChallengeResponsable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationChallengeResponsable.swift; path = Sources/Networking/AuthenticationChallengeResponsable.swift; sourceTree = ""; }; - 9E5DA0F73EA2D5964035418953C3748B /* EXPUnsupportedObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPUnsupportedObject.h; path = Expecta/EXPUnsupportedObject.h; sourceTree = ""; }; - A28937E8173CD476E20A4CB541E2F618 /* OCMock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMock.h; path = Source/OCMock/OCMock.h; sourceTree = ""; }; - A2DFB5FB1FBF6BDE66D3761B057DC4AF /* Mixpanel.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Mixpanel.m; path = Mixpanel/Mixpanel.m; sourceTree = ""; }; - A31D86646D8CE32EACAB67E8117537C0 /* NSPopover+MISSINGBackgroundView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSPopover+MISSINGBackgroundView.h"; path = "Pod/Classes/NSPopover+MISSINGBackgroundView.h"; sourceTree = ""; }; - A347DD9E83894ECF9E18A1321AF0DB4F /* SDWebImageIndicator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageIndicator.m; path = SDWebImage/SDWebImageIndicator.m; sourceTree = ""; }; - A37F4CA923DD13D2E2820A08C0F334FD /* OCPartialMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCPartialMockObject.h; path = Source/OCMock/OCPartialMockObject.h; sourceTree = ""; }; - A66E333CE92847BEBA79B50C188F884F /* SDImageIOCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageIOCoder.h; path = SDWebImage/SDImageIOCoder.h; sourceTree = ""; }; - A6ABFDFEBAB6F775540166E8CB0A76EF /* EasyMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EasyMapping.h; path = Sources/EasyMapping/EasyMapping.h; sourceTree = ""; }; - A6CF50AFABAA83508F094E26284AF209 /* EKPropertyHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKPropertyHelper.h; path = Sources/EasyMapping/EKPropertyHelper.h; sourceTree = ""; }; - A702A64B134CFFAB9B88CAA38D7E661A /* Mixpanel-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Mixpanel-macOS.debug.xcconfig"; sourceTree = ""; }; - A79507197F400407AD16AB92E7929F26 /* UIImageView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImageView+WebCache.h"; path = "SDWebImage/UIImageView+WebCache.h"; sourceTree = ""; }; - A7F63D471560A79A81C8EAD9832854AF /* EXPMatchers+beLessThan.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beLessThan.m"; path = "Expecta/Matchers/EXPMatchers+beLessThan.m"; sourceTree = ""; }; - A89D74222F1515674053BCA1F96B288F /* EXPMatchers+conformTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+conformTo.m"; path = "Expecta/Matchers/EXPMatchers+conformTo.m"; sourceTree = ""; }; - A8AF61BDDA49BA0BC455083325050B9F /* UIImage+MultiFormat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+MultiFormat.h"; path = "SDWebImage/UIImage+MultiFormat.h"; sourceTree = ""; }; - A90B1A399F5283F7832DC8F712C6C446 /* Delegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delegate.swift; path = Sources/Utility/Delegate.swift; sourceTree = ""; }; - A98D77B9153B7AB9A55C572FEB29D582 /* SDWebImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.release.xcconfig; sourceTree = ""; }; - AAEDA914FE1738DB4662140B337F1253 /* NSDateFormatter+EasyMappingAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSDateFormatter+EasyMappingAdditions.h"; path = "Sources/EasyMapping/NSDateFormatter+EasyMappingAdditions.h"; sourceTree = ""; }; - AAFF91ADD6AC060E30D04D8E2DDACF61 /* EXPMatchers+beginWith.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beginWith.m"; path = "Expecta/Matchers/EXPMatchers+beginWith.m"; sourceTree = ""; }; - AB955BF0D2B4CEC905C17CFD967F487E /* SDImageCacheDefine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCacheDefine.m; path = SDWebImage/SDImageCacheDefine.m; sourceTree = ""; }; - AB96CAFC5DCCB7374C5A881110FB8849 /* SDImageCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCache.h; path = SDWebImage/SDImageCache.h; sourceTree = ""; }; - ABB22FE656A62BED33D213D15B61E75E /* Kingfisher.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.debug.xcconfig; sourceTree = ""; }; - ABC34D53E5B62AFBC01AA6E7C79EDFE4 /* KFImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImage.swift; path = Sources/SwiftUI/KFImage.swift; sourceTree = ""; }; - AD1C8BD7DEB42F687DDF5D0C5BAF26A0 /* SDImageCacheConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCacheConfig.m; path = SDWebImage/SDImageCacheConfig.m; sourceTree = ""; }; - AE3615FE3C25BC5BFED9475620B18427 /* ExpectaSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ExpectaSupport.h; path = Expecta/ExpectaSupport.h; sourceTree = ""; }; - AE51649E85A3F7A92B1AB21D524878B9 /* OCMNotificationPoster.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMNotificationPoster.h; path = Source/OCMock/OCMNotificationPoster.h; sourceTree = ""; }; - AE5EF5CE5A54E9221AA60FE934863F4A /* MPLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MPLogger.h; path = Mixpanel/MPLogger.h; sourceTree = ""; }; - AF8D241D92929702644AC3C080CA4D97 /* SDWeakProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWeakProxy.m; path = SDWebImage/Private/SDWeakProxy.m; sourceTree = ""; }; - AFFB60D7E65E67C42E01EB132DB30B60 /* EXPMatchers+beInTheRangeOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beInTheRangeOf.h"; path = "Expecta/Matchers/EXPMatchers+beInTheRangeOf.h"; sourceTree = ""; }; - B08140437A792EA7441A031763E63BD5 /* NSMethodSignature+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSMethodSignature+OCMAdditions.m"; path = "Source/OCMock/NSMethodSignature+OCMAdditions.m"; sourceTree = ""; }; + 9DFFECBC682FD9C906742F24B35A3F1C /* SentryCrashExceptionApplication.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashExceptionApplication.h; path = Sources/Sentry/Public/SentryCrashExceptionApplication.h; sourceTree = ""; }; + 9E2B96990033B4F418F03E42E8155FFE /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/Networking/ImageDownloader.swift; sourceTree = ""; }; + 9E9FC117741B956A49CA4281D1D1444F /* EXPMatchers+beSupersetOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beSupersetOf.h"; path = "Expecta/Matchers/EXPMatchers+beSupersetOf.h"; sourceTree = ""; }; + 9EF84BD0B2F2B9D182E8A39951EE8A9B /* EasyMapping-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "EasyMapping-tvOS.debug.xcconfig"; path = "../EasyMapping-tvOS/EasyMapping-tvOS.debug.xcconfig"; sourceTree = ""; }; + 9F4D52F3B627B332A01C5715F76C62D8 /* SDImageCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCache.h; path = SDWebImage/SDImageCache.h; sourceTree = ""; }; + 9F9B7BC7DE91FC476DE62B33FF2103B1 /* SDWebImageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageManager.h; path = SDWebImage/SDWebImageManager.h; sourceTree = ""; }; + 9FF6CBBFF458151EFC2056A73D7092CE /* SentryAutoBreadcrumbTrackingIntegration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryAutoBreadcrumbTrackingIntegration.m; path = Sources/Sentry/SentryAutoBreadcrumbTrackingIntegration.m; sourceTree = ""; }; + A033ED022000B891E90E46281AE3C84C /* UIImage+Transform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Transform.m"; path = "SDWebImage/UIImage+Transform.m"; sourceTree = ""; }; + A03FCA222D59471B84B0261382857F95 /* SentryDispatchQueueWrapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryDispatchQueueWrapper.h; path = Sources/Sentry/include/SentryDispatchQueueWrapper.h; sourceTree = ""; }; + A0628EA6AE627462153793C03272C2CE /* SentrySessionCrashedHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySessionCrashedHandler.h; path = Sources/Sentry/include/SentrySessionCrashedHandler.h; sourceTree = ""; }; + A07387E3FEA32D2AC879F4FBE79D7CF2 /* SentryConcurrentRateLimitsDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryConcurrentRateLimitsDictionary.h; path = Sources/Sentry/include/SentryConcurrentRateLimitsDictionary.h; sourceTree = ""; }; + A09C87640D6D2DC5D6EB71A57E7E67BB /* NSMethodSignature+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSMethodSignature+OCMAdditions.h"; path = "Source/OCMock/NSMethodSignature+OCMAdditions.h"; sourceTree = ""; }; + A0ADA459399E5006B57CF039E0BFF87E /* Expecta-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Expecta-dummy.m"; sourceTree = ""; }; + A11A7A73E2BA6DE77E94D1B9080AFD49 /* EXPMatchers+beTruthy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beTruthy.m"; path = "Expecta/Matchers/EXPMatchers+beTruthy.m"; sourceTree = ""; }; + A183B8C88C10AE3947EC7E662488F951 /* SentryCrashInstallation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashInstallation.h; path = Sources/SentryCrash/Installations/SentryCrashInstallation.h; sourceTree = ""; }; + A1ED785B7119EA303867FB77D23DC691 /* SentryCrashMonitorContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitorContext.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h; sourceTree = ""; }; + A202CEF8C27DDD9E0C7DBA2D5E025C07 /* EXPExpect.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPExpect.h; path = Expecta/EXPExpect.h; sourceTree = ""; }; + A2255F2139506AB4C73A65EB517AFE79 /* ImageProgressive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProgressive.swift; path = Sources/Image/ImageProgressive.swift; sourceTree = ""; }; + A256F1C1E08340F2EEA91E8F3B75F656 /* SentryCrashJSONCodecObjC.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashJSONCodecObjC.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.h; sourceTree = ""; }; + A27A3F985112C5E7105FF757855141B3 /* OCProtocolMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCProtocolMockObject.m; path = Source/OCMock/OCProtocolMockObject.m; sourceTree = ""; }; + A2E6C9BD4CA6F7A05DFD31BEB92AD59D /* EXPMatchers+endWith.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+endWith.h"; path = "Expecta/Matchers/EXPMatchers+endWith.h"; sourceTree = ""; }; + A31FB9F387655224851D83FFE7738B1E /* EXPMatchers+beFalsy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beFalsy.h"; path = "Expecta/Matchers/EXPMatchers+beFalsy.h"; sourceTree = ""; }; + A339574BDAC6852EC8CD47F1A626B26E /* SentryCrashStackCursor_MachineContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashStackCursor_MachineContext.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.h; sourceTree = ""; }; + A33AA886DE0330C68ABC7B568A11AEEA /* EXPMatchers+equal.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+equal.m"; path = "Expecta/Matchers/EXPMatchers+equal.m"; sourceTree = ""; }; + A394BD3445668D99A5E87488474235A3 /* ImageDataProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProcessor.swift; path = Sources/Networking/ImageDataProcessor.swift; sourceTree = ""; }; + A4F20D84DBC0E8F03B43766CD57B6C5B /* OCMStubRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMStubRecorder.m; path = Source/OCMock/OCMStubRecorder.m; sourceTree = ""; }; + A50596FAFF371E0C7E67A7CA37C794AD /* UIImageView+HighlightedWebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImageView+HighlightedWebCache.h"; path = "SDWebImage/UIImageView+HighlightedWebCache.h"; sourceTree = ""; }; + A55A5E501307CDABEECE7608B972AA18 /* SentryCrashMonitor_NSException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_NSException.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.h; sourceTree = ""; }; + A58E63C8196E979642B5A41F2AA5F26A /* EXPFloatTuple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPFloatTuple.h; path = Expecta/EXPFloatTuple.h; sourceTree = ""; }; + A60658B35C750AD8DE167E3A43FF0C23 /* EXPMatchers+beTruthy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beTruthy.h"; path = "Expecta/Matchers/EXPMatchers+beTruthy.h"; sourceTree = ""; }; + A6197DD8D086D74EC7BFCCE051FD5F31 /* NSDate+SentryExtras.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSDate+SentryExtras.m"; path = "Sources/Sentry/NSDate+SentryExtras.m"; sourceTree = ""; }; + A6D2EFB975BFFCC2B00A3EB629C22CB7 /* Expecta.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Expecta.release.xcconfig; sourceTree = ""; }; + A7042E946A278D6275B3C37E519799F4 /* EXPMatchers+postNotification.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+postNotification.h"; path = "Expecta/Matchers/EXPMatchers+postNotification.h"; sourceTree = ""; }; + A73048B0940DC44FBE9BC89CC02BAD9C /* EKObjectMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKObjectMapping.h; path = Sources/EasyMapping/EKObjectMapping.h; sourceTree = ""; }; + A73B1AB046609EA753474A7985924C8C /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/Cache/ImageCache.swift; sourceTree = ""; }; + A84049969AB25295B25C07B265E0573A /* SentryCrashJSONCodec.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashJSONCodec.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.c; sourceTree = ""; }; + A8673ECA3B5E894D0AD1F258CFFFB9C9 /* SDWebImageTransition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageTransition.h; path = SDWebImage/SDWebImageTransition.h; sourceTree = ""; }; + A91922616AFB9EA146BD8FBEF311BEAC /* NSValue+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSValue+OCMAdditions.h"; path = "Source/OCMock/NSValue+OCMAdditions.h"; sourceTree = ""; }; + A9A6AB7B0D89F2EABE8504652874196B /* Deprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Deprecated.swift; path = Sources/General/Deprecated.swift; sourceTree = ""; }; + AA2793A28BA2F2951479D61E76981AF6 /* Pods-BitBotTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBotTests.release.xcconfig"; sourceTree = ""; }; + AA5DA7F5301E11295B7E5A404917A412 /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Utility/Box.swift; sourceTree = ""; }; + AAD1A4DFC439E32BC55F333A85B0D6B7 /* OCMArgAction.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMArgAction.m; path = Source/OCMock/OCMArgAction.m; sourceTree = ""; }; + ABE2CA9730DCE620663640615D743BB0 /* SentryId.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryId.h; path = Sources/Sentry/Public/SentryId.h; sourceTree = ""; }; + ABEEA66650DAFED36AC0A7B67BDC27BD /* OCMock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMock.h; path = Source/OCMock/OCMock.h; sourceTree = ""; }; + ABF82152AE21904F7720320408CF90EC /* SentryNSError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryNSError.h; path = Sources/Sentry/Public/SentryNSError.h; sourceTree = ""; }; + AC14140BA60C11A89D4E5C625E6C09F8 /* SentryCrashJSONCodecObjC.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashJSONCodecObjC.m; path = Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.m; sourceTree = ""; }; + ACC877162AAD2CD71819994ABEB546C0 /* Sentry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Sentry.h; path = Sources/Sentry/Public/Sentry.h; sourceTree = ""; }; + ACF78BEA53B328FF4AC085F3142F1197 /* SentrySystemEventsBreadcrumbs.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySystemEventsBreadcrumbs.h; path = Sources/Sentry/include/SentrySystemEventsBreadcrumbs.h; sourceTree = ""; }; + AD04F4E2AF56D7FBACEDB0A518996D17 /* OCMNotificationPoster.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMNotificationPoster.h; path = Source/OCMock/OCMNotificationPoster.h; sourceTree = ""; }; + AD1847DA1E09CA4FF64EBDDCE9E89BBD /* ExpectaObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ExpectaObject.h; path = Expecta/ExpectaObject.h; sourceTree = ""; }; + AD43111F7D7D4B981C14C7A679582A32 /* OCMRealObjectForwarder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMRealObjectForwarder.h; path = Source/OCMock/OCMRealObjectForwarder.h; sourceTree = ""; }; + AD6D919B73E1764BE2EA183589BCD2A2 /* SentryClient+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SentryClient+Private.h"; path = "Sources/Sentry/include/SentryClient+Private.h"; sourceTree = ""; }; + ADCBFFF10E2E79248CA56AECC1AB9EDB /* SentryHub.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryHub.h; path = Sources/Sentry/Public/SentryHub.h; sourceTree = ""; }; + AE40BA3D3BBB6AC28E2B587F77AD04F3 /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/General/Kingfisher.swift; sourceTree = ""; }; + AE44188648C57CDADB4BBBC4CC62CC3A /* SentryCrashStackCursor_Backtrace.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashStackCursor_Backtrace.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.h; sourceTree = ""; }; + AE56FFEC107368C3977D88E534EB6929 /* SDAsyncBlockOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAsyncBlockOperation.h; path = SDWebImage/Private/SDAsyncBlockOperation.h; sourceTree = ""; }; + AEA160530D3540C9520D2C636449E6B3 /* SDWebImageOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageOperation.h; path = SDWebImage/SDWebImageOperation.h; sourceTree = ""; }; + AF11E02E80C577B2B41594595DBFA01E /* SentryCrashMonitor_MachException.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMonitor_MachException.c; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.c; sourceTree = ""; }; + AF59753534C973EC2CA684E58AA58706 /* SentryScope+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SentryScope+Private.h"; path = "Sources/Sentry/include/SentryScope+Private.h"; sourceTree = ""; }; + AFA50A50F6E5469D4E4F53B09FAAFF11 /* SentryRequestOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryRequestOperation.h; path = Sources/Sentry/include/SentryRequestOperation.h; sourceTree = ""; }; + AFE14AC670BBDE68888F91AD1EAD112D /* SentrySwizzle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySwizzle.h; path = Sources/Sentry/include/SentrySwizzle.h; sourceTree = ""; }; + B0629066F58B4A33514A6AF0F03BDDD5 /* UIView+WebCacheOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIView+WebCacheOperation.m"; path = "SDWebImage/UIView+WebCacheOperation.m"; sourceTree = ""; }; + B074CAB984CC58579CF9DF157C294F9C /* EasyMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EasyMapping.h; path = Sources/EasyMapping/EasyMapping.h; sourceTree = ""; }; B0B214D775196BA7CA8E17E53048A493 /* libSDWebImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libSDWebImage.a; path = libSDWebImage.a; sourceTree = BUILT_PRODUCTS_DIR; }; - B0DC0C140D05CC9480A2E31FE8270445 /* OCMBoxedReturnValueProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMBoxedReturnValueProvider.h; path = Source/OCMock/OCMBoxedReturnValueProvider.h; sourceTree = ""; }; - B10A8149DBAEB5276086C1A25968D7C1 /* OCMVerifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMVerifier.h; path = Source/OCMock/OCMVerifier.h; sourceTree = ""; }; - B12A44060AD90C50C600229C1BF30CE6 /* SDImageCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCoder.h; path = SDWebImage/SDImageCoder.h; sourceTree = ""; }; - B1867608EDF91D60A4545F8CC26ABAD6 /* MPNetwork.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MPNetwork.m; path = Mixpanel/MPNetwork.m; sourceTree = ""; }; - B2A17A5B37C3FE1B72A0FA6216116FBC /* MemoryStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MemoryStorage.swift; path = Sources/Cache/MemoryStorage.swift; sourceTree = ""; }; - B2C4DBA9148322CD3B09452E7AAB0C0F /* EXPMatchers+raise.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+raise.h"; path = "Expecta/Matchers/EXPMatchers+raise.h"; sourceTree = ""; }; + B0F73FEAAFEBB7A8FB01FAB8C7D9136A /* EKPropertyMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKPropertyMapping.h; path = Sources/EasyMapping/EKPropertyMapping.h; sourceTree = ""; }; + B111E844834CEDC91CDE3BE38BD67D55 /* SDWebImagePrefetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImagePrefetcher.m; path = SDWebImage/SDWebImagePrefetcher.m; sourceTree = ""; }; + B1BAE2DAE9706E2DCF18FDA63A2EE109 /* EXPUnsupportedObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPUnsupportedObject.m; path = Expecta/EXPUnsupportedObject.m; sourceTree = ""; }; + B229986A8D850A78635DA668400B9541 /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/Cache/CacheSerializer.swift; sourceTree = ""; }; + B25757E02D53C1DF22036581F36AC94A /* OCObserverMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCObserverMockObject.h; path = Source/OCMock/OCObserverMockObject.h; sourceTree = ""; }; + B25FFE571A338D87EDF909EC906499E0 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image/Image.swift; sourceTree = ""; }; + B278697392A010FC841BA550A3EBD53F /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/Extensions/ImageView+Kingfisher.swift"; sourceTree = ""; }; B2F6BF787CDDE44EDE585C56D36FB0B0 /* libEasyMapping-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libEasyMapping-macOS.a"; path = "libEasyMapping-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - B346D043EFE755C02515D77ED01AE799 /* OCMMacroState.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMMacroState.m; path = Source/OCMock/OCMMacroState.m; sourceTree = ""; }; - B34983A86DB520A9C8E487CE9F7777E1 /* SDImageCacheConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCacheConfig.h; path = SDWebImage/SDImageCacheConfig.h; sourceTree = ""; }; - B451B418484BAF6ECD5CF187FC6C969A /* SessionDataTask.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDataTask.swift; path = Sources/Networking/SessionDataTask.swift; sourceTree = ""; }; - B470B8C6258E527FACDE6F72DFFF4D27 /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/Views/AnimatedImageView.swift; sourceTree = ""; }; - B49D6160F7105005451C92A516BDF8A3 /* OCProtocolMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCProtocolMockObject.h; path = Source/OCMock/OCProtocolMockObject.h; sourceTree = ""; }; - B4BE72DFF35188F0868B96621E9941CB /* SDImageFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageFrame.h; path = SDWebImage/SDImageFrame.h; sourceTree = ""; }; - B61DD45F82B8A39F266EC2207D8A76C6 /* OCMConstraint.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMConstraint.m; path = Source/OCMock/OCMConstraint.m; sourceTree = ""; }; - B77606847A2016C77AD6833DC877F24D /* SDImageCachesManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCachesManager.m; path = SDWebImage/SDImageCachesManager.m; sourceTree = ""; }; - B777B3F9C209D8C8FCDE4A8CD995CF28 /* UIImage+Metadata.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Metadata.m"; path = "SDWebImage/UIImage+Metadata.m"; sourceTree = ""; }; - B7CB631287A52D62DF7B28B085B33FF1 /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/Networking/RequestModifier.swift; sourceTree = ""; }; - B861323ED525752EA47B9D3053F1AB69 /* EXPMatchers+postNotification.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+postNotification.m"; path = "Expecta/Matchers/EXPMatchers+postNotification.m"; sourceTree = ""; }; - BAB9C1F071E04BF93DF16CB45635E34F /* SDWebImagePrefetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImagePrefetcher.h; path = SDWebImage/SDWebImagePrefetcher.h; sourceTree = ""; }; - BAB9E6683D0915936373DC5385FC954E /* EXPMatchers+beGreaterThan.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beGreaterThan.h"; path = "Expecta/Matchers/EXPMatchers+beGreaterThan.h"; sourceTree = ""; }; - BAED2AAE5E9EA784319F20AD830C8A32 /* MixpanelPeople.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MixpanelPeople.m; path = Mixpanel/MixpanelPeople.m; sourceTree = ""; }; - BAF78013740FC8148179C3E81058804A /* OCMReturnValueProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMReturnValueProvider.h; path = Source/OCMock/OCMReturnValueProvider.h; sourceTree = ""; }; - BB7A4B88754D7601CDEE23791D4591E1 /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/Networking/ImagePrefetcher.swift; sourceTree = ""; }; - BC7405D5402B6BFF2D28CD1EC298E665 /* EXPMatchers+beTruthy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beTruthy.m"; path = "Expecta/Matchers/EXPMatchers+beTruthy.m"; sourceTree = ""; }; - BD81E51E7A577A51A5C7F3AA815C5DAC /* EXPMatcherHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatcherHelpers.h; path = Expecta/Matchers/EXPMatcherHelpers.h; sourceTree = ""; }; - BDEBF23624FC6144C3220520A42B55A5 /* OCMRealObjectForwarder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMRealObjectForwarder.h; path = Source/OCMock/OCMRealObjectForwarder.h; sourceTree = ""; }; - BE2C372744DEFF3EFC56881622D25937 /* ImageDataProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProcessor.swift; path = Sources/Networking/ImageDataProcessor.swift; sourceTree = ""; }; - BE6767C8ABFABDC3AD0FF966CE31C70E /* EXPMatchers+beSupersetOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beSupersetOf.m"; path = "Expecta/Matchers/EXPMatchers+beSupersetOf.m"; sourceTree = ""; }; - BF0B3717271485DB8B8D4FCA96D24E52 /* OCMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMockObject.m; path = Source/OCMock/OCMockObject.m; sourceTree = ""; }; - C0AFA15C417FF566E42E3944E9CA79B6 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/Extensions/UIButton+Kingfisher.swift"; sourceTree = ""; }; - C148126AF9126A0D5EF8C178F3DD06A4 /* SDAnimatedImageView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageView.m; path = SDWebImage/SDAnimatedImageView.m; sourceTree = ""; }; - C241A712E068D87A38E56EF0F0DEB5DB /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/General/KingfisherOptionsInfo.swift; sourceTree = ""; }; - C2DFCA49B2CE55091A7252F70073E4D9 /* OCMStubRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMStubRecorder.h; path = Source/OCMock/OCMStubRecorder.h; sourceTree = ""; }; + B352E3B766B7B86A89E0481FEEFCA38C /* OCMMacroState.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMMacroState.m; path = Source/OCMock/OCMMacroState.m; sourceTree = ""; }; + B37D0C9232F6AFE55239134BD3478B63 /* Sentry-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Sentry-tvOS.debug.xcconfig"; path = "../Sentry-tvOS/Sentry-tvOS.debug.xcconfig"; sourceTree = ""; }; + B436EC62C08B574E6FEA12C19BE5C8C3 /* UIView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIView+WebCache.m"; path = "SDWebImage/UIView+WebCache.m"; sourceTree = ""; }; + B4ACE71B7BF8F77EA48BC5C6B292247F /* AVAssetImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AVAssetImageDataProvider.swift; path = Sources/General/ImageSource/AVAssetImageDataProvider.swift; sourceTree = ""; }; + B524FC3A2CD1BCD9A80259FC8CE87C5F /* SDImageGraphics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGraphics.h; path = SDWebImage/SDImageGraphics.h; sourceTree = ""; }; + B55607C0615FFE6430F17A69A880EB12 /* SentryCurrentDateProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCurrentDateProvider.h; path = Sources/Sentry/include/SentryCurrentDateProvider.h; sourceTree = ""; }; + B67294EB0F7BE16140AA5419E527DE10 /* SentryCrashReportStore.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashReportStore.c; path = Sources/SentryCrash/Recording/SentryCrashReportStore.c; sourceTree = ""; }; + B6762EED2051F9E5E49DF5AF973AC7F1 /* Expecta.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Expecta.debug.xcconfig; sourceTree = ""; }; + B69653CC54B8A80021F43EC587AB9266 /* SDWebImageCacheKeyFilter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCacheKeyFilter.m; path = SDWebImage/SDWebImageCacheKeyFilter.m; sourceTree = ""; }; + B696723444D17E2C081123ABAC3C0EE7 /* ImageDownloaderDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloaderDelegate.swift; path = Sources/Networking/ImageDownloaderDelegate.swift; sourceTree = ""; }; + B6DAA8E43339786802C0F8CC809AC768 /* NSBezierPath+RoundedCorners.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSBezierPath+RoundedCorners.m"; path = "SDWebImage/Private/NSBezierPath+RoundedCorners.m"; sourceTree = ""; }; + B7B0452CB83EB470B9D578159CD4EC40 /* SentryGlobalEventProcessor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryGlobalEventProcessor.m; path = Sources/Sentry/SentryGlobalEventProcessor.m; sourceTree = ""; }; + B7E43F64E96E0C3A23315AD8FDD875B5 /* SentryCrashMonitor_Signal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_Signal.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.h; sourceTree = ""; }; + B871ADB422CB46B0A68EFB7C06F829F5 /* Mixpanel-macOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Mixpanel-macOS-dummy.m"; sourceTree = ""; }; + B890219F03689D886CBA4020B1CD7B14 /* SentryCrashSymbolicator.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashSymbolicator.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.c; sourceTree = ""; }; + B8AF8D7DF499D5D21A642832F339131F /* SentryCrashCPU.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashCPU.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashCPU.h; sourceTree = ""; }; + B93A61CED72D42D90093A6C9AE0216A4 /* OCClassMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCClassMockObject.m; path = Source/OCMock/OCClassMockObject.m; sourceTree = ""; }; + B96ED94280EE507E42A646706D56CE1C /* SentryCrashCPU_Apple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashCPU_Apple.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashCPU_Apple.h; sourceTree = ""; }; + B9746E334F7B96E4F782D91BECC052AB /* NSDateFormatter+EasyMappingAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSDateFormatter+EasyMappingAdditions.h"; path = "Sources/EasyMapping/NSDateFormatter+EasyMappingAdditions.h"; sourceTree = ""; }; + B9A9599914DD2E69DFA3308658CC6D8D /* Pods-BitBot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBot.release.xcconfig"; sourceTree = ""; }; + BA132010529E4E7E70FB8CD58C22D44A /* OCMock-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "OCMock-prefix.pch"; sourceTree = ""; }; + BA6674821E44BAAADC77D5FB4CD7671F /* NSData+SentryCompression.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSData+SentryCompression.h"; path = "Sources/Sentry/include/NSData+SentryCompression.h"; sourceTree = ""; }; + BB20062D0FA5FA812F3E4061BB7427CB /* SDImageAssetManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAssetManager.m; path = SDWebImage/Private/SDImageAssetManager.m; sourceTree = ""; }; + BB20C65D91E6BA3A93FCE00CC0AEE9FB /* Mixpanel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Mixpanel.h; path = Mixpanel/Mixpanel.h; sourceTree = ""; }; + BB9836C3922D9280D5ECB5E16654E761 /* NSButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Kingfisher.swift"; path = "Sources/Extensions/NSButton+Kingfisher.swift"; sourceTree = ""; }; + BBAB57A64E6C4CD076398499D4EFB432 /* SentryException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryException.m; path = Sources/Sentry/SentryException.m; sourceTree = ""; }; + BBC0FD88956CF8F23259FCE3D7B5E7C9 /* SentryThread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryThread.h; path = Sources/Sentry/Public/SentryThread.h; sourceTree = ""; }; + BBCCBA0D6DE3EFC7812C64133351C711 /* SentryQueueableRequestManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryQueueableRequestManager.m; path = Sources/Sentry/SentryQueueableRequestManager.m; sourceTree = ""; }; + BD89E69E85081CB3BFA0DA50E6BD729C /* SDImageCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCoder.m; path = SDWebImage/SDImageCoder.m; sourceTree = ""; }; + BE880AB1DB81B927C0BC664948EAC229 /* OCMInvocationStub.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMInvocationStub.m; path = Source/OCMock/OCMInvocationStub.m; sourceTree = ""; }; + BEAA547EB86BF0690AF84A817A3EE1B1 /* SessionDataTask.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDataTask.swift; path = Sources/Networking/SessionDataTask.swift; sourceTree = ""; }; + BEF7F0C7B39D9162359E52B189FE8F21 /* EKManagedObjectModel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKManagedObjectModel.h; path = Sources/EasyMapping/EKManagedObjectModel.h; sourceTree = ""; }; + BFE1C8C5066FDEED8D3A06A903580C81 /* SentrySession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySession.h; path = Sources/Sentry/Public/SentrySession.h; sourceTree = ""; }; + C02A9CF89AD5F57E5E1DC0F438331741 /* SentryCrashDebug.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashDebug.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashDebug.c; sourceTree = ""; }; + C071660C8956DB87DA658081A5D78D83 /* NSArray+SentrySanitize.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSArray+SentrySanitize.m"; path = "Sources/Sentry/NSArray+SentrySanitize.m"; sourceTree = ""; }; + C09407241B2BDC8483771D6D0859B8D2 /* SentryCrashSymbolicator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashSymbolicator.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.h; sourceTree = ""; }; + C0D2656F2A875ECFE893BF18B2E16492 /* OCMExceptionReturnValueProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMExceptionReturnValueProvider.h; path = Source/OCMock/OCMExceptionReturnValueProvider.h; sourceTree = ""; }; + C1170EDAC4979B5BA7E361047AC4B2AC /* Mixpanel-macOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Mixpanel-macOS-prefix.pch"; sourceTree = ""; }; + C14C6D61A8BD9081A41C40D24192DE44 /* OCMIndirectReturnValueProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMIndirectReturnValueProvider.h; path = Source/OCMock/OCMIndirectReturnValueProvider.h; sourceTree = ""; }; + C16CDA7D12CE2887C6C67BA402461988 /* EKMappingBlocks.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKMappingBlocks.h; path = Sources/EasyMapping/EKMappingBlocks.h; sourceTree = ""; }; + C190ED49B8AF2D2705779E1DD6001A3F /* SentryCrashDefaultBinaryImageProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashDefaultBinaryImageProvider.m; path = Sources/Sentry/SentryCrashDefaultBinaryImageProvider.m; sourceTree = ""; }; + C1E333E813AEA3E1D1114D3717C7022B /* SentryCrashReportConverter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportConverter.h; path = Sources/Sentry/include/SentryCrashReportConverter.h; sourceTree = ""; }; + C209DBD35687683B0353434E2C4ED4BA /* ExtensionHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionHelpers.swift; path = Sources/Utility/ExtensionHelpers.swift; sourceTree = ""; }; + C324EB3A7AC0090B4AAEA7B08A40BE78 /* SentryFrame.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryFrame.m; path = Sources/Sentry/SentryFrame.m; sourceTree = ""; }; + C335C90B0893B78D0E77022821932C64 /* WKInterfaceImage+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKInterfaceImage+Kingfisher.swift"; path = "Sources/Extensions/WKInterfaceImage+Kingfisher.swift"; sourceTree = ""; }; + C35F4308293B135C7155C0CA4BD07558 /* SentryUser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryUser.h; path = Sources/Sentry/Public/SentryUser.h; sourceTree = ""; }; + C3AAE60C4B38EA9E0AAAACD0701EA5D4 /* SentryMessage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryMessage.m; path = Sources/Sentry/SentryMessage.m; sourceTree = ""; }; + C3D92E3100FDE0A02B9E624C29649659 /* SDImageCacheDefine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCacheDefine.m; path = SDWebImage/SDImageCacheDefine.m; sourceTree = ""; }; C3F44C782D64D7EB20B61CE3844EBFAD /* libKingfisher.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libKingfisher.a; path = libKingfisher.a; sourceTree = BUILT_PRODUCTS_DIR; }; - C4AD47EAF619C857BEC113A2047709F2 /* NSValue+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSValue+OCMAdditions.h"; path = "Source/OCMock/NSValue+OCMAdditions.h"; sourceTree = ""; }; - C51171701AD5DE91435B7C6FD44F6D03 /* SDImageCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCache.m; path = SDWebImage/SDImageCache.m; sourceTree = ""; }; - C5120B28D0AE9A8B5959FFD25D7546BC /* SDWebImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.debug.xcconfig; sourceTree = ""; }; - C53946AE1D25D3DC688DD052BB4CB2E2 /* UIImage+ForceDecode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+ForceDecode.m"; path = "SDWebImage/UIImage+ForceDecode.m"; sourceTree = ""; }; - C5E5CB7681E3DEE123040E6870391D7B /* MixpanelExceptionHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MixpanelExceptionHandler.m; path = Mixpanel/MixpanelExceptionHandler.m; sourceTree = ""; }; - C65DA8ADE9DE5648BC51913F68D68BAF /* SDImageCodersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCodersManager.m; path = SDWebImage/SDImageCodersManager.m; sourceTree = ""; }; - C7066153845C9CB987D2089FEA9C46FB /* SDImageTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageTransformer.m; path = SDWebImage/SDImageTransformer.m; sourceTree = ""; }; - C7125132C005FB99631CECCD953414BE /* SDImageFrame.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageFrame.m; path = SDWebImage/SDImageFrame.m; sourceTree = ""; }; - C7F1EF4C2BBDB132CCEA2EF7D0E40DB7 /* SDDiskCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDDiskCache.h; path = SDWebImage/SDDiskCache.h; sourceTree = ""; }; - C8A287D51E44E395A8E8B248838B4501 /* EXPMatchers+beGreaterThan.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beGreaterThan.m"; path = "Expecta/Matchers/EXPMatchers+beGreaterThan.m"; sourceTree = ""; }; - CA228BFDCE8A94062372DD786096FF3A /* MPNetwork.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MPNetwork.h; path = Mixpanel/MPNetwork.h; sourceTree = ""; }; - CA7B1F26AECE4763BAE90DED00BAA021 /* OCMVerifier.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMVerifier.m; path = Source/OCMock/OCMVerifier.m; sourceTree = ""; }; - CAC12ECB76F6C71543B1881C9B5C61CB /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Sources/Networking/RedirectHandler.swift; sourceTree = ""; }; - CC2F761AAA0A1F14AFF60CDD39F72515 /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Sources/Networking/SessionDelegate.swift; sourceTree = ""; }; - CC64D7274DFE874DDD39C89A939D4580 /* Mixpanel-tvOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "Mixpanel-tvOS-prefix.pch"; path = "../Mixpanel-tvOS/Mixpanel-tvOS-prefix.pch"; sourceTree = ""; }; - CCEA1E80C1838E1C1C3C444B2BDB99C1 /* SDMemoryCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDMemoryCache.m; path = SDWebImage/SDMemoryCache.m; sourceTree = ""; }; - CDFEF876C8EAD0CF4C05038DE14DCF71 /* UIView+WebCacheOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+WebCacheOperation.h"; path = "SDWebImage/UIView+WebCacheOperation.h"; sourceTree = ""; }; - CE29FA38779771C8131E0BCCE1BE4F27 /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; - CE8F4F22CA4D6315D5E43C50269C56E5 /* MixpanelPeople.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelPeople.h; path = Mixpanel/MixpanelPeople.h; sourceTree = ""; }; - CEAD97C29EFAB8BEAC263DB3B303A5E4 /* ExpectaObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ExpectaObject.h; path = Expecta/ExpectaObject.h; sourceTree = ""; }; - CF60C676F1FF87B5008152CBE76B8114 /* OCMArg.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMArg.m; path = Source/OCMock/OCMArg.m; sourceTree = ""; }; - CF710639283DDEDD96354E54E3A7E665 /* OCMStubRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMStubRecorder.m; path = Source/OCMock/OCMStubRecorder.m; sourceTree = ""; }; - CF86FD09614080A1FDCD4A411FA33226 /* Expecta.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Expecta.release.xcconfig; sourceTree = ""; }; - D05EB1789A448153E0F229D5CC5BA22A /* EXPMatchers+beIdenticalTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beIdenticalTo.h"; path = "Expecta/Matchers/EXPMatchers+beIdenticalTo.h"; sourceTree = ""; }; - D09347008ADF9857FE17C7C03E5FD631 /* EXPMatchers+beFalsy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beFalsy.h"; path = "Expecta/Matchers/EXPMatchers+beFalsy.h"; sourceTree = ""; }; - D1B6AFD85D4587CFCB86308270A778F3 /* NSButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Kingfisher.swift"; path = "Sources/Extensions/NSButton+Kingfisher.swift"; sourceTree = ""; }; - D1EB4E17FB5EAD0DC2A47732102AED43 /* MixpanelPeoplePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelPeoplePrivate.h; path = Mixpanel/MixpanelPeoplePrivate.h; sourceTree = ""; }; + C43F69BAD51BED8B5077272C9934AE97 /* EXPMatchers+raise.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+raise.m"; path = "Expecta/Matchers/EXPMatchers+raise.m"; sourceTree = ""; }; + C44D2D0E6F4C6EF2EE76172E3124101F /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Sources/Networking/RedirectHandler.swift; sourceTree = ""; }; + C4A6679DBB5BEDCF84D9F0F1B2E6204D /* Sentry-macOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Sentry-macOS-dummy.m"; sourceTree = ""; }; + C5884F3C5EDA3C444E34EAEFA5496AB2 /* EXPMatchers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatchers.h; path = Expecta/Matchers/EXPMatchers.h; sourceTree = ""; }; + C5E2A317B34E97C0BC9E7D8A5432134F /* SentryCrashObjCApple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashObjCApple.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashObjCApple.h; sourceTree = ""; }; + C5F608D42A6E990A153F1AB8E208946B /* SDInternalMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDInternalMacros.h; path = SDWebImage/Private/SDInternalMacros.h; sourceTree = ""; }; + C61D629079DD747B52BE9B257FF97536 /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/Views/AnimatedImageView.swift; sourceTree = ""; }; + C7C372CE3D39CEC75B4CF8BEFF4657D6 /* Sentry-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Sentry-macOS.release.xcconfig"; sourceTree = ""; }; + C7EBFD7698607DF70418A78E51D73576 /* OCMock.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = OCMock.release.xcconfig; sourceTree = ""; }; + C7FE1EF9F428C6334E0F097B069FC11C /* SentryCrashReportFields.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportFields.h; path = Sources/SentryCrash/Recording/SentryCrashReportFields.h; sourceTree = ""; }; + C871A5023CDCEF1BAB6E6FD1DEE58644 /* SentryCrashMonitor_System.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_System.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h; sourceTree = ""; }; + C885E0C6872E0DD37AE7F83D152E4CC8 /* SentryHttpDateParser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryHttpDateParser.h; path = Sources/Sentry/include/SentryHttpDateParser.h; sourceTree = ""; }; + C932E34914D61B118DFFB14264E4F46F /* SentryCrashSysCtl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashSysCtl.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.h; sourceTree = ""; }; + CA279AE3C2EB34F9499A2B45631985DE /* SentryCrashReportFixer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportFixer.h; path = Sources/SentryCrash/Recording/SentryCrashReportFixer.h; sourceTree = ""; }; + CAAE2845DDE3787AE62AC63FD77B83AE /* SentrySpanContext.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentrySpanContext.m; path = Sources/Sentry/SentrySpanContext.m; sourceTree = ""; }; + CAD47560D17493EDE1906F5E071CE326 /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; + CADE90E5E97059DA721F894B29C72DBC /* SentrySession+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SentrySession+Private.h"; path = "Sources/Sentry/include/SentrySession+Private.h"; sourceTree = ""; }; + CB32A5329227AA32586B5F39F8AC262F /* NSString+SentryUnsignedLongLongValue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSString+SentryUnsignedLongLongValue.m"; path = "Sources/Sentry/NSString+SentryUnsignedLongLongValue.m"; sourceTree = ""; }; + CB51C6354F85DBE35F75A892B2A35813 /* OCProtocolMockObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCProtocolMockObject.h; path = Source/OCMock/OCProtocolMockObject.h; sourceTree = ""; }; + CD2B67146BB65F60C7F9AA52A0242BB2 /* SDWebImageDownloaderOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderOperation.h; path = SDWebImage/SDWebImageDownloaderOperation.h; sourceTree = ""; }; + CD43EB3DB8F1A13F4F230EB3F12BD14D /* SentryCrashIsAppImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashIsAppImage.h; path = Sources/Sentry/include/SentryCrashIsAppImage.h; sourceTree = ""; }; + CD4A38B44E188BC0AE09430BFEDA430A /* SentryDsn.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryDsn.h; path = Sources/Sentry/Public/SentryDsn.h; sourceTree = ""; }; + CD9E7F9949C74A81F649A55858744F7D /* SentryDateUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryDateUtil.h; path = Sources/Sentry/include/SentryDateUtil.h; sourceTree = ""; }; + CDB702BF91B1964D255A4A5C424C327E /* NSString+SentryUnsignedLongLongValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSString+SentryUnsignedLongLongValue.h"; path = "Sources/Sentry/include/NSString+SentryUnsignedLongLongValue.h"; sourceTree = ""; }; + CDC039A57E303FB78B1A337C34F6D1D1 /* EXPMatchers+raiseWithReason.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+raiseWithReason.h"; path = "Expecta/Matchers/EXPMatchers+raiseWithReason.h"; sourceTree = ""; }; + CDE4D9299F0AF2CF5B0B8F25A0A284BE /* SentryCrashFileUtils.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashFileUtils.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.c; sourceTree = ""; }; + CEDD3F9A418E86363FCB41C14161DC01 /* SentryAppState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryAppState.h; path = Sources/Sentry/include/SentryAppState.h; sourceTree = ""; }; + CF16C145406DA3D8215F2D031636900B /* SentryCrashID.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashID.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashID.h; sourceTree = ""; }; + CF5EAFB93582013A51B76C904CC6049D /* EKObjectMapping.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKObjectMapping.m; path = Sources/EasyMapping/EKObjectMapping.m; sourceTree = ""; }; + CFCECE13EE1E489D7FE9331B3E9AA5A5 /* Sentry-tvOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "Sentry-tvOS-dummy.m"; path = "../Sentry-tvOS/Sentry-tvOS-dummy.m"; sourceTree = ""; }; + CFF959F28BA7ACD5D882BBA3D1C58893 /* Kingfisher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Kingfisher.h; path = Sources/Kingfisher.h; sourceTree = ""; }; + D01CF0850D3D4C872590CBFBDC03EB5A /* EXPMatchers+haveCountOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+haveCountOf.h"; path = "Expecta/Matchers/EXPMatchers+haveCountOf.h"; sourceTree = ""; }; + D10EBA641A0E8165BB44E4DE84E910B2 /* SentryAttachment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryAttachment.h; path = Sources/Sentry/Public/SentryAttachment.h; sourceTree = ""; }; + D11372170552F442945E0B5B17587894 /* SentryMeta.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryMeta.m; path = Sources/Sentry/SentryMeta.m; sourceTree = ""; }; + D17B64FED552F0A53E4F9A17E1256AB7 /* SDImageAPNGCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAPNGCoder.m; path = SDWebImage/SDImageAPNGCoder.m; sourceTree = ""; }; + D1CFE48E766C5DA9E609AC5092AAF2E7 /* SentryInternalNotificationNames.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryInternalNotificationNames.h; path = Sources/Sentry/include/SentryInternalNotificationNames.h; sourceTree = ""; }; + D1DC52144056CD5535375140BBE4CB3B /* NSMethodSignature+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSMethodSignature+OCMAdditions.m"; path = "Source/OCMock/NSMethodSignature+OCMAdditions.m"; sourceTree = ""; }; D1ED9B7F321F11235F0BE332E0790E64 /* libNSPopover+MISSINGBackgroundView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libNSPopover+MISSINGBackgroundView.a"; path = "libNSPopover+MISSINGBackgroundView.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - D2716E4B1649A8833BD6F9C1D271B8FF /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/Cache/CacheSerializer.swift; sourceTree = ""; }; - D4575EADBF96D18BF9DFAA46148F03C4 /* OCMFunctions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMFunctions.h; path = Source/OCMock/OCMFunctions.h; sourceTree = ""; }; - D485CBA57281576025CB61EA90A15158 /* OCMExpectationRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMExpectationRecorder.m; path = Source/OCMock/OCMExpectationRecorder.m; sourceTree = ""; }; - D493740B17BEFB6678A8F660966907B4 /* EXPMatchers+match.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+match.m"; path = "Expecta/Matchers/EXPMatchers+match.m"; sourceTree = ""; }; - D5099A766F6792981B7C98BC25284ECF /* libPods-BitriseATV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-BitriseATV.a"; path = "libPods-BitriseATV.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - D5AB3D0F067AB772EEF8D8D8D9A117DF /* SDImageCoderHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCoderHelper.m; path = SDWebImage/SDImageCoderHelper.m; sourceTree = ""; }; - D63ED8C5E87F5585A4A167D6E5FB9767 /* Mixpanel-macOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Mixpanel-macOS-dummy.m"; sourceTree = ""; }; - D7DBBFCB3167A86CC54D0C3B37C27514 /* EXPMatchers+beginWith.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beginWith.h"; path = "Expecta/Matchers/EXPMatchers+beginWith.h"; sourceTree = ""; }; - D83248A5D588A9C43ABA5B21486F7E1A /* EXPMatchers+beSupersetOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beSupersetOf.h"; path = "Expecta/Matchers/EXPMatchers+beSupersetOf.h"; sourceTree = ""; }; - D884EC3FBCA256B592A7BF175DB4A590 /* NSTextAttachment+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextAttachment+Kingfisher.swift"; path = "Sources/Extensions/NSTextAttachment+Kingfisher.swift"; sourceTree = ""; }; - D8E7588C6AFE9808A46E814936CA84E2 /* SDImageLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageLoader.h; path = SDWebImage/SDImageLoader.h; sourceTree = ""; }; - D9927B59B79490141F493494FE1CBDC3 /* SDWebImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloader.h; path = SDWebImage/SDWebImageDownloader.h; sourceTree = ""; }; - D9ABE2D50C0C884ED625EA5D881E8AC0 /* SDImageGIFCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGIFCoder.h; path = SDWebImage/SDImageGIFCoder.h; sourceTree = ""; }; - DA17C17C59D9A85314409E681085E34B /* EXPMatchers+equal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+equal.h"; path = "Expecta/Matchers/EXPMatchers+equal.h"; sourceTree = ""; }; - DAF61E9AD9175C992A05DFE48ACC2DA1 /* SDWebImageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageManager.h; path = SDWebImage/SDWebImageManager.h; sourceTree = ""; }; - DB0F4C1F56DCCAAEECFB8F0FA1242FBE /* SDmetamacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDmetamacros.h; path = SDWebImage/Private/SDmetamacros.h; sourceTree = ""; }; - DC92E918B3166C9B4C4BDB94D6E2FB81 /* OCMReturnValueProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMReturnValueProvider.m; path = Source/OCMock/OCMReturnValueProvider.m; sourceTree = ""; }; - DCDB3631B71D0F22347F02109F35CE70 /* OCMInvocationExpectation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMInvocationExpectation.h; path = Source/OCMock/OCMInvocationExpectation.h; sourceTree = ""; }; - DCEEF6F299FC1EF75CECA90833D64E31 /* SDImageTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageTransformer.h; path = SDWebImage/SDImageTransformer.h; sourceTree = ""; }; - DD84EF43057F7DFB3FA4F18A6B3077C3 /* EKPropertyMapping.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKPropertyMapping.m; path = Sources/EasyMapping/EKPropertyMapping.m; sourceTree = ""; }; - DE0029E0313EE4BBF6B907525159A0A5 /* NSArray+FlattenArray.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSArray+FlattenArray.h"; path = "Sources/EasyMapping/NSArray+FlattenArray.h"; sourceTree = ""; }; - DE6870ABB57D3FAD177D239F959883AA /* ImageProgressive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProgressive.swift; path = Sources/Image/ImageProgressive.swift; sourceTree = ""; }; - DE92320C17159F72A6BA50CD088843A8 /* SDImageCoderHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCoderHelper.h; path = SDWebImage/SDImageCoderHelper.h; sourceTree = ""; }; - DF94BD6EDCCFD2443825163FB8B65A38 /* EKManagedObjectMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKManagedObjectMapping.h; path = Sources/EasyMapping/EKManagedObjectMapping.h; sourceTree = ""; }; + D22AF5F63AD1761496D54AE9764983A6 /* OCMObserverRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMObserverRecorder.h; path = Source/OCMock/OCMObserverRecorder.h; sourceTree = ""; }; + D27C49F3B33A9DC4BA1676033B188637 /* SentryNSURLRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryNSURLRequest.h; path = Sources/Sentry/include/SentryNSURLRequest.h; sourceTree = ""; }; + D281AC19FFB91D8781E163939DDB432A /* NSButton+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSButton+WebCache.m"; path = "SDWebImage/NSButton+WebCache.m"; sourceTree = ""; }; + D31491006FD74023E72260AE10EAB3EA /* SentryUserFeedback.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryUserFeedback.m; path = Sources/Sentry/SentryUserFeedback.m; sourceTree = ""; }; + D42B31391B2FAC25C05285540C1CF6F6 /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/General/KingfisherOptionsInfo.swift; sourceTree = ""; }; + D4E58AC687FF6638E95247AC8D47481E /* SentryDebugMeta.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryDebugMeta.m; path = Sources/Sentry/SentryDebugMeta.m; sourceTree = ""; }; + D5139F1EF9D079FC16A2A8568E1BCA1F /* EKPropertyHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKPropertyHelper.m; path = Sources/EasyMapping/EKPropertyHelper.m; sourceTree = ""; }; + D5DE137007B263FBF5F21EC0F26AF27A /* SentryCrashDoctor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashDoctor.m; path = Sources/SentryCrash/Recording/SentryCrashDoctor.m; sourceTree = ""; }; + D60913A7573D0C51BD7A2D9982EA74E4 /* SentryGlobalEventProcessor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryGlobalEventProcessor.h; path = Sources/Sentry/include/SentryGlobalEventProcessor.h; sourceTree = ""; }; + D611C4E992B69008A1A656939508A290 /* SentryCrashDefaultBinaryImageProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashDefaultBinaryImageProvider.h; path = Sources/Sentry/include/SentryCrashDefaultBinaryImageProvider.h; sourceTree = ""; }; + D627A23129220606C34D687C6A9E1E86 /* ImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProvider.swift; path = Sources/General/ImageSource/ImageDataProvider.swift; sourceTree = ""; }; + D63CDF6E2D49F7055CDF917E715932E8 /* SentryOutOfMemoryTrackingIntegration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryOutOfMemoryTrackingIntegration.m; path = Sources/Sentry/SentryOutOfMemoryTrackingIntegration.m; sourceTree = ""; }; + D759D1EF7CB9A6791C8A65C27143C696 /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Views/Indicator.swift; sourceTree = ""; }; + D786DB1ACA3291F506237438289B40BA /* UIImage+GIF.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+GIF.h"; path = "SDWebImage/UIImage+GIF.h"; sourceTree = ""; }; + D7BC83D8B30962F7F9482DEAB81BF427 /* SentryDebugMetaBuilder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryDebugMetaBuilder.m; path = Sources/Sentry/SentryDebugMetaBuilder.m; sourceTree = ""; }; + D7C8972FA1895EECCF701E7E43D21BD0 /* NSNotificationCenter+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSNotificationCenter+OCMAdditions.m"; path = "Source/OCMock/NSNotificationCenter+OCMAdditions.m"; sourceTree = ""; }; + D7FF1BC66B772F592CC4BB58F4662E01 /* NSValue+Expecta.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSValue+Expecta.m"; path = "Expecta/NSValue+Expecta.m"; sourceTree = ""; }; + D8478733C770AD8B5E60B4BFFF6C7BFB /* SDAnimatedImageView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageView.m; path = SDWebImage/SDAnimatedImageView.m; sourceTree = ""; }; + D86F21A61B42BA1F53F84900700F92A6 /* MPNetwork.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MPNetwork.h; path = Mixpanel/MPNetwork.h; sourceTree = ""; }; + D8728A92B3768750BE8C034BB8A6C225 /* MPFoundation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MPFoundation.h; path = Mixpanel/MPFoundation.h; sourceTree = ""; }; + D88D303335E70DB46B148AF73F042D6E /* TracesSampler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = TracesSampler.m; path = Sources/Sentry/TracesSampler.m; sourceTree = ""; }; + D937487D98CF1317A50F757709136421 /* OCMMacroState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMMacroState.h; path = Source/OCMock/OCMMacroState.h; sourceTree = ""; }; + D94575F97C3B97906EA0DF45F8B3665F /* EKObjectModel.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKObjectModel.m; path = Sources/EasyMapping/EKObjectModel.m; sourceTree = ""; }; + D9612BF50019AFAE4BFFBC23DE2E36FB /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Sources/Utility/Result.swift; sourceTree = ""; }; + D9762FEC996DD0B9D2CB88F3325CEE40 /* UIImageView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImageView+WebCache.h"; path = "SDWebImage/UIImageView+WebCache.h"; sourceTree = ""; }; + D9BC90810FA98ED7665170917F955CB8 /* SentryDebugMetaBuilder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryDebugMetaBuilder.h; path = Sources/Sentry/include/SentryDebugMetaBuilder.h; sourceTree = ""; }; + DA34AA796C52BB44C0BD196FB3DFF6F8 /* SentryDefaultCurrentDateProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryDefaultCurrentDateProvider.h; path = Sources/Sentry/include/SentryDefaultCurrentDateProvider.h; sourceTree = ""; }; + DAD60C8C2D829AF89945E853ED1CA1F3 /* EXPMatchers+beFalsy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beFalsy.m"; path = "Expecta/Matchers/EXPMatchers+beFalsy.m"; sourceTree = ""; }; + DB9FF4A48AF84AF31680A56E61A2BF84 /* MixpanelType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelType.h; path = Mixpanel/MixpanelType.h; sourceTree = ""; }; + DC0181CAABD875283907391EB7A5F605 /* EXPMatchers+contain.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+contain.h"; path = "Expecta/Matchers/EXPMatchers+contain.h"; sourceTree = ""; }; + DC1A06E37E387E8DFDB3FAC7C71EADA3 /* SentryAutoBreadcrumbTrackingIntegration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryAutoBreadcrumbTrackingIntegration.h; path = Sources/Sentry/include/SentryAutoBreadcrumbTrackingIntegration.h; sourceTree = ""; }; + DC3A1C125FE9A2938808FC9189B98F86 /* SentryCrashThread.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashThread.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashThread.c; sourceTree = ""; }; + DC78BE6918A6EB0A9A1BB56F9F6F0F2F /* UIColor+HexString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIColor+HexString.h"; path = "SDWebImage/Private/UIColor+HexString.h"; sourceTree = ""; }; + DC8FE91A1ADA4F3ED0E95C05F4EFD64F /* SentryFrameRemover.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryFrameRemover.m; path = Sources/Sentry/SentryFrameRemover.m; sourceTree = ""; }; + DCD6C5ADDBAA1A94B1A204F0A2616531 /* SentryCrashDate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashDate.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashDate.h; sourceTree = ""; }; + DDF3E3AFB8E2DB0B1288BA44784E32C1 /* UIImage+Metadata.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Metadata.m"; path = "SDWebImage/UIImage+Metadata.m"; sourceTree = ""; }; + DE6AFAD4DA89E40DCBFF481259AAE455 /* NSInvocation+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSInvocation+OCMAdditions.m"; path = "Source/OCMock/NSInvocation+OCMAdditions.m"; sourceTree = ""; }; + DEBA5D47513477CC60EDE11609A69A63 /* NSBezierPath+RoundedCorners.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSBezierPath+RoundedCorners.h"; path = "SDWebImage/Private/NSBezierPath+RoundedCorners.h"; sourceTree = ""; }; + DF5D8291C1A5901C39977D7EC0026FDB /* SentryTransport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryTransport.h; path = Sources/Sentry/include/SentryTransport.h; sourceTree = ""; }; + DF6CA6E602B6EA673C00D2C1246FD365 /* SDWebImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImage.h; path = WebImage/SDWebImage.h; sourceTree = ""; }; + DF94D725DA123E1FA30C9D95416E1258 /* SDAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImage.h; path = SDWebImage/SDAnimatedImage.h; sourceTree = ""; }; + E018C8C2D434DF9416FE294E909F30D8 /* SentryFrameRemover.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryFrameRemover.h; path = Sources/Sentry/include/SentryFrameRemover.h; sourceTree = ""; }; + E030A61F17D17FD81E63D627666FECDB /* SizeExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SizeExtensions.swift; path = Sources/Utility/SizeExtensions.swift; sourceTree = ""; }; + E06EC8CDC64B1745C9173D810AF762B5 /* SentryEnvelope.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryEnvelope.h; path = Sources/Sentry/Public/SentryEnvelope.h; sourceTree = ""; }; E080202F8E0B54182443BA49E85C276D /* libPods-BitBotTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-BitBotTests.a"; path = "libPods-BitBotTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - E0B8907B5FA48B7D00DB2A720E163707 /* NSBezierPath+RoundedCorners.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSBezierPath+RoundedCorners.h"; path = "SDWebImage/Private/NSBezierPath+RoundedCorners.h"; sourceTree = ""; }; - E11CFD92FC370BCCF6D215A51D9C5197 /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = Sources/Cache/Storage.swift; sourceTree = ""; }; - E1F9C7D969CDEFF23E17FF615A85E88D /* SDImageCodersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCodersManager.h; path = SDWebImage/SDImageCodersManager.h; sourceTree = ""; }; - E36EE74316446360E858F1A44D7319F5 /* EXPExpect.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPExpect.m; path = Expecta/EXPExpect.m; sourceTree = ""; }; - E37875E266D4B7C82B4F961406679121 /* MixpanelExceptionHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelExceptionHandler.h; path = Mixpanel/MixpanelExceptionHandler.h; sourceTree = ""; }; - E40BB8DAF48D8157DA1CF09C26A8A2BB /* EKRelationshipMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKRelationshipMapping.h; path = Sources/EasyMapping/EKRelationshipMapping.h; sourceTree = ""; }; - E4B961693B51CABFAC71DD5C6A5A4BD9 /* SDAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImage.m; path = SDWebImage/SDAnimatedImage.m; sourceTree = ""; }; - E50EC90DBAC89E8993831BC6DC782C31 /* EXPMatchers+beKindOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beKindOf.h"; path = "Expecta/Matchers/EXPMatchers+beKindOf.h"; sourceTree = ""; }; - E53CB9C53DE644CC0018E828836F22E8 /* WKInterfaceImage+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKInterfaceImage+Kingfisher.swift"; path = "Sources/Extensions/WKInterfaceImage+Kingfisher.swift"; sourceTree = ""; }; - E5E86E996D1B62900F3CCF346D1721A1 /* EKMappingBlocks.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKMappingBlocks.h; path = Sources/EasyMapping/EKMappingBlocks.h; sourceTree = ""; }; - E64B5C4A3967E3452D518761D1B3B356 /* NSNotificationCenter+OCMAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSNotificationCenter+OCMAdditions.h"; path = "Source/OCMock/NSNotificationCenter+OCMAdditions.h"; sourceTree = ""; }; - E6D8C758008A57827694D4028880F6AF /* SDWebImageOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageOperation.h; path = SDWebImage/SDWebImageOperation.h; sourceTree = ""; }; - E87388CE197F1A31AEB8AD9280A4837C /* EXPMatchers+postNotification.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+postNotification.h"; path = "Expecta/Matchers/EXPMatchers+postNotification.h"; sourceTree = ""; }; - E9A310A735E4E90BCC6A9FD46539E260 /* NSImage+Compatibility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSImage+Compatibility.m"; path = "SDWebImage/NSImage+Compatibility.m"; sourceTree = ""; }; + E1874710A7496BA57237D6BDA6C21AC3 /* EXPMatchers+beLessThan.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beLessThan.h"; path = "Expecta/Matchers/EXPMatchers+beLessThan.h"; sourceTree = ""; }; + E1A2DA9F20E042F158279FE9D1897627 /* SessionMetadata.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SessionMetadata.m; path = Mixpanel/SessionMetadata.m; sourceTree = ""; }; + E1E2C83FDCC2689D4A0B69747EF511C0 /* SentryHexAddressFormatter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryHexAddressFormatter.h; path = Sources/Sentry/include/SentryHexAddressFormatter.h; sourceTree = ""; }; + E2A90A5DEB09F21EA190C89343DE0462 /* NSData+ImageContentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSData+ImageContentType.h"; path = "SDWebImage/NSData+ImageContentType.h"; sourceTree = ""; }; + E313C6D74AB03A8A9C0A213DFF159F90 /* SentryCrashDefaultMachineContextWrapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashDefaultMachineContextWrapper.m; path = Sources/Sentry/SentryCrashDefaultMachineContextWrapper.m; sourceTree = ""; }; + E3C41018B6941535465C50E902AC4F40 /* SDImageCoderHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCoderHelper.m; path = SDWebImage/SDImageCoderHelper.m; sourceTree = ""; }; + E482E15A51417B629DB9DA89BFC13FB6 /* SentryRandom.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryRandom.h; path = Sources/Sentry/include/SentryRandom.h; sourceTree = ""; }; + E4C37732B893111733DF0A4585B21DFD /* SentryHttpDateParser.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryHttpDateParser.m; path = Sources/Sentry/SentryHttpDateParser.m; sourceTree = ""; }; + E50C0637D8244791201E8A2D80B8B6DB /* SDWebImageDefine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDefine.h; path = SDWebImage/SDWebImageDefine.h; sourceTree = ""; }; + E5772F49F24A961F4D2A7CC2EF2C22D7 /* SentryCrashMonitor_CPPException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashMonitor_CPPException.h; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.h; sourceTree = ""; }; + E5B37F686C226E712A6CCF4F485ECD08 /* libSentry-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libSentry-tvOS.a"; path = "libSentry-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + E5D86D1F25D9DEDAABC2D4BF04C13638 /* SentryError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryError.h; path = Sources/Sentry/Public/SentryError.h; sourceTree = ""; }; + E637A1CA51A72009B436C19799A1EB1A /* SentryCrash.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrash.m; path = Sources/SentryCrash/Recording/SentryCrash.m; sourceTree = ""; }; + E6429B66FC50FB2E00DE7EBBD2B39441 /* SDWebImageCacheSerializer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCacheSerializer.m; path = SDWebImage/SDWebImageCacheSerializer.m; sourceTree = ""; }; + E73AE987835897A07BBC6DCC00651DCE /* SentrySerializable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySerializable.h; path = Sources/Sentry/Public/SentrySerializable.h; sourceTree = ""; }; + E7498EE2465516ED35F4F3252FDF30A4 /* ExpectaSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ExpectaSupport.h; path = Expecta/ExpectaSupport.h; sourceTree = ""; }; + E772C6FC8CD4F5F3153C1AD785CA8BB4 /* SentryCrashReportStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportStore.h; path = Sources/SentryCrash/Recording/SentryCrashReportStore.h; sourceTree = ""; }; + E7A20D0EF6CC27822F5F673A4C0CE300 /* SentryTransaction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryTransaction.h; path = Sources/Sentry/include/SentryTransaction.h; sourceTree = ""; }; + E7D07B95AE09FB5092665CB55709027B /* SentryCrashSysCtl.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashSysCtl.c; path = Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.c; sourceTree = ""; }; + E7E2786467AFA14CB5DA07F30C390C8E /* Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Expecta.h; path = Expecta/Expecta.h; sourceTree = ""; }; + E9A6894E165A917A3864A338D7E718A9 /* SentryCrashReport.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashReport.c; path = Sources/SentryCrash/Recording/SentryCrashReport.c; sourceTree = ""; }; E9B409220A02F6C80445A0AB2DB98F47 /* libMixpanel-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libMixpanel-macOS.a"; path = "libMixpanel-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - EA4CC493C28070726E85F63F85A7A9AE /* MixpanelGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelGroup.h; path = Mixpanel/MixpanelGroup.h; sourceTree = ""; }; - EA8160747C5E6AB38E0ACF3334FC8E0A /* SDWebImageDownloader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloader.m; path = SDWebImage/SDWebImageDownloader.m; sourceTree = ""; }; - EA9C39723282F9332BBB781FEF173318 /* Mixpanel-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Mixpanel-tvOS.release.xcconfig"; path = "../Mixpanel-tvOS/Mixpanel-tvOS.release.xcconfig"; sourceTree = ""; }; - EAAE51390887C89B5D97F214B2C00459 /* UIView+WebCacheOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIView+WebCacheOperation.m"; path = "SDWebImage/UIView+WebCacheOperation.m"; sourceTree = ""; }; - EB4E0393C303A359234E843EF87DF639 /* EKObjectModel.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKObjectModel.m; path = Sources/EasyMapping/EKObjectModel.m; sourceTree = ""; }; - ECA18B43D913EC3A721AAC261D96C6C7 /* SDImageCacheDefine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCacheDefine.h; path = SDWebImage/SDImageCacheDefine.h; sourceTree = ""; }; - EF50D0E3C285699A5C23F1433D765799 /* EKObjectMapping.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKObjectMapping.h; path = Sources/EasyMapping/EKObjectMapping.h; sourceTree = ""; }; - EF5ED803BC5085BF65F2CF57CD8552BE /* UIImage+Transform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Transform.h"; path = "SDWebImage/UIImage+Transform.h"; sourceTree = ""; }; - EF98DF418E129E42ACB5735BCF2BF2DA /* NSData+ImageContentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSData+ImageContentType.h"; path = "SDWebImage/NSData+ImageContentType.h"; sourceTree = ""; }; - EFBD8DF4B22DC67C05839F4DEFC4965E /* ExpectaObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ExpectaObject.m; path = Expecta/ExpectaObject.m; sourceTree = ""; }; - EFCD5E8499D6681EF43BD1B9686D12B6 /* EXPMatchers+beIdenticalTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beIdenticalTo.m"; path = "Expecta/Matchers/EXPMatchers+beIdenticalTo.m"; sourceTree = ""; }; - F0526B10B105C72A02DCB7A5FE5042FD /* SDImageAPNGCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAPNGCoder.h; path = SDWebImage/SDImageAPNGCoder.h; sourceTree = ""; }; - F1A219168B99676409EC7DFBA7644FD2 /* EXPMatchers+beFalsy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beFalsy.m"; path = "Expecta/Matchers/EXPMatchers+beFalsy.m"; sourceTree = ""; }; - F2DF1B744FF4D6FEE1E610217915FC33 /* EXPExpect.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPExpect.h; path = Expecta/EXPExpect.h; sourceTree = ""; }; - F2F4BAD2957BC72E97702E11DDD7C68F /* SDWebImageDownloaderConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderConfig.m; path = SDWebImage/SDWebImageDownloaderConfig.m; sourceTree = ""; }; + EAC198E0EA2F49AA7D4D66A51EE2F528 /* SentryLevelMapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryLevelMapper.m; path = Sources/Sentry/SentryLevelMapper.m; sourceTree = ""; }; + EB76A04ABD9F9A9253A632D1D64AFC25 /* SDWebImageDownloader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloader.m; path = SDWebImage/SDWebImageDownloader.m; sourceTree = ""; }; + EBF50F815E871FC102F8AA6473815C6C /* SentryCrashReportFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashReportFilter.h; path = Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilter.h; sourceTree = ""; }; + EC1A9E5F4BFAB7EC1F350C715A897657 /* SDImageCachesManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCachesManager.m; path = SDWebImage/SDImageCachesManager.m; sourceTree = ""; }; + EC1EEE25B6064557720CF2B1812DF2FD /* SentryStacktraceBuilder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryStacktraceBuilder.h; path = Sources/Sentry/include/SentryStacktraceBuilder.h; sourceTree = ""; }; + EC93C90F2B5676049CC384D0AB9C6972 /* SentryAutoSessionTrackingIntegration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryAutoSessionTrackingIntegration.m; path = Sources/Sentry/SentryAutoSessionTrackingIntegration.m; sourceTree = ""; }; + ECAA70483A39BCA0C0C7E356FB322F42 /* EXPFloatTuple.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPFloatTuple.m; path = Expecta/EXPFloatTuple.m; sourceTree = ""; }; + EE191BC83E04210BBFF33CDC23B799B5 /* EXPBlockDefinedMatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPBlockDefinedMatcher.h; path = Expecta/EXPBlockDefinedMatcher.h; sourceTree = ""; }; + EE4528E0DF692080615D4E109A960DBD /* SentrySpan.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentrySpan.h; path = Sources/Sentry/include/SentrySpan.h; sourceTree = ""; }; + EE73BC7E6B9CE2CE444F233D3BD368DA /* OCMConstraint.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMConstraint.h; path = Source/OCMock/OCMConstraint.h; sourceTree = ""; }; + EE988064E682B9A56B6A0555F5C13ADF /* NSDate+SentryExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSDate+SentryExtras.h"; path = "Sources/Sentry/include/NSDate+SentryExtras.h"; sourceTree = ""; }; + EF4162342FE010A64DF41F62EFFE32FC /* SentryScope.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryScope.h; path = Sources/Sentry/Public/SentryScope.h; sourceTree = ""; }; + EF55C9584F47C438713DC40D4B95320A /* SentryConcurrentRateLimitsDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryConcurrentRateLimitsDictionary.m; path = Sources/Sentry/SentryConcurrentRateLimitsDictionary.m; sourceTree = ""; }; + EFA3E94236148B21C103665DBDE36A19 /* OCObserverMockObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCObserverMockObject.m; path = Source/OCMock/OCObserverMockObject.m; sourceTree = ""; }; + F0A2594C9B5A62A6BFE259F3838B7420 /* SDImageLoadersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageLoadersManager.m; path = SDWebImage/SDImageLoadersManager.m; sourceTree = ""; }; + F0B2CB9BEC64D0147EDC960E67516CE5 /* OCMObserverRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMObserverRecorder.m; path = Source/OCMock/OCMObserverRecorder.m; sourceTree = ""; }; + F0B701C1D482E92F4504D38FE92A930F /* SentryCrashCString.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashCString.m; path = Sources/SentryCrash/Reporting/Tools/SentryCrashCString.m; sourceTree = ""; }; + F1EA89C71E01F52BE17CFAEEE8951B4E /* EXPMatchers+contain.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+contain.m"; path = "Expecta/Matchers/EXPMatchers+contain.m"; sourceTree = ""; }; + F1EDFC2372A9C734629885AC1A91E4AE /* OCMInvocationMatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMInvocationMatcher.h; path = Source/OCMock/OCMInvocationMatcher.h; sourceTree = ""; }; + F1EEA3D5D4E1598D0CBCE3D4DDBF2997 /* SentryMechanismMeta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryMechanismMeta.h; path = Sources/Sentry/Public/SentryMechanismMeta.h; sourceTree = ""; }; + F2C7A6B01B0431E52F0426FFA9FA836E /* EKManagedObjectMapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKManagedObjectMapper.h; path = Sources/EasyMapping/EKManagedObjectMapper.h; sourceTree = ""; }; + F2D31996EC48D78A198DBE8858B6151B /* EXPMatchers+beSubclassOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beSubclassOf.h"; path = "Expecta/Matchers/EXPMatchers+beSubclassOf.h"; sourceTree = ""; }; + F2F27DBEE78FB424F0C52D196487096B /* SentryFrameInAppLogic.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryFrameInAppLogic.m; path = Sources/Sentry/SentryFrameInAppLogic.m; sourceTree = ""; }; F30C125DB91902F63DC73AEF0B0E6111 /* libOCMock.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libOCMock.a; path = libOCMock.a; sourceTree = BUILT_PRODUCTS_DIR; }; - F3984CAB8C188467A7244F99E6549DBA /* SDWebImageCacheSerializer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCacheSerializer.h; path = SDWebImage/SDWebImageCacheSerializer.h; sourceTree = ""; }; - F4BC3BB600D3B7C15CE82551B31038F4 /* SDMemoryCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDMemoryCache.h; path = SDWebImage/SDMemoryCache.h; sourceTree = ""; }; - F51B87BA367652C3BCC69A7011799597 /* EXPMatchers+beLessThanOrEqualTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beLessThanOrEqualTo.m"; path = "Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.m"; sourceTree = ""; }; - F51DC93A2A3D54A2D4F61A23822537CE /* OCMPassByRefSetter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMPassByRefSetter.m; path = Source/OCMock/OCMPassByRefSetter.m; sourceTree = ""; }; - F59A8E40E78247C519309C3B12780135 /* RetryStrategy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryStrategy.swift; path = Sources/Networking/RetryStrategy.swift; sourceTree = ""; }; - F636E0DDE0B197D611D4A55CAA456E8A /* SDWebImageError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageError.h; path = SDWebImage/SDWebImageError.h; sourceTree = ""; }; - F64D0719D26112193FCA87432721368E /* SDImageGraphics.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageGraphics.m; path = SDWebImage/SDImageGraphics.m; sourceTree = ""; }; - F6C56A9F51004DF35A9E404C806859D9 /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Sources/Utility/Result.swift; sourceTree = ""; }; - F793FB1C97CF78722676CC204B89E8E5 /* EXPMatchers+beInTheRangeOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beInTheRangeOf.m"; path = "Expecta/Matchers/EXPMatchers+beInTheRangeOf.m"; sourceTree = ""; }; - F7E833D00F12D9C5B291BDACCB608EF3 /* SDWebImageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageManager.m; path = SDWebImage/SDWebImageManager.m; sourceTree = ""; }; - F8C2BCD9F1BBFAAB59F270D2B46CF7FC /* MixpanelGroupPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MixpanelGroupPrivate.h; path = Mixpanel/MixpanelGroupPrivate.h; sourceTree = ""; }; - FB5F5C16EA219A45277F93692511FE19 /* EXPMatchers+beLessThan.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beLessThan.h"; path = "Expecta/Matchers/EXPMatchers+beLessThan.h"; sourceTree = ""; }; - FB705C2A74FFD57028D54FF85DF69212 /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/Extensions/ImageView+Kingfisher.swift"; sourceTree = ""; }; - FB7834F6AE8114671D7CB158B5EFFCA3 /* EKObjectModel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKObjectModel.h; path = Sources/EasyMapping/EKObjectModel.h; sourceTree = ""; }; - FBBE22C9909097D742F0E488B3666B9D /* Pods-BitBotTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-BitBotTests.release.xcconfig"; sourceTree = ""; }; - FD2AF4F508F39F4D9663F4F03F9771E5 /* Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Expecta.h; path = Expecta/Expecta.h; sourceTree = ""; }; - FD36DF9DEA7AAFADFD9A80C290313970 /* EXPMatcherHelpers.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPMatcherHelpers.m; path = Expecta/Matchers/EXPMatcherHelpers.m; sourceTree = ""; }; - FE7AEC369A0AEE80E22A9B7E80A1E866 /* OCMInvocationMatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMInvocationMatcher.h; path = Source/OCMock/OCMInvocationMatcher.h; sourceTree = ""; }; - FE84606C704FBD829A674F2E080A6873 /* NSBezierPath+RoundedCorners.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSBezierPath+RoundedCorners.m"; path = "SDWebImage/Private/NSBezierPath+RoundedCorners.m"; sourceTree = ""; }; - FF0058A401EA270668A032E2940DB3A9 /* UIImage+MemoryCacheCost.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+MemoryCacheCost.h"; path = "SDWebImage/UIImage+MemoryCacheCost.h"; sourceTree = ""; }; - FF9D2408F0179139A6EE67D8C782CADB /* Deprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Deprecated.swift; path = Sources/General/Deprecated.swift; sourceTree = ""; }; - FFD7C099325EE5900027A4F8102FF204 /* UIImageView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+WebCache.m"; path = "SDWebImage/UIImageView+WebCache.m"; sourceTree = ""; }; + F317A88BF3EC0E25B9D3EEEE2368BF99 /* SentryLog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryLog.m; path = Sources/Sentry/SentryLog.m; sourceTree = ""; }; + F3258D01C395815147B1578AF9AFD710 /* UIButton+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIButton+WebCache.h"; path = "SDWebImage/UIButton+WebCache.h"; sourceTree = ""; }; + F3864646ED479BF8F6292472141DE6C4 /* MixpanelPeople.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MixpanelPeople.m; path = Mixpanel/MixpanelPeople.m; sourceTree = ""; }; + F39921B3FB050F3374B5EC60FC1119BE /* EKPropertyMapping.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EKPropertyMapping.m; path = Sources/EasyMapping/EKPropertyMapping.m; sourceTree = ""; }; + F3A79920CFA1BDBD9E75FB348D29B205 /* SentryCrashMonitor_Signal.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashMonitor_Signal.c; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.c; sourceTree = ""; }; + F3E5EA14068E6E74A749A04470626998 /* NSObject+Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+Expecta.h"; path = "Expecta/NSObject+Expecta.h"; sourceTree = ""; }; + F4AEF7C2E260CF1EAEC434B6350410F7 /* EXPMatchers+haveCountOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+haveCountOf.m"; path = "Expecta/Matchers/EXPMatchers+haveCountOf.m"; sourceTree = ""; }; + F4C3B484D92B78C21F5D450A1F3A5B12 /* SentryHub+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SentryHub+Private.h"; path = "Sources/Sentry/include/SentryHub+Private.h"; sourceTree = ""; }; + F5E6AD007B410E94A2BBD08C73803082 /* SentryEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryEvent.m; path = Sources/Sentry/SentryEvent.m; sourceTree = ""; }; + F5F2B1490B6DD7BB39A64E8C982E68A6 /* SDImageCacheConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCacheConfig.h; path = SDWebImage/SDImageCacheConfig.h; sourceTree = ""; }; + F714842293BA367D0CABC101D6E183F2 /* GIFAnimatedImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GIFAnimatedImage.swift; path = Sources/Image/GIFAnimatedImage.swift; sourceTree = ""; }; + F7799C05177DB8BEF9236E1AF5D9AA12 /* NSPopover+MISSINGBackgroundView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSPopover+MISSINGBackgroundView.h"; path = "Pod/Classes/NSPopover+MISSINGBackgroundView.h"; sourceTree = ""; }; + F77BFB3507FA24ADF2D491C22BDA2118 /* SDImageCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCoder.h; path = SDWebImage/SDImageCoder.h; sourceTree = ""; }; + F7D074B3F94A6FA8E0911B6B79FCE292 /* SentryOptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryOptions.h; path = Sources/Sentry/Public/SentryOptions.h; sourceTree = ""; }; + F7D9640F4FF58EE0BFA4681BD8524652 /* NSObject+OCMAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+OCMAdditions.m"; path = "Source/OCMock/NSObject+OCMAdditions.m"; sourceTree = ""; }; + F80977F97FF7554E700DD6D4126D3A7F /* SentryDefaultRateLimits.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryDefaultRateLimits.m; path = Sources/Sentry/SentryDefaultRateLimits.m; sourceTree = ""; }; + F8651300AE05A68F5000B0FEDFB83E6E /* SentryCrashMonitor_NSException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SentryCrashMonitor_NSException.m; path = Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.m; sourceTree = ""; }; + F8678DC07C3A0A61B18287BFACB10934 /* SentryCrashStackEntryMapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashStackEntryMapper.h; path = Sources/Sentry/include/SentryCrashStackEntryMapper.h; sourceTree = ""; }; + F8E6838B2952D27DD32D3B00DF7C1B66 /* OCMInvocationMatcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = OCMInvocationMatcher.m; path = Source/OCMock/OCMInvocationMatcher.m; sourceTree = ""; }; + F8F3224D9568E6D6B837E95D55B0F917 /* SentryRateLimits.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryRateLimits.h; path = Sources/Sentry/include/SentryRateLimits.h; sourceTree = ""; }; + F97C641D4A8FFBE3CBDB534ACFE13EBA /* SentryCrashReportFixer.c */ = {isa = PBXFileReference; includeInIndex = 1; name = SentryCrashReportFixer.c; path = Sources/SentryCrash/Recording/SentryCrashReportFixer.c; sourceTree = ""; }; + FA8333751F570A5824ED5639096D2900 /* UIImage+Transform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Transform.h"; path = "SDWebImage/UIImage+Transform.h"; sourceTree = ""; }; + FB4D53C11D7F99FD3BC21C897B80C49B /* EKCoreDataImporter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKCoreDataImporter.h; path = Sources/EasyMapping/EKCoreDataImporter.h; sourceTree = ""; }; + FBE1E2A79F4BFD1C2ED9B7F27661C283 /* SDImageCoderHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCoderHelper.h; path = SDWebImage/SDImageCoderHelper.h; sourceTree = ""; }; + FC629D7EE5D4E3D25A8DC71977FB9A70 /* SentryEnvelopeItemType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryEnvelopeItemType.h; path = Sources/Sentry/Public/SentryEnvelopeItemType.h; sourceTree = ""; }; + FC95A102DAE7A1D73682B3D27AA87AD8 /* Mixpanel-tvOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "Mixpanel-tvOS-prefix.pch"; path = "../Mixpanel-tvOS/Mixpanel-tvOS-prefix.pch"; sourceTree = ""; }; + FD09A0A8C776D6C7C89CC9A450B4C376 /* EXPMatchers+beGreaterThan.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beGreaterThan.h"; path = "Expecta/Matchers/EXPMatchers+beGreaterThan.h"; sourceTree = ""; }; + FD1BA966CD9EDA0D91BE150F4DDEFEAD /* OCMReturnValueProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = OCMReturnValueProvider.h; path = Source/OCMock/OCMReturnValueProvider.h; sourceTree = ""; }; + FE765919E608D58C7F7808F9D1CD06FF /* SDWebImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.release.xcconfig; sourceTree = ""; }; + FEDE59956F01BAB8149B4FE239EBD53A /* EKPropertyHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EKPropertyHelper.h; path = Sources/EasyMapping/EKPropertyHelper.h; sourceTree = ""; }; + FF122E9704C7DFBCE5DFE35410F55E32 /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Image/Placeholder.swift; sourceTree = ""; }; + FF14B9E54E4823DBAA00FF762A1568CE /* SentryDefaultRateLimits.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryDefaultRateLimits.h; path = Sources/Sentry/include/SentryDefaultRateLimits.h; sourceTree = ""; }; + FF9C78A3E1CB9EF63637883B8EB32A9D /* SentryCrashStackCursor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SentryCrashStackCursor.h; path = Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 08C46F08A460541B973B18FCA1696A65 /* Frameworks */ = { + 1AE61C9B9057F97684EE72AED6241999 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 1AE61C9B9057F97684EE72AED6241999 /* Frameworks */ = { + 2836C5AA3B809D7000F0E459D52CA94A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 1EA450F97847E6DD061D87A5E0922369 /* Frameworks */ = { + 5BB493345968306178E4EB14AA0243B6 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 2836C5AA3B809D7000F0E459D52CA94A /* Frameworks */ = { + 5D224C12B5501195C58017F069561795 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 5BB493345968306178E4EB14AA0243B6 /* Frameworks */ = { + 734751269D7D53DCF1B21966A4616524 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 734751269D7D53DCF1B21966A4616524 /* Frameworks */ = { + 7BEA3D9019E4FDFCACCA8685F4D5551F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 7BEA3D9019E4FDFCACCA8685F4D5551F /* Frameworks */ = { + 8D363785CE11370BD4C44703D64F42F0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 8209CF3A735AFBB93189E3D4BC0BF3AA /* Frameworks */ = { + A30B9605D92124983E25EE53BE79A1C1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 8D363785CE11370BD4C44703D64F42F0 /* Frameworks */ = { + BAE34610F1A8C5B8E5B3A8C5D66C68BC /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -1014,6 +1991,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D749AAD97CD31854E742276AC771C73A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DD7550735958432B251541845AA1A53F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; FC92D6E4A445D045DF36E9BA55C834D8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1024,277 +2015,310 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0D52C5FC1CFA59718787E43CBB7ACB80 /* Core */ = { + 1372CFF84AF9666CCDD3BEE2BE07B8E4 /* Targets Support Files */ = { isa = PBXGroup; children = ( - A6ABFDFEBAB6F775540166E8CB0A76EF /* EasyMapping.h */, - 73CA4DF78364101A233A47EDD6EEA713 /* EKCoreDataImporter.h */, - 189145CF4A26929B148653BA2D875C0D /* EKCoreDataImporter.m */, - 06603B8AC9B141505673852488A83DE1 /* EKManagedObjectMapper.h */, - 72B0ED45761C3EADB29E9166055000A4 /* EKManagedObjectMapper.m */, - DF94BD6EDCCFD2443825163FB8B65A38 /* EKManagedObjectMapping.h */, - 5C141A466F16A0C707E292C28A7A0411 /* EKManagedObjectMapping.m */, - 8CF995B7342B40A45E27459B69A702C2 /* EKManagedObjectModel.h */, - 249B7DEFAAD79ED621BF410C85E4E76A /* EKManagedObjectModel.m */, - 0C3CBC28B037AB6A9DBB7C58473725CF /* EKMapper.h */, - 4E8CE8F303F0D4706A0082068622A245 /* EKMapper.m */, - E5E86E996D1B62900F3CCF346D1721A1 /* EKMappingBlocks.h */, - 39819557A29A9D29DD6D53EB13C399F4 /* EKMappingBlocks.m */, - 8D6A91E801016258D4C031AE91650396 /* EKMappingProtocol.h */, - EF50D0E3C285699A5C23F1433D765799 /* EKObjectMapping.h */, - 83490DAFF67A0197CFB5F511B3FE126F /* EKObjectMapping.m */, - FB7834F6AE8114671D7CB158B5EFFCA3 /* EKObjectModel.h */, - EB4E0393C303A359234E843EF87DF639 /* EKObjectModel.m */, - A6CF50AFABAA83508F094E26284AF209 /* EKPropertyHelper.h */, - 355A7BC4978D41B9A315D86124F632C4 /* EKPropertyHelper.m */, - 92C2004006AECCC51DCE4B55AD73B019 /* EKPropertyMapping.h */, - DD84EF43057F7DFB3FA4F18A6B3077C3 /* EKPropertyMapping.m */, - E40BB8DAF48D8157DA1CF09C26A8A2BB /* EKRelationshipMapping.h */, - 4BFF7D460EC190F4EF6ED180A3017FC0 /* EKRelationshipMapping.m */, - 6E042C755F61BFCB46472E73B468A7F8 /* EKSerializer.h */, - 3494C85ECF06448B0147FD86227506AA /* EKSerializer.m */, - DE0029E0313EE4BBF6B907525159A0A5 /* NSArray+FlattenArray.h */, - 57148ECBF1DD36D149E773F13491AC48 /* NSArray+FlattenArray.m */, - AAEDA914FE1738DB4662140B337F1253 /* NSDateFormatter+EasyMappingAdditions.h */, + 1A1180CDEA41C596185CA91B31A3B29C /* Pods-BitBot */, + 6684DD12711CB3465E66DFE68763CF4A /* Pods-BitBotATV */, + 5BCBCE4A0FA422061D0BA7A9F8813035 /* Pods-BitBotTests */, ); - name = Core; + name = "Targets Support Files"; + sourceTree = ""; + }; + 1A1180CDEA41C596185CA91B31A3B29C /* Pods-BitBot */ = { + isa = PBXGroup; + children = ( + 14A5388595A1D1C81EF01AB89A8478D4 /* Pods-BitBot-acknowledgements.markdown */, + 6D36DF8121B4044216DF887F9A7EA8BD /* Pods-BitBot-acknowledgements.plist */, + 0B84BCB752C7801A42B7566DCD7F888B /* Pods-BitBot-dummy.m */, + 4FD1228EA2E85C9985EC483AD3EEC37E /* Pods-BitBot.debug.xcconfig */, + B9A9599914DD2E69DFA3308658CC6D8D /* Pods-BitBot.release.xcconfig */, + ); + name = "Pods-BitBot"; + path = "Target Support Files/Pods-BitBot"; sourceTree = ""; }; - 0F044C1E909B65B27C6DAA0A1CDA92EA /* Pods-BitriseATV */ = { + 1DF5CA0FF253D0D6E8E067B9CA1823FF /* Support Files */ = { isa = PBXGroup; children = ( - 6F1DE796615553F706BC5482E0896830 /* Pods-BitriseATV.modulemap */, - 166E5AA4004AA292F3940708D09686C0 /* Pods-BitriseATV-acknowledgements.markdown */, - 044181C5DB4A0D04183ABE8F9B246D79 /* Pods-BitriseATV-acknowledgements.plist */, - 0737FD1FACF633D70616CB317F2EC64C /* Pods-BitriseATV-dummy.m */, - 8734B79633EB68199F968AD242A66EC8 /* Pods-BitriseATV-umbrella.h */, - 3B555045479DF24DFFDE23E9DBFADB5E /* Pods-BitriseATV.debug.xcconfig */, - 7836184F3B8A75E0D19FAB2308E5024E /* Pods-BitriseATV.release.xcconfig */, - ); - name = "Pods-BitriseATV"; - path = "Target Support Files/Pods-BitriseATV"; + B871ADB422CB46B0A68EFB7C06F829F5 /* Mixpanel-macOS-dummy.m */, + C1170EDAC4979B5BA7E361047AC4B2AC /* Mixpanel-macOS-prefix.pch */, + 4DB313DA821938D69711108885AC28DC /* Mixpanel-macOS.debug.xcconfig */, + 053C481FDFE0573C79EB67973EAB3864 /* Mixpanel-macOS.release.xcconfig */, + 7FB28F864B2530B901ECC2199761359A /* Mixpanel-tvOS-dummy.m */, + FC95A102DAE7A1D73682B3D27AA87AD8 /* Mixpanel-tvOS-prefix.pch */, + 001C309BA5BC26FE8099864DCB397F9B /* Mixpanel-tvOS.debug.xcconfig */, + 34F08715426C01748685B152C7ADCAFA /* Mixpanel-tvOS.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/Mixpanel-macOS"; sourceTree = ""; }; - 107F45AEBF55A0D98E99D105DDEFBDEC /* SDWebImage */ = { + 37CFDA1DFE292FDBBC35ED96F460A104 /* Kingfisher */ = { isa = PBXGroup; children = ( - 86F7B9CC679A8C8DEE9428DAE2B6E17F /* Core */, - 1D2DEC674F67758A15BBA44C2A4844B6 /* Support Files */, + 6744B7B7BB7AE523C1818F0F621B804F /* Core */, + 72DA2E88250883AA2A51BFA39F49079C /* Support Files */, + ABD8C909FEF34671B34631A1B56A9835 /* SwiftUI */, ); - name = SDWebImage; - path = SDWebImage; + name = Kingfisher; + path = Kingfisher; sourceTree = ""; }; - 1D2DEC674F67758A15BBA44C2A4844B6 /* Support Files */ = { + 4EA53F896B2F7FA4EC381E297B2693DA /* EasyMapping */ = { isa = PBXGroup; children = ( - 14BF7FAE70B1B4B7DAA59DBCEB9CF9B8 /* SDWebImage-dummy.m */, - 64E775D257ACD72CBD411B058EA94408 /* SDWebImage-prefix.pch */, - C5120B28D0AE9A8B5959FFD25D7546BC /* SDWebImage.debug.xcconfig */, - A98D77B9153B7AB9A55C572FEB29D582 /* SDWebImage.release.xcconfig */, + A2B90001DA7C6262FFB271F8B1C19777 /* Core */, + EC0463D1AEDC6B911535371FDB9FB238 /* Support Files */, ); - name = "Support Files"; - path = "../Target Support Files/SDWebImage"; + name = EasyMapping; + path = EasyMapping; sourceTree = ""; }; - 1FC50B83D29B4182C6134983B9BA472A /* Pods */ = { + 55E1EF58993792E5314D82EB663FB5F8 /* NSPopover+MISSINGBackgroundView */ = { isa = PBXGroup; children = ( - EF8CE1F90CAB5D9208B75263EE621687 /* EasyMapping */, - CBE7EF899B7F10B020B1A1471B20ACE2 /* Expecta */, - 7EC1A663CB6C81FAC632D79B03038BB6 /* Kingfisher */, - A82C623B25ECB3A13AE3D6351192EF21 /* Mixpanel */, - 3936EF51BE2AC2A6EF625AB6F98903C8 /* NSPopover+MISSINGBackgroundView */, - 3F4BD49B9D17EC097B20FB0BF69C9CDB /* OCMock */, - 107F45AEBF55A0D98E99D105DDEFBDEC /* SDWebImage */, + F7799C05177DB8BEF9236E1AF5D9AA12 /* NSPopover+MISSINGBackgroundView.h */, + 4480333F342523BA7314F31E49980C8A /* NSPopover+MISSINGBackgroundView.m */, + A781BB95CDF652F02AEE8764FB4500C2 /* Support Files */, ); - name = Pods; + name = "NSPopover+MISSINGBackgroundView"; + path = "NSPopover+MISSINGBackgroundView"; sourceTree = ""; }; - 24A7452F80A07CE0EECFC76CCB9D9648 /* Support Files */ = { + 5AB4C80A295CE81464F7BF07A8E03069 /* Support Files */ = { isa = PBXGroup; children = ( - 6AD3C6229239FD004ECDF3767CC55B62 /* OCMock-dummy.m */, - 0E5FFCEAE0562BAE4C8E1775E814D99E /* OCMock-prefix.pch */, - 4072B0EAE2E33D5AB029517D512D41C4 /* OCMock.debug.xcconfig */, - 5B4DD3877C768331D8354899F3365C4F /* OCMock.release.xcconfig */, + C4A6679DBB5BEDCF84D9F0F1B2E6204D /* Sentry-macOS-dummy.m */, + 83B0A87BB96EDBECBD9BCB1443F6108A /* Sentry-macOS-prefix.pch */, + 37CFFB37B0F2EA6788D515BD2C299784 /* Sentry-macOS.debug.xcconfig */, + C7C372CE3D39CEC75B4CF8BEFF4657D6 /* Sentry-macOS.release.xcconfig */, + CFCECE13EE1E489D7FE9331B3E9AA5A5 /* Sentry-tvOS-dummy.m */, + 489798041B2405CC8A490AB0B42C55D7 /* Sentry-tvOS-prefix.pch */, + B37D0C9232F6AFE55239134BD3478B63 /* Sentry-tvOS.debug.xcconfig */, + 12975D01A5CEFC84922A28BC64869E48 /* Sentry-tvOS.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/OCMock"; + path = "../Target Support Files/Sentry-macOS"; sourceTree = ""; }; - 3385C7455987DC0240B4BDB90CF06FA4 /* SwiftUI */ = { + 5BCBCE4A0FA422061D0BA7A9F8813035 /* Pods-BitBotTests */ = { isa = PBXGroup; children = ( - 8C6D94943ABA018F8FE56BDBE9FC1191 /* ImageBinder.swift */, - ABC34D53E5B62AFBC01AA6E7C79EDFE4 /* KFImage.swift */, + 8C26A4BB3B912B165DC20DB7D54CB0C8 /* Pods-BitBotTests-acknowledgements.markdown */, + 456AD22FE7425CEF9CCB07B74D2628F0 /* Pods-BitBotTests-acknowledgements.plist */, + 2DB85262F5F33A0C16F18E0EB8E0C8CF /* Pods-BitBotTests-dummy.m */, + 17A69362E1FC166F5C2F8F3C55D67E3F /* Pods-BitBotTests.debug.xcconfig */, + AA2793A28BA2F2951479D61E76981AF6 /* Pods-BitBotTests.release.xcconfig */, ); - name = SwiftUI; + name = "Pods-BitBotTests"; + path = "Target Support Files/Pods-BitBotTests"; sourceTree = ""; }; - 3936EF51BE2AC2A6EF625AB6F98903C8 /* NSPopover+MISSINGBackgroundView */ = { + 6684DD12711CB3465E66DFE68763CF4A /* Pods-BitBotATV */ = { isa = PBXGroup; children = ( - A31D86646D8CE32EACAB67E8117537C0 /* NSPopover+MISSINGBackgroundView.h */, - 38F1E72982CFDB8599746F32A1F0AE2B /* NSPopover+MISSINGBackgroundView.m */, - D259B3C87B5716DBA090C82854E3B135 /* Support Files */, + 618DA7F1FC6944A9A00D902E64D718B7 /* Pods-BitBotATV.modulemap */, + 4B8128A487CD674959BF7DC3296CA01D /* Pods-BitBotATV-acknowledgements.markdown */, + 21C7B5AF640DAF194C58F14F0E88A87D /* Pods-BitBotATV-acknowledgements.plist */, + 2B8B4F5B5F48C2BEC0FE0781579AF143 /* Pods-BitBotATV-dummy.m */, + 3B724904092136FEEDB93380DA4070C0 /* Pods-BitBotATV-umbrella.h */, + 70B4ECF8EB965BEFCBC17F7120D404FA /* Pods-BitBotATV.debug.xcconfig */, + 298DE2A21DD8DFBCCC013ED8A37AFD59 /* Pods-BitBotATV.release.xcconfig */, ); - name = "NSPopover+MISSINGBackgroundView"; - path = "NSPopover+MISSINGBackgroundView"; + name = "Pods-BitBotATV"; + path = "Target Support Files/Pods-BitBotATV"; sourceTree = ""; }; - 397304429E3D7F6FB66E515A7FD5C0D6 /* Core */ = { + 6744B7B7BB7AE523C1818F0F621B804F /* Core */ = { isa = PBXGroup; children = ( - B470B8C6258E527FACDE6F72DFFF4D27 /* AnimatedImageView.swift */, - 9DFE2561372FBEC8433424B1A3A78FAB /* AuthenticationChallengeResponsable.swift */, - 5D24152DABCFDC9F1C6AB214D1B4287E /* AVAssetImageDataProvider.swift */, - 29266D803785F362E1AB4EEACA447597 /* Box.swift */, - D2716E4B1649A8833BD6F9C1D271B8FF /* CacheSerializer.swift */, - 1DBA344177BE60B9FC857B007F7899D1 /* CallbackQueue.swift */, - A90B1A399F5283F7832DC8F712C6C446 /* Delegate.swift */, - FF9D2408F0179139A6EE67D8C782CADB /* Deprecated.swift */, - 09B515D14713BF4D5C47A28E2BF5C779 /* DiskStorage.swift */, - 6CD77A9208BF0386967CD1A399611065 /* ExtensionHelpers.swift */, - 8205653621A0B670E7F3FDF4C5C36A58 /* Filter.swift */, - 6A33E007596522D13A845FC4E36F8249 /* FormatIndicatedCacheSerializer.swift */, - 5657918E85BD137F9793730413845AE0 /* GIFAnimatedImage.swift */, - 2D929F40722EA1C8DDAA7A14BE7CF771 /* Image.swift */, - 5DC2EB0F2557488F898BF21B5847CD85 /* ImageCache.swift */, - BE2C372744DEFF3EFC56881622D25937 /* ImageDataProcessor.swift */, - 2C28179F76171CCE9AEBC4B5827CF3E9 /* ImageDataProvider.swift */, - 7A37018142E46FB872419EF3966E8ECC /* ImageDownloader.swift */, - 7D2C6CCA336F42607F337E1EFA0006F8 /* ImageDownloaderDelegate.swift */, - 528A49D37E1026AEB96C97C085C90019 /* ImageDrawing.swift */, - 992D60F0497E6F51CEAB91FF2C9FE24F /* ImageFormat.swift */, - 19A77DFF172A3A9B3729D9A8DDA0481D /* ImageModifier.swift */, - BB7A4B88754D7601CDEE23791D4591E1 /* ImagePrefetcher.swift */, - 787B08443FD92595FA0DC41A0BC847C3 /* ImageProcessor.swift */, - DE6870ABB57D3FAD177D239F959883AA /* ImageProgressive.swift */, - 69FB273327E44E351B5D4832E76556BF /* ImageTransition.swift */, - FB705C2A74FFD57028D54FF85DF69212 /* ImageView+Kingfisher.swift */, - 350AB591550DC8BE6E78A18724372109 /* Indicator.swift */, - 6D39C95C6BA2F7ACA778BFE91D762354 /* Kingfisher.h */, - 0C8DDBE02D435933578C3D9CF9DB3219 /* Kingfisher.swift */, - 3BF364F43D01D31692287DD1152F310C /* KingfisherError.swift */, - 5B960D4FD6AAA51C641D3555812B4072 /* KingfisherManager.swift */, - C241A712E068D87A38E56EF0F0DEB5DB /* KingfisherOptionsInfo.swift */, - B2A17A5B37C3FE1B72A0FA6216116FBC /* MemoryStorage.swift */, - D1B6AFD85D4587CFCB86308270A778F3 /* NSButton+Kingfisher.swift */, - D884EC3FBCA256B592A7BF175DB4A590 /* NSTextAttachment+Kingfisher.swift */, - 4C7771685DCCEB9E674423E98EFC435C /* Placeholder.swift */, - CAC12ECB76F6C71543B1881C9B5C61CB /* RedirectHandler.swift */, - B7CB631287A52D62DF7B28B085B33FF1 /* RequestModifier.swift */, - 1565092550B223C4AA495868EA9ACCAE /* Resource.swift */, - F6C56A9F51004DF35A9E404C806859D9 /* Result.swift */, - F59A8E40E78247C519309C3B12780135 /* RetryStrategy.swift */, - 51944D9571F5EFD1BED19D1CFCBF2FF7 /* Runtime.swift */, - B451B418484BAF6ECD5CF187FC6C969A /* SessionDataTask.swift */, - CC2F761AAA0A1F14AFF60CDD39F72515 /* SessionDelegate.swift */, - 8FF9B9E3CA15D993513213755D00B89B /* SizeExtensions.swift */, - 04A3FDEAC8848912398C906327E13BA3 /* Source.swift */, - E11CFD92FC370BCCF6D215A51D9C5197 /* Storage.swift */, - 186F2A0989590D228E0BEE7E95FD3268 /* String+MD5.swift */, - C0AFA15C417FF566E42E3944E9CA79B6 /* UIButton+Kingfisher.swift */, - E53CB9C53DE644CC0018E828836F22E8 /* WKInterfaceImage+Kingfisher.swift */, + C61D629079DD747B52BE9B257FF97536 /* AnimatedImageView.swift */, + 7692F573D1E2DC63616021DF3412CD78 /* AuthenticationChallengeResponsable.swift */, + B4ACE71B7BF8F77EA48BC5C6B292247F /* AVAssetImageDataProvider.swift */, + AA5DA7F5301E11295B7E5A404917A412 /* Box.swift */, + B229986A8D850A78635DA668400B9541 /* CacheSerializer.swift */, + 6FC7A323C502BBC6AEDE47DEC7EC501D /* CallbackQueue.swift */, + 79AD15A04248C56802F9B6C75D3019A1 /* Delegate.swift */, + A9A6AB7B0D89F2EABE8504652874196B /* Deprecated.swift */, + 16ABE2EA48367A888D50B0F067C45957 /* DiskStorage.swift */, + C209DBD35687683B0353434E2C4ED4BA /* ExtensionHelpers.swift */, + 5C42085705C144EED1AC95F520556B2D /* Filter.swift */, + 69D2E3393AB08042B490CCC899D7E965 /* FormatIndicatedCacheSerializer.swift */, + F714842293BA367D0CABC101D6E183F2 /* GIFAnimatedImage.swift */, + B25FFE571A338D87EDF909EC906499E0 /* Image.swift */, + A73B1AB046609EA753474A7985924C8C /* ImageCache.swift */, + A394BD3445668D99A5E87488474235A3 /* ImageDataProcessor.swift */, + D627A23129220606C34D687C6A9E1E86 /* ImageDataProvider.swift */, + 9E2B96990033B4F418F03E42E8155FFE /* ImageDownloader.swift */, + B696723444D17E2C081123ABAC3C0EE7 /* ImageDownloaderDelegate.swift */, + 928F1C804CA779C74BBAD7277B516830 /* ImageDrawing.swift */, + 5E08B03BCD7615E02B7D315BB800CD90 /* ImageFormat.swift */, + 1CFD317BCE11392832E42B3F7239B444 /* ImageModifier.swift */, + 1EE01D24380B370BF657B7428A0587C7 /* ImagePrefetcher.swift */, + 5D7893BCF8FC30708A78AA396189D1B3 /* ImageProcessor.swift */, + A2255F2139506AB4C73A65EB517AFE79 /* ImageProgressive.swift */, + 23EF580A0426C81F2EA1FBA4B7DE4D86 /* ImageTransition.swift */, + B278697392A010FC841BA550A3EBD53F /* ImageView+Kingfisher.swift */, + D759D1EF7CB9A6791C8A65C27143C696 /* Indicator.swift */, + CFF959F28BA7ACD5D882BBA3D1C58893 /* Kingfisher.h */, + AE40BA3D3BBB6AC28E2B587F77AD04F3 /* Kingfisher.swift */, + 89AF6C11A3C19706E7C785D56D93D67C /* KingfisherError.swift */, + 702074EA12749CFCFBDF2CDA24573ED5 /* KingfisherManager.swift */, + D42B31391B2FAC25C05285540C1CF6F6 /* KingfisherOptionsInfo.swift */, + 1DE114970A6D97164E402E9B61139AA6 /* MemoryStorage.swift */, + BB9836C3922D9280D5ECB5E16654E761 /* NSButton+Kingfisher.swift */, + 78926F9F16D6B661CB5C56915AB11082 /* NSTextAttachment+Kingfisher.swift */, + FF122E9704C7DFBCE5DFE35410F55E32 /* Placeholder.swift */, + C44D2D0E6F4C6EF2EE76172E3124101F /* RedirectHandler.swift */, + 382B6780F0FBF48423885E733831C75C /* RequestModifier.swift */, + 8AC2EE6A36100366A5ACE15D447ED6CB /* Resource.swift */, + D9612BF50019AFAE4BFFBC23DE2E36FB /* Result.swift */, + 4F03E9E2CCBA2497C85A620AD66646FF /* RetryStrategy.swift */, + 475E42A215A0DAE591C36514C111C296 /* Runtime.swift */, + BEAA547EB86BF0690AF84A817A3EE1B1 /* SessionDataTask.swift */, + 0E4EA5E277EE2AC8B664CD9FC2A9ED44 /* SessionDelegate.swift */, + E030A61F17D17FD81E63D627666FECDB /* SizeExtensions.swift */, + 72E56A84AF11E5CA2CC24F859B6B60B1 /* Source.swift */, + 3F51174B10209840F57501FA9C81C780 /* Storage.swift */, + 0C3109EA3A2A5C9AD325830B1B6C99F9 /* String+MD5.swift */, + 37036428688A5CFD9A0E8390B2C3836D /* UIButton+Kingfisher.swift */, + C335C90B0893B78D0E77022821932C64 /* WKInterfaceImage+Kingfisher.swift */, ); name = Core; sourceTree = ""; }; - 3F4BD49B9D17EC097B20FB0BF69C9CDB /* OCMock */ = { + 68D7C6EC57361107D82B92DC46906EEF /* OCMock */ = { isa = PBXGroup; children = ( - 31AF941F182276F2B40F2B726E75143E /* NSInvocation+OCMAdditions.h */, - 1DA71E408B0A6D56446C2E5779AD7559 /* NSInvocation+OCMAdditions.m */, - 6D5A6014B717BFC26FF621490622E081 /* NSMethodSignature+OCMAdditions.h */, - B08140437A792EA7441A031763E63BD5 /* NSMethodSignature+OCMAdditions.m */, - E64B5C4A3967E3452D518761D1B3B356 /* NSNotificationCenter+OCMAdditions.h */, - 360B43EA2822638B014CA70237DF74A3 /* NSNotificationCenter+OCMAdditions.m */, - 85ECDF65524CC0F3870C9F005C733141 /* NSObject+OCMAdditions.h */, - 78045319F740F63C57B362B9AB2A8748 /* NSObject+OCMAdditions.m */, - C4AD47EAF619C857BEC113A2047709F2 /* NSValue+OCMAdditions.h */, - 0426F8771A05633CAB423C142380FDAF /* NSValue+OCMAdditions.m */, - 2AE081BC4555FD7F02A0623282541F09 /* OCClassMockObject.h */, - 475B134AC1BCAE5FB01505BBA2261DE5 /* OCClassMockObject.m */, - 6B20C9C2696FB4B6D8468F8C0CA32447 /* OCMArg.h */, - CF60C676F1FF87B5008152CBE76B8114 /* OCMArg.m */, - 293AD8FB310917B27312010B015B0E5B /* OCMArgAction.h */, - 1FBDC4AD70DE3D06B76913290ED7B449 /* OCMArgAction.m */, - 9C5FEDDA3B696F572A41CCB38C8E8A8B /* OCMBlockArgCaller.h */, - 473387FDA75A441BDCAD6FD610A4E523 /* OCMBlockArgCaller.m */, - 96C752DC496BB2334FBC711B6DDD2A5A /* OCMBlockCaller.h */, - 047081A3E965601782291A1E4B25BEF0 /* OCMBlockCaller.m */, - B0DC0C140D05CC9480A2E31FE8270445 /* OCMBoxedReturnValueProvider.h */, - 6081C8356E7ECFDEDE70DCC46FC0D70B /* OCMBoxedReturnValueProvider.m */, - 6551499803C2FE69FD6CA4FB03E5FEE6 /* OCMConstraint.h */, - B61DD45F82B8A39F266EC2207D8A76C6 /* OCMConstraint.m */, - 46209163AE3F1146C82075ECDBD3EC77 /* OCMExceptionReturnValueProvider.h */, - 1A2EC3E9C1B6EA6971044D90C040768F /* OCMExceptionReturnValueProvider.m */, - 034943133D11EBBBF83DA60CEFA92DE2 /* OCMExpectationRecorder.h */, - D485CBA57281576025CB61EA90A15158 /* OCMExpectationRecorder.m */, - D4575EADBF96D18BF9DFAA46148F03C4 /* OCMFunctions.h */, - 5D4483DDBD04DB89E950F27F6C029DE7 /* OCMFunctions.m */, - 0672A0F9DA8817B2A4DA4AE2F34F966F /* OCMFunctionsPrivate.h */, - 94DCC4C3FF9A74FFBEEB2AD03F66E76B /* OCMIndirectReturnValueProvider.h */, - 0BF93FF0D3C987DFC760391725FE25CA /* OCMIndirectReturnValueProvider.m */, - DCDB3631B71D0F22347F02109F35CE70 /* OCMInvocationExpectation.h */, - 053A44FACD30EF6E275D6704FBE18CCE /* OCMInvocationExpectation.m */, - FE7AEC369A0AEE80E22A9B7E80A1E866 /* OCMInvocationMatcher.h */, - 729E44DF9F35A91C782042717748FC55 /* OCMInvocationMatcher.m */, - 66C80F683A1878C39827AB1A8ADE2339 /* OCMInvocationStub.h */, - 43338F28496A583931F32BF4E684495B /* OCMInvocationStub.m */, - 22B9F0B59BE15B06B82FFF9A49E8EC66 /* OCMLocation.h */, - 720EF1ED28AC3B688CE6F3FB9E438EBE /* OCMLocation.m */, - 3F6312424838238EECCB0C1BA1002684 /* OCMMacroState.h */, - B346D043EFE755C02515D77ED01AE799 /* OCMMacroState.m */, - AE51649E85A3F7A92B1AB21D524878B9 /* OCMNotificationPoster.h */, - 61A13E39F8EC94CD85DD2643FE333FD7 /* OCMNotificationPoster.m */, - 1A0B00C0866927A55EB7CF92B97DBEA1 /* OCMObserverRecorder.h */, - 9446B364CFDB08ADB0802CC3DFCB3D16 /* OCMObserverRecorder.m */, - A28937E8173CD476E20A4CB541E2F618 /* OCMock.h */, - 14C0DCDD5D84614288FC9861FADD8501 /* OCMockObject.h */, - BF0B3717271485DB8B8D4FCA96D24E52 /* OCMockObject.m */, - 32370B87A6CE0AA519B6CEDF99F910BF /* OCMPassByRefSetter.h */, - F51DC93A2A3D54A2D4F61A23822537CE /* OCMPassByRefSetter.m */, - BDEBF23624FC6144C3220520A42B55A5 /* OCMRealObjectForwarder.h */, - 53DA50CB5C5309A4A85E7F9584687889 /* OCMRealObjectForwarder.m */, - 474825B5D9CD57231E0863576494A2A1 /* OCMRecorder.h */, - 7088AC11AE8AF76D0ACEC401EF65AB5F /* OCMRecorder.m */, - BAF78013740FC8148179C3E81058804A /* OCMReturnValueProvider.h */, - DC92E918B3166C9B4C4BDB94D6E2FB81 /* OCMReturnValueProvider.m */, - C2DFCA49B2CE55091A7252F70073E4D9 /* OCMStubRecorder.h */, - CF710639283DDEDD96354E54E3A7E665 /* OCMStubRecorder.m */, - B10A8149DBAEB5276086C1A25968D7C1 /* OCMVerifier.h */, - CA7B1F26AECE4763BAE90DED00BAA021 /* OCMVerifier.m */, - 963F1099A35439CB4AC27D2E19814B39 /* OCObserverMockObject.h */, - 64B36E4A5223DC3E8BA26A6EEB6B2779 /* OCObserverMockObject.m */, - A37F4CA923DD13D2E2820A08C0F334FD /* OCPartialMockObject.h */, - 98F64D946D0D5EAA81CC1B0F9D334199 /* OCPartialMockObject.m */, - B49D6160F7105005451C92A516BDF8A3 /* OCProtocolMockObject.h */, - 3C2868DF29A9449DC2CB6512DC6F2458 /* OCProtocolMockObject.m */, - 24A7452F80A07CE0EECFC76CCB9D9648 /* Support Files */, + 2537FB4C8CB0778DD625F206CF385CA8 /* NSInvocation+OCMAdditions.h */, + DE6AFAD4DA89E40DCBFF481259AAE455 /* NSInvocation+OCMAdditions.m */, + A09C87640D6D2DC5D6EB71A57E7E67BB /* NSMethodSignature+OCMAdditions.h */, + D1DC52144056CD5535375140BBE4CB3B /* NSMethodSignature+OCMAdditions.m */, + 5D15A2DBE72CBB3651486C29CE7CFA7C /* NSNotificationCenter+OCMAdditions.h */, + D7C8972FA1895EECCF701E7E43D21BD0 /* NSNotificationCenter+OCMAdditions.m */, + 558CF21D6FBBA3B07A824C9121767409 /* NSObject+OCMAdditions.h */, + F7D9640F4FF58EE0BFA4681BD8524652 /* NSObject+OCMAdditions.m */, + A91922616AFB9EA146BD8FBEF311BEAC /* NSValue+OCMAdditions.h */, + 656E06E6545A067AF16918EE5E3123DD /* NSValue+OCMAdditions.m */, + 5E586A05DDB15DCAAD49489B0632C0DA /* OCClassMockObject.h */, + B93A61CED72D42D90093A6C9AE0216A4 /* OCClassMockObject.m */, + 249A6E6554241E9A2E70500432FE1E9B /* OCMArg.h */, + 99FF117BFA025DA2B85FF183B445BBF2 /* OCMArg.m */, + 76C875F37828366270A19D86E3E42D6C /* OCMArgAction.h */, + AAD1A4DFC439E32BC55F333A85B0D6B7 /* OCMArgAction.m */, + 437EAEDD38DB97E2357378A28B74AF85 /* OCMBlockArgCaller.h */, + 69132E45666D517B599B0E045DE67502 /* OCMBlockArgCaller.m */, + 0565FE21AB63AFEF67A9CA59773523DE /* OCMBlockCaller.h */, + 1F184392A295DE2E19C93D0C8B7143C7 /* OCMBlockCaller.m */, + 915D25D749AA3B4EC0FB0BAA6674D9C8 /* OCMBoxedReturnValueProvider.h */, + 17C94CDAF70A626A6557896E3013D3F6 /* OCMBoxedReturnValueProvider.m */, + EE73BC7E6B9CE2CE444F233D3BD368DA /* OCMConstraint.h */, + 427528E5351360795A2FC716F0A61A43 /* OCMConstraint.m */, + C0D2656F2A875ECFE893BF18B2E16492 /* OCMExceptionReturnValueProvider.h */, + 1A29DCD4677EEB50CC5E79F957801968 /* OCMExceptionReturnValueProvider.m */, + 8085360E3336A58D8C1F511F7DBE7D78 /* OCMExpectationRecorder.h */, + 21463A3730433C3AA2E07A0BA53A08B9 /* OCMExpectationRecorder.m */, + 47B69B903C4DE4A0125C0FFF10DD800F /* OCMFunctions.h */, + 8D3A4B1DBA7E15E533F1C21B73BD47EB /* OCMFunctions.m */, + 6F26D1CBB432719C60FC75BFF2DD1E67 /* OCMFunctionsPrivate.h */, + C14C6D61A8BD9081A41C40D24192DE44 /* OCMIndirectReturnValueProvider.h */, + 20BBA88BD1BC2C4981789AC0163EA2C8 /* OCMIndirectReturnValueProvider.m */, + 0CE7F630B356E6F9F3E9B043676AEAAD /* OCMInvocationExpectation.h */, + 5E0CA3D813A44762422977B90EA44465 /* OCMInvocationExpectation.m */, + F1EDFC2372A9C734629885AC1A91E4AE /* OCMInvocationMatcher.h */, + F8E6838B2952D27DD32D3B00DF7C1B66 /* OCMInvocationMatcher.m */, + 2156CED034416F787C882CDFFADC6829 /* OCMInvocationStub.h */, + BE880AB1DB81B927C0BC664948EAC229 /* OCMInvocationStub.m */, + 358E2C8396B00E243809000DFC3F9F46 /* OCMLocation.h */, + 03DB632D03C3927CA1825C545CACA388 /* OCMLocation.m */, + D937487D98CF1317A50F757709136421 /* OCMMacroState.h */, + B352E3B766B7B86A89E0481FEEFCA38C /* OCMMacroState.m */, + AD04F4E2AF56D7FBACEDB0A518996D17 /* OCMNotificationPoster.h */, + 35AB175A6910B81B03372F043897023B /* OCMNotificationPoster.m */, + D22AF5F63AD1761496D54AE9764983A6 /* OCMObserverRecorder.h */, + F0B2CB9BEC64D0147EDC960E67516CE5 /* OCMObserverRecorder.m */, + ABEEA66650DAFED36AC0A7B67BDC27BD /* OCMock.h */, + 2AF331BB4BA9B2DC12487F3DBD970080 /* OCMockObject.h */, + 3D3669E97FB5BC347CDC0D1D98051F84 /* OCMockObject.m */, + 943A6DC32F2A12EA051DDB9E22D150E3 /* OCMPassByRefSetter.h */, + 1D5DE687FE4F1B67174712D0C059309B /* OCMPassByRefSetter.m */, + AD43111F7D7D4B981C14C7A679582A32 /* OCMRealObjectForwarder.h */, + 970C3CABE864F4EBDD5E4EDF8AB861F8 /* OCMRealObjectForwarder.m */, + 0E416F122F76468EAD9E8E52289FD699 /* OCMRecorder.h */, + 00C44F2BE6F0FFAADFDB233517EF0AF4 /* OCMRecorder.m */, + FD1BA966CD9EDA0D91BE150F4DDEFEAD /* OCMReturnValueProvider.h */, + 9CCE329FFD1284B959ACC03EA2F58404 /* OCMReturnValueProvider.m */, + 353D6F3694A36EA3F9994B9E30E9C7D2 /* OCMStubRecorder.h */, + A4F20D84DBC0E8F03B43766CD57B6C5B /* OCMStubRecorder.m */, + 66C034548AF4F3B544F25A2A0632AAFF /* OCMVerifier.h */, + 0B5C408964654E9EFD65EF335BD11CA5 /* OCMVerifier.m */, + B25757E02D53C1DF22036581F36AC94A /* OCObserverMockObject.h */, + EFA3E94236148B21C103665DBDE36A19 /* OCObserverMockObject.m */, + 6139A0A10B75059FF153ECA3DE15D1AB /* OCPartialMockObject.h */, + 97957EFCC33E464C409C5390DF5D48D2 /* OCPartialMockObject.m */, + CB51C6354F85DBE35F75A892B2A35813 /* OCProtocolMockObject.h */, + A27A3F985112C5E7105FF757855141B3 /* OCProtocolMockObject.m */, + D8F92B2F5E1229AC5548F51DDA9E38F3 /* Support Files */, ); name = OCMock; path = OCMock; sourceTree = ""; }; - 4481518BBA79B7F388B6C0627BC4B162 /* Support Files */ = { + 72DA2E88250883AA2A51BFA39F49079C /* Support Files */ = { isa = PBXGroup; children = ( - D63ED8C5E87F5585A4A167D6E5FB9767 /* Mixpanel-macOS-dummy.m */, - 8787EAF8E690F3E1FBAE6C743D84431F /* Mixpanel-macOS-prefix.pch */, - A702A64B134CFFAB9B88CAA38D7E661A /* Mixpanel-macOS.debug.xcconfig */, - 48A8FADBD7E4D999799E8CC0E67046CA /* Mixpanel-macOS.release.xcconfig */, - 4C54643A14053405BDB4037BC6923EEB /* Mixpanel-tvOS-dummy.m */, - CC64D7274DFE874DDD39C89A939D4580 /* Mixpanel-tvOS-prefix.pch */, - 246A0C87B8EFEDCCF03667CE8BE5FD36 /* Mixpanel-tvOS.debug.xcconfig */, - EA9C39723282F9332BBB781FEF173318 /* Mixpanel-tvOS.release.xcconfig */, + 393E830D1A859C819F8DDFFC69C8727E /* Kingfisher.modulemap */, + 88F98F21A3A4AF3F01F89B2CF4C1CA0A /* Kingfisher-dummy.m */, + 3FC7D392594228556B4C17B83C67DA94 /* Kingfisher-prefix.pch */, + CAD47560D17493EDE1906F5E071CE326 /* Kingfisher-umbrella.h */, + 8C5412152A02375F97BCFA96C31002E2 /* Kingfisher.debug.xcconfig */, + 705CC9DAC8C56CAB1394F921EF7B3595 /* Kingfisher.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/Mixpanel-macOS"; + path = "../Target Support Files/Kingfisher"; + sourceTree = ""; + }; + 907E406CEEAD533572737C93D69F202A /* SDWebImage */ = { + isa = PBXGroup; + children = ( + EBADA6BB88B55D19AAA7FCF801B29170 /* Core */, + C93D669BFDBCD1F97EEE3B3EA66F25E0 /* Support Files */, + ); + name = SDWebImage; + path = SDWebImage; + sourceTree = ""; + }; + 952016718C396B557DF35CDCEC7EF258 /* Mixpanel */ = { + isa = PBXGroup; + children = ( + BB20C65D91E6BA3A93FCE00CC0AEE9FB /* Mixpanel.h */, + 918C1E8E18681194571CC7CC409D810F /* Mixpanel.m */, + 7B651AA679368297876836D632672329 /* MixpanelExceptionHandler.h */, + 6FB17A41E13C12B1D2AA71FAF3E004C2 /* MixpanelExceptionHandler.m */, + 327F432D938896DE00325DA3BCAC1A8E /* MixpanelGroup.h */, + 4801355A25E5488A0DF0A051F6ADB977 /* MixpanelGroup.m */, + 6710CF323F6003446FA076D00037B1B7 /* MixpanelGroupPrivate.h */, + 9C0A1B0E54182F7303BF9551261EC6D3 /* MixpanelPeople.h */, + F3864646ED479BF8F6292472141DE6C4 /* MixpanelPeople.m */, + 8AD8082B1558E9CD4FE81D97AA7EFBB9 /* MixpanelPeoplePrivate.h */, + 2D213DC3D25A75835B758B314D291EB4 /* MixpanelPrivate.h */, + DB9FF4A48AF84AF31680A56E61A2BF84 /* MixpanelType.h */, + 41A323BD55CEF8F8697370A91DF02F88 /* MixpanelType.m */, + D8728A92B3768750BE8C034BB8A6C225 /* MPFoundation.h */, + 301E1022D63C63981FEEEE645954B1C3 /* MPLogger.h */, + D86F21A61B42BA1F53F84900700F92A6 /* MPNetwork.h */, + 04FBACCD33706E0D6F5EE7CD78059B44 /* MPNetwork.m */, + 4AC9CB050C910E77C9B12CB287704992 /* MPNetworkPrivate.h */, + 2CC1924BC66C4930A9848851D49802FB /* SessionMetadata.h */, + E1A2DA9F20E042F158279FE9D1897627 /* SessionMetadata.m */, + 1DF5CA0FF253D0D6E8E067B9CA1823FF /* Support Files */, + ); + name = Mixpanel; + path = Mixpanel; sourceTree = ""; }; - 5FA33FA1E08B26B49B9CE37244438424 /* Products */ = { + 9CC236F0C10169F836B5966D2BD67D0C /* Products */ = { isa = PBXGroup; children = ( B2F6BF787CDDE44EDE585C56D36FB0B0 /* libEasyMapping-macOS.a */, @@ -1306,373 +2330,693 @@ D1ED9B7F321F11235F0BE332E0790E64 /* libNSPopover+MISSINGBackgroundView.a */, F30C125DB91902F63DC73AEF0B0E6111 /* libOCMock.a */, 46F4F400E88483A3268939ED4F54B477 /* libPods-BitBot.a */, + 304D7AE95A8997C86DF9D893909AE6FD /* libPods-BitBotATV.a */, E080202F8E0B54182443BA49E85C276D /* libPods-BitBotTests.a */, - D5099A766F6792981B7C98BC25284ECF /* libPods-BitriseATV.a */, B0B214D775196BA7CA8E17E53048A493 /* libSDWebImage.a */, + 62754719072EA7728FFA28F8BA5B8676 /* libSentry-macOS.a */, + E5B37F686C226E712A6CCF4F485ECD08 /* libSentry-tvOS.a */, ); name = Products; sourceTree = ""; }; - 5FE238A40353A3A2DCDAEB78EEA086A3 /* Support Files */ = { + A282124BCCDAC1BA2663ECADE53917C1 /* Sentry */ = { isa = PBXGroup; children = ( - 583B47951CD7CBE1EA97C970D494BBC4 /* EasyMapping-macOS-dummy.m */, - 9B71A33DA344B8FA3913B5CA3B8538FE /* EasyMapping-macOS-prefix.pch */, - 8398C38511B633C2B4E5C963995956D8 /* EasyMapping-macOS.debug.xcconfig */, - 855230599E967A05447F178A3D557046 /* EasyMapping-macOS.release.xcconfig */, - 0FB84539B3D19B7FFC818161CE30CFF9 /* EasyMapping-tvOS-dummy.m */, - 7E0252387946370A3D69E36D50D29E59 /* EasyMapping-tvOS-prefix.pch */, - 77D06687A5169837CF67DDCE96D0602B /* EasyMapping-tvOS.debug.xcconfig */, - 5DEFBD22C13412C0F8792B77A2536966 /* EasyMapping-tvOS.release.xcconfig */, + FE932BD5B75EB7FB5B2D18456ECF2FB6 /* Core */, + 5AB4C80A295CE81464F7BF07A8E03069 /* Support Files */, ); - name = "Support Files"; - path = "../Target Support Files/EasyMapping-macOS"; + name = Sentry; + path = Sentry; sourceTree = ""; }; - 7EC1A663CB6C81FAC632D79B03038BB6 /* Kingfisher */ = { + A2B90001DA7C6262FFB271F8B1C19777 /* Core */ = { isa = PBXGroup; children = ( - 397304429E3D7F6FB66E515A7FD5C0D6 /* Core */, - D86761825ACED43AA65D1FC881042ECA /* Support Files */, - 3385C7455987DC0240B4BDB90CF06FA4 /* SwiftUI */, + B074CAB984CC58579CF9DF157C294F9C /* EasyMapping.h */, + FB4D53C11D7F99FD3BC21C897B80C49B /* EKCoreDataImporter.h */, + 3DC68AE22AB019032DD1A0EA782C4614 /* EKCoreDataImporter.m */, + F2C7A6B01B0431E52F0426FFA9FA836E /* EKManagedObjectMapper.h */, + 1DBBDC9C6D38AE230697D019D427B5D5 /* EKManagedObjectMapper.m */, + 3D08DE0D01595536B14C06E957A81A17 /* EKManagedObjectMapping.h */, + 4083F4A45B92B9A4CDA43A2E616B20D5 /* EKManagedObjectMapping.m */, + BEF7F0C7B39D9162359E52B189FE8F21 /* EKManagedObjectModel.h */, + 4D19CFB58A52BB6ECB5EAB0DAF6B03C2 /* EKManagedObjectModel.m */, + 05F5B2D858E5616537CDD4EA800C5173 /* EKMapper.h */, + 36737DC870746AD789DBCD3EC70812EE /* EKMapper.m */, + C16CDA7D12CE2887C6C67BA402461988 /* EKMappingBlocks.h */, + 20FDCB67501389A381C2608C683D619B /* EKMappingBlocks.m */, + 0542808674F5A10FF9784DA1864F8CBC /* EKMappingProtocol.h */, + A73048B0940DC44FBE9BC89CC02BAD9C /* EKObjectMapping.h */, + CF5EAFB93582013A51B76C904CC6049D /* EKObjectMapping.m */, + 56D5464E1A54D9ADA7C36F10D96C010C /* EKObjectModel.h */, + D94575F97C3B97906EA0DF45F8B3665F /* EKObjectModel.m */, + FEDE59956F01BAB8149B4FE239EBD53A /* EKPropertyHelper.h */, + D5139F1EF9D079FC16A2A8568E1BCA1F /* EKPropertyHelper.m */, + B0F73FEAAFEBB7A8FB01FAB8C7D9136A /* EKPropertyMapping.h */, + F39921B3FB050F3374B5EC60FC1119BE /* EKPropertyMapping.m */, + 1E480A4679A415C223FF40639884AF28 /* EKRelationshipMapping.h */, + 0311EFB6DC50C64A6FA83FA56E458E77 /* EKRelationshipMapping.m */, + 80F38BDE157D18A99DE165F15628E9D8 /* EKSerializer.h */, + 1884FAF2A8FA6485B812BC2FF3A2D02F /* EKSerializer.m */, + 158A69E47F44FC87022EB7B284DB6CED /* NSArray+FlattenArray.h */, + 6DE263CCD7DE182693CA38B30F831375 /* NSArray+FlattenArray.m */, + B9746E334F7B96E4F782D91BECC052AB /* NSDateFormatter+EasyMappingAdditions.h */, ); - name = Kingfisher; - path = Kingfisher; + name = Core; sourceTree = ""; }; - 86F7B9CC679A8C8DEE9428DAE2B6E17F /* Core */ = { + A781BB95CDF652F02AEE8764FB4500C2 /* Support Files */ = { isa = PBXGroup; children = ( - E0B8907B5FA48B7D00DB2A720E163707 /* NSBezierPath+RoundedCorners.h */, - FE84606C704FBD829A674F2E080A6873 /* NSBezierPath+RoundedCorners.m */, - 797C915C816B98FD9BD12C5C555F9F81 /* NSButton+WebCache.h */, - 708030192838B80AB5E0460B6E687194 /* NSButton+WebCache.m */, - EF98DF418E129E42ACB5735BCF2BF2DA /* NSData+ImageContentType.h */, - 914886C9DE73B54DB69A91E71C457CCF /* NSData+ImageContentType.m */, - 524F0C8BF02AF437472F424326751775 /* NSImage+Compatibility.h */, - E9A310A735E4E90BCC6A9FD46539E260 /* NSImage+Compatibility.m */, - 704865349FC0AA93ABA47EC6250E2567 /* SDAnimatedImage.h */, - E4B961693B51CABFAC71DD5C6A5A4BD9 /* SDAnimatedImage.m */, - 95563B1EA47DD86FC4817BE8339B6101 /* SDAnimatedImageRep.h */, - 7CB305224A079CA6B534CB5DA4136DC6 /* SDAnimatedImageRep.m */, - 56899FE50A2A99881362A35F2005FEED /* SDAnimatedImageView.h */, - C148126AF9126A0D5EF8C178F3DD06A4 /* SDAnimatedImageView.m */, - 2A9D899A31143DE07964B6EBB4EE2084 /* SDAnimatedImageView+WebCache.h */, - 45967075B8CB5A601521BEDEDDDF70B6 /* SDAnimatedImageView+WebCache.m */, - 22D2D345016F9C053B3D1566570DA5EC /* SDAsyncBlockOperation.h */, - 3CF287C63E99637D48551E625B228C5D /* SDAsyncBlockOperation.m */, - C7F1EF4C2BBDB132CCEA2EF7D0E40DB7 /* SDDiskCache.h */, - 14A88043724A1C2FF5276F579A74A83A /* SDDiskCache.m */, - F0526B10B105C72A02DCB7A5FE5042FD /* SDImageAPNGCoder.h */, - 5C70B107A43E113F3F1055B97D5C64B2 /* SDImageAPNGCoder.m */, - 5A0CF62073129C73345E453F1671A2E7 /* SDImageAPNGCoderInternal.h */, - 58AB2C510FC2C1A8E0B56D19E4967D17 /* SDImageAssetManager.h */, - 9D08CFD0ACE4C85B21B2BFE8F037E58E /* SDImageAssetManager.m */, - AB96CAFC5DCCB7374C5A881110FB8849 /* SDImageCache.h */, - C51171701AD5DE91435B7C6FD44F6D03 /* SDImageCache.m */, - B34983A86DB520A9C8E487CE9F7777E1 /* SDImageCacheConfig.h */, - AD1C8BD7DEB42F687DDF5D0C5BAF26A0 /* SDImageCacheConfig.m */, - ECA18B43D913EC3A721AAC261D96C6C7 /* SDImageCacheDefine.h */, - AB955BF0D2B4CEC905C17CFD967F487E /* SDImageCacheDefine.m */, - 8A2370785CF931AAD343E57522428185 /* SDImageCachesManager.h */, - B77606847A2016C77AD6833DC877F24D /* SDImageCachesManager.m */, - 508C1A1C5A4AFFB6E7B04F71FE0E0F71 /* SDImageCachesManagerOperation.h */, - 88B972C3230D9A90FF61B58C59DF04F5 /* SDImageCachesManagerOperation.m */, - B12A44060AD90C50C600229C1BF30CE6 /* SDImageCoder.h */, - 247A6911F6FD4DACEE1AEF5DF4F49FAD /* SDImageCoder.m */, - DE92320C17159F72A6BA50CD088843A8 /* SDImageCoderHelper.h */, - D5AB3D0F067AB772EEF8D8D8D9A117DF /* SDImageCoderHelper.m */, - E1F9C7D969CDEFF23E17FF615A85E88D /* SDImageCodersManager.h */, - C65DA8ADE9DE5648BC51913F68D68BAF /* SDImageCodersManager.m */, - B4BE72DFF35188F0868B96621E9941CB /* SDImageFrame.h */, - C7125132C005FB99631CECCD953414BE /* SDImageFrame.m */, - D9ABE2D50C0C884ED625EA5D881E8AC0 /* SDImageGIFCoder.h */, - 4D823CF7CA5CAC63795CA9BBD5473A44 /* SDImageGIFCoder.m */, - 7D3DE9686C65C2AA5CCCAED5C15AB8CD /* SDImageGIFCoderInternal.h */, - 09C7E99EBC284F25C7F8ADED9BFDCB12 /* SDImageGraphics.h */, - F64D0719D26112193FCA87432721368E /* SDImageGraphics.m */, - A66E333CE92847BEBA79B50C188F884F /* SDImageIOCoder.h */, - 1AD3CE5E6A7204EFCF0A94875B0F200C /* SDImageIOCoder.m */, - D8E7588C6AFE9808A46E814936CA84E2 /* SDImageLoader.h */, - 827735D4D43CE0DDCD15D60859120C75 /* SDImageLoader.m */, - 8BE56A866D956C48B3A07A077AA30E6F /* SDImageLoadersManager.h */, - 7D2247CF28BF90D35DD24088EB9F8425 /* SDImageLoadersManager.m */, - DCEEF6F299FC1EF75CECA90833D64E31 /* SDImageTransformer.h */, - C7066153845C9CB987D2089FEA9C46FB /* SDImageTransformer.m */, - 67DD828DE7647C11596D9C8075277B0B /* SDInternalMacros.h */, - 86BD8B43E38AFBC6B15B04EA3903A324 /* SDInternalMacros.m */, - F4BC3BB600D3B7C15CE82551B31038F4 /* SDMemoryCache.h */, - CCEA1E80C1838E1C1C3C444B2BDB99C1 /* SDMemoryCache.m */, - DB0F4C1F56DCCAAEECFB8F0FA1242FBE /* SDmetamacros.h */, - 57EB895450DA2C40A1B05B17486D7202 /* SDWeakProxy.h */, - AF8D241D92929702644AC3C080CA4D97 /* SDWeakProxy.m */, - 1EE7E1C448B38B420808CC8605F8256B /* SDWebImage.h */, - 64B05964124210B349236926810AC127 /* SDWebImageCacheKeyFilter.h */, - 99D75CBB7C8193D992BF15A7EBAA9F4D /* SDWebImageCacheKeyFilter.m */, - F3984CAB8C188467A7244F99E6549DBA /* SDWebImageCacheSerializer.h */, - 97D86A9D76DC8AE9454534808B623C55 /* SDWebImageCacheSerializer.m */, - 5D00809841220351032F8DECD98C2663 /* SDWebImageCompat.h */, - 8959A8DF80C3F2AD13A28DF2D9F0AFAA /* SDWebImageCompat.m */, - 460A2613309D6A90A54CEB827940AF8C /* SDWebImageDefine.h */, - 27D77C7ACC32A1A1AD494E09082CAD36 /* SDWebImageDefine.m */, - D9927B59B79490141F493494FE1CBDC3 /* SDWebImageDownloader.h */, - EA8160747C5E6AB38E0ACF3334FC8E0A /* SDWebImageDownloader.m */, - 0DEF35F27ACDB14F4FFBB034E4AA2831 /* SDWebImageDownloaderConfig.h */, - F2F4BAD2957BC72E97702E11DDD7C68F /* SDWebImageDownloaderConfig.m */, - 05AFD55F4788466522B9FA8D8BA16EAE /* SDWebImageDownloaderOperation.h */, - 8C299D6117A127858E519895CF940442 /* SDWebImageDownloaderOperation.m */, - 68B65178DEB4E187ADC99E5892714533 /* SDWebImageDownloaderRequestModifier.h */, - 230B187CA6AF6024F2B0036E0D164D04 /* SDWebImageDownloaderRequestModifier.m */, - F636E0DDE0B197D611D4A55CAA456E8A /* SDWebImageError.h */, - 4B6A690A9A6C6A1F35D533D71672AE8D /* SDWebImageError.m */, - 69318348B3B55B4AC7307DBB4F4DAC01 /* SDWebImageIndicator.h */, - A347DD9E83894ECF9E18A1321AF0DB4F /* SDWebImageIndicator.m */, - DAF61E9AD9175C992A05DFE48ACC2DA1 /* SDWebImageManager.h */, - F7E833D00F12D9C5B291BDACCB608EF3 /* SDWebImageManager.m */, - E6D8C758008A57827694D4028880F6AF /* SDWebImageOperation.h */, - BAB9C1F071E04BF93DF16CB45635E34F /* SDWebImagePrefetcher.h */, - 8B05FBC154203BB747B882B6E725E759 /* SDWebImagePrefetcher.m */, - 570A465B0497E83886347A5D4E94102B /* SDWebImageTransition.h */, - 61FCFC3F530E4D72E86BE5E1C3002D95 /* SDWebImageTransition.m */, - 2067A7813FC3405752095AB40D062988 /* UIButton+WebCache.h */, - 4D4CAD6A25521E9242F03EE13302FB7A /* UIButton+WebCache.m */, - 14F645E945F39049D018050DE34D1761 /* UIColor+HexString.h */, - 0BB323D9D7D7016C8AD08C2E3E150D08 /* UIColor+HexString.m */, - 913EBD22558950862D0830EE189B272F /* UIImage+ForceDecode.h */, - C53946AE1D25D3DC688DD052BB4CB2E2 /* UIImage+ForceDecode.m */, - 717A6A925F8110E257AE946485EDA856 /* UIImage+GIF.h */, - 95DD4922510FE102A4125D8B906D4721 /* UIImage+GIF.m */, - FF0058A401EA270668A032E2940DB3A9 /* UIImage+MemoryCacheCost.h */, - 19CD256D264D78BEB3371940A41DBACA /* UIImage+MemoryCacheCost.m */, - 48E34B5E54DDDCE905E3AEA8359FA621 /* UIImage+Metadata.h */, - B777B3F9C209D8C8FCDE4A8CD995CF28 /* UIImage+Metadata.m */, - A8AF61BDDA49BA0BC455083325050B9F /* UIImage+MultiFormat.h */, - 697AF15476B4F23A75BDC507ED83ABB5 /* UIImage+MultiFormat.m */, - EF5ED803BC5085BF65F2CF57CD8552BE /* UIImage+Transform.h */, - 890A2F3CF1A55C6200A25E16CE6BAB19 /* UIImage+Transform.m */, - 140022B9A102D37A032DBA6B152CA4E5 /* UIImageView+HighlightedWebCache.h */, - 104C5B6C851601D859293E092AC36D08 /* UIImageView+HighlightedWebCache.m */, - A79507197F400407AD16AB92E7929F26 /* UIImageView+WebCache.h */, - FFD7C099325EE5900027A4F8102FF204 /* UIImageView+WebCache.m */, - 4EA37B59FEEFC4126008D4438093882D /* UIView+WebCache.h */, - 33C60B7348A877E265B19BBA7EE57AFF /* UIView+WebCache.m */, - CDFEF876C8EAD0CF4C05038DE14DCF71 /* UIView+WebCacheOperation.h */, - EAAE51390887C89B5D97F214B2C00459 /* UIView+WebCacheOperation.m */, + 6FD6179D6616CC83F0EBC88FEB40E3F2 /* NSPopover+MISSINGBackgroundView-dummy.m */, + 381477C01B8DA099AEF2076D35832CB9 /* NSPopover+MISSINGBackgroundView-prefix.pch */, + 23FA33D338D06AE28C6AC2CADC005ED6 /* NSPopover+MISSINGBackgroundView.debug.xcconfig */, + 256EE003D93BB1CAD0C8CAA7F1CFF85A /* NSPopover+MISSINGBackgroundView.release.xcconfig */, ); - name = Core; + name = "Support Files"; + path = "../Target Support Files/NSPopover+MISSINGBackgroundView"; sourceTree = ""; }; - A82C623B25ECB3A13AE3D6351192EF21 /* Mixpanel */ = { + ABD8C909FEF34671B34631A1B56A9835 /* SwiftUI */ = { isa = PBXGroup; children = ( - 4D0D4DA41BE5383DA49503DAFA6F1445 /* Mixpanel.h */, - A2DFB5FB1FBF6BDE66D3761B057DC4AF /* Mixpanel.m */, - E37875E266D4B7C82B4F961406679121 /* MixpanelExceptionHandler.h */, - C5E5CB7681E3DEE123040E6870391D7B /* MixpanelExceptionHandler.m */, - EA4CC493C28070726E85F63F85A7A9AE /* MixpanelGroup.h */, - 8341906BAF78F592CBBECCA1690241F6 /* MixpanelGroup.m */, - F8C2BCD9F1BBFAAB59F270D2B46CF7FC /* MixpanelGroupPrivate.h */, - CE8F4F22CA4D6315D5E43C50269C56E5 /* MixpanelPeople.h */, - BAED2AAE5E9EA784319F20AD830C8A32 /* MixpanelPeople.m */, - D1EB4E17FB5EAD0DC2A47732102AED43 /* MixpanelPeoplePrivate.h */, - 4C5CEDC685B0DAF949C106E84D43A94C /* MixpanelPrivate.h */, - 708DE1D96C6A00BBDCE27C80AA4D2AA3 /* MixpanelType.h */, - 65C68E58B21D695F281A118140FF2F4E /* MixpanelType.m */, - 736FE3B1A3FD3F00512B7171439D130F /* MPFoundation.h */, - AE5EF5CE5A54E9221AA60FE934863F4A /* MPLogger.h */, - CA228BFDCE8A94062372DD786096FF3A /* MPNetwork.h */, - B1867608EDF91D60A4545F8CC26ABAD6 /* MPNetwork.m */, - 512768F8B3FF93AED6AA35F6FB770F30 /* MPNetworkPrivate.h */, - 6EBA2351A93813A05034F31E228E3098 /* SessionMetadata.h */, - 4EA6B926575B4BFD799AB7AB428D480C /* SessionMetadata.m */, - 4481518BBA79B7F388B6C0627BC4B162 /* Support Files */, + 66ECB3B7DF926F46DB3E2A027346DEC9 /* ImageBinder.swift */, + 95EC668E798CC7757D2A7FAE411066D4 /* KFImage.swift */, ); - name = Mixpanel; - path = Mixpanel; + name = SwiftUI; sourceTree = ""; }; - A928A4B651EF55E09657580956EDF03D /* Targets Support Files */ = { + B4A4697DEF8CF64F4855D3BB6C2CDC73 /* Expecta */ = { isa = PBXGroup; children = ( - EEF33D6AB8C0E1279B3496B704F1120D /* Pods-BitBot */, - B4DB9B6E5A9853B9C6D26219E2057F02 /* Pods-BitBotTests */, - 0F044C1E909B65B27C6DAA0A1CDA92EA /* Pods-BitriseATV */, + EE191BC83E04210BBFF33CDC23B799B5 /* EXPBlockDefinedMatcher.h */, + 504C881F5EF6D0E2B49BBA35F1FE88E7 /* EXPBlockDefinedMatcher.m */, + 1D3EE8F9270FE0BB85BFFCE0EEF64D69 /* EXPDefines.h */, + 32EE06144281D6F9D2433552BFE5F506 /* EXPDoubleTuple.h */, + 5413522E2E83F53BB8740D2CFB917577 /* EXPDoubleTuple.m */, + E7E2786467AFA14CB5DA07F30C390C8E /* Expecta.h */, + AD1847DA1E09CA4FF64EBDDCE9E89BBD /* ExpectaObject.h */, + 45787E0AEDF8AD16DDEA9AA886A226C0 /* ExpectaObject.m */, + E7498EE2465516ED35F4F3252FDF30A4 /* ExpectaSupport.h */, + 8F3707783B7E17EBAC2B40048C2B638B /* ExpectaSupport.m */, + A202CEF8C27DDD9E0C7DBA2D5E025C07 /* EXPExpect.h */, + 2B5C2078B50FD676339A2FEE36C2439C /* EXPExpect.m */, + A58E63C8196E979642B5A41F2AA5F26A /* EXPFloatTuple.h */, + ECAA70483A39BCA0C0C7E356FB322F42 /* EXPFloatTuple.m */, + 8EB0E1EE3862BD69F6E01020B2BDE08E /* EXPMatcher.h */, + 02DC83D5E00FE99440BD62AF984711A2 /* EXPMatcherHelpers.h */, + 9B8C060574C7D88BA3788F238D7F2FF8 /* EXPMatcherHelpers.m */, + C5884F3C5EDA3C444E34EAEFA5496AB2 /* EXPMatchers.h */, + 7A49E743371CDA3384FFE238BF4B61D3 /* EXPMatchers+beCloseTo.h */, + 2721B1D673A34DA349D3468D5EB061F5 /* EXPMatchers+beCloseTo.m */, + A31FB9F387655224851D83FFE7738B1E /* EXPMatchers+beFalsy.h */, + DAD60C8C2D829AF89945E853ED1CA1F3 /* EXPMatchers+beFalsy.m */, + 5B3ABCB4EFCA6459E64585F4A9691AE1 /* EXPMatchers+beginWith.h */, + 73EFA1A2808B11E38E10524558CCC4BA /* EXPMatchers+beginWith.m */, + FD09A0A8C776D6C7C89CC9A450B4C376 /* EXPMatchers+beGreaterThan.h */, + 251C6FF39FE45D49E74742E54367D150 /* EXPMatchers+beGreaterThan.m */, + 8CE4111130816741BE64DB8AA9AF25EE /* EXPMatchers+beGreaterThanOrEqualTo.h */, + 060A4FAD62F94BC224E0223323FCB29A /* EXPMatchers+beGreaterThanOrEqualTo.m */, + 8C23419431442D582D63E8ABBE30C470 /* EXPMatchers+beIdenticalTo.h */, + 8FA942C52C785545E4D4C42A7EAC6893 /* EXPMatchers+beIdenticalTo.m */, + 25E111C8A9A247EDA742310038540721 /* EXPMatchers+beInstanceOf.h */, + 43CC2DE11D8B53AA2809C93B3DF96B78 /* EXPMatchers+beInstanceOf.m */, + 6D87B40410B52B9EF1864370A90442B8 /* EXPMatchers+beInTheRangeOf.h */, + 0ED45AE327842259B4C32E6BCB45FAEF /* EXPMatchers+beInTheRangeOf.m */, + 00BA44563517EF05D49C2288AC8068CE /* EXPMatchers+beKindOf.h */, + 5A861715DA3C27C1CEC0B5149E88DE65 /* EXPMatchers+beKindOf.m */, + E1874710A7496BA57237D6BDA6C21AC3 /* EXPMatchers+beLessThan.h */, + 1F4071362B52F086A16600C4AF635940 /* EXPMatchers+beLessThan.m */, + 3BF03F0C7762E903D6D62F462E93BE35 /* EXPMatchers+beLessThanOrEqualTo.h */, + 0619CDE980999D5C59E9F15C006149DF /* EXPMatchers+beLessThanOrEqualTo.m */, + 557D34A7742B007287FCA4734299A008 /* EXPMatchers+beNil.h */, + 94AAB0857570A8D45394C82F74F2306E /* EXPMatchers+beNil.m */, + F2D31996EC48D78A198DBE8858B6151B /* EXPMatchers+beSubclassOf.h */, + 11925E02843BE5EF8939078EB45BAFA5 /* EXPMatchers+beSubclassOf.m */, + 9E9FC117741B956A49CA4281D1D1444F /* EXPMatchers+beSupersetOf.h */, + 4D3FBFA74344F4FF521DCE28F5DF4976 /* EXPMatchers+beSupersetOf.m */, + A60658B35C750AD8DE167E3A43FF0C23 /* EXPMatchers+beTruthy.h */, + A11A7A73E2BA6DE77E94D1B9080AFD49 /* EXPMatchers+beTruthy.m */, + 1863F1E2E1E6A795639A75A3C001F893 /* EXPMatchers+conformTo.h */, + 70122D147B4CFCF6BD5F06A6D048B8EB /* EXPMatchers+conformTo.m */, + DC0181CAABD875283907391EB7A5F605 /* EXPMatchers+contain.h */, + F1EA89C71E01F52BE17CFAEEE8951B4E /* EXPMatchers+contain.m */, + A2E6C9BD4CA6F7A05DFD31BEB92AD59D /* EXPMatchers+endWith.h */, + 3643E758C072AA39C0B4AA42EC9A2589 /* EXPMatchers+endWith.m */, + 3BF711190956F6B15EBCFD0EDA1345DF /* EXPMatchers+equal.h */, + A33AA886DE0330C68ABC7B568A11AEEA /* EXPMatchers+equal.m */, + D01CF0850D3D4C872590CBFBDC03EB5A /* EXPMatchers+haveCountOf.h */, + F4AEF7C2E260CF1EAEC434B6350410F7 /* EXPMatchers+haveCountOf.m */, + 5122E3FCDD75BB5EAA1489400AFCB5FD /* EXPMatchers+match.h */, + 97C100DF887E309856C0A3752A56C2EE /* EXPMatchers+match.m */, + A7042E946A278D6275B3C37E519799F4 /* EXPMatchers+postNotification.h */, + 71D17FB9AD23896A66494244B436948B /* EXPMatchers+postNotification.m */, + 180BA2E6B8B202B199C3249C471B57A1 /* EXPMatchers+raise.h */, + C43F69BAD51BED8B5077272C9934AE97 /* EXPMatchers+raise.m */, + CDC039A57E303FB78B1A337C34F6D1D1 /* EXPMatchers+raiseWithReason.h */, + 697E0B998BB4B99DC155F08BE3EFCC6C /* EXPMatchers+raiseWithReason.m */, + 4C8177EB82FABE600FA5B880534D57C6 /* EXPMatchers+respondTo.h */, + 7FC8E6210696D094872766EB0C6A7733 /* EXPMatchers+respondTo.m */, + 639DB5F3F4526DD4E2091E18B340C3C6 /* EXPUnsupportedObject.h */, + B1BAE2DAE9706E2DCF18FDA63A2EE109 /* EXPUnsupportedObject.m */, + F3E5EA14068E6E74A749A04470626998 /* NSObject+Expecta.h */, + 3A0B6EC88D0EFA74FC3FB8F0BBCCEC0F /* NSValue+Expecta.h */, + D7FF1BC66B772F592CC4BB58F4662E01 /* NSValue+Expecta.m */, + F1D027994ABA966E5327192A829951DB /* Support Files */, ); - name = "Targets Support Files"; + name = Expecta; + path = Expecta; sourceTree = ""; }; - B4DB9B6E5A9853B9C6D26219E2057F02 /* Pods-BitBotTests */ = { + C93D669BFDBCD1F97EEE3B3EA66F25E0 /* Support Files */ = { isa = PBXGroup; children = ( - 60C55B52DAF071CD4AE7F1521C437500 /* Pods-BitBotTests-acknowledgements.markdown */, - 3C3D9EAFFF76FF6E8C46C08845C3FBA8 /* Pods-BitBotTests-acknowledgements.plist */, - 7AD872128EF47421633BDF1B46487FC4 /* Pods-BitBotTests-dummy.m */, - 77F78C8F8B32756794A2F45D9AEABA88 /* Pods-BitBotTests.debug.xcconfig */, - FBBE22C9909097D742F0E488B3666B9D /* Pods-BitBotTests.release.xcconfig */, + 656179F2734A46FE73D7EAFE5EF0DD3D /* SDWebImage-dummy.m */, + 7A3C3A0A972837655DFEB8EFE38B16C9 /* SDWebImage-prefix.pch */, + 4753CFE0EA0A4BF9BBB242C45FBBDA64 /* SDWebImage.debug.xcconfig */, + FE765919E608D58C7F7808F9D1CD06FF /* SDWebImage.release.xcconfig */, ); - name = "Pods-BitBotTests"; - path = "Target Support Files/Pods-BitBotTests"; + name = "Support Files"; + path = "../Target Support Files/SDWebImage"; sourceTree = ""; }; - CBE7EF899B7F10B020B1A1471B20ACE2 /* Expecta */ = { + CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( - 50C87AB4B61D62461E9958E2BF8D9EA3 /* EXPBlockDefinedMatcher.h */, - 1B53664E19E87DE3381B734459ABCFC4 /* EXPBlockDefinedMatcher.m */, - 841BB69169E16B75648566DC54E4D405 /* EXPDefines.h */, - 7236B3230AD0889A724CF497043F01A6 /* EXPDoubleTuple.h */, - 7D7624BD7181C0A641F064CB8136FF73 /* EXPDoubleTuple.m */, - FD2AF4F508F39F4D9663F4F03F9771E5 /* Expecta.h */, - CEAD97C29EFAB8BEAC263DB3B303A5E4 /* ExpectaObject.h */, - EFBD8DF4B22DC67C05839F4DEFC4965E /* ExpectaObject.m */, - AE3615FE3C25BC5BFED9475620B18427 /* ExpectaSupport.h */, - 7B82369BE8E0B9F11564DBC9E55086EC /* ExpectaSupport.m */, - F2DF1B744FF4D6FEE1E610217915FC33 /* EXPExpect.h */, - E36EE74316446360E858F1A44D7319F5 /* EXPExpect.m */, - 6904639B2FA8645216AE60AAC09C6246 /* EXPFloatTuple.h */, - 6F469FC4B15200F7960D4286CC2DD92D /* EXPFloatTuple.m */, - 4C0C745CE85F9303B8FFDAC722E056D0 /* EXPMatcher.h */, - BD81E51E7A577A51A5C7F3AA815C5DAC /* EXPMatcherHelpers.h */, - FD36DF9DEA7AAFADFD9A80C290313970 /* EXPMatcherHelpers.m */, - 99FFE72BA41D124C3E66032BEA09225D /* EXPMatchers.h */, - 89777E5F7D16F4D26949703CC7890AFB /* EXPMatchers+beCloseTo.h */, - 760EC8BECFAB5CE1F17ABEB898648C77 /* EXPMatchers+beCloseTo.m */, - D09347008ADF9857FE17C7C03E5FD631 /* EXPMatchers+beFalsy.h */, - F1A219168B99676409EC7DFBA7644FD2 /* EXPMatchers+beFalsy.m */, - D7DBBFCB3167A86CC54D0C3B37C27514 /* EXPMatchers+beginWith.h */, - AAFF91ADD6AC060E30D04D8E2DDACF61 /* EXPMatchers+beginWith.m */, - BAB9E6683D0915936373DC5385FC954E /* EXPMatchers+beGreaterThan.h */, - C8A287D51E44E395A8E8B248838B4501 /* EXPMatchers+beGreaterThan.m */, - 6DC77D01AD9862B5693CDB9BCB87267C /* EXPMatchers+beGreaterThanOrEqualTo.h */, - 708F9116E82E223F9775AA96F1EF8AB8 /* EXPMatchers+beGreaterThanOrEqualTo.m */, - D05EB1789A448153E0F229D5CC5BA22A /* EXPMatchers+beIdenticalTo.h */, - EFCD5E8499D6681EF43BD1B9686D12B6 /* EXPMatchers+beIdenticalTo.m */, - 7049926894FD903D522F31E5CBCA8396 /* EXPMatchers+beInstanceOf.h */, - 37A99D4A2DF1C02DCA3946CF86D88A1B /* EXPMatchers+beInstanceOf.m */, - AFFB60D7E65E67C42E01EB132DB30B60 /* EXPMatchers+beInTheRangeOf.h */, - F793FB1C97CF78722676CC204B89E8E5 /* EXPMatchers+beInTheRangeOf.m */, - E50EC90DBAC89E8993831BC6DC782C31 /* EXPMatchers+beKindOf.h */, - 7F31796752F8CF5D9D0D58B025055067 /* EXPMatchers+beKindOf.m */, - FB5F5C16EA219A45277F93692511FE19 /* EXPMatchers+beLessThan.h */, - A7F63D471560A79A81C8EAD9832854AF /* EXPMatchers+beLessThan.m */, - 0A45A1DA22EEDF7CB3E3C2FBF2C94C67 /* EXPMatchers+beLessThanOrEqualTo.h */, - F51B87BA367652C3BCC69A7011799597 /* EXPMatchers+beLessThanOrEqualTo.m */, - 76BFB8CE05074AF39CC140752DEB82FE /* EXPMatchers+beNil.h */, - 318683794EA84AA46B81F67D9B6A5C41 /* EXPMatchers+beNil.m */, - 3BC2E0DACFEAD5F5379C305F858D25B6 /* EXPMatchers+beSubclassOf.h */, - 4CDEE8194B56CF2FED272F0BF55F6583 /* EXPMatchers+beSubclassOf.m */, - D83248A5D588A9C43ABA5B21486F7E1A /* EXPMatchers+beSupersetOf.h */, - BE6767C8ABFABDC3AD0FF966CE31C70E /* EXPMatchers+beSupersetOf.m */, - 6C63BC121FDC54C77FBD9748ACCBC838 /* EXPMatchers+beTruthy.h */, - BC7405D5402B6BFF2D28CD1EC298E665 /* EXPMatchers+beTruthy.m */, - 38C45A85D39A9B8B7ABE3423AF6C7262 /* EXPMatchers+conformTo.h */, - A89D74222F1515674053BCA1F96B288F /* EXPMatchers+conformTo.m */, - 6D2D40E796780AAE41183B9F4680FA66 /* EXPMatchers+contain.h */, - 8A05896299BDD20F8E0B2FBC121EDD15 /* EXPMatchers+contain.m */, - 351E1639156085007A4F6BA6D161F9F3 /* EXPMatchers+endWith.h */, - 955CBA37DD5C01B043411285DB126CB0 /* EXPMatchers+endWith.m */, - DA17C17C59D9A85314409E681085E34B /* EXPMatchers+equal.h */, - 674EF19E7E47344921FFEA25FC8EAE0F /* EXPMatchers+equal.m */, - 5765F80701F6F392447C2ABA53BCD83D /* EXPMatchers+haveCountOf.h */, - 717AAB42E5B837F0CD5E8614F92BE548 /* EXPMatchers+haveCountOf.m */, - 1F0E14AADA908BBB95E09797A0968416 /* EXPMatchers+match.h */, - D493740B17BEFB6678A8F660966907B4 /* EXPMatchers+match.m */, - E87388CE197F1A31AEB8AD9280A4837C /* EXPMatchers+postNotification.h */, - B861323ED525752EA47B9D3053F1AB69 /* EXPMatchers+postNotification.m */, - B2C4DBA9148322CD3B09452E7AAB0C0F /* EXPMatchers+raise.h */, - 90D9077EE66C60A9B04C97F6FDD53C0C /* EXPMatchers+raise.m */, - 31AC3F6479D957A7F4E7816F61098F4A /* EXPMatchers+raiseWithReason.h */, - 341D4E70DB49D4DCD350DA4D9ED20A0A /* EXPMatchers+raiseWithReason.m */, - 49022F133FF236AA7B02EBB4B4827D07 /* EXPMatchers+respondTo.h */, - 9B0855654A0B2D8977CEEC37544E90A9 /* EXPMatchers+respondTo.m */, - 9E5DA0F73EA2D5964035418953C3748B /* EXPUnsupportedObject.h */, - 26BED9F59C1EC352A91517BE7ED5DA93 /* EXPUnsupportedObject.m */, - 1A5502588214C14362D4206E958AB4DC /* NSObject+Expecta.h */, - 8A0BBFFD2EA27DA6B09E2875385A2052 /* NSValue+Expecta.h */, - 0F69AE167CA5113FE2264E86ED76DE4E /* NSValue+Expecta.m */, - CEE0113CD783B7109B2B1798ADD9AFF8 /* Support Files */, + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + D89477F20FB1DE18A04690586D7808C4 /* Frameworks */, + FD9FCB7B71275FD6E621CD260AC4BFE5 /* Pods */, + 9CC236F0C10169F836B5966D2BD67D0C /* Products */, + 1372CFF84AF9666CCDD3BEE2BE07B8E4 /* Targets Support Files */, ); - name = Expecta; - path = Expecta; sourceTree = ""; }; - CEE0113CD783B7109B2B1798ADD9AFF8 /* Support Files */ = { + D89477F20FB1DE18A04690586D7808C4 /* Frameworks */ = { isa = PBXGroup; children = ( - 7F86E9C0BC3ADA6A7A59A633361DA940 /* Expecta-dummy.m */, - 91298D8445BED58F32A59F0D7442D7D1 /* Expecta-prefix.pch */, - 5611299158585069B560CAC196D9809F /* Expecta.debug.xcconfig */, - CF86FD09614080A1FDCD4A411FA33226 /* Expecta.release.xcconfig */, ); - name = "Support Files"; - path = "../Target Support Files/Expecta"; + name = Frameworks; sourceTree = ""; }; - CF1408CF629C7361332E53B88F7BD30C = { + D8F92B2F5E1229AC5548F51DDA9E38F3 /* Support Files */ = { isa = PBXGroup; children = ( - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - D89477F20FB1DE18A04690586D7808C4 /* Frameworks */, - 1FC50B83D29B4182C6134983B9BA472A /* Pods */, - 5FA33FA1E08B26B49B9CE37244438424 /* Products */, - A928A4B651EF55E09657580956EDF03D /* Targets Support Files */, + 91098A929162682414A487BF62B0C51E /* OCMock-dummy.m */, + BA132010529E4E7E70FB8CD58C22D44A /* OCMock-prefix.pch */, + 27BA44A4FAB2F26DB7AD3821A298F697 /* OCMock.debug.xcconfig */, + C7EBFD7698607DF70418A78E51D73576 /* OCMock.release.xcconfig */, ); + name = "Support Files"; + path = "../Target Support Files/OCMock"; sourceTree = ""; }; - D259B3C87B5716DBA090C82854E3B135 /* Support Files */ = { + EBADA6BB88B55D19AAA7FCF801B29170 /* Core */ = { isa = PBXGroup; children = ( - 49424D224EA68C64A3D1A8ED64880769 /* NSPopover+MISSINGBackgroundView-dummy.m */, - 9319667CC0041FDC3FC13F7C93E6E462 /* NSPopover+MISSINGBackgroundView-prefix.pch */, - 0E44BF2888ADFDF6796D186A5C321643 /* NSPopover+MISSINGBackgroundView.debug.xcconfig */, - 2F2AE65500BCABFDFD85D713147C54F4 /* NSPopover+MISSINGBackgroundView.release.xcconfig */, + DEBA5D47513477CC60EDE11609A69A63 /* NSBezierPath+RoundedCorners.h */, + B6DAA8E43339786802C0F8CC809AC768 /* NSBezierPath+RoundedCorners.m */, + 96FC816744C2BCCA51CED048731F0C91 /* NSButton+WebCache.h */, + D281AC19FFB91D8781E163939DDB432A /* NSButton+WebCache.m */, + E2A90A5DEB09F21EA190C89343DE0462 /* NSData+ImageContentType.h */, + 6AA0F981BE89DFC51FBDA98DD87025D9 /* NSData+ImageContentType.m */, + 37E0C1DAB986269E65DF3BF1A45C66D1 /* NSImage+Compatibility.h */, + 6BCD39F27356B900115C3AB0529AFDD5 /* NSImage+Compatibility.m */, + DF94D725DA123E1FA30C9D95416E1258 /* SDAnimatedImage.h */, + 73EAEF93218258282F3A5E40521101B2 /* SDAnimatedImage.m */, + 094D47CB9ED66B51D0B71F70E8BE1EF5 /* SDAnimatedImageRep.h */, + 86690CFE527A596F3B6AA8038D199EA2 /* SDAnimatedImageRep.m */, + 6B2A47368F861EA82DD76288F964703F /* SDAnimatedImageView.h */, + D8478733C770AD8B5E60B4BFFF6C7BFB /* SDAnimatedImageView.m */, + 50F41EB095A01EDA99B2B497F53C1F0E /* SDAnimatedImageView+WebCache.h */, + 7533734215B52194CC28854B3989C0B9 /* SDAnimatedImageView+WebCache.m */, + AE56FFEC107368C3977D88E534EB6929 /* SDAsyncBlockOperation.h */, + 3EE249DEE7BB07E67055EB8B9D87F3F5 /* SDAsyncBlockOperation.m */, + 0FE0E39861C5E3259ECA3D9D2E49DAFD /* SDDiskCache.h */, + 1F04A6A52D80B51E2844EAB7D7922D07 /* SDDiskCache.m */, + 13D79AE204DDA50C7C3F4E8E04D32276 /* SDImageAPNGCoder.h */, + D17B64FED552F0A53E4F9A17E1256AB7 /* SDImageAPNGCoder.m */, + 9387616F36BC353A71CA06624B067969 /* SDImageAPNGCoderInternal.h */, + 058E44E46F03F2A6AB8936F8843AE72A /* SDImageAssetManager.h */, + BB20062D0FA5FA812F3E4061BB7427CB /* SDImageAssetManager.m */, + 9F4D52F3B627B332A01C5715F76C62D8 /* SDImageCache.h */, + 223B6A8C24D4E6A3F09A2E454C53B4C3 /* SDImageCache.m */, + F5F2B1490B6DD7BB39A64E8C982E68A6 /* SDImageCacheConfig.h */, + 2AD68E665E1E63202CCC33440DEE5688 /* SDImageCacheConfig.m */, + 0D606D5FCFC2B24362878D144E408FB4 /* SDImageCacheDefine.h */, + C3D92E3100FDE0A02B9E624C29649659 /* SDImageCacheDefine.m */, + 668302F463985196E28640C57429DA13 /* SDImageCachesManager.h */, + EC1A9E5F4BFAB7EC1F350C715A897657 /* SDImageCachesManager.m */, + 09A3F0CF22C5A4DA1A8DA024DAD3E614 /* SDImageCachesManagerOperation.h */, + 459D974EAA55D2D6B05023A91ADD1E1A /* SDImageCachesManagerOperation.m */, + F77BFB3507FA24ADF2D491C22BDA2118 /* SDImageCoder.h */, + BD89E69E85081CB3BFA0DA50E6BD729C /* SDImageCoder.m */, + FBE1E2A79F4BFD1C2ED9B7F27661C283 /* SDImageCoderHelper.h */, + E3C41018B6941535465C50E902AC4F40 /* SDImageCoderHelper.m */, + 3A37B1F725D56C8C4BCE30AB4B450E10 /* SDImageCodersManager.h */, + 639B0100D981E73C7785C98B61DB4A2C /* SDImageCodersManager.m */, + 3DCDDE6A99DD91D67C0528308889B8C9 /* SDImageFrame.h */, + 1B891BFE89B9952888C4A187D6D6181D /* SDImageFrame.m */, + 119E9DE2FE8F50178BC215E54D111A7E /* SDImageGIFCoder.h */, + 0CF3E89497AE3160C90222810494D9F3 /* SDImageGIFCoder.m */, + 59325D1A1541A07E74163513B6C7AF55 /* SDImageGIFCoderInternal.h */, + B524FC3A2CD1BCD9A80259FC8CE87C5F /* SDImageGraphics.h */, + 143C0131251CC3EC130B715BA6A780CD /* SDImageGraphics.m */, + 91A9040BA97087B23F51E478BA701A6F /* SDImageIOCoder.h */, + 1F1A254848526B7085E6D816DBA83162 /* SDImageIOCoder.m */, + 571073AB176AFE9D5425295A0BEB0C02 /* SDImageLoader.h */, + 297F53EBDB02A11F591EC8C9D9F3F878 /* SDImageLoader.m */, + 03B5D1CBA2A3F931626E0F1CEF40E95D /* SDImageLoadersManager.h */, + F0A2594C9B5A62A6BFE259F3838B7420 /* SDImageLoadersManager.m */, + 49BD7D6166DAB82CE8BE016B0182FCC1 /* SDImageTransformer.h */, + 1302D0CB32C03B303DEC187E3830CF72 /* SDImageTransformer.m */, + C5F608D42A6E990A153F1AB8E208946B /* SDInternalMacros.h */, + 7ECE59D4410E525D049CBF05D59E2720 /* SDInternalMacros.m */, + 5286CE54B4C0709E1A5746B083322665 /* SDMemoryCache.h */, + 33DA7E311D382D1E2A185A8363040779 /* SDMemoryCache.m */, + 10BFBB8F051AEE483FAA09C828C9ADE1 /* SDmetamacros.h */, + 6D2F0B54A0E96CE375161189B18840A5 /* SDWeakProxy.h */, + 7069DDCC3D9FD25F2944D0A9C7BD3812 /* SDWeakProxy.m */, + DF6CA6E602B6EA673C00D2C1246FD365 /* SDWebImage.h */, + 231648EF993E94C012C047EDB0A87DD7 /* SDWebImageCacheKeyFilter.h */, + B69653CC54B8A80021F43EC587AB9266 /* SDWebImageCacheKeyFilter.m */, + 55DC328A5DFB6F98942A41EA53199E96 /* SDWebImageCacheSerializer.h */, + E6429B66FC50FB2E00DE7EBBD2B39441 /* SDWebImageCacheSerializer.m */, + 4F73D52AE3C01661DE55ACA0D0E98D50 /* SDWebImageCompat.h */, + 974630185E5A0C273B1868FF0A45382C /* SDWebImageCompat.m */, + E50C0637D8244791201E8A2D80B8B6DB /* SDWebImageDefine.h */, + 970D9F8EDEB3B80C1218D90CD500232C /* SDWebImageDefine.m */, + 951C5CBA2B0F0DBF578D98D52943E388 /* SDWebImageDownloader.h */, + EB76A04ABD9F9A9253A632D1D64AFC25 /* SDWebImageDownloader.m */, + 5C32FAAC06813A2BAB1ED4111D5695E4 /* SDWebImageDownloaderConfig.h */, + 7C1E4494082CC0E21EBD915E0B5B25F8 /* SDWebImageDownloaderConfig.m */, + CD2B67146BB65F60C7F9AA52A0242BB2 /* SDWebImageDownloaderOperation.h */, + 3D88D09A9D5B23D66D2E3164E233965A /* SDWebImageDownloaderOperation.m */, + 7B4ACCDC92441FA388B90ED4B3F3E349 /* SDWebImageDownloaderRequestModifier.h */, + 8AF45A5DF93EB934D1C9A9A778501710 /* SDWebImageDownloaderRequestModifier.m */, + 04DE6B370E3EE3FE5D61EECEE498400B /* SDWebImageError.h */, + 846A6C09F2ABC29168D385CAA2D58969 /* SDWebImageError.m */, + 0D1A435A8F0243D5863B9B7E1A343AD4 /* SDWebImageIndicator.h */, + 13B1D742BA9A979DF92459A477916420 /* SDWebImageIndicator.m */, + 9F9B7BC7DE91FC476DE62B33FF2103B1 /* SDWebImageManager.h */, + 126910B9AFE2B293DE3439F8733DBEF0 /* SDWebImageManager.m */, + AEA160530D3540C9520D2C636449E6B3 /* SDWebImageOperation.h */, + 7C4A9EB2EB2E18572F51BBB3635C4566 /* SDWebImagePrefetcher.h */, + B111E844834CEDC91CDE3BE38BD67D55 /* SDWebImagePrefetcher.m */, + A8673ECA3B5E894D0AD1F258CFFFB9C9 /* SDWebImageTransition.h */, + 4B4728D9253591A76583B4851D369268 /* SDWebImageTransition.m */, + F3258D01C395815147B1578AF9AFD710 /* UIButton+WebCache.h */, + 9980BF60F7882669ADCC6EACBE8B4B67 /* UIButton+WebCache.m */, + DC78BE6918A6EB0A9A1BB56F9F6F0F2F /* UIColor+HexString.h */, + 85CEE7611CA747051932DE9C7ADA24E4 /* UIColor+HexString.m */, + 96DB10A52721644F3864476CAF337A2C /* UIImage+ForceDecode.h */, + 0C103D4E297EFF00119BCB966FCB8FA6 /* UIImage+ForceDecode.m */, + D786DB1ACA3291F506237438289B40BA /* UIImage+GIF.h */, + 88368478BD964F0C78E7C27C1D7E9A38 /* UIImage+GIF.m */, + 6C76FF267314E0DA402A592F00DDAE6D /* UIImage+MemoryCacheCost.h */, + 8323FE2B3DEDEFC6B6B60BBBEA74D18E /* UIImage+MemoryCacheCost.m */, + 0C686F67FB022C1485E7B62E2841750A /* UIImage+Metadata.h */, + DDF3E3AFB8E2DB0B1288BA44784E32C1 /* UIImage+Metadata.m */, + 7078F92F031EADAB7617667F38967D79 /* UIImage+MultiFormat.h */, + 7868BA38D167639FC1B3A1A064F98CAA /* UIImage+MultiFormat.m */, + FA8333751F570A5824ED5639096D2900 /* UIImage+Transform.h */, + A033ED022000B891E90E46281AE3C84C /* UIImage+Transform.m */, + A50596FAFF371E0C7E67A7CA37C794AD /* UIImageView+HighlightedWebCache.h */, + 82CABB27D18CEA8BFA0E6F9422B6FA84 /* UIImageView+HighlightedWebCache.m */, + D9762FEC996DD0B9D2CB88F3325CEE40 /* UIImageView+WebCache.h */, + 33B716A52A3BD31594FA249C2ED9CBA5 /* UIImageView+WebCache.m */, + 468F25D684EB369BC80024F1557AE98E /* UIView+WebCache.h */, + B436EC62C08B574E6FEA12C19BE5C8C3 /* UIView+WebCache.m */, + 861E4C71E1A5734D8A890EC87DDBB518 /* UIView+WebCacheOperation.h */, + B0629066F58B4A33514A6AF0F03BDDD5 /* UIView+WebCacheOperation.m */, ); - name = "Support Files"; - path = "../Target Support Files/NSPopover+MISSINGBackgroundView"; + name = Core; sourceTree = ""; }; - D86761825ACED43AA65D1FC881042ECA /* Support Files */ = { + EC0463D1AEDC6B911535371FDB9FB238 /* Support Files */ = { isa = PBXGroup; children = ( - CE29FA38779771C8131E0BCCE1BE4F27 /* Kingfisher.modulemap */, - 664A0614E5FE37713C8FCFFC25070016 /* Kingfisher-dummy.m */, - 1F8C9B0F00CA5E3B955DBC8BA1B1BBB2 /* Kingfisher-prefix.pch */, - 97ABC7DE2E6E7D85D21D2C42E767EDC4 /* Kingfisher-umbrella.h */, - ABB22FE656A62BED33D213D15B61E75E /* Kingfisher.debug.xcconfig */, - 9BD2815D50FF77D25D8698E01B52BFC3 /* Kingfisher.release.xcconfig */, + 5A1A3F63E2060CABB0E5098F6A5ED0E8 /* EasyMapping-macOS-dummy.m */, + 152CDD8BC8FA40BCB765CC2A15B6444A /* EasyMapping-macOS-prefix.pch */, + 29C750494B2288788DB4B51460D5DEE6 /* EasyMapping-macOS.debug.xcconfig */, + 74966EDE9BC6FA94BEC3BE0444039F20 /* EasyMapping-macOS.release.xcconfig */, + 1C3A060C3967F3342A7DCC03CFA813D6 /* EasyMapping-tvOS-dummy.m */, + 3CD47642CEB2A2790CA703FAD8DF55D4 /* EasyMapping-tvOS-prefix.pch */, + 9EF84BD0B2F2B9D182E8A39951EE8A9B /* EasyMapping-tvOS.debug.xcconfig */, + 599951F618E605ABAD714564410AC8E3 /* EasyMapping-tvOS.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/Kingfisher"; + path = "../Target Support Files/EasyMapping-macOS"; sourceTree = ""; }; - D89477F20FB1DE18A04690586D7808C4 /* Frameworks */ = { + F1D027994ABA966E5327192A829951DB /* Support Files */ = { isa = PBXGroup; children = ( + A0ADA459399E5006B57CF039E0BFF87E /* Expecta-dummy.m */, + 1A63360C057BAF9E95C3C6ED480FF8E1 /* Expecta-prefix.pch */, + B6762EED2051F9E5E49DF5AF973AC7F1 /* Expecta.debug.xcconfig */, + A6D2EFB975BFFCC2B00A3EB629C22CB7 /* Expecta.release.xcconfig */, ); - name = Frameworks; + name = "Support Files"; + path = "../Target Support Files/Expecta"; sourceTree = ""; }; - EEF33D6AB8C0E1279B3496B704F1120D /* Pods-BitBot */ = { + FD9FCB7B71275FD6E621CD260AC4BFE5 /* Pods */ = { isa = PBXGroup; children = ( - 451058C9822FCCFCFA0769D8F9C0EF8D /* Pods-BitBot-acknowledgements.markdown */, - 3F62CF50DC8FA9E8FA9A41282444BAB3 /* Pods-BitBot-acknowledgements.plist */, - 130BFADFF57F3645DF20CCE614833C47 /* Pods-BitBot-dummy.m */, - 405CE14212D8D81B57A9E972895A31D7 /* Pods-BitBot.debug.xcconfig */, - 04C89116FD3CAABF943C05E0EECAB17B /* Pods-BitBot.release.xcconfig */, + 4EA53F896B2F7FA4EC381E297B2693DA /* EasyMapping */, + B4A4697DEF8CF64F4855D3BB6C2CDC73 /* Expecta */, + 37CFDA1DFE292FDBBC35ED96F460A104 /* Kingfisher */, + 952016718C396B557DF35CDCEC7EF258 /* Mixpanel */, + 55E1EF58993792E5314D82EB663FB5F8 /* NSPopover+MISSINGBackgroundView */, + 68D7C6EC57361107D82B92DC46906EEF /* OCMock */, + 907E406CEEAD533572737C93D69F202A /* SDWebImage */, + A282124BCCDAC1BA2663ECADE53917C1 /* Sentry */, ); - name = "Pods-BitBot"; - path = "Target Support Files/Pods-BitBot"; + name = Pods; sourceTree = ""; }; - EF8CE1F90CAB5D9208B75263EE621687 /* EasyMapping */ = { + FE932BD5B75EB7FB5B2D18456ECF2FB6 /* Core */ = { isa = PBXGroup; children = ( - 0D52C5FC1CFA59718787E43CBB7ACB80 /* Core */, - 5FE238A40353A3A2DCDAEB78EEA086A3 /* Support Files */, + 1754A6ED4900E0794C9F85E0D875BED1 /* Container+SentryDeepSearch.h */, + 3A2CBF658B1028843343F4D084C7F808 /* Container+SentryDeepSearch.m */, + 37BD8D3AB94FFA0798CB394794BCBAD9 /* fishhook.c */, + 50E59068B900E048C38B63AE64FFC855 /* fishhook.h */, + 4F7AACCA9011988D5EA92395F682A784 /* NSArray+SentrySanitize.h */, + C071660C8956DB87DA658081A5D78D83 /* NSArray+SentrySanitize.m */, + BA6674821E44BAAADC77D5FB4CD7671F /* NSData+SentryCompression.h */, + 3298B34DB4E92B8B598D382D9EFE204A /* NSData+SentryCompression.m */, + EE988064E682B9A56B6A0555F5C13ADF /* NSDate+SentryExtras.h */, + A6197DD8D086D74EC7BFCCE051FD5F31 /* NSDate+SentryExtras.m */, + 76D9E7F762492B8E9172AB546A66189B /* NSDictionary+SentrySanitize.h */, + 7899C1894601F14A332E8A700E2B043C /* NSDictionary+SentrySanitize.m */, + 20A2C767F5807D413097F6C204719CA6 /* NSError+SentrySimpleConstructor.h */, + 3CB6B2ED6DFCB782ACC85B2D4C2B7F22 /* NSError+SentrySimpleConstructor.m */, + CDB702BF91B1964D255A4A5C424C327E /* NSString+SentryUnsignedLongLongValue.h */, + CB32A5329227AA32586B5F39F8AC262F /* NSString+SentryUnsignedLongLongValue.m */, + ACC877162AAD2CD71819994ABEB546C0 /* Sentry.h */, + CEDD3F9A418E86363FCB41C14161DC01 /* SentryAppState.h */, + 8D3339DEF95FA636F126C2080A088321 /* SentryAppState.m */, + 5724B0A9796694E79E16B52BE58B5C79 /* SentryAsynchronousOperation.h */, + 7FD7012E4F272E888FCB789C2A861DD6 /* SentryAsynchronousOperation.m */, + D10EBA641A0E8165BB44E4DE84E910B2 /* SentryAttachment.h */, + 912295245C4EFAE6597BD5624C6D29CE /* SentryAttachment.m */, + DC1A06E37E387E8DFDB3FAC7C71EADA3 /* SentryAutoBreadcrumbTrackingIntegration.h */, + 9FF6CBBFF458151EFC2056A73D7092CE /* SentryAutoBreadcrumbTrackingIntegration.m */, + 1D9816E9BA0E9C1D408810DF06B24A0B /* SentryAutoSessionTrackingIntegration.h */, + EC93C90F2B5676049CC384D0AB9C6972 /* SentryAutoSessionTrackingIntegration.m */, + 10C33D949E0F21DC36A9644F03202279 /* SentryBreadcrumb.h */, + 11A50C52679A85C930D61E41E25F0A15 /* SentryBreadcrumb.m */, + 729F7AFE262AF22B1D2157AE03081029 /* SentryBreadcrumbTracker.h */, + 2F01D2FB88692CCA07D12D161B9B3ABC /* SentryBreadcrumbTracker.m */, + 1693B04CD7105542A4995D7B1860CB4C /* SentryClient.h */, + 1BEE132FA31AD0DE7FE890AA026022DE /* SentryClient.m */, + AD6D919B73E1764BE2EA183589BCD2A2 /* SentryClient+Private.h */, + A07387E3FEA32D2AC879F4FBE79D7CF2 /* SentryConcurrentRateLimitsDictionary.h */, + EF55C9584F47C438713DC40D4B95320A /* SentryConcurrentRateLimitsDictionary.m */, + 0D34CB3DFF8BF5C1EAC6DDE6A5A0F132 /* SentryCrash.h */, + E637A1CA51A72009B436C19799A1EB1A /* SentryCrash.m */, + 4FDBE617EF1EA76B9219DC475DFE0B4D /* SentryCrashAdapter.h */, + 54D39586091AD5DC73D4742E3DF9BBEE /* SentryCrashAdapter.m */, + 87CD89D239B8AD49C9E6A7B041C940CC /* SentryCrashBinaryImageProvider.h */, + 310F43800A6087EA88D2D109C93895D5 /* SentryCrashC.c */, + 3AC17A06B2CD1137FBA04236CCCD1715 /* SentryCrashC.h */, + 100CF4E00773DF746C10C45D5F9A6A88 /* SentryCrashCachedData.c */, + 73FBF880D819F3A37A47DF758F95393E /* SentryCrashCachedData.h */, + 8D05EB46779D7C5A818D73B62F77753B /* SentryCrashCPU.c */, + B8AF8D7DF499D5D21A642832F339131F /* SentryCrashCPU.h */, + B96ED94280EE507E42A646706D56CE1C /* SentryCrashCPU_Apple.h */, + 8AF6BB3EE258D3AC2AA0C205519F518D /* SentryCrashCPU_arm.c */, + 2D70F821154E7BBE09D9B7BEDB0361E2 /* SentryCrashCPU_arm64.c */, + 76CD924DD05728AB3BF84E8D93885369 /* SentryCrashCPU_x86_32.c */, + 9B535A4FC57286211DE40388C054BDAC /* SentryCrashCPU_x86_64.c */, + 438F5D72C80C54963277C3109A0652B0 /* SentryCrashCString.h */, + F0B701C1D482E92F4504D38FE92A930F /* SentryCrashCString.m */, + 98B74495E6501725B2A5B7348E1C93AE /* SentryCrashDate.c */, + DCD6C5ADDBAA1A94B1A204F0A2616531 /* SentryCrashDate.h */, + C02A9CF89AD5F57E5E1DC0F438331741 /* SentryCrashDebug.c */, + 6A1732A4F71AA53446C68DDCB89BC9A1 /* SentryCrashDebug.h */, + D611C4E992B69008A1A656939508A290 /* SentryCrashDefaultBinaryImageProvider.h */, + C190ED49B8AF2D2705779E1DD6001A3F /* SentryCrashDefaultBinaryImageProvider.m */, + 67C4AF11F6139DA148872B8D9BAE44BC /* SentryCrashDefaultMachineContextWrapper.h */, + E313C6D74AB03A8A9C0A213DFF159F90 /* SentryCrashDefaultMachineContextWrapper.m */, + 8466E48F03D70CA17AC83C7B881AE446 /* SentryCrashDoctor.h */, + D5DE137007B263FBF5F21EC0F26AF27A /* SentryCrashDoctor.m */, + 02FE69406B0C2F87D52C67EBB5E19FCE /* SentryCrashDynamicLinker.c */, + 36CE61210416761404325FA95F4B0B13 /* SentryCrashDynamicLinker.h */, + 9DFFECBC682FD9C906742F24B35A3F1C /* SentryCrashExceptionApplication.h */, + 7A08B9374BA62246F90A56F8B705B234 /* SentryCrashExceptionApplication.m */, + CDE4D9299F0AF2CF5B0B8F25A0A284BE /* SentryCrashFileUtils.c */, + 9D487B3797BA0C1BE5BA1380E70BF1D8 /* SentryCrashFileUtils.h */, + 50C09C43E38AC5954BD87B5EE7401748 /* SentryCrashID.c */, + CF16C145406DA3D8215F2D031636900B /* SentryCrashID.h */, + A183B8C88C10AE3947EC7E662488F951 /* SentryCrashInstallation.h */, + 1F88FA256932D4EFA23E52859A5ED9BD /* SentryCrashInstallation.m */, + 707B03E715E22776FCC31962771A7E2D /* SentryCrashInstallation+Private.h */, + 87B8D862925C1E3D10970596A63C2CEC /* SentryCrashInstallationReporter.h */, + 03B0EEABA146653D4D0D5E83C4159A4F /* SentryCrashInstallationReporter.m */, + 5F0F3D31B52CB059E34ADCD8A40B4082 /* SentryCrashIntegration.h */, + 131891EA60BFD2C10D365038115CC8C2 /* SentryCrashIntegration.m */, + CD43EB3DB8F1A13F4F230EB3F12BD14D /* SentryCrashIsAppImage.h */, + A84049969AB25295B25C07B265E0573A /* SentryCrashJSONCodec.c */, + 13DE92C9C62C1580212860559CDCDB61 /* SentryCrashJSONCodec.h */, + A256F1C1E08340F2EEA91E8F3B75F656 /* SentryCrashJSONCodecObjC.h */, + AC14140BA60C11A89D4E5C625E6C09F8 /* SentryCrashJSONCodecObjC.m */, + 2A983085F3DFDC173B710B3C170F3368 /* SentryCrashLogger.c */, + 5DA0F2519E0F70EF0D35210ADB5F9D21 /* SentryCrashLogger.h */, + 864951E1419140446120DB8592F5D890 /* SentryCrashMach.c */, + 4BA0261A606C77F7BFED637CC3557677 /* SentryCrashMach.h */, + 31BD2E6667910A3319B47B6397FB7A7D /* SentryCrashMachineContext.c */, + 6F0FFBDBC22ED035FD2A99177FA77B13 /* SentryCrashMachineContext.h */, + 4D48E9E19EDCAF24050949D06D6DD6E2 /* SentryCrashMachineContext_Apple.h */, + 668A94876717C5D861AE21C2D9206219 /* SentryCrashMachineContextWrapper.h */, + 794F16D3AAB9F5CF04D4FDAB7BC7EC48 /* SentryCrashMemory.c */, + 77E6411FB561EA85553780EA72EC7EDB /* SentryCrashMemory.h */, + 9B6F60DE19BDBE6C64EBB8CF63D6EEE1 /* SentryCrashMonitor.c */, + 1B7B262830FE791A2992275F9570DE8C /* SentryCrashMonitor.h */, + 17D19B09C84E2416E96D186E823E81E8 /* SentryCrashMonitor_AppState.c */, + 01CF90EEF3339577C8BEECE383A29D05 /* SentryCrashMonitor_AppState.h */, + 216E33880C75DB02F09EBC7E6442708D /* SentryCrashMonitor_CPPException.cpp */, + E5772F49F24A961F4D2A7CC2EF2C22D7 /* SentryCrashMonitor_CPPException.h */, + 3ED720BAD2544EC968D1F33773CF08EB /* SentryCrashMonitor_Deadlock.h */, + 6E3B8940A8DA7525FD7DD22402B5A63D /* SentryCrashMonitor_Deadlock.m */, + AF11E02E80C577B2B41594595DBFA01E /* SentryCrashMonitor_MachException.c */, + 8A825AE1B597340584246AA8758C978F /* SentryCrashMonitor_MachException.h */, + A55A5E501307CDABEECE7608B972AA18 /* SentryCrashMonitor_NSException.h */, + F8651300AE05A68F5000B0FEDFB83E6E /* SentryCrashMonitor_NSException.m */, + F3A79920CFA1BDBD9E75FB348D29B205 /* SentryCrashMonitor_Signal.c */, + B7E43F64E96E0C3A23315AD8FDD875B5 /* SentryCrashMonitor_Signal.h */, + C871A5023CDCEF1BAB6E6FD1DEE58644 /* SentryCrashMonitor_System.h */, + 977EB770ABF48ED5105390B227CF1057 /* SentryCrashMonitor_System.m */, + 24AF02D97FDECA148365DA4E0103FF00 /* SentryCrashMonitor_User.c */, + 05A5DAC0EC5EF59D6C15397258A939C9 /* SentryCrashMonitor_User.h */, + 8118BBD07F06D9B65E67B6C0CAA7BAD5 /* SentryCrashMonitor_Zombie.c */, + 1F6115F119202A304EEF57D5B2954F18 /* SentryCrashMonitor_Zombie.h */, + A1ED785B7119EA303867FB77D23DC691 /* SentryCrashMonitorContext.h */, + 2756ECD1BE253C72B9421EB065BC47A9 /* SentryCrashMonitorType.c */, + 10F5894E3DCDD857C93D93387290D1C5 /* SentryCrashMonitorType.h */, + 8473F3DC171840EAC0BDA09D6FA0E4A0 /* SentryCrashObjC.c */, + 28F30BDB100EE20988EF30AF46D98AE9 /* SentryCrashObjC.h */, + C5E2A317B34E97C0BC9E7D8A5432134F /* SentryCrashObjCApple.h */, + E9A6894E165A917A3864A338D7E718A9 /* SentryCrashReport.c */, + 8F0537A8A90D413531F5A9EA15E6D7FD /* SentryCrashReport.h */, + C1E333E813AEA3E1D1114D3717C7022B /* SentryCrashReportConverter.h */, + 2CB00895C3B8D81E78B53D91E9A3ED2F /* SentryCrashReportConverter.m */, + C7FE1EF9F428C6334E0F097B069FC11C /* SentryCrashReportFields.h */, + EBF50F815E871FC102F8AA6473815C6C /* SentryCrashReportFilter.h */, + 3C0D06F888A372154BF1F8BA0B428CC3 /* SentryCrashReportFilterBasic.h */, + 149E0F5BB4F3EAB50454D198D95531E3 /* SentryCrashReportFilterBasic.m */, + F97C641D4A8FFBE3CBDB534ACFE13EBA /* SentryCrashReportFixer.c */, + CA279AE3C2EB34F9499A2B45631985DE /* SentryCrashReportFixer.h */, + 085DF157C909A8A4111A1513A172F832 /* SentryCrashReportSink.h */, + 26D65938F613F4DCAC1F063D925D9C8B /* SentryCrashReportSink.m */, + B67294EB0F7BE16140AA5419E527DE10 /* SentryCrashReportStore.c */, + E772C6FC8CD4F5F3153C1AD785CA8BB4 /* SentryCrashReportStore.h */, + 50C776FAE04FB29E201583DFAC74FE9F /* SentryCrashReportVersion.h */, + 06D304B144FA7C586C57986E3612227B /* SentryCrashReportWriter.h */, + 5E10825BF1E02BA77AD12B4EFCB737B7 /* SentryCrashSignalInfo.c */, + 74410FD9A799F3F268BFA760FFFE0B0F /* SentryCrashSignalInfo.h */, + 422EB5E0CBDCA3F2BC8CD610045F4AC6 /* SentryCrashStackCursor.c */, + FF9C78A3E1CB9EF63637883B8EB32A9D /* SentryCrashStackCursor.h */, + 479F6C5B2AD83CECCF85A2F820906395 /* SentryCrashStackCursor_Backtrace.c */, + AE44188648C57CDADB4BBBC4CC62CC3A /* SentryCrashStackCursor_Backtrace.h */, + 7DDB6D70780CEE79091CB18DC8FFCA26 /* SentryCrashStackCursor_MachineContext.c */, + A339574BDAC6852EC8CD47F1A626B26E /* SentryCrashStackCursor_MachineContext.h */, + 9107D3E7F68DC7DB538D9EFB06A196E2 /* SentryCrashStackCursor_SelfThread.c */, + 433A671CB2FACC218F4EFC5EA60169C7 /* SentryCrashStackCursor_SelfThread.h */, + F8678DC07C3A0A61B18287BFACB10934 /* SentryCrashStackEntryMapper.h */, + 098D18C816918B0625F2EFAC46124416 /* SentryCrashStackEntryMapper.m */, + 0691D3E0BDC9CD8351C20F1978A97E1F /* SentryCrashString.c */, + 8522E68E0FED7627A746EDFD9DDD0700 /* SentryCrashString.h */, + B890219F03689D886CBA4020B1CD7B14 /* SentryCrashSymbolicator.c */, + C09407241B2BDC8483771D6D0859B8D2 /* SentryCrashSymbolicator.h */, + E7D07B95AE09FB5092665CB55709027B /* SentryCrashSysCtl.c */, + C932E34914D61B118DFFB14264E4F46F /* SentryCrashSysCtl.h */, + 733EB9949216F382705773FC086855B6 /* SentryCrashSystemCapabilities.h */, + DC3A1C125FE9A2938808FC9189B98F86 /* SentryCrashThread.c */, + 71699EDEB34DA036C4C91F1111D82BC0 /* SentryCrashThread.h */, + 09F7FF971894B9A06B4ECBF1B884BCEE /* SentryCrashUUIDConversion.c */, + 07D346136A47A1485152ECFBB337DF36 /* SentryCrashUUIDConversion.h */, + 021507B63C15C6275FA1614AA26D56C7 /* SentryCrashVarArgs.h */, + 52ED80A99741A76F678B412BF5FC91DA /* SentryCurrentDate.h */, + 6028B0CECC6A8136E220A86E8C686B05 /* SentryCurrentDate.m */, + B55607C0615FFE6430F17A69A880EB12 /* SentryCurrentDateProvider.h */, + CD9E7F9949C74A81F649A55858744F7D /* SentryDateUtil.h */, + 4E61FB7499176B62067C34B234D8526A /* SentryDateUtil.m */, + 28C04358E6A2DC7343F90687D9DB0E7F /* SentryDebugMeta.h */, + D4E58AC687FF6638E95247AC8D47481E /* SentryDebugMeta.m */, + D9BC90810FA98ED7665170917F955CB8 /* SentryDebugMetaBuilder.h */, + D7BC83D8B30962F7F9482DEAB81BF427 /* SentryDebugMetaBuilder.m */, + DA34AA796C52BB44C0BD196FB3DFF6F8 /* SentryDefaultCurrentDateProvider.h */, + 0ABC382AC330CC67B3C949FB87775132 /* SentryDefaultCurrentDateProvider.m */, + FF14B9E54E4823DBAA00FF762A1568CE /* SentryDefaultRateLimits.h */, + F80977F97FF7554E700DD6D4126D3A7F /* SentryDefaultRateLimits.m */, + 1D679F841A6E4E79B5D1E35CA2A4D7CE /* SentryDefines.h */, + A03FCA222D59471B84B0261382857F95 /* SentryDispatchQueueWrapper.h */, + 283CF93D0E24384373D3F11E6A1D612E /* SentryDispatchQueueWrapper.m */, + CD4A38B44E188BC0AE09430BFEDA430A /* SentryDsn.h */, + 0995BB77768EED5B1928D052E061FED9 /* SentryDsn.m */, + E06EC8CDC64B1745C9173D810AF762B5 /* SentryEnvelope.h */, + 8ED89C1427E6BA14DF252DAAE9BBC9F5 /* SentryEnvelope.m */, + FC629D7EE5D4E3D25A8DC71977FB9A70 /* SentryEnvelopeItemType.h */, + 16C3715BC9F903D97400016275A722B9 /* SentryEnvelopeRateLimit.h */, + 2CDC994083E6028E0A5B0CB8C7F894C1 /* SentryEnvelopeRateLimit.m */, + E5D86D1F25D9DEDAABC2D4BF04C13638 /* SentryError.h */, + 7A65932F3946AFE7DE35B76CF74D0911 /* SentryError.m */, + 84148C4BBC5639650E918B7D1AE9FCA8 /* SentryEvent.h */, + F5E6AD007B410E94A2BBD08C73803082 /* SentryEvent.m */, + 539A29AA5C82086D87D861EF794BE53A /* SentryException.h */, + BBAB57A64E6C4CD076398499D4EFB432 /* SentryException.m */, + 643054DB8DBCF6B6727687DF0F36411F /* SentryFileContents.h */, + 1A9FFACA5FE82A9DE4CB2228561AEAED /* SentryFileContents.m */, + 017B91A7D74324D087DE3D13046EC99E /* SentryFileManager.h */, + 00A6995B33F3B7F8D6D346392CE2FAB1 /* SentryFileManager.m */, + 910A5EA3CAC3C38415BB28F6CF628F83 /* SentryFrame.h */, + C324EB3A7AC0090B4AAEA7B08A40BE78 /* SentryFrame.m */, + 33FE9136D837600FD6367096AD17FEEB /* SentryFrameInAppLogic.h */, + F2F27DBEE78FB424F0C52D196487096B /* SentryFrameInAppLogic.m */, + E018C8C2D434DF9416FE294E909F30D8 /* SentryFrameRemover.h */, + DC8FE91A1ADA4F3ED0E95C05F4EFD64F /* SentryFrameRemover.m */, + D60913A7573D0C51BD7A2D9982EA74E4 /* SentryGlobalEventProcessor.h */, + B7B0452CB83EB470B9D578159CD4EC40 /* SentryGlobalEventProcessor.m */, + E1E2C83FDCC2689D4A0B69747EF511C0 /* SentryHexAddressFormatter.h */, + 83C261258984F7E4A236711D1EA29A49 /* SentryHook.c */, + 6792D215AB742EF73C6E5D637C93536C /* SentryHook.h */, + C885E0C6872E0DD37AE7F83D152E4CC8 /* SentryHttpDateParser.h */, + E4C37732B893111733DF0A4585B21DFD /* SentryHttpDateParser.m */, + 58390617A0187652449D42C311506573 /* SentryHttpTransport.h */, + 5D480BEB3C3B1A576E713DB1B6413CD2 /* SentryHttpTransport.m */, + ADCBFFF10E2E79248CA56AECC1AB9EDB /* SentryHub.h */, + 051572966812B4346D5D43CB731AF26F /* SentryHub.m */, + F4C3B484D92B78C21F5D450A1F3A5B12 /* SentryHub+Private.h */, + ABE2CA9730DCE620663640615D743BB0 /* SentryId.h */, + 157863084A17F4A1D73C4C2C4237CF48 /* SentryId.m */, + 216232C7E3B491836F7FE4829869B5D7 /* SentryInstallation.h */, + 5EBC1AF6E820A7A363E11B50E41E5DA1 /* SentryInstallation.m */, + 65A8A898D3B71BB42B900D8CAEF6FB3A /* SentryIntegrationProtocol.h */, + D1CFE48E766C5DA9E609AC5092AAF2E7 /* SentryInternalNotificationNames.h */, + 2CA4FF39ED0B887747BAB6C80C3A034E /* SentryLevelMapper.h */, + EAC198E0EA2F49AA7D4D66A51EE2F528 /* SentryLevelMapper.m */, + 7C35F9CE61D977267F2235041B820E03 /* SentryLog.h */, + F317A88BF3EC0E25B9D3EEEE2368BF99 /* SentryLog.m */, + 2AD6FF53E585D37C0030DD7DDB732653 /* SentryLogOutput.h */, + 60FA170C048C44881C44223DA22C1A34 /* SentryLogOutput.m */, + 1E4DF4622B9F51C96D13D365CC3101A5 /* SentryMechanism.h */, + 35DF544F231298A2C3983E204103A328 /* SentryMechanism.m */, + F1EEA3D5D4E1598D0CBCE3D4DDBF2997 /* SentryMechanismMeta.h */, + 25EDDD7D1E2FDD44649448745A77ABAC /* SentryMechanismMeta.m */, + 4921086B7457B240615C849B4A4DE4A7 /* SentryMessage.h */, + C3AAE60C4B38EA9E0AAAACD0701EA5D4 /* SentryMessage.m */, + 8E00FC8189AAAB1B80CCE473B6C8AF52 /* SentryMeta.h */, + D11372170552F442945E0B5B17587894 /* SentryMeta.m */, + 0963B2E3E97A0722C7CBBDDB36B76860 /* SentryMigrateSessionInit.h */, + 4CCB6752988681478753D8ECC5D8F288 /* SentryMigrateSessionInit.m */, + ABF82152AE21904F7720320408CF90EC /* SentryNSError.h */, + 11570D4A1B52E97A9FA97C20AA7920A1 /* SentryNSError.m */, + D27C49F3B33A9DC4BA1676033B188637 /* SentryNSURLRequest.h */, + 472F88C1AE184846E3C92E70773C562C /* SentryNSURLRequest.m */, + F7D074B3F94A6FA8E0911B6B79FCE292 /* SentryOptions.h */, + 98FC521CFE4B7F822E15B95D82BF96FF /* SentryOptions.m */, + 0D55DD2E8B9C505A780231B6FA0855C7 /* SentryOutOfMemoryLogic.h */, + 6752AE45A10AE01FB384A64DA9F7E3A4 /* SentryOutOfMemoryLogic.m */, + 4995871A89A4C5222BE0FBF47A7FB17A /* SentryOutOfMemoryTracker.h */, + 5408BDB36266B7615E01E688550651A4 /* SentryOutOfMemoryTracker.m */, + 88DBEA1A6DF2FC4DE59CCC2CAE2B4235 /* SentryOutOfMemoryTrackingIntegration.h */, + D63CDF6E2D49F7055CDF917E715932E8 /* SentryOutOfMemoryTrackingIntegration.m */, + 77037A26EFAA75844B4E6E8757662060 /* SentryQueueableRequestManager.h */, + BBCCBA0D6DE3EFC7812C64133351C711 /* SentryQueueableRequestManager.m */, + E482E15A51417B629DB9DA89BFC13FB6 /* SentryRandom.h */, + 2685949B966DFD911386610465982AFF /* SentryRandom.m */, + 979EDE57A39CEF533C37EC090F0D5821 /* SentryRateLimitCategory.h */, + 3E01B96E9D6EEE758CC6F000CB4F7ED0 /* SentryRateLimitCategoryMapper.h */, + 0A52A6F3E00C33219FCD44F31FAD48FB /* SentryRateLimitCategoryMapper.m */, + 4F56E39159CAE9BE998C994876ED8E9D /* SentryRateLimitParser.h */, + 4CC646924C2D2C93556CA6232316B400 /* SentryRateLimitParser.m */, + F8F3224D9568E6D6B837E95D55B0F917 /* SentryRateLimits.h */, + 1861C909B39B2D38DFFDE22EABE4EA12 /* SentryRequestManager.h */, + AFA50A50F6E5469D4E4F53B09FAAFF11 /* SentryRequestOperation.h */, + 9B6F73B31552AA6B9946DE3D01FABFE1 /* SentryRequestOperation.m */, + 1DECCD676C555CF5BA3C512220A939A6 /* SentryRetryAfterHeaderParser.h */, + 97ED53DEEF94C51589000FDDBDD245FC /* SentryRetryAfterHeaderParser.m */, + 58976039A170F01993918E5B37032F00 /* SentrySampleDecision.h */, + 9400F8F8837DB55A86F586A9609B2117 /* SentrySamplingContext.h */, + 59E5B9EB4F70C9724CEC101658BE9A22 /* SentrySamplingContext.m */, + EF4162342FE010A64DF41F62EFFE32FC /* SentryScope.h */, + 2F57830DA0361A1D478D6FD1206B5C8C /* SentryScope.m */, + AF59753534C973EC2CA684E58AA58706 /* SentryScope+Private.h */, + 9D117F3A6C5BAE303986E03C59EAD73E /* SentryScope+Private.m */, + 72683F357F02D5EDA048DC6F23D4092D /* SentrySDK.h */, + 1A164679F41D45A5932DAA29D61891C2 /* SentrySDK.m */, + 2702815AF26E4C9FE035C2A0484F78AB /* SentrySDK+Private.h */, + 2BFEDAD83AB355F5DA2420B3CA6B2A99 /* SentrySdkInfo.h */, + 3F3523459F8BDE81CDD88934EA8F73B0 /* SentrySdkInfo.m */, + E73AE987835897A07BBC6DCC00651DCE /* SentrySerializable.h */, + 893F74730AB7653048453181D4060B4E /* SentrySerialization.h */, + 442B5088AAD4A7635F001BBC8DA25200 /* SentrySerialization.m */, + BFE1C8C5066FDEED8D3A06A903580C81 /* SentrySession.h */, + 23CF50EB90747454BA5721ACEE41D52B /* SentrySession.m */, + CADE90E5E97059DA721F894B29C72DBC /* SentrySession+Private.h */, + A0628EA6AE627462153793C03272C2CE /* SentrySessionCrashedHandler.h */, + 4DAA072773DE54BFAA4917530A95F092 /* SentrySessionCrashedHandler.m */, + 205390348AA79A216C5E4236AF4C090A /* SentrySessionTracker.h */, + 3CA26FD9028DA58D96FBF18B6DBCD422 /* SentrySessionTracker.m */, + EE4528E0DF692080615D4E109A960DBD /* SentrySpan.h */, + 5169589B116558FFAAB8BE33DD6CFF16 /* SentrySpan.m */, + 01C8C1525E5E47B587B3B1805005ABEE /* SentrySpanContext.h */, + CAAE2845DDE3787AE62AC63FD77B83AE /* SentrySpanContext.m */, + 08B901DA30F9297F9B7E39C00791CAE4 /* SentrySpanId.h */, + 5F8FC0B52735277BF7A7F2DBB43DBB93 /* SentrySpanId.m */, + 78AFD32C679BA0512CD29B01C52FD8E0 /* SentrySpanProtocol.h */, + 258332C878F6E9B127D8D8CDC15ABBBB /* SentrySpanStatus.h */, + 707760BF81A4C4F1570470CC648600BC /* SentryStacktrace.h */, + 41B0A65DF6211BF2861ABE6E500D3B7E /* SentryStacktrace.m */, + EC1EEE25B6064557720CF2B1812DF2FD /* SentryStacktraceBuilder.h */, + 0D11B4BDEC059D18FA4E0388AD0D8785 /* SentryStacktraceBuilder.m */, + AFE14AC670BBDE68888F91AD1EAD112D /* SentrySwizzle.h */, + 4E52820D73978A25A8C1B784E898C377 /* SentrySwizzle.m */, + ACF78BEA53B328FF4AC085F3142F1197 /* SentrySystemEventsBreadcrumbs.h */, + 8D21CAAD0ADD11B944B272D58532943B /* SentrySystemEventsBreadcrumbs.m */, + BBC0FD88956CF8F23259FCE3D7B5E7C9 /* SentryThread.h */, + 89B11BFCB1A668E910E7D78C6959D8B2 /* SentryThread.m */, + 0EE44E030124FB9FEF6EEA1B78AC4F09 /* SentryThreadInspector.h */, + 6885FD677F329175EFEA133271225111 /* SentryThreadInspector.m */, + 745E8932DD0AB64C1A0DB120B425D892 /* SentryTracer.h */, + 8AABDDA011743888BE5370D828CE8324 /* SentryTracer.m */, + E7A20D0EF6CC27822F5F673A4C0CE300 /* SentryTransaction.h */, + 0F77AE7AF85B51FDC734F0B9716C1B11 /* SentryTransaction.m */, + 4B10146712CA2C75052E427FF98FEE76 /* SentryTransactionContext.h */, + 1CD9DCB3C79818BF4DC9700BE32E0785 /* SentryTransactionContext.m */, + DF5D8291C1A5901C39977D7EC0026FDB /* SentryTransport.h */, + 8FB87107341CDBA82C7CEB2B131A51B3 /* SentryTransportFactory.h */, + 249A621C3105048EAC1AAFF00A061841 /* SentryTransportFactory.m */, + C35F4308293B135C7155C0CA4BD07558 /* SentryUser.h */, + 17C1EC470E15CDC0A396B6A75163FD54 /* SentryUser.m */, + 61B13957C17E507A36360EEC6762EEB2 /* SentryUserFeedback.h */, + D31491006FD74023E72260AE10EAB3EA /* SentryUserFeedback.m */, + 46AB541CCB0ABA088F628178E27D63A8 /* TracesSampler.h */, + D88D303335E70DB46B148AF73F042D6E /* TracesSampler.m */, ); - name = EasyMapping; - path = EasyMapping; + name = Core; sourceTree = ""; }; /* End PBXGroup section */ @@ -1737,6 +3081,186 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 48B8A2D865C5A1C9EB7B4EE014F7AB8F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F78114247A88B45FB1793C1B91EF4239 /* Container+SentryDeepSearch.h in Headers */, + 5F093700A2F831DEDB72E6B79A78BD92 /* fishhook.h in Headers */, + 61B3038A5DD13EDCC32F709956ECCA64 /* NSArray+SentrySanitize.h in Headers */, + EE3B38AAF28EC96D14AD7FAA38D3ABB2 /* NSData+SentryCompression.h in Headers */, + F9977D025D4848E253BB040AD7F0A0D2 /* NSDate+SentryExtras.h in Headers */, + 718B9E93210A8AF5B8EB02F07073FCBD /* NSDictionary+SentrySanitize.h in Headers */, + C5D677C161E34D4601D39E703062F674 /* NSError+SentrySimpleConstructor.h in Headers */, + 5A478B7929BA7487BC065F93AF68C319 /* NSString+SentryUnsignedLongLongValue.h in Headers */, + C998AC42B31D27D637E71C147B6DF9DC /* Sentry.h in Headers */, + C2EC7A9CB370F4E283C430C290734AE4 /* SentryAppState.h in Headers */, + F46A1C326588B04A3D0092FAC2D9F92E /* SentryAsynchronousOperation.h in Headers */, + 329727CC5B87F69BAF0886DC846F57EE /* SentryAttachment.h in Headers */, + 03F5CFCBF0C1033ABC8951B2B406ADB4 /* SentryAutoBreadcrumbTrackingIntegration.h in Headers */, + FEF8707835935AC79B6D2B5D976963ED /* SentryAutoSessionTrackingIntegration.h in Headers */, + 9F6E2AA5B19A49BAFBBA3D17CDA34036 /* SentryBreadcrumb.h in Headers */, + 382C9C3A0F41581340331A194F3672E6 /* SentryBreadcrumbTracker.h in Headers */, + 24DCA3772E4FA6F77D08880B8E47904F /* SentryClient+Private.h in Headers */, + FEF34113D2C3F5CB5DABDB5E60726650 /* SentryClient.h in Headers */, + 4A646460F7E6DD2AD4970FCFEBEC2EE1 /* SentryConcurrentRateLimitsDictionary.h in Headers */, + 9A1D2DAB700D2F165A7631E5BD9F2790 /* SentryCrash.h in Headers */, + 02C261C3E5A39ACC64244A8F380FBCAB /* SentryCrashAdapter.h in Headers */, + 624F4C5F3039A454392C2150A801171D /* SentryCrashBinaryImageProvider.h in Headers */, + 0C6A47A81D7BB7EB3044BCECB58EA76F /* SentryCrashC.h in Headers */, + 1815CB239F54F1DBB6D094492FA67935 /* SentryCrashCachedData.h in Headers */, + E02F2060665C40B704ECA410BE4504FC /* SentryCrashCPU.h in Headers */, + B37091C335BA5DB4EAD19B61DFB7883A /* SentryCrashCPU_Apple.h in Headers */, + B07538E7C6D99FB5BAC78A3C8DBB42E1 /* SentryCrashCString.h in Headers */, + 3F6E67C32D7BED098DF9740C1A5A0877 /* SentryCrashDate.h in Headers */, + 02AB7FD6E971C0E6E3EFC2953296850F /* SentryCrashDebug.h in Headers */, + 26D1A2F917DAD31D34EB0245FE6253F0 /* SentryCrashDefaultBinaryImageProvider.h in Headers */, + 3883614D0C16437A09C006BDB41B0E37 /* SentryCrashDefaultMachineContextWrapper.h in Headers */, + CBFCBAB70247D43B34732B30B02289F3 /* SentryCrashDoctor.h in Headers */, + D461A4857C4768E0B6600988641B76A5 /* SentryCrashDynamicLinker.h in Headers */, + 6E891DCCC0B5B58C59E6925437E24B5F /* SentryCrashExceptionApplication.h in Headers */, + C9FFFDB86316A0ECA4373D2F31D4EBFD /* SentryCrashFileUtils.h in Headers */, + 8E205C644854D0686EA55BD2B7A564F4 /* SentryCrashID.h in Headers */, + 06395D1A27A40E21AAB0A02DF8BFFA5E /* SentryCrashInstallation+Private.h in Headers */, + A1C36CC845958977873951337FC4C3BE /* SentryCrashInstallation.h in Headers */, + 2B16EA7802DB6BAB1B388CCFCB29ACA9 /* SentryCrashInstallationReporter.h in Headers */, + 7BF6CB8A03E9EE464778CF4ACBAC80E2 /* SentryCrashIntegration.h in Headers */, + 3B91CCA46476F9085E8D56D81ADC6437 /* SentryCrashIsAppImage.h in Headers */, + 6B88B156844760908D535DDB2E59A0B9 /* SentryCrashJSONCodec.h in Headers */, + 7E9548ABBA08444FF57D3BB9E89CF89B /* SentryCrashJSONCodecObjC.h in Headers */, + 893111B6205B7FE5EB13264511A6697C /* SentryCrashLogger.h in Headers */, + 771B768E46483AF4B29811AAA06AEFDA /* SentryCrashMach.h in Headers */, + 891E6FBFF27D16F0454DB3503DFD112A /* SentryCrashMachineContext.h in Headers */, + 8BE5F8AFD9599FB4D542FEEA1E61299B /* SentryCrashMachineContext_Apple.h in Headers */, + 8CAB3898BB17F34D23346496CE0E0A67 /* SentryCrashMachineContextWrapper.h in Headers */, + 47FE0CB05A96A5894033A8B83225F6BC /* SentryCrashMemory.h in Headers */, + A71370F4935778355DF49316C4130053 /* SentryCrashMonitor.h in Headers */, + F45DC3D227892AECA7091CFA5783DE9C /* SentryCrashMonitor_AppState.h in Headers */, + 6153DC71AA743CCC08CE7F3A614F7CC8 /* SentryCrashMonitor_CPPException.h in Headers */, + A327DFEF86D8B57F7C0091B904B8D876 /* SentryCrashMonitor_Deadlock.h in Headers */, + 93D5BBA4B364F5312887A675E25388AC /* SentryCrashMonitor_MachException.h in Headers */, + 9311CFD012D1CDC16E9719C9087A640E /* SentryCrashMonitor_NSException.h in Headers */, + E49674D8BE2B14B254D787410495D4BE /* SentryCrashMonitor_Signal.h in Headers */, + E4B3DBA8AE6557EBE579E89ABBAACFD3 /* SentryCrashMonitor_System.h in Headers */, + D220F073B1BBC9D6C8740FE14B20194E /* SentryCrashMonitor_User.h in Headers */, + 0F32EB10487FD4E1AFB085354A2F4642 /* SentryCrashMonitor_Zombie.h in Headers */, + 332F71C7E4732A9E1865EBF987DC1E79 /* SentryCrashMonitorContext.h in Headers */, + 07193DD81439174D4B8DDA86835AB0CD /* SentryCrashMonitorType.h in Headers */, + 65966C9F6D9F555A0B4FE2A59AB2F87E /* SentryCrashObjC.h in Headers */, + 0D4AA798F6D543876B4184B6A08E716B /* SentryCrashObjCApple.h in Headers */, + A1D4BF93966F679CA1158691ECADAFD2 /* SentryCrashReport.h in Headers */, + 0B21FA5871B6F62512CC91D4AF3F1646 /* SentryCrashReportConverter.h in Headers */, + B42F53A5373F6DBD58A3753377F11A3F /* SentryCrashReportFields.h in Headers */, + A731311E14FA86A1B4802C3C114AE6F8 /* SentryCrashReportFilter.h in Headers */, + 368AC5FD67E926ACA2C7E206F8F4FA59 /* SentryCrashReportFilterBasic.h in Headers */, + 9BA4EDC40FABB96AE639CE795D3F3D8A /* SentryCrashReportFixer.h in Headers */, + B4414D2644F388ADC0C39DC930324A90 /* SentryCrashReportSink.h in Headers */, + 9A14041987B17C1D70C8E93B78DC1415 /* SentryCrashReportStore.h in Headers */, + 615D536041DDBBEEADE84CBF41513838 /* SentryCrashReportVersion.h in Headers */, + B587FF3B640203FF67D0AAC3E7A9580B /* SentryCrashReportWriter.h in Headers */, + 5C85782CEC7616BA354A317B7536DC8E /* SentryCrashSignalInfo.h in Headers */, + 9024F577BCA603F64895B5436E882A31 /* SentryCrashStackCursor.h in Headers */, + 0F8D3E5A1F385A27C17AC3FBAF77D7B9 /* SentryCrashStackCursor_Backtrace.h in Headers */, + 7E7E5DDA00EFB9CAE1711863C6DFED43 /* SentryCrashStackCursor_MachineContext.h in Headers */, + D4D9F57DC6C5FB4B2A01201DA81A5A8E /* SentryCrashStackCursor_SelfThread.h in Headers */, + 5A2CCC68530C7040F1777EC4D2F1551F /* SentryCrashStackEntryMapper.h in Headers */, + B67DB68BFDA7EE795AC74CB0AC45001A /* SentryCrashString.h in Headers */, + 19B029DC65FAE863E6B0136CE5DAAE3F /* SentryCrashSymbolicator.h in Headers */, + 78EA884E98093B5FC97DD7710FD70779 /* SentryCrashSysCtl.h in Headers */, + 8BEE89715D6281CD53F462F0E2BBA599 /* SentryCrashSystemCapabilities.h in Headers */, + 130DD540BB6A30E2A78896396C4EFBB3 /* SentryCrashThread.h in Headers */, + D3429C53587B3AACD6152043D5AEE6B2 /* SentryCrashUUIDConversion.h in Headers */, + B02325814394E4F3606C1F8EDC5E9367 /* SentryCrashVarArgs.h in Headers */, + B44FC2AB5B47F10C09A1C458049CF21A /* SentryCurrentDate.h in Headers */, + E69FAAB07BA64EFA282DD6533749448D /* SentryCurrentDateProvider.h in Headers */, + 73325E46BC27E70CA40360B7A2D50C2F /* SentryDateUtil.h in Headers */, + 8BB9EEED678887D3E12AFE3B32A961F4 /* SentryDebugMeta.h in Headers */, + D3ED628D907EC5A5812F6282B1865B35 /* SentryDebugMetaBuilder.h in Headers */, + D90DF2DC3D1C9A3AA4339CABEAE770EF /* SentryDefaultCurrentDateProvider.h in Headers */, + 87A149568A9FFB275ABA463F08C4F4D0 /* SentryDefaultRateLimits.h in Headers */, + C6BC24640D2B9B336247D9EA26C59E9B /* SentryDefines.h in Headers */, + D6A40A9E58A4D053EAFC59EA5A1D3510 /* SentryDispatchQueueWrapper.h in Headers */, + 58227EE0228AD65F67824364F3F00008 /* SentryDsn.h in Headers */, + 833ACF674B6B23FE6A1430E23AC875D3 /* SentryEnvelope.h in Headers */, + 124B5CDCE1A2C1CC04D40D0A096A4149 /* SentryEnvelopeItemType.h in Headers */, + EDDC5F0F11F9259AFF050359E79DB57E /* SentryEnvelopeRateLimit.h in Headers */, + 7CE32DF6E2711D45C5D8E729C54A4AE1 /* SentryError.h in Headers */, + B0BBCE4814FD7D6927440AE418591B2E /* SentryEvent.h in Headers */, + 1219102F3ACBEB268E978460516FFDA4 /* SentryException.h in Headers */, + AD5E020DE6D6894A6DE52ED3425E7E3D /* SentryFileContents.h in Headers */, + 23FF3738AF42DAA97EDC406C88BFBF94 /* SentryFileManager.h in Headers */, + 9FDE4F42EC733A5EBE03577A1B0BD616 /* SentryFrame.h in Headers */, + AF1CE89AB242EE3E79A62A11D1DB45BA /* SentryFrameInAppLogic.h in Headers */, + B5C28A763C4100F75703229CB27148BB /* SentryFrameRemover.h in Headers */, + F4CFA29E646297ADEA02FE0D2AB9F89C /* SentryGlobalEventProcessor.h in Headers */, + BB73937DFA779CE341839F29F767FC96 /* SentryHexAddressFormatter.h in Headers */, + 6B2003806D88FB4BEA846EA5179B13E2 /* SentryHook.h in Headers */, + F76ADB72D5BB24A5A59F9FA06C9B3D9D /* SentryHttpDateParser.h in Headers */, + 476F20500C2C3F50C35E23390D1E003C /* SentryHttpTransport.h in Headers */, + 7DDF7F2CB636B216C8763FB6C3C08005 /* SentryHub+Private.h in Headers */, + 909179C22A3DF2C07DC45F86FB02083F /* SentryHub.h in Headers */, + B2152DBDF58C09D82AE8E9697E15C092 /* SentryId.h in Headers */, + E9D14ECAFF22E8A41399D2A863A239AF /* SentryInstallation.h in Headers */, + 8E0BA9176D8C95E9F1436C2E7F95D421 /* SentryIntegrationProtocol.h in Headers */, + 0E635614142E32FD9F8C01EDB69B1625 /* SentryInternalNotificationNames.h in Headers */, + 17D16CC85A55F7893378226320FDDEEA /* SentryLevelMapper.h in Headers */, + 346B0A9DA79A7C913D04703A59139DA9 /* SentryLog.h in Headers */, + 39DE503905BDCF4F110A16EEDB54F1AC /* SentryLogOutput.h in Headers */, + 94B6DAFE2FD3A0309F25E7EAAC53DA34 /* SentryMechanism.h in Headers */, + 3C5178CDD33187B18E01DF7B336950A0 /* SentryMechanismMeta.h in Headers */, + D43E2D8252B250C938F3C06A5C5A4E8B /* SentryMessage.h in Headers */, + 6564DDC2D24997D5B15457DCDE8744F0 /* SentryMeta.h in Headers */, + 498E5A14A3BAD36D01F3C817BAC822DF /* SentryMigrateSessionInit.h in Headers */, + A7EA36DC1811C699D2C4C0831FB9EADC /* SentryNSError.h in Headers */, + 51E38CC17B40B0DBEA0811D622A0C1F0 /* SentryNSURLRequest.h in Headers */, + D6F6AD5F0E32B5E8AB6BF2E7C098A05A /* SentryOptions.h in Headers */, + D7085F72FF2D1C4C93B114D39C880216 /* SentryOutOfMemoryLogic.h in Headers */, + 54D82C0542CED2FE83F2350B5DF89707 /* SentryOutOfMemoryTracker.h in Headers */, + 433DA65CBD4E6720A0F5FE8F37FEEEBD /* SentryOutOfMemoryTrackingIntegration.h in Headers */, + A370F8BBD13111FDFCFA7A10577C35EF /* SentryQueueableRequestManager.h in Headers */, + 98B330E41CE45CED9AC0C426F192F000 /* SentryRandom.h in Headers */, + 6344EAFAA20DD33EDF1D34CA754571BC /* SentryRateLimitCategory.h in Headers */, + 39540AB3BF2C0D0AC47D97AB9036F71E /* SentryRateLimitCategoryMapper.h in Headers */, + A495437891EBB7938E7068677FB64F68 /* SentryRateLimitParser.h in Headers */, + C5B32C4394CCEDB572459394BDB3FC60 /* SentryRateLimits.h in Headers */, + 34E54E4279F1798CD2967306D23D9D4D /* SentryRequestManager.h in Headers */, + 5334639B9FFD9F04E02BE4E9F91499C2 /* SentryRequestOperation.h in Headers */, + 3D6384561F570C0C678EF055B88E4F23 /* SentryRetryAfterHeaderParser.h in Headers */, + 0A268D01D23A774FAFAC6C9C35594A43 /* SentrySampleDecision.h in Headers */, + 0C91143C982032738F7EB25775DA3B6F /* SentrySamplingContext.h in Headers */, + A01199D4151D6DEFF98D292E794581A9 /* SentryScope+Private.h in Headers */, + D4B33820AB9FF17E1E0FE9530ED39E1C /* SentryScope.h in Headers */, + 8B44F94C4180A18C6D5863A149DEE715 /* SentrySDK+Private.h in Headers */, + 923E97A02255B4F84AAAE4DD6AC6C6E4 /* SentrySDK.h in Headers */, + F70FFCE7CD088CF1051BE01852B7DED5 /* SentrySdkInfo.h in Headers */, + E57EE5D6EF2562B002AB69429AD0B7F4 /* SentrySerializable.h in Headers */, + C04B253BED4BD526528573F487619765 /* SentrySerialization.h in Headers */, + 900483F018B375B428D1E32F3DB919BE /* SentrySession+Private.h in Headers */, + 79A75320E54F09C2F7E8C8E6F5F10D8E /* SentrySession.h in Headers */, + F3F17BC2AE9E98FE68B5DF1435F8DDC7 /* SentrySessionCrashedHandler.h in Headers */, + 08FDBF25279270022964AA3CCBF6633C /* SentrySessionTracker.h in Headers */, + 2D566410B96E56D417C8BB7542C67A91 /* SentrySpan.h in Headers */, + 4826CB79FAB8E2AE560D9924A300270B /* SentrySpanContext.h in Headers */, + 0303374046837710F3D28C3B0B4CD039 /* SentrySpanId.h in Headers */, + 39CDE5B1AA525EEFEFF30B9538B8A7FB /* SentrySpanProtocol.h in Headers */, + CC7B01EF0F57A09A5BA86CD7F719C811 /* SentrySpanStatus.h in Headers */, + A65F2AEE7FB68576B6E1BC8C7184DFAA /* SentryStacktrace.h in Headers */, + 9347C0404D47A3B1FCC09D8DF592F0B4 /* SentryStacktraceBuilder.h in Headers */, + D33081A99EF7C3EF8FEF87979943D427 /* SentrySwizzle.h in Headers */, + 940F21B9A3A36EF8ED734718FC13FDC5 /* SentrySystemEventsBreadcrumbs.h in Headers */, + 61C0D893E3B2DAD5ADC53BD84FA920C1 /* SentryThread.h in Headers */, + F7ED9EAD3805A6C58C1466646CE20A82 /* SentryThreadInspector.h in Headers */, + ED7200380D9FCD751F09B5EF1C4612BE /* SentryTracer.h in Headers */, + A442B55E72B9E343A34C6185EF5BEE51 /* SentryTransaction.h in Headers */, + 9C335E0C75EF070C6D4A83AEC64FBF01 /* SentryTransactionContext.h in Headers */, + 8A12D80BDE28291F4B892EC9AC16A7F5 /* SentryTransport.h in Headers */, + 6B6C1C4E6311F21507FCE7DB7090AB87 /* SentryTransportFactory.h in Headers */, + 8D3CF898A1AED34C26AF862E7E3EB71C /* SentryUser.h in Headers */, + C11A2ACA77C6BF8D6821D2DB9C28E096 /* SentryUserFeedback.h in Headers */, + 57119A5FDC2E82134E056FB0BF0AD593 /* TracesSampler.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 559DF3BD40FAE2478E30F355A3BE9218 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -1783,6 +3307,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5F0E0615A305E3D6F56D60BD0F706AEE /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C60568B491B9DC158DED56407047852A /* Pods-BitBotATV-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F77E05E8806560501D00AAF695E0C66 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -1803,13 +3335,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 751EC745883019FD316D29D2792DC2F2 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 833E1749875AB868E8FFC8312F7183A8 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -1833,18 +3358,197 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 98C5E32839097FD59A14F1445625F2BD /* Headers */ = { + 95D0D06C8C76306CB4132979D505E396 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 0BE6A4F2147AF27E1F426CB73618739B /* Container+SentryDeepSearch.h in Headers */, + 0C278D28FBE5D9ABCAC2C28B87930AA3 /* fishhook.h in Headers */, + E574DFE0C6E91C79181C033CAB99842D /* NSArray+SentrySanitize.h in Headers */, + B6D28D12D9F9B9D61C988129EA6D1919 /* NSData+SentryCompression.h in Headers */, + 25AA61B3AFA6BA2174C68BCEC65EFD44 /* NSDate+SentryExtras.h in Headers */, + 570CB48E1424192AEA23FCD7F4FDA23F /* NSDictionary+SentrySanitize.h in Headers */, + 997852819F690AE3E059573B84BE10A2 /* NSError+SentrySimpleConstructor.h in Headers */, + B5E7B7574A67181C856E0C677ABFBBAE /* NSString+SentryUnsignedLongLongValue.h in Headers */, + 635A6105DE7E61EB7B657250BEE397EF /* Sentry.h in Headers */, + A5DAC4AA05505E57069CB3192FB88517 /* SentryAppState.h in Headers */, + A5C99AC00D6E07276A05C23CFF9CE496 /* SentryAsynchronousOperation.h in Headers */, + 1E13E59EAB5B4BBF1C9EACB6A6F103FC /* SentryAttachment.h in Headers */, + 3A5EC68C9C94AF6767B9DE70F70F765D /* SentryAutoBreadcrumbTrackingIntegration.h in Headers */, + 615AE5B2C412C6521AC9ADE3634DB859 /* SentryAutoSessionTrackingIntegration.h in Headers */, + D1E9BBF25DF848728F82B7AC88E2744C /* SentryBreadcrumb.h in Headers */, + E85244D0F4D0AC8555C380CB0F9D57DF /* SentryBreadcrumbTracker.h in Headers */, + 88410B62B8DE587A46FC7585ED83D331 /* SentryClient+Private.h in Headers */, + 3D382E499B8BCAF8A1B0B32C227B41A1 /* SentryClient.h in Headers */, + BD285C4B8AA93E741611DD1556DE4069 /* SentryConcurrentRateLimitsDictionary.h in Headers */, + 33DF0A3CD48108AEA7B20F04837298F4 /* SentryCrash.h in Headers */, + 332EDD4B52609D9E2FAB74C157DABA76 /* SentryCrashAdapter.h in Headers */, + A6627DDCBAC5902427F06406C17FBD90 /* SentryCrashBinaryImageProvider.h in Headers */, + 46662E1A6DCBA8F8F0BF54DB050B85F6 /* SentryCrashC.h in Headers */, + 9150E0D884F547968001FEA0DD1ADE07 /* SentryCrashCachedData.h in Headers */, + BDFF7A69B6B203BC4DB6ADBF3EC42CAC /* SentryCrashCPU.h in Headers */, + B089A167D7843D388D7257B183119170 /* SentryCrashCPU_Apple.h in Headers */, + F2282BCB06ED4241E1DA9AA02C18452F /* SentryCrashCString.h in Headers */, + F7152A7109DC2A6E38B386B924771ED0 /* SentryCrashDate.h in Headers */, + 8C51FD9693D6F334A594DE8C39D1533E /* SentryCrashDebug.h in Headers */, + 3392D2E960D7DC25FC7654AE46D88826 /* SentryCrashDefaultBinaryImageProvider.h in Headers */, + 52EFF2F07728CEDF82364F4272365EE0 /* SentryCrashDefaultMachineContextWrapper.h in Headers */, + 9226C7A923AA1CE7A87F1372C673CD47 /* SentryCrashDoctor.h in Headers */, + D5F038BE87A55128BD2AADFF1B2BCC66 /* SentryCrashDynamicLinker.h in Headers */, + 31E32A4CB736BDDFD999D5C2B5853A54 /* SentryCrashExceptionApplication.h in Headers */, + F31B3B28D61829979B9811837CD06A59 /* SentryCrashFileUtils.h in Headers */, + C035140AB4EE01C891E20BBFF8D6796E /* SentryCrashID.h in Headers */, + D5BEB27AAC6AB430F127D8BD0CC6F0CB /* SentryCrashInstallation+Private.h in Headers */, + 6519FB4DA2CEEAED9D69014D004A62B1 /* SentryCrashInstallation.h in Headers */, + C5E3E4FF82E3E5EF903C7C3BA4AF5B24 /* SentryCrashInstallationReporter.h in Headers */, + 7F72D00FC206707FB310CA57D371D9EC /* SentryCrashIntegration.h in Headers */, + FEF54D75494F24857B6C60CA6B9C31BD /* SentryCrashIsAppImage.h in Headers */, + 971B4C9BAB43DFD9C22A3BCAD962B882 /* SentryCrashJSONCodec.h in Headers */, + 2F2B73383C4EB46C4A2568304CC40A8F /* SentryCrashJSONCodecObjC.h in Headers */, + F2D916718D2E7D7E0610969A627E93FD /* SentryCrashLogger.h in Headers */, + 67B9250508EF1FBDB01B02BD6CEFD873 /* SentryCrashMach.h in Headers */, + FE02EFB4C22E56F997DD6019B06D38D7 /* SentryCrashMachineContext.h in Headers */, + A9F97A22BB3B6CE7148194717E4E415F /* SentryCrashMachineContext_Apple.h in Headers */, + B49614695970F83CFEE68B8A61EBEA1C /* SentryCrashMachineContextWrapper.h in Headers */, + B4596B592E540A4887A76F8367BB64D2 /* SentryCrashMemory.h in Headers */, + C61B8F138CBC985B7A4D0477D6FB013F /* SentryCrashMonitor.h in Headers */, + C678D9267C3C16D92EDDD7A1125FBED0 /* SentryCrashMonitor_AppState.h in Headers */, + 4A2D9307A43FBFC4899C02144F46D403 /* SentryCrashMonitor_CPPException.h in Headers */, + 99FA053F5CAB636FD11312F40EBBF0CC /* SentryCrashMonitor_Deadlock.h in Headers */, + 28C5305E54BEE838C2417164F7FD6DC8 /* SentryCrashMonitor_MachException.h in Headers */, + 1305E3E5FE7BBCA238F58E82FF3CB112 /* SentryCrashMonitor_NSException.h in Headers */, + 4C1A04A84B22F36975D2918553B1F42D /* SentryCrashMonitor_Signal.h in Headers */, + F82B1826A74659DF7FCAB6AC03AF559E /* SentryCrashMonitor_System.h in Headers */, + 040D38DE5CCF1E753AE9E01F499B9995 /* SentryCrashMonitor_User.h in Headers */, + B814EB568E6FC783F451588AF8D3C426 /* SentryCrashMonitor_Zombie.h in Headers */, + 0EA31AE23591C4AEE8C9CB6632ACDBCB /* SentryCrashMonitorContext.h in Headers */, + FF5D013AA6280083C7EC16BE7E6273A1 /* SentryCrashMonitorType.h in Headers */, + F9B6CD3150A237B72B34F88D3018C20D /* SentryCrashObjC.h in Headers */, + 8A590AC6ADAC4DA97B2EFBE1D37EB17D /* SentryCrashObjCApple.h in Headers */, + D99F4EBB23AB24DDC6FA644C1E33B45B /* SentryCrashReport.h in Headers */, + 5A251C978AB6ADB201CD3EA58FF1545A /* SentryCrashReportConverter.h in Headers */, + 71246DF7E5A02CA452078BB762FCDE3E /* SentryCrashReportFields.h in Headers */, + 88599A80B45E050AA4D5961445F67AB7 /* SentryCrashReportFilter.h in Headers */, + 63418C3CB4D94D127C02E7FE00232B26 /* SentryCrashReportFilterBasic.h in Headers */, + 9A3DCF423259DA1AC1A0F0851FFACEEB /* SentryCrashReportFixer.h in Headers */, + 20C529D50C75C371E15BCDFFE0A15F98 /* SentryCrashReportSink.h in Headers */, + 2FE1E99E3D73775B86C84EECBA5FA1D9 /* SentryCrashReportStore.h in Headers */, + D774878A421998994EB39DCAA8A1C49A /* SentryCrashReportVersion.h in Headers */, + 5F314721A1272DEBCF5175CCCDD84486 /* SentryCrashReportWriter.h in Headers */, + 28A5F2DCB9AA922830068A1224805A96 /* SentryCrashSignalInfo.h in Headers */, + 0B96707E793EFD952A2B721150F3D645 /* SentryCrashStackCursor.h in Headers */, + AF9EF75D319BC6E2B0931FCF66671E51 /* SentryCrashStackCursor_Backtrace.h in Headers */, + 33D272880DFB19B6207525CA74B37084 /* SentryCrashStackCursor_MachineContext.h in Headers */, + C725C2700A842B1555ADD982ACAF618A /* SentryCrashStackCursor_SelfThread.h in Headers */, + 0B285E0008F37AEA783281D73964CB74 /* SentryCrashStackEntryMapper.h in Headers */, + 2B1F867E090435A7F8A6B65678467E7C /* SentryCrashString.h in Headers */, + BFC529FCE9A65F74DDAD7E762A7CACAE /* SentryCrashSymbolicator.h in Headers */, + FB70BFE525506DF077F57FC93C4FCCFB /* SentryCrashSysCtl.h in Headers */, + B348C492A2322F68A812B67B6B85F1A3 /* SentryCrashSystemCapabilities.h in Headers */, + 4EB9BDDBBCD6A403D4A7D96618AA63D2 /* SentryCrashThread.h in Headers */, + 54662FF12326414D001D5672DFF9C1EF /* SentryCrashUUIDConversion.h in Headers */, + 549BDD1035830AA7FB7B2903B2F7220E /* SentryCrashVarArgs.h in Headers */, + CBADF46CE902738535173A40F8CDCB18 /* SentryCurrentDate.h in Headers */, + 1E3042F668BEAF92BEB9422C8E13A263 /* SentryCurrentDateProvider.h in Headers */, + B95AED6298F5C65D4C3F8709A6E4F12D /* SentryDateUtil.h in Headers */, + C32D97BF144988C4F1BFFBCDDBF3EB84 /* SentryDebugMeta.h in Headers */, + 741CA1BF0828521988A5B6CA703D1186 /* SentryDebugMetaBuilder.h in Headers */, + 310F4B5D204D4775A758F8B778E52B8D /* SentryDefaultCurrentDateProvider.h in Headers */, + 0F1E156138AA4165ED144E0EABC9A887 /* SentryDefaultRateLimits.h in Headers */, + C6090CD48338384D778BF641E5F3A0BF /* SentryDefines.h in Headers */, + EF3E4E23B0E99E5E5BE8C2366E21173E /* SentryDispatchQueueWrapper.h in Headers */, + 31F103D325335CB0DF660BBA17444855 /* SentryDsn.h in Headers */, + 3DD573909A68DB21A9E8B66F24EDB1A7 /* SentryEnvelope.h in Headers */, + 7C98299820092A85E03BE0AA7D50544E /* SentryEnvelopeItemType.h in Headers */, + 0033350F9C449649F2B63AD620B68BEC /* SentryEnvelopeRateLimit.h in Headers */, + BA2B72C5C0861493B8E9294F56D25DEB /* SentryError.h in Headers */, + 3BC722FA65856E8F66EDC14D13738212 /* SentryEvent.h in Headers */, + A6A77EA563BBBEFD3FF877C6A4182750 /* SentryException.h in Headers */, + 7AD1876CCEDCFC178AE50A92FB354C46 /* SentryFileContents.h in Headers */, + 3FA9FCD25576E9BC1EF36B8AAE9D3654 /* SentryFileManager.h in Headers */, + FEA4F45A367766F9BE6388400546169B /* SentryFrame.h in Headers */, + 441820200996CE7A1B2BA6704C0F6D2C /* SentryFrameInAppLogic.h in Headers */, + 8BC2BA168054057AF362766F99E3F191 /* SentryFrameRemover.h in Headers */, + 5F7DD505806A3BDCD84050AC6A2382DF /* SentryGlobalEventProcessor.h in Headers */, + 760EA6582D011C79E40B3547614BE51B /* SentryHexAddressFormatter.h in Headers */, + A39292434983FA18E0545CD074BAA88F /* SentryHook.h in Headers */, + 22F13A37E9DEBC541FA2DDFFC69F9446 /* SentryHttpDateParser.h in Headers */, + 5A2341AA325EBF1CD740D22651775746 /* SentryHttpTransport.h in Headers */, + DEC7CC434258CA15D2A02AB3290DFB1E /* SentryHub+Private.h in Headers */, + CB45D40EE97B85586D2492895D4F675D /* SentryHub.h in Headers */, + BED27B3404A4315E4BCCB1358AECCDC6 /* SentryId.h in Headers */, + 1ABA6AB04474E83F6F40C5337D2D2C4F /* SentryInstallation.h in Headers */, + 73F6F988D5F232F32F108A406FC4114F /* SentryIntegrationProtocol.h in Headers */, + 7B816F3A0D2D0E23A4AC290F4A4C0148 /* SentryInternalNotificationNames.h in Headers */, + 507BAAB8A950EAEF74FEADE94D3805F1 /* SentryLevelMapper.h in Headers */, + 911EC9AFFFF296275D29DAC4A64491DF /* SentryLog.h in Headers */, + BEC07B848EB8497572F6C76FF78EE3C9 /* SentryLogOutput.h in Headers */, + 10982A735A92B1781B7D0319A0B89D4C /* SentryMechanism.h in Headers */, + 3FF1F325FEEAF8CD6EB331DB94FBA56F /* SentryMechanismMeta.h in Headers */, + A641B211305122B6B0930D3AE1DF9E0C /* SentryMessage.h in Headers */, + BB8AB85AB145BF1FE8770FFECE80675F /* SentryMeta.h in Headers */, + 7A1E8A59D9CA4B52C4672688EC481FB5 /* SentryMigrateSessionInit.h in Headers */, + BC7E14094D5830551C418F2B4BB0F799 /* SentryNSError.h in Headers */, + 7D98220C51E00B83BFC8F8D1839BE934 /* SentryNSURLRequest.h in Headers */, + 376B34322C3C942845B6A48214F2D45A /* SentryOptions.h in Headers */, + 0F0E966DCF3F4695681B9D66EF334E76 /* SentryOutOfMemoryLogic.h in Headers */, + 8FCA295ED2D88E35A9C91DA0ADA5E63A /* SentryOutOfMemoryTracker.h in Headers */, + 03430978B7D0D125FC3F6D3C9D64BFD5 /* SentryOutOfMemoryTrackingIntegration.h in Headers */, + CB3B359D511D88BA92FBE3611ED9BE62 /* SentryQueueableRequestManager.h in Headers */, + 5FA5F9D87EBC05469A0D34F5CF820715 /* SentryRandom.h in Headers */, + B19B0811B8D0A22FFA5936396666C55E /* SentryRateLimitCategory.h in Headers */, + 75056239E3EC9B8A86168309EBE50E43 /* SentryRateLimitCategoryMapper.h in Headers */, + 679BC695B4EF085AF72BF1A570150ED5 /* SentryRateLimitParser.h in Headers */, + 022CC0766440E05D2F84E24EA9F53A5C /* SentryRateLimits.h in Headers */, + 50232D2B692E825625A3AD2600732F3C /* SentryRequestManager.h in Headers */, + 7F8A9A8BA27DB615A23982C18288990E /* SentryRequestOperation.h in Headers */, + 89EBA8DBE12DC4404793C89F509D8CE9 /* SentryRetryAfterHeaderParser.h in Headers */, + 0F5E1D54200B7ABEC45030D6BB49E2BC /* SentrySampleDecision.h in Headers */, + 26DE4140E14E294975042563DAF50F36 /* SentrySamplingContext.h in Headers */, + B6954F38C15CA4FD0B251EF76865606B /* SentryScope+Private.h in Headers */, + B01939CFE9617A00F0F4308B6FBAF370 /* SentryScope.h in Headers */, + 7D4A97B89E96F7C217B98B82CBCA591C /* SentrySDK+Private.h in Headers */, + 8085654A7283CBE196F3AB934C2E3E47 /* SentrySDK.h in Headers */, + 43A18C37EE1C1C6D06A302F8641F9FFC /* SentrySdkInfo.h in Headers */, + B7049B8112BB72962F49E3DA3280A41F /* SentrySerializable.h in Headers */, + 7DD9E43AA2CA169E95FF9EC27909FFD5 /* SentrySerialization.h in Headers */, + 855DC8BDD9380B4B88E39500031037AC /* SentrySession+Private.h in Headers */, + 4AA81A4B215994DB285F4F536CB447DC /* SentrySession.h in Headers */, + B43AC1BF85A55FE20FE10925797906AE /* SentrySessionCrashedHandler.h in Headers */, + EF2C974E1FC14FC9BA4B3C0A8A489B98 /* SentrySessionTracker.h in Headers */, + 3C8C22FD31AB056456134B4727C6CAE5 /* SentrySpan.h in Headers */, + 87F7881EBD28763D12C01D5E581D5F3F /* SentrySpanContext.h in Headers */, + 263CB8C21A0D8B4917D73251A016719F /* SentrySpanId.h in Headers */, + 04B9D3BB21C760E8993AF3EE5EEEF93F /* SentrySpanProtocol.h in Headers */, + 19D56BAFFB87CE38FEC9E4866CC9DB34 /* SentrySpanStatus.h in Headers */, + CC4D8A8E836D1D85C55998DF01F1D381 /* SentryStacktrace.h in Headers */, + EE5C24CB39E9430C35331506D899ED28 /* SentryStacktraceBuilder.h in Headers */, + 69614D3B0ACC2D4C956A6E489FF0C333 /* SentrySwizzle.h in Headers */, + 5947B0CBF56733EEABEDDF47FF4ED82E /* SentrySystemEventsBreadcrumbs.h in Headers */, + AFB32B60015F518A3836ED5665ACDE1F /* SentryThread.h in Headers */, + D44E1C13840064E02442E7E3DBEC3A89 /* SentryThreadInspector.h in Headers */, + F52F60C7410EFCA45AA9BBDF421C69B7 /* SentryTracer.h in Headers */, + 67EEEF94B813BA4B16BB9D86AEC0D791 /* SentryTransaction.h in Headers */, + 22DDBBE17C9149D396F4913460A6C2D5 /* SentryTransactionContext.h in Headers */, + C7C6B1961A79784E2959E58DF6D14733 /* SentryTransport.h in Headers */, + A9B06F5E33552A9640D0E4D2A5159786 /* SentryTransportFactory.h in Headers */, + 802CFE26A7F695D6DDBADAD2623BFB28 /* SentryUser.h in Headers */, + C80EB621E26F3A5701927765966B4CB7 /* SentryUserFeedback.h in Headers */, + 90FF09F84EC1A0A92A39666604FD54CD /* TracesSampler.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A997C35E6C5934ED6B091653422DA1C8 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - A426789C2D1E7982E071C4506EAA7E3F /* Headers */ = { + B4B1B6175DCD6E97650FEEE106140088 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C37A3EC15BF828DDE5546F8E78E3599A /* Pods-BitriseATV-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1961,6 +3665,27 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 37AABE85D2AFC81F84254DF805B5019D /* Pods-BitBotATV */ = { + isa = PBXNativeTarget; + buildConfigurationList = 94D26E73A9E729ADB2F7724EE8448937 /* Build configuration list for PBXNativeTarget "Pods-BitBotATV" */; + buildPhases = ( + 5F0E0615A305E3D6F56D60BD0F706AEE /* Headers */, + 5801E3C08982F4F743E80CA504F7E35B /* Sources */, + 5D224C12B5501195C58017F069561795 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 61F7FD85059539E2A6F96805E1C95987 /* PBXTargetDependency */, + 8DE47BFD0ECECD2C378E7703A3BFB33E /* PBXTargetDependency */, + 937ECD2EC27813D8E36A5B662EE2562B /* PBXTargetDependency */, + C33AF9D79674F839ECC2389000DF20D4 /* PBXTargetDependency */, + ); + name = "Pods-BitBotATV"; + productName = "Pods-BitBotATV"; + productReference = 304D7AE95A8997C86DF9D893909AE6FD /* libPods-BitBotATV.a */; + productType = "com.apple.product-type.library.static"; + }; 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */ = { isa = PBXNativeTarget; buildConfigurationList = 2A900E3BE8C1DFA89137E03CFAEC55C6 /* Build configuration list for PBXNativeTarget "SDWebImage" */; @@ -2029,6 +3754,23 @@ productReference = E9B409220A02F6C80445A0AB2DB98F47 /* libMixpanel-macOS.a */; productType = "com.apple.product-type.library.static"; }; + 9AA8A98273205387E6FF9B148A006F31 /* Sentry-macOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = B0A0BA9DB9C21344E4DA2377DE79E560 /* Build configuration list for PBXNativeTarget "Sentry-macOS" */; + buildPhases = ( + 95D0D06C8C76306CB4132979D505E396 /* Headers */, + 2F1A03B1F06BF0F0BFDBAB91B1D8A9D8 /* Sources */, + DD7550735958432B251541845AA1A53F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Sentry-macOS"; + productName = "Sentry-macOS"; + productReference = 62754719072EA7728FFA28F8BA5B8676 /* libSentry-macOS.a */; + productType = "com.apple.product-type.library.static"; + }; C260B5A26D3CD54F215E5E39371483B6 /* OCMock */ = { isa = PBXNativeTarget; buildConfigurationList = B6B75D75BE3B7AA1CD0D7FA6535DB001 /* Build configuration list for PBXNativeTarget "OCMock" */; @@ -2080,6 +3822,23 @@ productReference = 08F7F0770B4878B9883B87DCD8569CB4 /* libExpecta.a */; productType = "com.apple.product-type.library.static"; }; + DDC5B143847B1E75AB9687D42E6EF6B8 /* Sentry-tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 57FA21740CD506FC1C8CAB634FCD592D /* Build configuration list for PBXNativeTarget "Sentry-tvOS" */; + buildPhases = ( + 48B8A2D865C5A1C9EB7B4EE014F7AB8F /* Headers */, + 672538061ECB15A81877D3ED05274557 /* Sources */, + A30B9605D92124983E25EE53BE79A1C1 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Sentry-tvOS"; + productName = "Sentry-tvOS"; + productReference = E5B37F686C226E712A6CCF4F485ECD08 /* libSentry-tvOS.a */; + productType = "com.apple.product-type.library.static"; + }; E64F498650CA1EED2135C3BEA452F3FD /* NSPopover+MISSINGBackgroundView */ = { isa = PBXNativeTarget; buildConfigurationList = CCF04642631788A4DEBDD5E8DDC775C2 /* Build configuration list for PBXNativeTarget "NSPopover+MISSINGBackgroundView" */; @@ -2117,19 +3876,20 @@ }; EF68D578CA0C3D7CEDE4A31C9014F26F /* Pods-BitBot */ = { isa = PBXNativeTarget; - buildConfigurationList = 6CC15D75F43CA86436233A2F6F95AEEF /* Build configuration list for PBXNativeTarget "Pods-BitBot" */; + buildConfigurationList = 2F4F894C5C2B3E49BC5BAF8B20ADF05A /* Build configuration list for PBXNativeTarget "Pods-BitBot" */; buildPhases = ( - 98C5E32839097FD59A14F1445625F2BD /* Headers */, - EC8B9758267C56295E1BDA516E69D48D /* Sources */, - 1EA450F97847E6DD061D87A5E0922369 /* Frameworks */, + B4B1B6175DCD6E97650FEEE106140088 /* Headers */, + 4F5DAAE1E1D82B63C4EED814F9DCFF31 /* Sources */, + D749AAD97CD31854E742276AC771C73A /* Frameworks */, ); buildRules = ( ); dependencies = ( - F8EB942A5782783656E16993DD7113CB /* PBXTargetDependency */, - 8175199035521EAAD36678AF8A832ABE /* PBXTargetDependency */, - E7AFDD991FE2FBF8BB817DB27BFF26C9 /* PBXTargetDependency */, - FE503746B49AB1EDEDCA3368A1790FD5 /* PBXTargetDependency */, + 466B1C7A95F2D6F6145D58E663F8F1F9 /* PBXTargetDependency */, + E232BAF750A4C89AD706E7290FB70CCA /* PBXTargetDependency */, + 176B2E7FBE96FA3A326AA6CAB1D40367 /* PBXTargetDependency */, + E570B1EF27867F0A42DE7D22D4118E20 /* PBXTargetDependency */, + 585B8ED6B8833E2696AAD208F04D61A5 /* PBXTargetDependency */, ); name = "Pods-BitBot"; productName = "Pods-BitBot"; @@ -2138,44 +3898,24 @@ }; F0F445E69D68B288D8C0DA052D54D94F /* Pods-BitBotTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 79623E89E95A26FBC46B15D2C797706C /* Build configuration list for PBXNativeTarget "Pods-BitBotTests" */; + buildConfigurationList = 88F2D97C39B11398472B8B4B757617D2 /* Build configuration list for PBXNativeTarget "Pods-BitBotTests" */; buildPhases = ( - 751EC745883019FD316D29D2792DC2F2 /* Headers */, - B6E8CDDE9A2A02D35BAE743ACA626777 /* Sources */, - 08C46F08A460541B973B18FCA1696A65 /* Frameworks */, + A997C35E6C5934ED6B091653422DA1C8 /* Headers */, + 9927C3471E8B7B97B14407266C932595 /* Sources */, + BAE34610F1A8C5B8E5B3A8C5D66C68BC /* Frameworks */, ); buildRules = ( ); dependencies = ( - 067AA26D667AEF82DC22E4890F063A36 /* PBXTargetDependency */, - 5CA20655AFF1BCAFB0A0E7781F1F90EE /* PBXTargetDependency */, - 6CCF908DFAD96DCDF276CA276D5BC64A /* PBXTargetDependency */, + 32BC53040C563E885A3E071B70C5C214 /* PBXTargetDependency */, + 647C75D02B0AE011CA0CCAD1702A56E5 /* PBXTargetDependency */, + 19C549C2E4D50F4E6F6F5E1A6EE95CE2 /* PBXTargetDependency */, ); name = "Pods-BitBotTests"; productName = "Pods-BitBotTests"; productReference = E080202F8E0B54182443BA49E85C276D /* libPods-BitBotTests.a */; productType = "com.apple.product-type.library.static"; }; - F273139B306C278AA86E3CACA06F7D28 /* Pods-BitriseATV */ = { - isa = PBXNativeTarget; - buildConfigurationList = A1F32E0BFA1538B4AE80C80F1B9500F0 /* Build configuration list for PBXNativeTarget "Pods-BitriseATV" */; - buildPhases = ( - A426789C2D1E7982E071C4506EAA7E3F /* Headers */, - F837CA5FD35A051D3C103F8B1FCF9EC2 /* Sources */, - 8209CF3A735AFBB93189E3D4BC0BF3AA /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - FC9D87BCDD02A7CD9A08982ADC964B77 /* PBXTargetDependency */, - 6596CCEECEEA6E503F383BEF9340BCAA /* PBXTargetDependency */, - 402BAA2AB421F6B06827E71D3387DB1E /* PBXTargetDependency */, - ); - name = "Pods-BitriseATV"; - productName = "Pods-BitriseATV"; - productReference = D5099A766F6792981B7C98BC25284ECF /* libPods-BitriseATV.a */; - productType = "com.apple.product-type.library.static"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -2194,7 +3934,7 @@ Base, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = 5FA33FA1E08B26B49B9CE37244438424 /* Products */; + productRefGroup = 9CC236F0C10169F836B5966D2BD67D0C /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( @@ -2207,9 +3947,11 @@ E64F498650CA1EED2135C3BEA452F3FD /* NSPopover+MISSINGBackgroundView */, C260B5A26D3CD54F215E5E39371483B6 /* OCMock */, EF68D578CA0C3D7CEDE4A31C9014F26F /* Pods-BitBot */, + 37AABE85D2AFC81F84254DF805B5019D /* Pods-BitBotATV */, F0F445E69D68B288D8C0DA052D54D94F /* Pods-BitBotTests */, - F273139B306C278AA86E3CACA06F7D28 /* Pods-BitriseATV */, 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */, + 9AA8A98273205387E6FF9B148A006F31 /* Sentry-macOS */, + DDC5B143847B1E75AB9687D42E6EF6B8 /* Sentry-tvOS */, ); }; /* End PBXProject section */ @@ -2284,6 +4026,166 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2F1A03B1F06BF0F0BFDBAB91B1D8A9D8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9C2CDCF43CFFCE702DC78698C0B0C5F3 /* Container+SentryDeepSearch.m in Sources */, + 4963DE75332B884EA58EA2DEE9C9EED5 /* fishhook.c in Sources */, + 2CA22754CA1D08462ACBE3F9F3726D95 /* NSArray+SentrySanitize.m in Sources */, + FBF07C1C9AB7CD1D8F80419FAE4A07E5 /* NSData+SentryCompression.m in Sources */, + B87E1E284805A1F6AB2AB20F873CAE1D /* NSDate+SentryExtras.m in Sources */, + 0F791D68F15E4822C7832B3FEB63375D /* NSDictionary+SentrySanitize.m in Sources */, + 6E4BC11268613D03E0F8462E9D2A2F34 /* NSError+SentrySimpleConstructor.m in Sources */, + 85BE28A0CABD9D6EF1960009050D8520 /* NSString+SentryUnsignedLongLongValue.m in Sources */, + A5C6DFA12D0A2BA2B82620C5EE9D351D /* Sentry-macOS-dummy.m in Sources */, + 6E14D0FD44BFC002E827AAB8A17262D4 /* SentryAppState.m in Sources */, + 80529F3D8C05C5746E805CE7D3721416 /* SentryAsynchronousOperation.m in Sources */, + 0B87D9B83388B5AEC1D63BEB0E468CD6 /* SentryAttachment.m in Sources */, + B82BBBCFE5BED28B1276BE76A577FB08 /* SentryAutoBreadcrumbTrackingIntegration.m in Sources */, + 2B48CF877B00FA2F8B00C1A069B2D662 /* SentryAutoSessionTrackingIntegration.m in Sources */, + 54C326EF57C7E16518F74581C09DC09B /* SentryBreadcrumb.m in Sources */, + EBBFA7EB42BA30826988AAADAC95CEA8 /* SentryBreadcrumbTracker.m in Sources */, + 47F6C508CFBB0667B100157CAB4AF4A7 /* SentryClient.m in Sources */, + 40CF419E980658251FC55B629C1C85AF /* SentryConcurrentRateLimitsDictionary.m in Sources */, + 46886563296F6F5DEAE5CABFC1A5AF0D /* SentryCrash.m in Sources */, + 56F641AFBA9F63851BF88F1F8A7504EE /* SentryCrashAdapter.m in Sources */, + 00F873799DDD0CF0ECCFD7B5EF38364C /* SentryCrashC.c in Sources */, + 28AD902BEAB65883967CCC67EC8B8A82 /* SentryCrashCachedData.c in Sources */, + D9EE52832C1F335A45446FCA91745985 /* SentryCrashCPU.c in Sources */, + 309B84784D7DBFFE4D99D7854FE7B115 /* SentryCrashCPU_arm.c in Sources */, + ED65D8FBF27E9C32762C6954B6A734FB /* SentryCrashCPU_arm64.c in Sources */, + 021CB55D395846970B94FAFCCAA5DC1B /* SentryCrashCPU_x86_32.c in Sources */, + 384D6A5F12F43434A7E43AEFE93E9147 /* SentryCrashCPU_x86_64.c in Sources */, + B60B6F7F6F6DDB622761C08B097868E7 /* SentryCrashCString.m in Sources */, + A589DDECC7AD32CA25386B92F3D9C278 /* SentryCrashDate.c in Sources */, + 972D0C8F72933F21B9E2468F683C20F0 /* SentryCrashDebug.c in Sources */, + 97A9132C49185CF94832897F6AD9628A /* SentryCrashDefaultBinaryImageProvider.m in Sources */, + 26247F0051223C088BCBAC226FA84A0E /* SentryCrashDefaultMachineContextWrapper.m in Sources */, + BB35FC9133C0FBCFFE9E86876DF26218 /* SentryCrashDoctor.m in Sources */, + 895D03A412632626D6F0B85833F2BA2E /* SentryCrashDynamicLinker.c in Sources */, + DDDB8810D4060879C45257F86768D8C6 /* SentryCrashExceptionApplication.m in Sources */, + 661C9CDABDE0692A04AE80032B927C34 /* SentryCrashFileUtils.c in Sources */, + EE6D8FAA3554E12D373196359FDFC70A /* SentryCrashID.c in Sources */, + 5F18E6BC35A41A9B0BF224F3FD74653A /* SentryCrashInstallation.m in Sources */, + 58A87B73F1B7F00D3B235B2AABB5DF54 /* SentryCrashInstallationReporter.m in Sources */, + 9351ED3AB561718C306EA994867C7A79 /* SentryCrashIntegration.m in Sources */, + DF5C758538361B44620EA8A4E5872C43 /* SentryCrashJSONCodec.c in Sources */, + F1FDD232C9658A5AF7D0DC6DE2D79CC4 /* SentryCrashJSONCodecObjC.m in Sources */, + 7435A798ACDD217B72A81934709A9322 /* SentryCrashLogger.c in Sources */, + FE4F9B8C36D3B69A06CA5B8C01449F7D /* SentryCrashMach.c in Sources */, + ABC57616D491AD6705C6B5B40C9DAF85 /* SentryCrashMachineContext.c in Sources */, + C32BD5CC8E760ABAC14D0FA5C4ECE841 /* SentryCrashMemory.c in Sources */, + 5E843800864DE1218AA446BB6142B8E7 /* SentryCrashMonitor.c in Sources */, + 4F2A0FE52C169B30779382C75D251BE8 /* SentryCrashMonitor_AppState.c in Sources */, + 5B1BD40A04E368A003BEFF0FAEEFD59D /* SentryCrashMonitor_CPPException.cpp in Sources */, + 67596C213D1304AFA32F996B6E8F62F3 /* SentryCrashMonitor_Deadlock.m in Sources */, + 866D5D586F49531EEA423588B41AB08B /* SentryCrashMonitor_MachException.c in Sources */, + 71954657A5F0B37B52770DBBC8D5D445 /* SentryCrashMonitor_NSException.m in Sources */, + 63D65A705F4B4C3E464A78E7F16C275D /* SentryCrashMonitor_Signal.c in Sources */, + 1CE803860576BC6FA2F369A0EB19D015 /* SentryCrashMonitor_System.m in Sources */, + 99C5D4C03DC0C21BCE641165479FA71A /* SentryCrashMonitor_User.c in Sources */, + E1E0CF18E339AD1DE62A57BB5617A073 /* SentryCrashMonitor_Zombie.c in Sources */, + 8F192AF8E29E7B0796977E14C60C12A1 /* SentryCrashMonitorType.c in Sources */, + BF76B135520EAF1E074BA691AEB3811C /* SentryCrashObjC.c in Sources */, + 7D147924B4DE3C80D96C1A68BC0ECBFE /* SentryCrashReport.c in Sources */, + A9059641712404E39B1370D94DFC5CED /* SentryCrashReportConverter.m in Sources */, + E3215503404E4C075EDC9E1EA2B87611 /* SentryCrashReportFilterBasic.m in Sources */, + 93095F594EB27EB7D64B75CDB1A0CBE9 /* SentryCrashReportFixer.c in Sources */, + 4C9FAA6D05D6ED82480FCCB04F9A6BBA /* SentryCrashReportSink.m in Sources */, + D1C07ADBB8066A91EF931BF54F8033D2 /* SentryCrashReportStore.c in Sources */, + 29070F37FD7A660E573815EEBCEB47B9 /* SentryCrashSignalInfo.c in Sources */, + 2BBF47486443C99FE5519B2C27EAF1A6 /* SentryCrashStackCursor.c in Sources */, + A8E1E6D13E9C202131DBEB99E17CA82F /* SentryCrashStackCursor_Backtrace.c in Sources */, + 35C45AC728A83DE07326B4F8ADB08A72 /* SentryCrashStackCursor_MachineContext.c in Sources */, + CE060F39A2CC9263A33E91C9A87968C2 /* SentryCrashStackCursor_SelfThread.c in Sources */, + E8D29FE759687DF80EF8CFA23CD1EFA4 /* SentryCrashStackEntryMapper.m in Sources */, + BE8A5B2559FBE02B1005CBE2223A1E02 /* SentryCrashString.c in Sources */, + 83F31D6D135422CA0C1FE0CAE40CF492 /* SentryCrashSymbolicator.c in Sources */, + 7F2FCA4A64914994B1149350E45C2B8F /* SentryCrashSysCtl.c in Sources */, + 27A742BBA9FBC26A6E6CD59939F7C4D0 /* SentryCrashThread.c in Sources */, + B2D1AA2A21989FFBE36B49993FA51B1C /* SentryCrashUUIDConversion.c in Sources */, + A9FF3EBA5BE9A7E842FDA570134BA848 /* SentryCurrentDate.m in Sources */, + 1192C87EE0EDF2562FB83CDBECD9FCFD /* SentryDateUtil.m in Sources */, + 5E7B816536368B9FD5ED26E2F24C0CD8 /* SentryDebugMeta.m in Sources */, + CD9FF47BE5185B042B632E8D0C0E1479 /* SentryDebugMetaBuilder.m in Sources */, + 92765930E3B94F317E132E9356D88FAC /* SentryDefaultCurrentDateProvider.m in Sources */, + 99B83DAC578920B3E2BD4736533E57A9 /* SentryDefaultRateLimits.m in Sources */, + 0229A6C32A076719C11ABB418B7CEF0C /* SentryDispatchQueueWrapper.m in Sources */, + BBE7DF9CF894DFD35F04F8E3626E7821 /* SentryDsn.m in Sources */, + B712F3D7BB3F77A62982F72BB96E3AFF /* SentryEnvelope.m in Sources */, + E024EBCB7B48EE1543EA135EF10321A9 /* SentryEnvelopeRateLimit.m in Sources */, + D20371540B07C552220E2CE0629F02AF /* SentryError.m in Sources */, + 44177ECC2FA1171A09F071042D42C2E3 /* SentryEvent.m in Sources */, + 51E04F1081F50758FEC19131B9E5D1E0 /* SentryException.m in Sources */, + 679EB6C977D909B92783A2F62B16521F /* SentryFileContents.m in Sources */, + F29867510A722B452658DDB7DBA68B6B /* SentryFileManager.m in Sources */, + 6B8EBB605F20A9C7866EB19ADF49DE37 /* SentryFrame.m in Sources */, + 9E7C7FAE7DB2991CAEC21B9A38CB3700 /* SentryFrameInAppLogic.m in Sources */, + AD220444D975F808498256F647D8EABC /* SentryFrameRemover.m in Sources */, + 771BD7A0914FA4CD9E181CD54D5F48B1 /* SentryGlobalEventProcessor.m in Sources */, + 4423078F86C2E7B54145D76885A13888 /* SentryHook.c in Sources */, + 981EF60CF03CC56C4FDE66DD95072934 /* SentryHttpDateParser.m in Sources */, + E37564826AE0CDBE4D990D3ABF81886D /* SentryHttpTransport.m in Sources */, + 62DC6E15DDA7806F8EAED5653ACF07F5 /* SentryHub.m in Sources */, + 51BAF9D7D861DD3F4F9F283CCEDDE16F /* SentryId.m in Sources */, + 89788A6CD0B5D2C2FD98CD74F7BF0D10 /* SentryInstallation.m in Sources */, + A810535B1D3418C355D09AFC9AAE45F4 /* SentryLevelMapper.m in Sources */, + AF8F7B4506188565F09AD4D19A80EFE0 /* SentryLog.m in Sources */, + 349490565ABEE6D73096D9F5C17B4B7F /* SentryLogOutput.m in Sources */, + 4D6915E7C20FFFFA995E5C9FDDA64C78 /* SentryMechanism.m in Sources */, + E8B9E1BFBAF7D8C1BAE2A45B815A5CAC /* SentryMechanismMeta.m in Sources */, + 40F9B5C5A2DBA02C1AD3F1D71C7B468D /* SentryMessage.m in Sources */, + ADCBEB3BBFB482CEFCAFE5585FAB6D7F /* SentryMeta.m in Sources */, + 5C3F77A130703D262FC147E1ABEF98AC /* SentryMigrateSessionInit.m in Sources */, + 4237B1CD76E9152BA664855BF6CC6202 /* SentryNSError.m in Sources */, + B0EBEC7D8D557110409295660CCD3F7A /* SentryNSURLRequest.m in Sources */, + 5ADD752DC119365A2AA9345A38BDB5AB /* SentryOptions.m in Sources */, + B91BD03920E3C188E391B90EA0BF1A4E /* SentryOutOfMemoryLogic.m in Sources */, + CDADC0A1DE193095622BBF32AA2BAC80 /* SentryOutOfMemoryTracker.m in Sources */, + A514279639E922DD686A2C17BD238BEC /* SentryOutOfMemoryTrackingIntegration.m in Sources */, + C8CBA5E819C92018016880FC72F72550 /* SentryQueueableRequestManager.m in Sources */, + DCAA497864C4E51B0DE87A8471A89CD5 /* SentryRandom.m in Sources */, + 7D4250439096E28950B8756D4376218E /* SentryRateLimitCategoryMapper.m in Sources */, + 80E594CD0EC375F13CD7310167173DA1 /* SentryRateLimitParser.m in Sources */, + 6E168BB4333A8951E277B8454E15A4C7 /* SentryRequestOperation.m in Sources */, + 2252C975D5E36FEB868A0FBC10D3E173 /* SentryRetryAfterHeaderParser.m in Sources */, + B98D09E680FD5AD6C240EEA05BF673EC /* SentrySamplingContext.m in Sources */, + DBB8E5610A5A5166183574ADAB57FA53 /* SentryScope+Private.m in Sources */, + 977A269A6DD9969DB827B44E70EF4000 /* SentryScope.m in Sources */, + 4A2A2ECD9B7D18856D088C5EC2D15418 /* SentrySDK.m in Sources */, + B9C9E6FDAE332F9A7BCEDEE21FA33A0B /* SentrySdkInfo.m in Sources */, + F02D1477C4F448BAB10E3E23A2948EBD /* SentrySerialization.m in Sources */, + F4E756CB7F54C54379983FE68B61693C /* SentrySession.m in Sources */, + 032E5388FE0C4113337FECBDA12FEEFE /* SentrySessionCrashedHandler.m in Sources */, + 7EE7E487A3FA00050BF84EDE48E06476 /* SentrySessionTracker.m in Sources */, + 5C6E15752F48AEFE649D5F15B8462A45 /* SentrySpan.m in Sources */, + 0E0BDAD6524C03845FFA300E7FCF550B /* SentrySpanContext.m in Sources */, + 386925CC6164F7530A7CD706170498DF /* SentrySpanId.m in Sources */, + 745EAB9B11A2CDA962198A0BDE269394 /* SentryStacktrace.m in Sources */, + 892AB9E1F334AB05954703FB547DB06B /* SentryStacktraceBuilder.m in Sources */, + 0CB9B55735A73E69F337D6925C1D67CD /* SentrySwizzle.m in Sources */, + D0C823A67ADEEE4E9F61DE3BD3BF1A40 /* SentrySystemEventsBreadcrumbs.m in Sources */, + 3253A1DE32096BAB15AC7D2DEB5DF435 /* SentryThread.m in Sources */, + 4EDF0F8A5BB1BBF3F72F87FBF9D4887D /* SentryThreadInspector.m in Sources */, + 2ECD0E4C2802CEC73D5FF007581194FA /* SentryTracer.m in Sources */, + 86BC1E8283EC3D4A4108C17FD2482DFE /* SentryTransaction.m in Sources */, + BE8130356652C7F976E9B4263C3AE820 /* SentryTransactionContext.m in Sources */, + A60283C3AF52B127660FD68951CF8D27 /* SentryTransportFactory.m in Sources */, + D901CE4658B14AD9AC9D87ACD0F8938F /* SentryUser.m in Sources */, + 27FF6FF7A140CAB98827EA6F68F90D7D /* SentryUserFeedback.m in Sources */, + AA9E92FFF1588E9B0489222BED552DA0 /* TracesSampler.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4F5DAAE1E1D82B63C4EED814F9DCFF31 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 712C6A45D1129E62850CB79D5ACD340F /* Pods-BitBot-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 51DB80496DE70BA36A9EA8688505A899 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2305,6 +4207,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5801E3C08982F4F743E80CA504F7E35B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C8CF588D582C12C62CC76685B66B6518 /* Pods-BitBotATV-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63BDFE6421C75A1ADACA963E7B47E4E0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2326,6 +4236,158 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 672538061ECB15A81877D3ED05274557 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D2A945CADDDBE837C69ABF57DEC53050 /* Container+SentryDeepSearch.m in Sources */, + 69A46C5860D341060EA3A5B2B35BC9FB /* fishhook.c in Sources */, + 15D2A19DB46A147228619855051D29BE /* NSArray+SentrySanitize.m in Sources */, + 97DD26AE2DBAD80F87679FCA6732BC5A /* NSData+SentryCompression.m in Sources */, + 7004415DCED00085428458F405D8EC33 /* NSDate+SentryExtras.m in Sources */, + B7D699155A8B5E76B2DA483A3E96F862 /* NSDictionary+SentrySanitize.m in Sources */, + A8258677EF0DCD40B4E937D946ADEF4A /* NSError+SentrySimpleConstructor.m in Sources */, + 06AFBDB6BF3B72745AB6F83BABE60C84 /* NSString+SentryUnsignedLongLongValue.m in Sources */, + 0F4705701AAD5ED85AA7DBB042A4712F /* Sentry-tvOS-dummy.m in Sources */, + 2726C0617CCB2E7829158A457641D4A4 /* SentryAppState.m in Sources */, + A1BEFAC9339924AEB6B79413211D05A5 /* SentryAsynchronousOperation.m in Sources */, + F13B85AEC0704EC5A948CBFB93E78F6E /* SentryAttachment.m in Sources */, + 94C2D2CAA567894E9CD228DEDCF66044 /* SentryAutoBreadcrumbTrackingIntegration.m in Sources */, + 76C84E41EF308B3492D1D0C7E8EF79DF /* SentryAutoSessionTrackingIntegration.m in Sources */, + F655B1CEDC459E321B19A5D24BED6B90 /* SentryBreadcrumb.m in Sources */, + C8EA44C7497A9E85036BB910258DE166 /* SentryBreadcrumbTracker.m in Sources */, + 343FEF7BBB93D1BB48BB25E4F6E128DA /* SentryClient.m in Sources */, + 9FB1648CE2E58896B4CE11FFDDF42604 /* SentryConcurrentRateLimitsDictionary.m in Sources */, + 2CFC6B18F22665A941B9DA0C1C3FEB82 /* SentryCrash.m in Sources */, + CFB7776438921226B9BFA7F30F057AA0 /* SentryCrashAdapter.m in Sources */, + D3E7E2B9DE3E35E462B074F9D8CA2D8A /* SentryCrashC.c in Sources */, + A5F1DCB17662413E75F50B57E3DC4E5F /* SentryCrashCachedData.c in Sources */, + D0706D9C488551E4233E22E5B276DD47 /* SentryCrashCPU.c in Sources */, + C7504B7D8EAB7A0036BBCD418A8CFD1B /* SentryCrashCPU_arm.c in Sources */, + E71A0D1EF31C210971C5049BE82F9EFC /* SentryCrashCPU_arm64.c in Sources */, + FD3C3E6900DB90A452B87AAD7B449E58 /* SentryCrashCPU_x86_32.c in Sources */, + 494A8450E53A2F638171049E31106D57 /* SentryCrashCPU_x86_64.c in Sources */, + F43821994B65DA151E605E370C9623BF /* SentryCrashCString.m in Sources */, + F887644D7436B365A7F46E37F91932CA /* SentryCrashDate.c in Sources */, + E7EC0E343BB0B34F48C6A260AD493B22 /* SentryCrashDebug.c in Sources */, + 085F3A44FF0EB115121C2AB43D72F001 /* SentryCrashDefaultBinaryImageProvider.m in Sources */, + 235E6007FB481FCAF9ACE09DBA49CD73 /* SentryCrashDefaultMachineContextWrapper.m in Sources */, + C5704F541D472183ECD228FCA6FA4AF8 /* SentryCrashDoctor.m in Sources */, + B8D415D848D08F942B73D5168C0F114A /* SentryCrashDynamicLinker.c in Sources */, + A85951B63AE13857A9454593CFE075D2 /* SentryCrashExceptionApplication.m in Sources */, + 34B24EC9EF1F355F35873412EB34BEE8 /* SentryCrashFileUtils.c in Sources */, + BC3EC5377F513E07E873442F925E82BB /* SentryCrashID.c in Sources */, + 5AF3539D5B4FD0E9BA7ED3648BE2E7F4 /* SentryCrashInstallation.m in Sources */, + 6B10EDF8693EEC2BDB03124725098505 /* SentryCrashInstallationReporter.m in Sources */, + 2F17B8F399F7CA46935ED1D46E657325 /* SentryCrashIntegration.m in Sources */, + C82581DE2C0A93D72CA2FB8500058889 /* SentryCrashJSONCodec.c in Sources */, + 16995CDC4E1A838D97993D629400A3B1 /* SentryCrashJSONCodecObjC.m in Sources */, + 0B6134267A0EEE08E4546B8A97A24599 /* SentryCrashLogger.c in Sources */, + 1EBDD2B28C8B1BDF757769E92E8E80BA /* SentryCrashMach.c in Sources */, + E7BE4B4599818EC03B8BECE5B8408717 /* SentryCrashMachineContext.c in Sources */, + 626AF15E28B5B47357F8EFF24D8168C2 /* SentryCrashMemory.c in Sources */, + 6869CCB933286B8A3D3F5991783E0921 /* SentryCrashMonitor.c in Sources */, + CD705D455A111FACD53E87EC3FA174E3 /* SentryCrashMonitor_AppState.c in Sources */, + 852148C44AD655794A071ACAA389F48C /* SentryCrashMonitor_CPPException.cpp in Sources */, + A26C4EB868D918E726F5887BD4145D8F /* SentryCrashMonitor_Deadlock.m in Sources */, + DEE0373521A4CF2B19982E6D5D0BC349 /* SentryCrashMonitor_MachException.c in Sources */, + 6FCB1A72E475707BE1EC1862E0B01AFD /* SentryCrashMonitor_NSException.m in Sources */, + A848463EEC33CA28BE553CA42A747EA2 /* SentryCrashMonitor_Signal.c in Sources */, + 0580739B35F3E13E331EF1D4C6EC5AAC /* SentryCrashMonitor_System.m in Sources */, + C11B9DC682963BE29B7EE76E6838D9AF /* SentryCrashMonitor_User.c in Sources */, + 15F113A6B9C45658AFC05D44CEB1141D /* SentryCrashMonitor_Zombie.c in Sources */, + CCA4DDC7D3E05B419041A5DF596B2FFD /* SentryCrashMonitorType.c in Sources */, + F76BBA5C5563ABBB3B5F31D39607DC86 /* SentryCrashObjC.c in Sources */, + E912C8C2D42BCD36D1449E7E6CC5B3F2 /* SentryCrashReport.c in Sources */, + 64AD9E0AAF2CC323FDD4BCB5C1784B10 /* SentryCrashReportConverter.m in Sources */, + D379C5760B3D23B41E33D545A0780174 /* SentryCrashReportFilterBasic.m in Sources */, + ED75521511EB41296F116A15159AD7AE /* SentryCrashReportFixer.c in Sources */, + A474EEA7620B4B70761B02343CF79040 /* SentryCrashReportSink.m in Sources */, + B6CBC14845016BC0387EE16974AD5121 /* SentryCrashReportStore.c in Sources */, + 79FD8117A6E29FD70CC62236B2A20E07 /* SentryCrashSignalInfo.c in Sources */, + 4C70358EE6DFC36C1A723019F0ED86FF /* SentryCrashStackCursor.c in Sources */, + C3D4CDC2CF942B1742CC609DC94612F1 /* SentryCrashStackCursor_Backtrace.c in Sources */, + 36694278FBCC39D9A25D3713E6D90485 /* SentryCrashStackCursor_MachineContext.c in Sources */, + D6B66398722F5CCDDB3F403BF69BB89A /* SentryCrashStackCursor_SelfThread.c in Sources */, + 49122F1AAFCC4C67F9FC08F06C9476E3 /* SentryCrashStackEntryMapper.m in Sources */, + 4F92BEA5A066C3FB1A18E12C73B7D92D /* SentryCrashString.c in Sources */, + 88869CED8C3936032A81468A19686E55 /* SentryCrashSymbolicator.c in Sources */, + D754CAF796FC5A962BAE1D97A4C57B2A /* SentryCrashSysCtl.c in Sources */, + 8BE513058B1421AA8F5AA44689B2E65A /* SentryCrashThread.c in Sources */, + A45E62E1B3CD8100D1980D99279488CC /* SentryCrashUUIDConversion.c in Sources */, + 0076745D50ACBF53F8CAFD0A43C99848 /* SentryCurrentDate.m in Sources */, + 9C25C59B12F769D4309BDC960DFD81D5 /* SentryDateUtil.m in Sources */, + 35F323C91106C14A77D1ED71480C31BB /* SentryDebugMeta.m in Sources */, + 9BB39052C25415D9EDCFC3CF7F930AB9 /* SentryDebugMetaBuilder.m in Sources */, + 6419B1751F19550BC6C5035C3AEE3E02 /* SentryDefaultCurrentDateProvider.m in Sources */, + CCA0672CF48281CC9A2033E1CDBC32A8 /* SentryDefaultRateLimits.m in Sources */, + 8CFF71693CA5B723B7D6CA98CF3B210E /* SentryDispatchQueueWrapper.m in Sources */, + A48FAEBA4B6D5975A2A4CF8EC37E9A3D /* SentryDsn.m in Sources */, + 3B8DA4EF7CBB3EDF7045DF2232786261 /* SentryEnvelope.m in Sources */, + 85DB8C763AEC85C2609506000A94E295 /* SentryEnvelopeRateLimit.m in Sources */, + 7E5DF1232CC16AC178FADB8447DA222E /* SentryError.m in Sources */, + 45A54480B743ECC3DE568B170DB0B8D1 /* SentryEvent.m in Sources */, + 10DE4447065F7B39B0213549E5291746 /* SentryException.m in Sources */, + 8D3FB5D2661E03576E9A1F25C000D895 /* SentryFileContents.m in Sources */, + A196AE57DF39127949AB29665E18F251 /* SentryFileManager.m in Sources */, + EFEC3B834850107DF18A4E6573924F4F /* SentryFrame.m in Sources */, + 195C16A090EB57E09CF7DC44C5C16206 /* SentryFrameInAppLogic.m in Sources */, + A81D9CD8A55BDCF4776392B3426F0AEA /* SentryFrameRemover.m in Sources */, + 44188681506D134274D1626284F91312 /* SentryGlobalEventProcessor.m in Sources */, + 21B6AE69441E82E2E5716EF3231492A9 /* SentryHook.c in Sources */, + 621D184BFA75881116AF407ECBE236DD /* SentryHttpDateParser.m in Sources */, + FE65C2D61F4C878F71AA42B73712713A /* SentryHttpTransport.m in Sources */, + 2575E63759688B01F29224EE5CE0D567 /* SentryHub.m in Sources */, + 20C469D06B05527A1CDA62407159871B /* SentryId.m in Sources */, + DE44B2D3B46369E0B4DE0FA4CDC52025 /* SentryInstallation.m in Sources */, + EE7561DADC01EC301AB898348FC979FA /* SentryLevelMapper.m in Sources */, + 15A345758D8182D5622A75B1009514FB /* SentryLog.m in Sources */, + 376F295FE52F25B45BE3C81F5F158818 /* SentryLogOutput.m in Sources */, + 5583A8B7B1712E13D8A18CE1998BD17B /* SentryMechanism.m in Sources */, + E68D16336B2C434E08A5B4CD88EEA461 /* SentryMechanismMeta.m in Sources */, + 4B89E5B5DB9661FEF250097B68406DBF /* SentryMessage.m in Sources */, + 2FA1093AF879015B0B01BD1AE304D9BE /* SentryMeta.m in Sources */, + A36930E3A99533EF350A99423B9CE2B9 /* SentryMigrateSessionInit.m in Sources */, + D1B44FF4003BA2096A4F9D5560E93318 /* SentryNSError.m in Sources */, + EFE13FDCCE755F3CC51B529A445A03F9 /* SentryNSURLRequest.m in Sources */, + 1DF756CE0E40EB5671264AEA58B2B231 /* SentryOptions.m in Sources */, + 5B4D6F932A6FA06910BB47BC43843683 /* SentryOutOfMemoryLogic.m in Sources */, + F9CEFE5A097E1CE7ECB2E4DCB3ADF385 /* SentryOutOfMemoryTracker.m in Sources */, + 20B2F87DE97F1A2661A5A268DEBABA00 /* SentryOutOfMemoryTrackingIntegration.m in Sources */, + B03B0C90097E42CE81DB8A43E8DAF504 /* SentryQueueableRequestManager.m in Sources */, + A5752F690CF82DAD517E95D985B786F1 /* SentryRandom.m in Sources */, + FBF300F7DD65088A9B5EE1282366227F /* SentryRateLimitCategoryMapper.m in Sources */, + 2CB3EA10753C3BE4CB7774CB28971D8D /* SentryRateLimitParser.m in Sources */, + 80BF14D9BB67EDA3DB5AA61E0B56CDC4 /* SentryRequestOperation.m in Sources */, + 8F155838723CB6DF9EA0055DD0DB8709 /* SentryRetryAfterHeaderParser.m in Sources */, + 5B654328900B9B578AAD634B921C4332 /* SentrySamplingContext.m in Sources */, + 1A2C3447836599F5FB5220C32241D0E5 /* SentryScope+Private.m in Sources */, + 3E05CEFCFE31C9A066BBF5976601333B /* SentryScope.m in Sources */, + 2EFDAE49DE30F6F1219FAFFAA4917E26 /* SentrySDK.m in Sources */, + EDE754E56B7360B384477BFEA2843424 /* SentrySdkInfo.m in Sources */, + 028B09647AC4074230DB89C08982BC38 /* SentrySerialization.m in Sources */, + F292104E173BC8CD5140919937BC8369 /* SentrySession.m in Sources */, + 4CD1C2912781807CB5322849038088EF /* SentrySessionCrashedHandler.m in Sources */, + 7C4E62B83E124848E307238125176B9D /* SentrySessionTracker.m in Sources */, + FD97D8B642908F34B8B8BA157C3201FD /* SentrySpan.m in Sources */, + E5574067990DA712969838F8A332D594 /* SentrySpanContext.m in Sources */, + 03BDE0470F8061C9F55D6839E534A465 /* SentrySpanId.m in Sources */, + AE344EC3B051D94E99753BA9A18D1E45 /* SentryStacktrace.m in Sources */, + F131FBD0A4730878E5B7AF2E7469FEBD /* SentryStacktraceBuilder.m in Sources */, + 213C095EF87C2009F3EAEA96C0B72A97 /* SentrySwizzle.m in Sources */, + F702374985354DA721560D79EC608FE9 /* SentrySystemEventsBreadcrumbs.m in Sources */, + 9477444E5C1483D09FE487575F31FC1D /* SentryThread.m in Sources */, + 61F0FD43504B408AE0A1C0B74EF76871 /* SentryThreadInspector.m in Sources */, + 9E1B8E2CB017BC7545F2DE5EFDCF7B74 /* SentryTracer.m in Sources */, + 429A8916BCB6A4DBF540EE74DF598BC0 /* SentryTransaction.m in Sources */, + C43CD2D29B91567CE7495F83ED9B5D4C /* SentryTransactionContext.m in Sources */, + 4B83DA974BBFBCDF4A52EE13FB629C23 /* SentryTransportFactory.m in Sources */, + 793BBCBCD78226E4F2845B64AD10AB86 /* SentryUser.m in Sources */, + 195A249E1689E50752E0BCC1BF9014AB /* SentryUserFeedback.m in Sources */, + A29A7313B9C82077B6DE4D83D2AC3ECE /* TracesSampler.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 77A886CE460325632799915A6919DD53 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2376,6 +4438,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9927C3471E8B7B97B14407266C932595 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1DC14E6955C085C49A36A11EC77E5709 /* Pods-BitBotTests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AEB438FDE7D0114FA491230F658BB9FC /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2406,14 +4476,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B6E8CDDE9A2A02D35BAE743ACA626777 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9FC370801990ED9E104479E716BAC81B /* Pods-BitBotTests-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; EA281FCD0F625D46F2270068FF82E8ED /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2537,164 +4599,183 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - EC8B9758267C56295E1BDA516E69D48D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DA177C99E993E85CAADBBF5B6F262069 /* Pods-BitBot-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F837CA5FD35A051D3C103F8B1FCF9EC2 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EEC88630DC3F804E03AF715DF8BF8422 /* Pods-BitriseATV-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 067AA26D667AEF82DC22E4890F063A36 /* PBXTargetDependency */ = { + 176B2E7FBE96FA3A326AA6CAB1D40367 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "NSPopover+MISSINGBackgroundView"; + target = E64F498650CA1EED2135C3BEA452F3FD /* NSPopover+MISSINGBackgroundView */; + targetProxy = 59523D5EF63DEAEB8A81836F110D0B6C /* PBXContainerItemProxy */; + }; + 19C549C2E4D50F4E6F6F5E1A6EE95CE2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-BitBot"; + target = EF68D578CA0C3D7CEDE4A31C9014F26F /* Pods-BitBot */; + targetProxy = 1FA47FCCCC1D40E782349AFD330D6DDC /* PBXContainerItemProxy */; + }; + 32BC53040C563E885A3E071B70C5C214 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Expecta; target = DC371B7477C88184274EC6710690F97C /* Expecta */; - targetProxy = 7687F4F24F52C9FE25608AF8A2DC5F2C /* PBXContainerItemProxy */; + targetProxy = 0CF6F1759A8CD7D79985829219F186EE /* PBXContainerItemProxy */; }; - 402BAA2AB421F6B06827E71D3387DB1E /* PBXTargetDependency */ = { + 466B1C7A95F2D6F6145D58E663F8F1F9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "Mixpanel-tvOS"; - target = DBD5E5EA15DC8E29C6771390FFF80639 /* Mixpanel-tvOS */; - targetProxy = 04C9088432689A38DA79B08BFB3A949F /* PBXContainerItemProxy */; + name = "EasyMapping-macOS"; + target = 61C08C8B4FDF80F2237C00557D267969 /* EasyMapping-macOS */; + targetProxy = 636620EDFC8FCA2B6E6179AB44140931 /* PBXContainerItemProxy */; }; - 5CA20655AFF1BCAFB0A0E7781F1F90EE /* PBXTargetDependency */ = { + 585B8ED6B8833E2696AAD208F04D61A5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = OCMock; - target = C260B5A26D3CD54F215E5E39371483B6 /* OCMock */; - targetProxy = 29FE6F6A34AFE952E2A50FEC2B75B9EF /* PBXContainerItemProxy */; + name = "Sentry-macOS"; + target = 9AA8A98273205387E6FF9B148A006F31 /* Sentry-macOS */; + targetProxy = E0223640F20B5760574822FD5DBD6F57 /* PBXContainerItemProxy */; }; - 6596CCEECEEA6E503F383BEF9340BCAA /* PBXTargetDependency */ = { + 61F7FD85059539E2A6F96805E1C95987 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Kingfisher; - target = E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */; - targetProxy = 82CCD1B3AFED5DE20DF7E7ECE5D2D3B0 /* PBXContainerItemProxy */; + name = "EasyMapping-tvOS"; + target = 74A6508FB061133A1E28C2850A437667 /* EasyMapping-tvOS */; + targetProxy = C41FEF88C256678BA5687E5FFAA9104C /* PBXContainerItemProxy */; }; - 6CCF908DFAD96DCDF276CA276D5BC64A /* PBXTargetDependency */ = { + 647C75D02B0AE011CA0CCAD1702A56E5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "Pods-BitBot"; - target = EF68D578CA0C3D7CEDE4A31C9014F26F /* Pods-BitBot */; - targetProxy = 793E5E4E79FE365625F2200313175089 /* PBXContainerItemProxy */; + name = OCMock; + target = C260B5A26D3CD54F215E5E39371483B6 /* OCMock */; + targetProxy = 1CC5AD975176C539F11396BFAE88B22D /* PBXContainerItemProxy */; }; - 8175199035521EAAD36678AF8A832ABE /* PBXTargetDependency */ = { + 8DE47BFD0ECECD2C378E7703A3BFB33E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "Mixpanel-macOS"; - target = 8E2EC09E06710CFBAD6AF578E2A14F7C /* Mixpanel-macOS */; - targetProxy = C934252033DEBEE9562CD435915B6006 /* PBXContainerItemProxy */; + name = Kingfisher; + target = E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */; + targetProxy = 1AE05166B989BC2CF1ACCF236D3EC544 /* PBXContainerItemProxy */; }; - E7AFDD991FE2FBF8BB817DB27BFF26C9 /* PBXTargetDependency */ = { + 937ECD2EC27813D8E36A5B662EE2562B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "NSPopover+MISSINGBackgroundView"; - target = E64F498650CA1EED2135C3BEA452F3FD /* NSPopover+MISSINGBackgroundView */; - targetProxy = 2B39365175D1273474422C3CE9DC4302 /* PBXContainerItemProxy */; + name = "Mixpanel-tvOS"; + target = DBD5E5EA15DC8E29C6771390FFF80639 /* Mixpanel-tvOS */; + targetProxy = 4965B6FC2CB5165C16835D1F7B86323D /* PBXContainerItemProxy */; }; - F8EB942A5782783656E16993DD7113CB /* PBXTargetDependency */ = { + C33AF9D79674F839ECC2389000DF20D4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "EasyMapping-macOS"; - target = 61C08C8B4FDF80F2237C00557D267969 /* EasyMapping-macOS */; - targetProxy = F1BD7307B4B464D2BDE817FDE6E2C066 /* PBXContainerItemProxy */; + name = "Sentry-tvOS"; + target = DDC5B143847B1E75AB9687D42E6EF6B8 /* Sentry-tvOS */; + targetProxy = C4A8C00BCE5EB35E1CAC96F2A06F18EB /* PBXContainerItemProxy */; }; - FC9D87BCDD02A7CD9A08982ADC964B77 /* PBXTargetDependency */ = { + E232BAF750A4C89AD706E7290FB70CCA /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "EasyMapping-tvOS"; - target = 74A6508FB061133A1E28C2850A437667 /* EasyMapping-tvOS */; - targetProxy = C8B92276696C6B5A2C7E2EE3E1DDFC61 /* PBXContainerItemProxy */; + name = "Mixpanel-macOS"; + target = 8E2EC09E06710CFBAD6AF578E2A14F7C /* Mixpanel-macOS */; + targetProxy = 8CC4C52963C396ABA46B9008938897FC /* PBXContainerItemProxy */; }; - FE503746B49AB1EDEDCA3368A1790FD5 /* PBXTargetDependency */ = { + E570B1EF27867F0A42DE7D22D4118E20 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SDWebImage; target = 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */; - targetProxy = 3DFC3AD45B68FDD68130A30B67DCCB2F /* PBXContainerItemProxy */; + targetProxy = 51E799C0C44219F9ECCF37169173711B /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 0AEE265A9DE866CA1B97A817ADAA63A5 /* Debug */ = { + 0845DA6C9352100451338B40393842F2 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 298DE2A21DD8DFBCCC013ED8A37AFD59 /* Pods-BitBotATV.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-BitBotATV/Pods-BitBotATV.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 14.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 0F6E546CEB318624AD0C7AAFB68EE9DB /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C5120B28D0AE9A8B5959FFD25D7546BC /* SDWebImage.debug.xcconfig */; + baseConfigurationReference = 4DB313DA821938D69711108885AC28DC /* Mixpanel-macOS.debug.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/SDWebImage/SDWebImage-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/Mixpanel-macOS/Mixpanel-macOS-prefix.pch"; MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = SDWebImage; - PRODUCT_NAME = SDWebImage; + PRODUCT_MODULE_NAME = Mixpanel; + PRODUCT_NAME = "Mixpanel-macOS"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; }; name = Debug; }; - 1DE49D7F4286EE3E28089262FB4A3A71 /* Release */ = { + 15A0CAA51C39D7E7E6F80EEEE9E1D53E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 855230599E967A05447F178A3D557046 /* EasyMapping-macOS.release.xcconfig */; + baseConfigurationReference = B9A9599914DD2E69DFA3308658CC6D8D /* Pods-BitBot.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = "-"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/EasyMapping-macOS/EasyMapping-macOS-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.9; + MACH_O_TYPE = staticlib; + MACOSX_DEPLOYMENT_TARGET = 10.12; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = EasyMapping; - PRODUCT_NAME = "EasyMapping-macOS"; - PUBLIC_HEADERS_FOLDER_PATH = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; }; name = Release; }; - 24E4D14B4FF7CC1E8FA449CA2B6AC4BB /* Debug */ = { + 1CB85AF0FF709B6E2A5537540F78ACF8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 77D06687A5169837CF67DDCE96D0602B /* EasyMapping-tvOS.debug.xcconfig */; + baseConfigurationReference = 053C481FDFE0573C79EB67973EAB3864 /* Mixpanel-macOS.release.xcconfig */; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS-prefix.pch"; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/Mixpanel-macOS/Mixpanel-macOS-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = EasyMapping; - PRODUCT_NAME = "EasyMapping-tvOS"; + PRODUCT_MODULE_NAME = Mixpanel; + PRODUCT_NAME = "Mixpanel-macOS"; PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = appletvos; + SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; + SWIFT_VERSION = 4.2; }; - name = Debug; + name = Release; }; - 274044CD1BFF8C0239712BBEC92CB9E1 /* Debug */ = { + 1DD428F6731860C870C80916A2FB1880 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -2717,6 +4798,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -2756,143 +4838,142 @@ }; name = Debug; }; - 29B8AAAE81BA3DB8E205802FE981C4BA /* Release */ = { + 2465D79539F97284E03D0AB3EE2D9724 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 48A8FADBD7E4D999799E8CC0E67046CA /* Mixpanel-macOS.release.xcconfig */; + baseConfigurationReference = C7C372CE3D39CEC75B4CF8BEFF4657D6 /* Sentry-macOS.release.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/Mixpanel-macOS/Mixpanel-macOS-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/Sentry-macOS/Sentry-macOS-prefix.pch"; MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = Mixpanel; - PRODUCT_NAME = "Mixpanel-macOS"; + PRODUCT_MODULE_NAME = Sentry; + PRODUCT_NAME = "Sentry-macOS"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.2; }; name = Release; }; - 2D4BF854DFF080C8160824E13DFED64D /* Release */ = { + 24E4D14B4FF7CC1E8FA449CA2B6AC4BB /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7836184F3B8A75E0D19FAB2308E5024E /* Pods-BitriseATV.release.xcconfig */; + baseConfigurationReference = 9EF84BD0B2F2B9D182E8A39951EE8A9B /* EasyMapping-tvOS.debug.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-BitriseATV/Pods-BitriseATV.modulemap"; + GCC_PREFIX_HEADER = "Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS-prefix.pch"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = EasyMapping; + PRODUCT_NAME = "EasyMapping-tvOS"; + PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = appletvos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 14.0; - VALIDATE_PRODUCT = YES; + TVOS_DEPLOYMENT_TARGET = 9.0; }; - name = Release; + name = Debug; }; - 2F5B98FB041E158BCA2B2A3CD6591DC8 /* Release */ = { + 3B709206C47F6B3DF88523D68F75D614 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 04C89116FD3CAABF943C05E0EECAB17B /* Pods-BitBot.release.xcconfig */; + baseConfigurationReference = 12975D01A5CEFC84922A28BC64869E48 /* Sentry-tvOS.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - EXECUTABLE_PREFIX = lib; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; + GCC_PREFIX_HEADER = "Target Support Files/Sentry-tvOS/Sentry-tvOS-prefix.pch"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - SDKROOT = macosx; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = Sentry; + PRODUCT_NAME = "Sentry-tvOS"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = appletvos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.0; + VALIDATE_PRODUCT = YES; }; name = Release; }; - 385850E37507FD4988F28FDA7545901A /* Release */ = { + 4094900C3D82E25830EE1DF1ACBC6D58 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CF86FD09614080A1FDCD4A411FA33226 /* Expecta.release.xcconfig */; + baseConfigurationReference = 705CC9DAC8C56CAB1394F921EF7B3595 /* Kingfisher.release.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/Expecta/Expecta-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.8; + GCC_PREFIX_HEADER = "Target Support Files/Kingfisher/Kingfisher-prefix.pch"; + MODULEMAP_FILE = Headers/Public/Kingfisher/Kingfisher.modulemap; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = Expecta; - PRODUCT_NAME = Expecta; + PRODUCT_MODULE_NAME = Kingfisher; + PRODUCT_NAME = Kingfisher; PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = macosx; + SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 10.0; + VALIDATE_PRODUCT = YES; }; name = Release; }; - 4094900C3D82E25830EE1DF1ACBC6D58 /* Release */ = { + 47ACC5148F4146A1CA911265691E82A8 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9BD2815D50FF77D25D8698E01B52BFC3 /* Kingfisher.release.xcconfig */; + baseConfigurationReference = B37D0C9232F6AFE55239134BD3478B63 /* Sentry-tvOS.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/Kingfisher/Kingfisher-prefix.pch"; - MODULEMAP_FILE = Headers/Public/Kingfisher/Kingfisher.modulemap; + GCC_PREFIX_HEADER = "Target Support Files/Sentry-tvOS/Sentry-tvOS-prefix.pch"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = Kingfisher; - PRODUCT_NAME = Kingfisher; + PRODUCT_MODULE_NAME = Sentry; + PRODUCT_NAME = "Sentry-tvOS"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 10.0; - VALIDATE_PRODUCT = YES; + TVOS_DEPLOYMENT_TARGET = 9.0; }; - name = Release; + name = Debug; }; - 47276CB64FF8E9ED2A211B81CCA8FF6B /* Debug */ = { + 49462C653D7C671927E573943FB7C9DC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8398C38511B633C2B4E5C963995956D8 /* EasyMapping-macOS.debug.xcconfig */; + baseConfigurationReference = 4753CFE0EA0A4BF9BBB242C45FBBDA64 /* SDWebImage.debug.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = "-"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/EasyMapping-macOS/EasyMapping-macOS-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.9; + GCC_PREFIX_HEADER = "Target Support Files/SDWebImage/SDWebImage-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = EasyMapping; - PRODUCT_NAME = "EasyMapping-macOS"; + PRODUCT_MODULE_NAME = SDWebImage; + PRODUCT_NAME = SDWebImage; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -2900,23 +4981,69 @@ }; name = Debug; }; - 4BBBB259741FE5EB0A8CF0F88A9E1268 /* Debug */ = { + 54B828F935870DF19ACF6A7174548DA1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4072B0EAE2E33D5AB029517D512D41C4 /* OCMock.debug.xcconfig */; + baseConfigurationReference = 37CFFB37B0F2EA6788D515BD2C299784 /* Sentry-macOS.debug.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = "-"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/OCMock/OCMock-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/Sentry-macOS/Sentry-macOS-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.10; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = Sentry; + PRODUCT_NAME = "Sentry-macOS"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + }; + name = Debug; + }; + 59C639F9D6F92968811025DD04F9F44C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A6D2EFB975BFFCC2B00A3EB629C22CB7 /* Expecta.release.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/Expecta/Expecta-prefix.pch"; MACOSX_DEPLOYMENT_TARGET = 10.8; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = OCMock; - PRODUCT_NAME = OCMock; + PRODUCT_MODULE_NAME = Expecta; + PRODUCT_NAME = Expecta; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + }; + name = Release; + }; + 5AAAAE0706A97604FA7F3106CAA2634E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B6762EED2051F9E5E49DF5AF973AC7F1 /* Expecta.debug.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/Expecta/Expecta-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.8; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = Expecta; + PRODUCT_NAME = Expecta; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -2924,14 +5051,13 @@ }; name = Debug; }; - 514492F2E89CFC8B4D0BD7240659D2AA /* Debug */ = { + 5ADBB24C737A43CB22B733CF9B84A35B /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 77F78C8F8B32756794A2F45D9AEABA88 /* Pods-BitBotTests.debug.xcconfig */; + baseConfigurationReference = 4FD1228EA2E85C9985EC483AD3EEC37E /* Pods-BitBot.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -2947,23 +5073,45 @@ }; name = Debug; }; - 6B11D637603FF54F139C529231C26C55 /* Release */ = { + 5CC8F952FACDF0EA69FA2CF6306FB4FF /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2F2AE65500BCABFDFD85D713147C54F4 /* NSPopover+MISSINGBackgroundView.release.xcconfig */; + baseConfigurationReference = 27BA44A4FAB2F26DB7AD3821A298F697 /* OCMock.debug.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/OCMock/OCMock-prefix.pch"; MACOSX_DEPLOYMENT_TARGET = 10.8; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = NSPopover_MISSINGBackgroundView; - PRODUCT_NAME = "NSPopover+MISSINGBackgroundView"; + PRODUCT_MODULE_NAME = OCMock; + PRODUCT_NAME = OCMock; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + }; + name = Debug; + }; + 669E6CCFBD1B44427D87911ADA2A5D84 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C7EBFD7698607DF70418A78E51D73576 /* OCMock.release.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/OCMock/OCMock-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.8; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = OCMock; + PRODUCT_NAME = OCMock; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -2973,7 +5121,7 @@ }; 6BB16E33CCAF4D3B2159CAC29C95E7EC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = ABB22FE656A62BED33D213D15B61E75E /* Kingfisher.debug.xcconfig */; + baseConfigurationReference = 8C5412152A02375F97BCFA96C31002E2 /* Kingfisher.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2997,7 +5145,7 @@ }; 761ACA1AB6A03346460F536213C56EB6 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EA9C39723282F9332BBB781FEF173318 /* Mixpanel-tvOS.release.xcconfig */; + baseConfigurationReference = 34F08715426C01748685B152C7ADCAFA /* Mixpanel-tvOS.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -3019,23 +5167,22 @@ }; name = Release; }; - 8491FAF0DF3431B34A5D52FF021CABA8 /* Debug */ = { + 7A2F06D089C71A7DDF4BE65A34DBC008 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5611299158585069B560CAC196D9809F /* Expecta.debug.xcconfig */; + baseConfigurationReference = 23FA33D338D06AE28C6AC2CADC005ED6 /* NSPopover+MISSINGBackgroundView.debug.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/Expecta/Expecta-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView-prefix.pch"; MACOSX_DEPLOYMENT_TARGET = 10.8; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = Expecta; - PRODUCT_NAME = Expecta; + PRODUCT_MODULE_NAME = NSPopover_MISSINGBackgroundView; + PRODUCT_NAME = "NSPopover+MISSINGBackgroundView"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -3043,147 +5190,106 @@ }; name = Debug; }; - 8563808419D0701044E1FE5313565A52 /* Debug */ = { + 7AB788846B96DBFCF804418BEE568D1B /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 246A0C87B8EFEDCCF03667CE8BE5FD36 /* Mixpanel-tvOS.debug.xcconfig */; + baseConfigurationReference = 256EE003D93BB1CAD0C8CAA7F1CFF85A /* NSPopover+MISSINGBackgroundView.release.xcconfig */; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS-prefix.pch"; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.8; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = Mixpanel; - PRODUCT_NAME = "Mixpanel-tvOS"; + PRODUCT_MODULE_NAME = NSPopover_MISSINGBackgroundView; + PRODUCT_NAME = "NSPopover+MISSINGBackgroundView"; PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = appletvos; + SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; }; - name = Debug; + name = Release; }; - 882A688EF7334635BFF15DD61BB388AC /* Release */ = { + 7B6C45A8D45B06B3056EE3B567370516 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5DEFBD22C13412C0F8792B77A2536966 /* EasyMapping-tvOS.release.xcconfig */; + baseConfigurationReference = 29C750494B2288788DB4B51460D5DEE6 /* EasyMapping-macOS.debug.xcconfig */; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS-prefix.pch"; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/EasyMapping-macOS/EasyMapping-macOS-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.9; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; PRODUCT_MODULE_NAME = EasyMapping; - PRODUCT_NAME = "EasyMapping-tvOS"; + PRODUCT_NAME = "EasyMapping-macOS"; PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = appletvos; + SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - 8D95FE37C2CEDE8A0E37925D466FD795 /* Release */ = { + 8563808419D0701044E1FE5313565A52 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 001C309BA5BC26FE8099864DCB397F9B /* Mixpanel-tvOS.debug.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_RELEASE=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - STRIP_INSTALLED_PRODUCT = NO; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; - SYMROOT = "${SRCROOT}/../build"; - TVOS_DEPLOYMENT_TARGET = 14.0; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS-prefix.pch"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = Mixpanel; + PRODUCT_NAME = "Mixpanel-tvOS"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.0; }; - name = Release; + name = Debug; }; - 94353F3218782449CDFC64D46164D7BE /* Release */ = { + 882A688EF7334635BFF15DD61BB388AC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A98D77B9153B7AB9A55C572FEB29D582 /* SDWebImage.release.xcconfig */; + baseConfigurationReference = 599951F618E605ABAD714564410AC8E3 /* EasyMapping-tvOS.release.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/SDWebImage/SDWebImage-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + GCC_PREFIX_HEADER = "Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS-prefix.pch"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = SDWebImage; - PRODUCT_NAME = SDWebImage; + PRODUCT_MODULE_NAME = EasyMapping; + PRODUCT_NAME = "EasyMapping-tvOS"; PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = macosx; + SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.0; + VALIDATE_PRODUCT = YES; }; name = Release; }; - 962C267DC1CDE75729B3B78523ED3111 /* Debug */ = { + 8C6806F80778E5563D534129EF1C5FB8 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 405CE14212D8D81B57A9E972895A31D7 /* Pods-BitBot.debug.xcconfig */; + baseConfigurationReference = 17A69362E1FC166F5C2F8F3C55D67E3F /* Pods-BitBotTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3199,117 +5305,89 @@ }; name = Debug; }; - A4CD2427E3572E80BB2B41C4A5706F7A /* Debug */ = { + 93557F6968F22A516570CC33D0C41878 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A702A64B134CFFAB9B88CAA38D7E661A /* Mixpanel-macOS.debug.xcconfig */; + baseConfigurationReference = AA2793A28BA2F2951479D61E76981AF6 /* Pods-BitBotTests.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/Mixpanel-macOS/Mixpanel-macOS-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACH_O_TYPE = staticlib; + MACOSX_DEPLOYMENT_TARGET = 10.12; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = Mixpanel; - PRODUCT_NAME = "Mixpanel-macOS"; - PUBLIC_HEADERS_FOLDER_PATH = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.2; }; - name = Debug; + name = Release; }; - A4EC61E03C2B36693E29F784DB369616 /* Release */ = { + 9D5664F5CFDBBCBC7CF3BE4E713DDCAA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FBBE22C9909097D742F0E488B3666B9D /* Pods-BitBotTests.release.xcconfig */; + baseConfigurationReference = 70B4ECF8EB965BEFCBC17F7120D404FA /* Pods-BitBotATV.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - EXECUTABLE_PREFIX = lib; MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; + MODULEMAP_FILE = "Target Support Files/Pods-BitBotATV/Pods-BitBotATV.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - SDKROOT = macosx; + SDKROOT = appletvos; SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 14.0; }; - name = Release; + name = Debug; }; - AB74142FF97DB6284A3A98E147521D1A /* Debug */ = { + 9EEA9CF41176B28B8502B338BF69B496 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0E44BF2888ADFDF6796D186A5C321643 /* NSPopover+MISSINGBackgroundView.debug.xcconfig */; + baseConfigurationReference = 74966EDE9BC6FA94BEC3BE0444039F20 /* EasyMapping-macOS.release.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.8; + GCC_PREFIX_HEADER = "Target Support Files/EasyMapping-macOS/EasyMapping-macOS-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.9; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = NSPopover_MISSINGBackgroundView; - PRODUCT_NAME = "NSPopover+MISSINGBackgroundView"; + PRODUCT_MODULE_NAME = EasyMapping; + PRODUCT_NAME = "EasyMapping-macOS"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; }; - name = Debug; - }; - D57599ADDD854D8683231DC0F356606B /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B555045479DF24DFFDE23E9DBFADB5E /* Pods-BitriseATV.debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-BitriseATV/Pods-BitriseATV.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 14.0; - }; - name = Debug; + name = Release; }; - D73EB011ED0C1ACB31E66767F5F56CAF /* Release */ = { + ADAF38FD3C4B5AF7EA9695EBF95A9DC2 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5B4DD3877C768331D8354899F3365C4F /* OCMock.release.xcconfig */; + baseConfigurationReference = FE765919E608D58C7F7808F9D1CD06FF /* SDWebImage.release.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = "-"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/OCMock/OCMock-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.8; + GCC_PREFIX_HEADER = "Target Support Files/SDWebImage/SDWebImage-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = OCMock; - PRODUCT_NAME = OCMock; + PRODUCT_MODULE_NAME = SDWebImage; + PRODUCT_NAME = SDWebImage; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -3317,14 +5395,77 @@ }; name = Release; }; + C53C61943009D00FE2DC448B3FE9160D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + TVOS_DEPLOYMENT_TARGET = 14.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1C2F57D11C4087514079607029432149 /* Build configuration list for PBXNativeTarget "Mixpanel-macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - A4CD2427E3572E80BB2B41C4A5706F7A /* Debug */, - 29B8AAAE81BA3DB8E205802FE981C4BA /* Release */, + 0F6E546CEB318624AD0C7AAFB68EE9DB /* Debug */, + 1CB85AF0FF709B6E2A5537540F78ACF8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3332,8 +5473,17 @@ 2A900E3BE8C1DFA89137E03CFAEC55C6 /* Build configuration list for PBXNativeTarget "SDWebImage" */ = { isa = XCConfigurationList; buildConfigurations = ( - 0AEE265A9DE866CA1B97A817ADAA63A5 /* Debug */, - 94353F3218782449CDFC64D46164D7BE /* Release */, + 49462C653D7C671927E573943FB7C9DC /* Debug */, + ADAF38FD3C4B5AF7EA9695EBF95A9DC2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2F4F894C5C2B3E49BC5BAF8B20ADF05A /* Build configuration list for PBXNativeTarget "Pods-BitBot" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5ADBB24C737A43CB22B733CF9B84A35B /* Debug */, + 15A0CAA51C39D7E7E6F80EEEE9E1D53E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3350,17 +5500,17 @@ 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - 274044CD1BFF8C0239712BBEC92CB9E1 /* Debug */, - 8D95FE37C2CEDE8A0E37925D466FD795 /* Release */, + 1DD428F6731860C870C80916A2FB1880 /* Debug */, + C53C61943009D00FE2DC448B3FE9160D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6CC15D75F43CA86436233A2F6F95AEEF /* Build configuration list for PBXNativeTarget "Pods-BitBot" */ = { + 57FA21740CD506FC1C8CAB634FCD592D /* Build configuration list for PBXNativeTarget "Sentry-tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 962C267DC1CDE75729B3B78523ED3111 /* Debug */, - 2F5B98FB041E158BCA2B2A3CD6591DC8 /* Release */, + 47ACC5148F4146A1CA911265691E82A8 /* Debug */, + 3B709206C47F6B3DF88523D68F75D614 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3368,17 +5518,26 @@ 6DED44BA887C7B50F308C1DB11861EC2 /* Build configuration list for PBXNativeTarget "Expecta" */ = { isa = XCConfigurationList; buildConfigurations = ( - 8491FAF0DF3431B34A5D52FF021CABA8 /* Debug */, - 385850E37507FD4988F28FDA7545901A /* Release */, + 5AAAAE0706A97604FA7F3106CAA2634E /* Debug */, + 59C639F9D6F92968811025DD04F9F44C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 88F2D97C39B11398472B8B4B757617D2 /* Build configuration list for PBXNativeTarget "Pods-BitBotTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8C6806F80778E5563D534129EF1C5FB8 /* Debug */, + 93557F6968F22A516570CC33D0C41878 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 79623E89E95A26FBC46B15D2C797706C /* Build configuration list for PBXNativeTarget "Pods-BitBotTests" */ = { + 94D26E73A9E729ADB2F7724EE8448937 /* Build configuration list for PBXNativeTarget "Pods-BitBotATV" */ = { isa = XCConfigurationList; buildConfigurations = ( - 514492F2E89CFC8B4D0BD7240659D2AA /* Debug */, - A4EC61E03C2B36693E29F784DB369616 /* Release */, + 9D5664F5CFDBBCBC7CF3BE4E713DDCAA /* Debug */, + 0845DA6C9352100451338B40393842F2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3395,17 +5554,17 @@ 9E5C30C00C21E8FF92A304D53C1C8EBD /* Build configuration list for PBXNativeTarget "EasyMapping-macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 47276CB64FF8E9ED2A211B81CCA8FF6B /* Debug */, - 1DE49D7F4286EE3E28089262FB4A3A71 /* Release */, + 7B6C45A8D45B06B3056EE3B567370516 /* Debug */, + 9EEA9CF41176B28B8502B338BF69B496 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - A1F32E0BFA1538B4AE80C80F1B9500F0 /* Build configuration list for PBXNativeTarget "Pods-BitriseATV" */ = { + B0A0BA9DB9C21344E4DA2377DE79E560 /* Build configuration list for PBXNativeTarget "Sentry-macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - D57599ADDD854D8683231DC0F356606B /* Debug */, - 2D4BF854DFF080C8160824E13DFED64D /* Release */, + 54B828F935870DF19ACF6A7174548DA1 /* Debug */, + 2465D79539F97284E03D0AB3EE2D9724 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3413,8 +5572,8 @@ B6B75D75BE3B7AA1CD0D7FA6535DB001 /* Build configuration list for PBXNativeTarget "OCMock" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4BBBB259741FE5EB0A8CF0F88A9E1268 /* Debug */, - D73EB011ED0C1ACB31E66767F5F56CAF /* Release */, + 5CC8F952FACDF0EA69FA2CF6306FB4FF /* Debug */, + 669E6CCFBD1B44427D87911ADA2A5D84 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3422,8 +5581,8 @@ CCF04642631788A4DEBDD5E8DDC775C2 /* Build configuration list for PBXNativeTarget "NSPopover+MISSINGBackgroundView" */ = { isa = XCConfigurationList; buildConfigurations = ( - AB74142FF97DB6284A3A98E147521D1A /* Debug */, - 6B11D637603FF54F139C529231C26C55 /* Release */, + 7A2F06D089C71A7DDF4BE65A34DBC008 /* Debug */, + 7AB788846B96DBFCF804418BEE568D1B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Sentry/LICENSE.md b/Pods/Sentry/LICENSE.md new file mode 100644 index 00000000..5a483f25 --- /dev/null +++ b/Pods/Sentry/LICENSE.md @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Pods/Sentry/README.md b/Pods/Sentry/README.md new file mode 100644 index 00000000..8159d454 --- /dev/null +++ b/Pods/Sentry/README.md @@ -0,0 +1,70 @@ +

+ + + +
+

Official Sentry SDK for iOS / tvOS / macOS / watchOS (1).

+

+ +_Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us [**Check out our open positions**](https://sentry.io/careers/)_ + +[![Build](https://img.shields.io/github/workflow/status/getsentry/sentry-cocoa/Build%20%26%20Test)](https://github.com/getsentry/sentry-cocoa/actions?query=workflow%3A%22Build+%26+Test%22) +[![codebeat badge](https://codebeat.co/badges/07f0bc91-9102-4fd8-99a6-30b25dc98037)](https://codebeat.co/projects/github-com-getsentry-sentry-cocoa-master) +[![codecov.io](https://codecov.io/gh/getsentry/sentry-cocoa/branch/master/graph/badge.svg)](https://codecov.io/gh/getsentry/sentry-cocoa) +[![CocoaPods compadible](https://img.shields.io/cocoapods/v/Sentry.svg)](https://cocoapods.org/pods/Sentry) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![SwiftPM compatible](https://img.shields.io/badge/spm-compatible-brightgreen.svg?style=flat)](https://swift.org/package-manager) +![platforms](https://img.shields.io/cocoapods/p/Sentry.svg?style=flat) +[![Swift Package Index](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fgetsentry%2Fsentry-cocoa%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/getsentry/sentry-cocoa) +[![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) + +This SDK is written in Objective-C but also provides a nice Swift interface. + +# Initialization + +*Remember to call this as early in your application life cycle as possible* +Ideally in `applicationDidFinishLaunching` in `AppDelegate` + +```swift +import Sentry + +// .... + +SentrySDK.start { options in + options.dsn = "___PUBLIC_DSN___" + options.debug = true // Helpful to see what's going on +} +``` + +```objc +@import Sentry; + +// .... + +[SentrySDK startWithConfigureOptions:^(SentryOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.debug = @YES; // Helpful to see what's going on +}]; + +``` + +For more information checkout the [docs](https://docs.sentry.io/platforms/apple). + +(1)limited symbolication support and no crash handling. + +# Blog posts + +[How to use Sentry Attachments with Mobile Applications](https://blog.sentry.io/2021/02/03/how-to-use-sentry-attachments-with-mobile-applications/?utm_source=github&utm_medium=readme&utm_campaign=sentry-cocoa). + +[Close the Loop with User Feedback](https://blog.sentry.io/2021/02/16/close-the-loop-with-user-feedback/?utm_source=github&utm_medium=readme&utm_campaign=sentry-cocoa). + +[A Sanity Listicle for Mobile Developers](https://blog.sentry.io/2021/03/30/a-sanity-listicle-for-mobile-developers/?utm_source=github&utm_medium=readme&utm_campaign=sentry-cocoa). + +# Resources + +* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/apple/) +* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) +* [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](http://stackoverflow.com/questions/tagged/sentry) +* [![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-sentry-green.svg)](https://github.com/getsentry/.github/blob/master/CODE_OF_CONDUCT.md) +* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) diff --git a/Pods/Sentry/Sources/Sentry/NSArray+SentrySanitize.m b/Pods/Sentry/Sources/Sentry/NSArray+SentrySanitize.m new file mode 100644 index 00000000..a70002b1 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/NSArray+SentrySanitize.m @@ -0,0 +1,29 @@ +#import "NSArray+SentrySanitize.h" +#import "NSDate+SentryExtras.h" +#import "NSDictionary+SentrySanitize.h" + +@implementation NSArray (SentrySanitize) + +- (NSArray *)sentry_sanitize +{ + NSMutableArray *array = [NSMutableArray array]; + for (id rawValue in self) { + + if ([rawValue isKindOfClass:NSString.class]) { + [array addObject:rawValue]; + } else if ([rawValue isKindOfClass:NSNumber.class]) { + [array addObject:rawValue]; + } else if ([rawValue isKindOfClass:NSDictionary.class]) { + [array addObject:[(NSDictionary *)rawValue sentry_sanitize]]; + } else if ([rawValue isKindOfClass:NSArray.class]) { + [array addObject:[(NSArray *)rawValue sentry_sanitize]]; + } else if ([rawValue isKindOfClass:NSDate.class]) { + [array addObject:[(NSDate *)rawValue sentry_toIso8601String]]; + } else { + [array addObject:[rawValue description]]; + } + } + return array; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/NSData+SentryCompression.m b/Pods/Sentry/Sources/Sentry/NSData+SentryCompression.m new file mode 100644 index 00000000..564de63e --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/NSData+SentryCompression.m @@ -0,0 +1,60 @@ +#if __has_include() +# import +#endif + +#import "NSData+SentryCompression.h" +#import "SentryError.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation NSData (SentryCompression) + +- (NSData *_Nullable)sentry_gzippedWithCompressionLevel:(NSInteger)compressionLevel + error:(NSError *_Nullable *_Nullable)error +{ + uInt length = (uInt)[self length]; + if (length == 0) { + return [NSData data]; + } + + /// Init empty z_stream + z_stream stream; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.next_in = (Bytef *)(void *)self.bytes; + stream.total_out = 0; + stream.avail_out = 0; + stream.avail_in = length; + + int err; + + err = deflateInit2( + &stream, compressionLevel, Z_DEFLATED, (16 + MAX_WBITS), 9, Z_DEFAULT_STRATEGY); + if (err != Z_OK) { + if (error) { + *error = NSErrorFromSentryError(kSentryErrorCompressionError, @"deflateInit2 error"); + } + return nil; + } + + NSMutableData *compressedData = [NSMutableData dataWithLength:(NSUInteger)(length * 1.02 + 50)]; + Bytef *compressedBytes = [compressedData mutableBytes]; + NSUInteger compressedLength = [compressedData length]; + + /// compress + while (err == Z_OK) { + stream.next_out = compressedBytes + stream.total_out; + stream.avail_out = (uInt)(compressedLength - stream.total_out); + err = deflate(&stream, Z_FINISH); + } + + [compressedData setLength:stream.total_out]; + + deflateEnd(&stream); + return compressedData; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/NSDate+SentryExtras.m b/Pods/Sentry/Sources/Sentry/NSDate+SentryExtras.m new file mode 100644 index 00000000..7dfa18a1 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/NSDate+SentryExtras.m @@ -0,0 +1,53 @@ +#import "NSDate+SentryExtras.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation NSDate (SentryExtras) + ++ (NSDateFormatter *)getIso8601Formatter +{ + static NSDateFormatter *isoFormatter = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + isoFormatter = [[NSDateFormatter alloc] init]; + [isoFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; + isoFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; + [isoFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; + }); + + return isoFormatter; +} + ++ (NSDateFormatter *)getIso8601FormatterWithMillisecondPrecision +{ + static NSDateFormatter *isoFormatter = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + isoFormatter = [[NSDateFormatter alloc] init]; + [isoFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; + isoFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; + [isoFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"]; + }); + + return isoFormatter; +} + ++ (NSDate *)sentry_fromIso8601String:(NSString *)string +{ + NSDate *date = [[self.class getIso8601FormatterWithMillisecondPrecision] dateFromString:string]; + if (nil == date) { + // Parse date with low precision formatter for backward compatible + return [[self.class getIso8601Formatter] dateFromString:string]; + } else { + return date; + } +} + +- (NSString *)sentry_toIso8601String +{ + return [[self.class getIso8601FormatterWithMillisecondPrecision] stringFromDate:self]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/NSDictionary+SentrySanitize.m b/Pods/Sentry/Sources/Sentry/NSDictionary+SentrySanitize.m new file mode 100644 index 00000000..d4849a65 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/NSDictionary+SentrySanitize.m @@ -0,0 +1,41 @@ +#import "NSArray+SentrySanitize.h" +#import "NSDate+SentryExtras.h" +#import "NSDictionary+SentrySanitize.h" + +@implementation NSDictionary (SentrySanitize) + +- (NSDictionary *)sentry_sanitize +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + for (id rawKey in self.allKeys) { + id rawValue = [self objectForKey:rawKey]; + + NSString *stringKey; + if ([rawKey isKindOfClass:NSString.class]) { + stringKey = rawKey; + } else { + stringKey = [rawKey description]; + } + + if ([stringKey hasPrefix:@"__sentry"]) { + continue; // We don't want to add __sentry variables + } + + if ([rawValue isKindOfClass:NSString.class]) { + [dict setValue:rawValue forKey:stringKey]; + } else if ([rawValue isKindOfClass:NSNumber.class]) { + [dict setValue:rawValue forKey:stringKey]; + } else if ([rawValue isKindOfClass:NSDictionary.class]) { + [dict setValue:[(NSDictionary *)rawValue sentry_sanitize] forKey:stringKey]; + } else if ([rawValue isKindOfClass:NSArray.class]) { + [dict setValue:[(NSArray *)rawValue sentry_sanitize] forKey:stringKey]; + } else if ([rawValue isKindOfClass:NSDate.class]) { + [dict setValue:[(NSDate *)rawValue sentry_toIso8601String] forKey:stringKey]; + } else { + [dict setValue:[rawValue description] forKey:stringKey]; + } + } + return dict; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/NSString+SentryUnsignedLongLongValue.m b/Pods/Sentry/Sources/Sentry/NSString+SentryUnsignedLongLongValue.m new file mode 100644 index 00000000..3d160a87 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/NSString+SentryUnsignedLongLongValue.m @@ -0,0 +1,10 @@ +#import "NSString+SentryUnsignedLongLongValue.h" + +@implementation NSString (SentryUnsignedLongLongValue) + +- (unsigned long long)unsignedLongLongValue +{ + return strtoull([self UTF8String], NULL, 0); +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/Public/Sentry.h b/Pods/Sentry/Sources/Sentry/Public/Sentry.h new file mode 100644 index 00000000..12daf501 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/Sentry.h @@ -0,0 +1,44 @@ +#import + +//! Project version number for Sentry. +FOUNDATION_EXPORT double SentryVersionNumber; + +//! Project version string for Sentry. +FOUNDATION_EXPORT const unsigned char SentryVersionString[]; + +#import "SentryAttachment.h" +#import "SentryBreadcrumb.h" +#import "SentryClient.h" +#import "SentryCrashExceptionApplication.h" +#import "SentryDebugMeta.h" +#import "SentryDefines.h" +#import "SentryDsn.h" +#import "SentryEnvelope.h" +#import "SentryEnvelopeItemType.h" +#import "SentryError.h" +#import "SentryEvent.h" +#import "SentryException.h" +#import "SentryFrame.h" +#import "SentryHub.h" +#import "SentryId.h" +#import "SentryIntegrationProtocol.h" +#import "SentryMechanism.h" +#import "SentryMessage.h" +#import "SentryNSError.h" +#import "SentryOptions.h" +#import "SentrySDK.h" +#import "SentrySampleDecision.h" +#import "SentrySamplingContext.h" +#import "SentryScope.h" +#import "SentrySdkInfo.h" +#import "SentrySerializable.h" +#import "SentrySession.h" +#import "SentrySpanContext.h" +#import "SentrySpanId.h" +#import "SentrySpanProtocol.h" +#import "SentrySpanStatus.h" +#import "SentryStacktrace.h" +#import "SentryThread.h" +#import "SentryTransactionContext.h" +#import "SentryUser.h" +#import "SentryUserFeedback.h" diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryAttachment.h b/Pods/Sentry/Sources/Sentry/Public/SentryAttachment.h new file mode 100644 index 00000000..6a834143 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryAttachment.h @@ -0,0 +1,90 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * You can use an attachment to store additional files alongside an event. + */ +NS_SWIFT_NAME(Attachment) +@interface SentryAttachment : NSObject +SENTRY_NO_INIT + +/** + * Initializes an attachment with data. Sets the content type to "application/octet-stream". + * + * @param data The data for the attachment. + * @param filename The name of the attachment to display in Sentry. + */ +- (instancetype)initWithData:(NSData *)data filename:(NSString *)filename; + +/** + * Initializes an attachment with data. + * + * @param data The data for the attachment. + * @param filename The name of the attachment to display in Sentry. + * @param contentType The content type of the attachment. Default is "application/octet-stream". + */ +- (instancetype)initWithData:(NSData *)data + filename:(NSString *)filename + contentType:(NSString *)contentType; + +/** + * Initializes an attachment with a path. Uses the last path compontent of the path as a filename + * and sets the content type to "application/octet-stream". + * + * @discussion The file located at the pathname is read lazily when the SDK captures an event or + * transaction not when the attachment is initialized. + * + * @param path The path of the file whose contents you want to upload to Sentry. + */ +- (instancetype)initWithPath:(NSString *)path; + +/** + * Initializes an attachment with a path. Sets the content type to "application/octet-stream". + * + * @discussion The file located at the pathname is read lazily when the SDK captures an event or + * transaction not when the attachment is initialized. + * + * @param path The path of the file whose contents you want to upload to Sentry. + * @param filename The name of the attachment to display in Sentry. + */ +- (instancetype)initWithPath:(NSString *)path filename:(NSString *)filename; + +/** + * Initializes an attachment with a path. + * + * @discussion The file located at the pathname is read lazily when the SDK captures an event or + * transaction not when the attachment is initialized. + * + * @param path The path of the file whose contents you want to upload to Sentry. + * @param filename The name of the attachment to display in Sentry. + * @param contentType The content type of the attachment. Default is "application/octet-stream". + */ +- (instancetype)initWithPath:(NSString *)path + filename:(NSString *)filename + contentType:(NSString *)contentType; + +/** + * The data of the attachment. + */ +@property (readonly, nonatomic, strong) NSData *_Nullable data; + +/** + * The path of the attachment. + */ +@property (readonly, nonatomic, copy) NSString *_Nullable path; + +/** + * The filename of the attachment to display in Sentry. + */ +@property (readonly, nonatomic, copy) NSString *filename; + +/** + * The content type of the attachment. Default is "application/octet-stream". + */ +@property (readonly, nonatomic, copy) NSString *contentType; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryBreadcrumb.h b/Pods/Sentry/Sources/Sentry/Public/SentryBreadcrumb.h new file mode 100644 index 00000000..0fa5034f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryBreadcrumb.h @@ -0,0 +1,63 @@ +#import + +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(Breadcrumb) +@interface SentryBreadcrumb : NSObject + +/** + * Level of breadcrumb + */ +@property (nonatomic) SentryLevel level; + +/** + * Category of bookmark, can be any string + */ +@property (nonatomic, copy) NSString *category; + +/** + * NSDate when the breadcrumb happened + */ +@property (nonatomic, strong) NSDate *_Nullable timestamp; + +/** + * Type of breadcrumb, can be e.g.: http, empty, user, navigation + * This will be used as icon of the breadcrumb + */ +@property (nonatomic, copy) NSString *_Nullable type; + +/** + * Message for the breadcrumb + */ +@property (nonatomic, copy) NSString *_Nullable message; + +/** + * Arbitrary additional data that will be sent with the breadcrumb + */ +@property (nonatomic, strong) NSDictionary *_Nullable data; + +/** + * Initializer for SentryBreadcrumb + * + * @param level SentryLevel + * @param category String + * @return SentryBreadcrumb + */ +- (instancetype)initWithLevel:(SentryLevel)level category:(NSString *)category; +- (instancetype)init; ++ (instancetype)new NS_UNAVAILABLE; + +- (NSDictionary *)serialize; + +- (BOOL)isEqual:(id _Nullable)other; + +- (BOOL)isEqualToBreadcrumb:(SentryBreadcrumb *)breadcrumb; + +- (NSUInteger)hash; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryClient.h b/Pods/Sentry/Sources/Sentry/Public/SentryClient.h new file mode 100644 index 00000000..c60997fc --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryClient.h @@ -0,0 +1,118 @@ +#import + +#import "SentryDefines.h" + +@class SentryOptions, SentrySession, SentryEvent, SentryEnvelope, SentryScope, SentryFileManager, + SentryId, SentryUserFeedback, SentryTransaction; + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(Client) +@interface SentryClient : NSObject +SENTRY_NO_INIT + +@property (nonatomic, strong) SentryOptions *options; + +/** + * Initializes a SentryClient. Pass in an dictionary of options. + * + * @param options Options dictionary + * @return SentryClient + */ +- (_Nullable instancetype)initWithOptions:(SentryOptions *)options; + +/** + * Captures a manually created event and sends it to Sentry. + * + * @param event The event to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); + +/** + * Captures a manually created event and sends it to Sentry. + * + * @param event The event to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureEvent:(SentryEvent *)event + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(event:scope:)); + +/** + * Captures an error event and sends it to Sentry. + * + * @param error The error to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); + +/** + * Captures an error event and sends it to Sentry. + * + * @param error The error to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureError:(NSError *)error + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); + +/** + * Captures an exception event and sends it to Sentry. + * + * @param exception The exception to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); + +/** + * Captures an exception event and sends it to Sentry. + * + * @param exception The exception to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureException:(NSException *)exception + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); + +/** + * Captures a message event and sends it to Sentry. + * + * @param message The message to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); + +/** + * Captures a message event and sends it to Sentry. + * + * @param message The message to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureMessage:(NSString *)message + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); + +/** + * Captures a manually created user feedback and sends it to Sentry. + * + * @param userFeedback The user feedback to send to Sentry. + */ +- (void)captureUserFeedback:(SentryUserFeedback *)userFeedback + NS_SWIFT_NAME(capture(userFeedback:)); + +- (void)captureSession:(SentrySession *)session NS_SWIFT_NAME(capture(session:)); + +- (void)captureEnvelope:(SentryEnvelope *)envelope NS_SWIFT_NAME(capture(envelope:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryCrashExceptionApplication.h b/Pods/Sentry/Sources/Sentry/Public/SentryCrashExceptionApplication.h new file mode 100644 index 00000000..c70ecaf8 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryCrashExceptionApplication.h @@ -0,0 +1,14 @@ +// Don't move Foundation.h. We need it here in order to have +// TargetConditionals.h automatically imported. This is needed +// so that `#if TARGET_OS_OSX` is working fine. If we move +// this the SDK breaks for MacOS. +#import + +#if TARGET_OS_OSX +# import +@interface SentryCrashExceptionApplication : NSApplication +#else +@interface SentryCrashExceptionApplication : NSObject +#endif + +@end diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryDebugMeta.h b/Pods/Sentry/Sources/Sentry/Public/SentryDebugMeta.h new file mode 100644 index 00000000..304a33d6 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryDebugMeta.h @@ -0,0 +1,45 @@ +#import + +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(DebugMeta) +@interface SentryDebugMeta : NSObject + +/** + * UUID of image + */ +@property (nonatomic, copy) NSString *_Nullable uuid; + +/** + * Type of debug meta, mostly just apple + */ +@property (nonatomic, copy) NSString *_Nullable type; + +/** + * Name of the image + */ +@property (nonatomic, copy) NSString *_Nullable name; + +/** + * Image size + */ +@property (nonatomic, copy) NSNumber *_Nullable imageSize; + +/** + * Image address + */ +@property (nonatomic, copy) NSString *_Nullable imageAddress; + +/** + * Image vm address + */ +@property (nonatomic, copy) NSString *_Nullable imageVmAddress; + +- (instancetype)init; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryDefines.h b/Pods/Sentry/Sources/Sentry/Public/SentryDefines.h new file mode 100644 index 00000000..aea5368b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryDefines.h @@ -0,0 +1,119 @@ +#import + +#ifdef __cplusplus +# define SENTRY_EXTERN extern "C" __attribute__((visibility("default"))) +#else +# define SENTRY_EXTERN extern __attribute__((visibility("default"))) +#endif + +#if TARGET_OS_IOS || TARGET_OS_TV +# define SENTRY_HAS_UIDEVICE 1 +#else +# define SENTRY_HAS_UIDEVICE 0 +#endif + +#if SENTRY_HAS_UIDEVICE +# define SENTRY_HAS_UIKIT 1 +#else +# define SENTRY_HAS_UIKIT 0 +#endif + +#define SENTRY_NO_INIT \ + -(instancetype)init NS_UNAVAILABLE; \ + +(instancetype) new NS_UNAVAILABLE; + +@class SentryEvent, SentryBreadcrumb, SentrySamplingContext; +@protocol SentrySpan; + +/** + * Block used for returning after a request finished + */ +typedef void (^SentryRequestFinished)(NSError *_Nullable error); + +/** + * Block used for request operation finished, shouldDiscardEvent is YES if event + * should be deleted regardless if an error ocured or not + */ +typedef void (^SentryRequestOperationFinished)( + NSHTTPURLResponse *_Nullable response, NSError *_Nullable error); +/** + * Block can be used to mutate a breadcrumb before it's added to the scope. + * To avoid adding the breadcrumb altogether, return nil instead. + */ +typedef SentryBreadcrumb *_Nullable (^SentryBeforeBreadcrumbCallback)( + SentryBreadcrumb *_Nonnull breadcrumb); + +/** + * Block can be used to mutate event before its send. + * To avoid sending the event altogether, return nil instead. + */ +typedef SentryEvent *_Nullable (^SentryBeforeSendEventCallback)(SentryEvent *_Nonnull event); + +/** + * A callback to be notified when the last program execution terminated with a crash. + */ +typedef void (^SentryOnCrashedLastRunCallback)(SentryEvent *_Nonnull event); + +/** + * Block can be used to determine if an event should be queued and stored + * locally. It will be tried to send again after next successful send. Note that + * this will only be called once the event is created and send manually. Once it + * has been queued once it will be discarded if it fails again. + */ +typedef BOOL (^SentryShouldQueueEvent)( + NSHTTPURLResponse *_Nullable response, NSError *_Nullable error); + +/** + * Function pointer for a sampler callback. + * + * @param samplingContext context of the sampling. + * + * @return A sample rate between 0.0 and 1.0. + */ +typedef NSNumber *_Nullable (^SentryTracesSamplerCallback)( + SentrySamplingContext *_Nonnull samplingContext); + +/** + * Function pointer for span manipulation. + * + * @param span The span to be used. + */ +typedef void (^SentrySpanCallback)(id _Nullable span); + +/** + * Loglevel + */ +typedef NS_ENUM(NSInteger, SentryLogLevel) { + kSentryLogLevelNone = 1, + kSentryLogLevelError, + kSentryLogLevelDebug, + kSentryLogLevelVerbose +}; + +/** + * Sentry level + */ +typedef NS_ENUM(NSUInteger, SentryLevel) { + // Defaults to None which doesn't get serialized + kSentryLevelNone = 0, + // Goes from Debug to Fatal so possible to: (level > Info) { .. } + kSentryLevelDebug = 1, + kSentryLevelInfo = 2, + kSentryLevelWarning = 3, + kSentryLevelError = 4, + kSentryLevelFatal = 5 +}; + +/** + * Static internal helper to convert enum to string + */ +static NSString *_Nonnull const SentryLevelNames[] = { + @"none", + @"debug", + @"info", + @"warning", + @"error", + @"fatal", +}; + +static NSUInteger const defaultMaxBreadcrumbs = 100; diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryDsn.h b/Pods/Sentry/Sources/Sentry/Public/SentryDsn.h new file mode 100644 index 00000000..1b48571b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryDsn.h @@ -0,0 +1,19 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryDsn : NSObject + +@property (nonatomic, strong, readonly) NSURL *url; + +- (_Nullable instancetype)initWithString:(NSString *)dsnString + didFailWithError:(NSError *_Nullable *_Nullable)error; + +- (NSString *)getHash; + +- (NSURL *)getStoreEndpoint; +- (NSURL *)getEnvelopeEndpoint; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryEnvelope.h b/Pods/Sentry/Sources/Sentry/Public/SentryEnvelope.h new file mode 100644 index 00000000..54d6ff5e --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryEnvelope.h @@ -0,0 +1,137 @@ +#import + +#import "SentryDefines.h" + +@class SentryEvent, SentrySession, SentrySdkInfo, SentryId, SentryUserFeedback, SentryAttachment, + SentryTransaction; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryEnvelopeHeader : NSObject +SENTRY_NO_INIT + +/** + * Initializes an SentryEnvelopeHeader object with the specified eventId. + * + * Sets the sdkInfo from SentryMeta. + * + * @param eventId The identifier of the event. Can be nil if no event in the envelope or attachment + * related to event. + */ +- (instancetype)initWithId:(SentryId *_Nullable)eventId; + +/** + * Initializes an SentryEnvelopeHeader object with the specified eventId and skdInfo. + * + * It is recommended to use initWithId:eventId: because it sets the sdkInfo for you. + * + * @param eventId The identifier of the event. Can be nil if no event in the envelope or attachment + * related to event. + * @param sdkInfo sdkInfo Describes the Sentry SDK. Can be nil for backwards compatibility. New + * instances should always provide a version. + */ +- (instancetype)initWithId:(SentryId *_Nullable)eventId + andSdkInfo:(SentrySdkInfo *_Nullable)sdkInfo NS_DESIGNATED_INITIALIZER; + +/** + * The event identifier, if available. + * An event id exist if the envelope contains an event of items within it are + * related. i.e Attachments + */ +@property (nonatomic, readonly, copy) SentryId *_Nullable eventId; + +@property (nonatomic, readonly, copy) SentrySdkInfo *_Nullable sdkInfo; + +@end + +@interface SentryEnvelopeItemHeader : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithType:(NSString *)type length:(NSUInteger)length NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithType:(NSString *)type + length:(NSUInteger)length + filenname:(NSString *)filename + contentType:(NSString *)contentType; + +/** + * The type of the envelope item. + */ +@property (nonatomic, readonly, copy) NSString *type; +@property (nonatomic, readonly) NSUInteger length; +@property (nonatomic, readonly, copy) NSString *_Nullable filename; +@property (nonatomic, readonly, copy) NSString *_Nullable contentType; + +@end + +@interface SentryEnvelopeItem : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithEvent:(SentryEvent *)event; +- (instancetype)initWithSession:(SentrySession *)session; +- (instancetype)initWithUserFeedback:(SentryUserFeedback *)userFeedback; +- (_Nullable instancetype)initWithAttachment:(SentryAttachment *)attachment + maxAttachmentSize:(NSUInteger)maxAttachmentSize; +- (instancetype)initWithHeader:(SentryEnvelopeItemHeader *)header + data:(NSData *)data NS_DESIGNATED_INITIALIZER; + +/** + * The envelope item header. + */ +@property (nonatomic, readonly, strong) SentryEnvelopeItemHeader *header; + +/** + * The envelope payload. + */ +@property (nonatomic, readonly, strong) NSData *data; + +@end + +@interface SentryEnvelope : NSObject +SENTRY_NO_INIT + +// If no event, or no data related to event, id will be null +- (instancetype)initWithId:(SentryId *_Nullable)id singleItem:(SentryEnvelopeItem *)item; + +- (instancetype)initWithHeader:(SentryEnvelopeHeader *)header singleItem:(SentryEnvelopeItem *)item; + +// If no event, or no data related to event, id will be null +- (instancetype)initWithId:(SentryId *_Nullable)id items:(NSArray *)items; + +/** + * Initializes a SentryEnvelope with a single session. + * @param session to init the envelope with. + * @return an initialized SentryEnvelope + */ +- (instancetype)initWithSession:(SentrySession *)session; + +/** + * Initializes a SentryEnvelope with a list of sessions. + * Can be used when an operations that starts a session closes an ongoing + * session + * @param sessions to init the envelope with. + * @return an initialized SentryEnvelope + */ +- (instancetype)initWithSessions:(NSArray *)sessions; + +- (instancetype)initWithHeader:(SentryEnvelopeHeader *)header + items:(NSArray *)items NS_DESIGNATED_INITIALIZER; + +// Convenience init for a single event +- (instancetype)initWithEvent:(SentryEvent *)event; + +- (instancetype)initWithUserFeedback:(SentryUserFeedback *)userFeedback; + +/** + * The envelope header. + */ +@property (nonatomic, readonly, strong) SentryEnvelopeHeader *header; + +/** + * The envelope items. + */ +@property (nonatomic, readonly, strong) NSArray *items; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryEnvelopeItemType.h b/Pods/Sentry/Sources/Sentry/Public/SentryEnvelopeItemType.h new file mode 100644 index 00000000..d642c9b1 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryEnvelopeItemType.h @@ -0,0 +1,5 @@ +static NSString *const SentryEnvelopeItemTypeEvent = @"event"; +static NSString *const SentryEnvelopeItemTypeSession = @"session"; +static NSString *const SentryEnvelopeItemTypeUserFeedback = @"user_report"; +static NSString *const SentryEnvelopeItemTypeTransaction = @"transaction"; +static NSString *const SentryEnvelopeItemTypeAttachment = @"attachment"; diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryError.h b/Pods/Sentry/Sources/Sentry/Public/SentryError.h new file mode 100644 index 00000000..a2f54522 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryError.h @@ -0,0 +1,23 @@ +#import + +#import "SentryDefines.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, SentryError) { + kSentryErrorUnknownError = -1, + kSentryErrorInvalidDsnError = 100, + kSentryErrorSentryCrashNotInstalledError = 101, + kSentryErrorInvalidCrashReportError = 102, + kSentryErrorCompressionError = 103, + kSentryErrorJsonConversionError = 104, + kSentryErrorCouldNotFindDirectory = 105, + kSentryErrorRequestError = 106, + kSentryErrorEventNotSent = 107, +}; + +SENTRY_EXTERN NSError *_Nullable NSErrorFromSentryError(SentryError error, NSString *description); + +SENTRY_EXTERN NSString *const SentryErrorDomain; + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryEvent.h b/Pods/Sentry/Sources/Sentry/Public/SentryEvent.h new file mode 100644 index 00000000..7f1d96e1 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryEvent.h @@ -0,0 +1,185 @@ +#import + +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryThread, SentryException, SentryStacktrace, SentryUser, SentryDebugMeta, SentryContext, + SentryBreadcrumb, SentryId, SentryMessage; + +NS_SWIFT_NAME(Event) +@interface SentryEvent : NSObject + +/** + * This will be set by the initializer. + */ +@property (nonatomic, strong) SentryId *eventId; + +/** + * Message of the event. + */ +@property (nonatomic, strong) SentryMessage *_Nullable message; + +/** + * The error of the event. This property adds convenience to access the error directly in + * beforeSend. This property is not serialized. Instead when preparing the event the SentryClient + * puts the error into exceptions. + */ +@property (nonatomic, copy) NSError *_Nullable error; + +/** + * NSDate of when the event occured + */ +@property (nonatomic, strong) NSDate *_Nullable timestamp; + +/** + * NSDate of when the event started, mostly useful if event type transaction + */ +@property (nonatomic, strong) NSDate *_Nullable startTimestamp; + +/** + * SentryLevel of the event + */ +@property (nonatomic) enum SentryLevel level; + +/** + * Platform this will be used for symbolicating on the server should be "cocoa" + */ +@property (nonatomic, copy) NSString *platform; + +/** + * Define the logger name + */ +@property (nonatomic, copy) NSString *_Nullable logger; + +/** + * Define the server name + */ +@property (nonatomic, copy) NSString *_Nullable serverName; + +/** + * This property will be filled before the event is sent. Do not change it + * otherwise you know what you are doing. + */ +@property (nonatomic, copy) NSString *_Nullable releaseName; + +/** + * This property will be filled before the event is sent. Do not change it + * otherwise you know what you are doing. + */ +@property (nonatomic, copy) NSString *_Nullable dist; + +/** + * The environment used for this event + */ +@property (nonatomic, copy) NSString *_Nullable environment; + +/** + * The current transaction (state) on the crash + */ +@property (nonatomic, copy) NSString *_Nullable transaction; + +/** + * The type of the event, null, default or transaction + */ +@property (nonatomic, copy) NSString *_Nullable type; + +/** + * Arbitrary key:value (string:string ) data that will be shown with the event + */ +@property (nonatomic, strong) NSDictionary *_Nullable tags; + +/** + * Arbitrary additional information that will be sent with the event + */ +@property (nonatomic, strong) NSDictionary *_Nullable extra; + +/** + * Information about the sdk can be something like this. This will be set for + * you Don't touch it if you not know what you are doing. + * + * { + * version: "6.0.1", + * name: "sentry.cocoa", + * integrations: [ + * "react-native" + * ] + * } + */ +@property (nonatomic, strong) NSDictionary *_Nullable sdk; + +/** + * Modules of the event + */ +@property (nonatomic, strong) NSDictionary *_Nullable modules; + +/** + * Set the fingerprint of an event to determine the grouping + */ +@property (nonatomic, strong) NSArray *_Nullable fingerprint; + +/** + * Set the SentryUser for the event + */ +@property (nonatomic, strong) SentryUser *_Nullable user; + +/** + * This object contains meta information, will be set automatically overwrite + * only if you know what you are doing + */ +@property (nonatomic, strong) + NSDictionary *> *_Nullable context; + +/** + * Contains SentryThread if an crash occurred of it's an user reported exception + */ +@property (nonatomic, strong) NSArray *_Nullable threads; + +/** + * General information about the SentryException, usually there is only one + * exception in the array + */ +@property (nonatomic, strong) NSArray *_Nullable exceptions; + +/** + * Separate SentryStacktrace that can be sent with the event, besides threads + */ +@property (nonatomic, strong) SentryStacktrace *_Nullable stacktrace; + +/** + * Containing images loaded during runtime + */ +@property (nonatomic, strong) NSArray *_Nullable debugMeta; + +/** + * This contains all breadcrumbs available at the time when the event + * occurred/will be sent + */ +@property (nonatomic, strong) NSArray *_Nullable breadcrumbs; + +/** + * Init an SentryEvent will set all needed fields by default + * @return SentryEvent + */ +- (instancetype)init; + +/** + * Init an SentryEvent will set all needed fields by default + * @param level SentryLevel + * @return SentryEvent + */ +- (instancetype)initWithLevel:(enum SentryLevel)level NS_DESIGNATED_INITIALIZER; + +/** + * Initializes a SentryEvent with an NSError and sets the level to SentryLevelError. + * + * @param error The error of the event. + * + * @return The initialized SentryEvent. + */ +- (instancetype)initWithError:(NSError *)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryException.h b/Pods/Sentry/Sources/Sentry/Public/SentryException.h new file mode 100644 index 00000000..37eac9d8 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryException.h @@ -0,0 +1,54 @@ +#import + +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryStacktrace, SentryMechanism; + +NS_SWIFT_NAME(Exception) +@interface SentryException : NSObject +SENTRY_NO_INIT + +/** + * The name of the exception + */ +@property (nonatomic, copy) NSString *value; + +/** + * Type of the exception + */ +@property (nonatomic, copy) NSString *type; + +/** + * Additional information about the exception + */ +@property (nonatomic, strong) SentryMechanism *_Nullable mechanism; + +/** + * Can be set to define the module + */ +@property (nonatomic, copy) NSString *_Nullable module; + +/** + * An optional value which refers to a thread in `SentryEvent.threads`. + */ +@property (nonatomic, copy) NSNumber *_Nullable threadId; + +/** + * Stacktrace containing frames of this exception. + */ +@property (nonatomic, strong) SentryStacktrace *_Nullable stacktrace; + +/** + * Initialize an SentryException with value and type + * @param value String + * @param type String + * @return SentryException + */ +- (instancetype)initWithValue:(NSString *)value type:(NSString *)type; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryFrame.h b/Pods/Sentry/Sources/Sentry/Public/SentryFrame.h new file mode 100644 index 00000000..6dcb46f4 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryFrame.h @@ -0,0 +1,71 @@ +#import + +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(Frame) +@interface SentryFrame : NSObject + +/** + * SymbolAddress of the frame + */ +@property (nonatomic, copy) NSString *_Nullable symbolAddress; + +/** + * Filename is used only for reporting JS frames + */ +@property (nonatomic, copy) NSString *_Nullable fileName; + +/** + * Function name of the frame + */ +@property (nonatomic, copy) NSString *_Nullable function; + +/** + * Module of the frame, mostly unused + */ +@property (nonatomic, copy) NSString *_Nullable module; + +/** + * Corresponding package + */ +@property (nonatomic, copy) NSString *_Nullable package; + +/** + * ImageAddress if the image related to the frame + */ +@property (nonatomic, copy) NSString *_Nullable imageAddress; + +/** + * Set the platform for the individual frame, will use platform of the event. + * Mostly used for react native crashes. + */ +@property (nonatomic, copy) NSString *_Nullable platform; + +/** + * InstructionAddress of the frame + */ +@property (nonatomic, copy) NSString *_Nullable instructionAddress; + +/** + * User for react native, will be ignored for cocoa frames + */ +@property (nonatomic, copy) NSNumber *_Nullable lineNumber; + +/** + * User for react native, will be ignored for cocoa frames + */ +@property (nonatomic, copy) NSNumber *_Nullable columnNumber; + +/** + * Determines if the Frame is inApp or not + */ +@property (nonatomic, copy) NSNumber *_Nullable inApp; + +- (instancetype)init; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryHub.h b/Pods/Sentry/Sources/Sentry/Public/SentryHub.h new file mode 100644 index 00000000..e1841359 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryHub.h @@ -0,0 +1,263 @@ +#import "SentryDefines.h" +#import "SentryIntegrationProtocol.h" +#import "SentrySpanProtocol.h" + +@class SentryEvent, SentryClient, SentryScope, SentrySession, SentryUser, SentryBreadcrumb, + SentryId, SentryUserFeedback, SentryEnvelope, SentryTransactionContext; + +NS_ASSUME_NONNULL_BEGIN +@interface SentryHub : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithClient:(SentryClient *_Nullable)client + andScope:(SentryScope *_Nullable)scope; + +/** + * Since there's no scope stack, single hub instance, we keep the session here. + */ +@property (nonatomic, readonly, strong) SentrySession *_Nullable session; + +/** + * Starts a new session. If there's a running session, it ends it before starting the new one. + */ +- (void)startSession; + +/** + * Ends the current session. + */ +- (void)endSession; + +/** + * Ends the current session with the given timestamp. + * + * @param timestamp The timestamp to end the session with. + */ +- (void)endSessionWithTimestamp:(NSDate *)timestamp; + +@property (nonatomic, strong) + NSMutableArray *> *installedIntegrations; + +/** + * Captures a manually created event and sends it to Sentry. + * + * @param event The event to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); + +/** + * Captures a manually created event and sends it to Sentry. + * + * @param event The event to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureEvent:(SentryEvent *)event + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(event:scope:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param name The transaction name. + * @param operation Short code identifying the type of operation the span is measuring. + * + * @return The created transaction. + */ +- (id)startTransactionWithName:(NSString *)name + operation:(NSString *)operation + NS_SWIFT_NAME(startTransaction(name:operation:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param name The transaction name. + * @param operation Short code identifying the type of operation the span is measuring. + * @param bindToScope Indicates whether the new transaction should be bind to the scope. + * + * @return The created transaction. + */ +- (id)startTransactionWithName:(NSString *)name + operation:(NSString *)operation + bindToScope:(BOOL)bindToScope + NS_SWIFT_NAME(startTransaction(name:operation:bindToScope:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param transactionContext The transaction context. + * + * @return The created transaction. + */ +- (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + NS_SWIFT_NAME(startTransaction(transactionContext:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param transactionContext The transaction context. + * @param bindToScope Indicates whether the new transaction should be bind to the scope. + * + * @return The created transaction. + */ +- (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + bindToScope:(BOOL)bindToScope + NS_SWIFT_NAME(startTransaction(transactionContext:bindToScope:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param transactionContext The transaction context. + * @param bindToScope Indicates whether the new transaction should be bind to the scope. + * @param customSamplingContext Additional information about the sampling context. + * + * @return The created transaction. + */ +- (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + bindToScope:(BOOL)bindToScope + customSamplingContext:(NSDictionary *)customSamplingContext + NS_SWIFT_NAME(startTransaction(transactionContext:bindToScope:customSamplingContext:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param transactionContext The transaction context. + * @param customSamplingContext Additional information about the sampling context. + * + * @return The created transaction. + */ +- (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + customSamplingContext:(NSDictionary *)customSamplingContext + NS_SWIFT_NAME(startTransaction(transactionContext:customSamplingContext:)); + +/** + * Captures an error event and sends it to Sentry. + * + * @param error The error to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); + +/** + * Captures an error event and sends it to Sentry. + * + * @param error The error to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureError:(NSError *)error + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); + +/** + * Captures an exception event and sends it to Sentry. + * + * @param exception The exception to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); + +/** + * Captures an exception event and sends it to Sentry. + * + * @param exception The exception to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureException:(NSException *)exception + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); + +/** + * Captures a message event and sends it to Sentry. + * + * @param message The message to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); + +/** + * Captures a message event and sends it to Sentry. + * + * @param message The message to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ +- (SentryId *)captureMessage:(NSString *)message + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); + +/** + * Captures a manually created user feedback and sends it to Sentry. + * + * @param userFeedback The user feedback to send to Sentry. + */ +- (void)captureUserFeedback:(SentryUserFeedback *)userFeedback + NS_SWIFT_NAME(capture(userFeedback:)); + +/** + * Use this method to modify the Scope of the Hub. The SDK uses the Scope to attach + * contextual data to events. + * + * @param callback The callback for configuring the Scope of the Hub. + */ +- (void)configureScope:(void (^)(SentryScope *scope))callback; + +/** + * Adds a breadcrumb to the Scope of the Hub. + * + * @param crumb The Breadcrumb to add to the Scope of the Hub. + */ +- (void)addBreadcrumb:(SentryBreadcrumb *)crumb; + +/** + * Returns a client if there is a bound client on the Hub. + */ +- (SentryClient *_Nullable)getClient; + +/** + * Returns either the current scope and if nil a new one. + */ +@property (nonatomic, readonly, strong) SentryScope *scope; + +/** + * Binds a different client to the hub. + */ +- (void)bindClient:(SentryClient *_Nullable)client; + +/** + * Checks if integration is activated for bound client and returns it. + */ +- (id _Nullable)getIntegration:(NSString *)integrationName; + +/** + * Checks if a specific Integration (`integrationClass`) has been installed. + * + * @return BOOL If instance of `integrationClass` exists within `SentryHub.installedIntegrations`. + */ +- (BOOL)isIntegrationInstalled:(Class)integrationClass; + +/** + * Set user to the Scope of the Hub. + * + * @param user The user to set to the Scope. + */ +- (void)setUser:(SentryUser *_Nullable)user; + +/** + * The SDK reserves this method for hybrid SDKs, which use it to capture events. + * + * @discussion We increase the session error count if an envelope is passed in containing an + * event with event.level error or higher. Ideally, we would check the mechanism and/or exception + * list, like the Java and Python SDK do this, but this would require full deserialization of the + * event. + */ +- (void)captureEnvelope:(SentryEnvelope *)envelope NS_SWIFT_NAME(capture(envelope:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryId.h b/Pods/Sentry/Sources/Sentry/Public/SentryId.h new file mode 100644 index 00000000..dba269d2 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryId.h @@ -0,0 +1,46 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A wrapper around UUID. + * UUIDs are declared as either 32 character hexadecimal strings without dashes + * "12c2d058d58442709aa2eca08bf20986", or 36 character strings with dashes + * "12c2d058-d584-4270-9aa2-eca08bf20986". It is recommended to omit dashes and use UUID v4 in all + * cases. + */ +@interface SentryId : NSObject + +/** + * Creates a SentryId with a random SentryId. + */ +- (instancetype)init; + +/** + * Creates a SentryId with the given UUID. + */ +- (instancetype)initWithUUID:(NSUUID *)uuid; + +/** + * Creates a SentryId from a 32 character hexadecimal string without dashes such as + * "12c2d058d58442709aa2eca08bf20986" or a 36 character hexadecimal string such as such as + * "12c2d058-d584-4270-9aa2-eca08bf20986". + * + * @return SentryId.empty for invalid strings. + */ +- (instancetype)initWithUUIDString:(NSString *)string; + +/** + * Returns a 32 lowercase character hexadecimal string description of the SentryId, such as + * "12c2d058d58442709aa2eca08bf20986". + */ +@property (readonly, copy) NSString *sentryIdString; + +/** + * A SentryId with an empty UUID "00000000000000000000000000000000". + */ +@property (class, nonatomic, readonly, strong) SentryId *empty; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryIntegrationProtocol.h b/Pods/Sentry/Sources/Sentry/Public/SentryIntegrationProtocol.h new file mode 100644 index 00000000..1f4bc663 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryIntegrationProtocol.h @@ -0,0 +1,23 @@ +#import + +#import "SentryDefines.h" +#import "SentryOptions.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol SentryIntegrationProtocol + +/** + * Installs the integration and returns YES if successful. + */ +- (void)installWithOptions:(SentryOptions *)options; + +/** + * Uninstalls the integration. + */ +@optional +- (void)uninstall; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryMechanism.h b/Pods/Sentry/Sources/Sentry/Public/SentryMechanism.h new file mode 100644 index 00000000..3a1bd339 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryMechanism.h @@ -0,0 +1,59 @@ +#import + +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryNSError, SentryMechanismMeta; + +NS_SWIFT_NAME(Mechanism) +@interface SentryMechanism : NSObject +SENTRY_NO_INIT + +/** + * A unique identifier of this mechanism determining rendering and processing + * of the mechanism data + */ +@property (nonatomic, copy) NSString *type; + +/** + * Human readable description of the error mechanism and a possible hint on how to solve this error. + * We can't use description as it overlaps with NSObject.description. + */ +@property (nonatomic, copy) NSString *_Nullable desc; + +/** + * Arbitrary extra data that might help the user understand the error thrown by + * this mechanism + */ +@property (nonatomic, strong) NSDictionary *_Nullable data; + +/** + * Flag indicating whether the exception has been handled by the user + * (e.g. via ``try..catch``) + */ +@property (nonatomic, copy) NSNumber *_Nullable handled; + +/** + * Fully qualified URL to an online help resource, possible + * interpolated with error parameters + */ +@property (nonatomic, copy) NSString *_Nullable helpLink; + +/** + * Information from the operating system or runtime on the exception + * mechanism. + */ +@property (nullable, nonatomic, strong) SentryMechanismMeta *meta; + +/** + * Initialize an SentryMechanism with a type + * @param type String + * @return SentryMechanism + */ +- (instancetype)initWithType:(NSString *)type; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryMechanismMeta.h b/Pods/Sentry/Sources/Sentry/Public/SentryMechanismMeta.h new file mode 100644 index 00000000..891f9794 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryMechanismMeta.h @@ -0,0 +1,38 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" +#import + +@class SentryNSError; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The mechanism metadata usually carries error codes reported by the runtime or operating system, + * along with a platform-dependent interpretation of these codes. + * + * See https://develop.sentry.dev/sdk/event-payloads/exception/#meta-information. + */ +NS_SWIFT_NAME(MechanismMeta) +@interface SentryMechanismMeta : NSObject + +- (instancetype)init; + +/** + * Information on the POSIX signal. On Apple systems, signals also carry a code in addition to the + * signal number describing the signal in more detail. On Linux, this code does not exist. + */ +@property (nullable, nonatomic, strong) NSDictionary *signal; + +/** + * A Mach Exception on Apple systems comprising a code triple and optional descriptions. + */ +@property (nullable, nonatomic, strong) NSDictionary *machException; + +/** + * Sentry uses the NSErrors domain and code for grouping. Only domain and code are serialized. + */ +@property (nullable, nonatomic, strong) SentryNSError *error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryMessage.h b/Pods/Sentry/Sources/Sentry/Public/SentryMessage.h new file mode 100644 index 00000000..bd61581b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryMessage.h @@ -0,0 +1,43 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Carries a log message that describes an event or error. Optionally, it can carry a format string + * and structured parameters. This can help to group similar messages into the same issue. + * + * For more info checkout: https://develop.sentry.dev/sdk/event-payloads/message/ + */ +@interface SentryMessage : NSObject +SENTRY_NO_INIT + +/** + * Returns a SentyMessage with setting formatted. + * + * @param formatted The fully formatted message. If missing, Sentry will try to interpolate the + * message. It must not exceed 8192 characters. Longer messages will be truncated. + */ +- (instancetype)initWithFormatted:(NSString *)formatted; + +/** + * The fully formatted message. If missing, Sentry will try to interpolate the message. It must not + * exceed 8192 characters. Longer messages will be truncated. + */ +@property (nonatomic, readonly, copy) NSString *formatted; + +/** + * The raw message string (uninterpolated). It must not exceed 8192 characters. Longer messages will + * be truncated. + */ +@property (nonatomic, copy) NSString *_Nullable message; + +/** + * A list of formatting parameters for the raw message. + */ +@property (nonatomic, strong) NSArray *_Nullable params; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryNSError.h b/Pods/Sentry/Sources/Sentry/Public/SentryNSError.h new file mode 100644 index 00000000..af74383b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryNSError.h @@ -0,0 +1,33 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Sentry representation of an NSError to send to Sentry. + */ +@interface SentryNSError : NSObject +SENTRY_NO_INIT + +/** + * The domain of an NSError. + */ +@property (nonatomic, copy) NSString *domain; + +/** + * The error code of an NSError + */ +@property (nonatomic, assign) NSInteger code; + +/** + * Initializes SentryNSError and sets the domain and code. + * + * @param domain The domain of an NSError. + * @param code The error code of an NSError. + */ +- (instancetype)initWithDomain:(NSString *)domain code:(NSInteger)code; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryOptions.h b/Pods/Sentry/Sources/Sentry/Public/SentryOptions.h new file mode 100644 index 00000000..c4b1f73f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryOptions.h @@ -0,0 +1,208 @@ +#import "SentryDefines.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryDsn, SentrySdkInfo; + +NS_SWIFT_NAME(Options) +@interface SentryOptions : NSObject + +/** + * Init SentryOptions. + * @param options Options dictionary + * @return SentryOptions + */ +- (_Nullable instancetype)initWithDict:(NSDictionary *)options + didFailWithError:(NSError *_Nullable *_Nullable)error; + +/** + * The DSN tells the SDK where to send the events to. If this value is not provided, the SDK will + * not send any events. + */ +@property (nullable, nonatomic, strong) NSString *dsn; + +/** + * The parsed internal DSN. + */ +@property (nullable, nonatomic, strong) SentryDsn *parsedDsn; + +/** + * Turns debug mode on or off. If debug is enabled SDK will attempt to print out useful debugging + * information if something goes wrong. Default is disabled. + */ +@property (nonatomic, assign) BOOL debug; + +/** + * Minimum LogLevel to be used if debug is enabled. Default is debug. + */ +@property (nonatomic, assign) SentryLevel diagnosticLevel; + +/** + * This property will be filled before the event is sent. + */ +@property (nullable, nonatomic, copy) NSString *releaseName; + +/** + * This property will be filled before the event is sent. + */ +@property (nullable, nonatomic, copy) NSString *dist; + +/** + * The environment used for this event + */ +@property (nullable, nonatomic, copy) NSString *environment; + +/** + * Specifies wether this SDK should send events to Sentry. If set to NO events will be + * dropped in the client and not sent to Sentry. Default is YES. + */ +@property (nonatomic, assign) BOOL enabled; + +/** + * How many breadcrumbs do you want to keep in memory? + * Default is 100. + */ +@property (nonatomic, assign) NSUInteger maxBreadcrumbs; + +/** + * The maximum number of envelopes to keep in cache. Default is 30. + */ +@property (nonatomic, assign) NSUInteger maxCacheItems; + +/** + * This block can be used to modify the event before it will be serialized and + * sent + */ +@property (nullable, nonatomic, copy) SentryBeforeSendEventCallback beforeSend; + +/** + * This block can be used to modify the event before it will be serialized and + * sent + */ +@property (nullable, nonatomic, copy) SentryBeforeBreadcrumbCallback beforeBreadcrumb; + +/** + * This gets called shortly after the initialization of the SDK when the last program execution + * terminated with a crash. It is not guaranteed that this is called on the main thread. + * + * @discussion This callback is only executed once during the entire run of the program to avoid + * multiple callbacks if there are multiple crash events to send. This can happen when the program + * terminates with a crash before the SDK can send the crash event. You can look into beforeSend if + * you prefer a callback for every event. + */ +@property (nullable, nonatomic, copy) SentryOnCrashedLastRunCallback onCrashedLastRun; + +/** + * Array of integrations to install. + */ +@property (nullable, nonatomic, copy) NSArray *integrations; + +/** + * Array of default integrations. Will be used if integrations are nil + */ ++ (NSArray *)defaultIntegrations; + +/** + * Defines the sample rate of SentryClient, should be a float between 0.0 + * and 1.0. valid settings are 0.0 - 1.0 and nil + */ +@property (nullable, nonatomic, copy) NSNumber *sampleRate; + +/** + * Whether to enable automatic session tracking or not. Default is YES. + */ +@property (nonatomic, assign) BOOL enableAutoSessionTracking; + +/** + * Whether to enable to enable out of memory tracking or not. Default is YES. + */ +@property (nonatomic, assign) BOOL enableOutOfMemoryTracking; + +/** + * The interval to end a session if the App goes to the background. + */ +@property (nonatomic, assign) NSUInteger sessionTrackingIntervalMillis; + +/** + * When enabled, stack traces are automatically attached to all messages logged. Stack traces are + * always attached to exceptions but when this is set stack traces are also sent with messages. + * Stack traces are only attached for the current thread. + * + * This feature is enabled by default. + */ +@property (nonatomic, assign) BOOL attachStacktrace; + +/** + * Describes the Sentry SDK and its configuration used to capture and transmit an event. + */ +@property (nonatomic, readonly, strong) SentrySdkInfo *sdkInfo; + +/** + * The maximum size for each attachment in bytes. Default is 20 MiB / 20 * 1024 * 1024 bytes. + * + * Please also check the maximum attachment size of relay to make sure your attachments don't get + * discarded there: https://docs.sentry.io/product/relay/options/ + */ +@property (nonatomic, assign) NSUInteger maxAttachmentSize; + +/** + * When enabled, the SDK sends personal identifiable along with events. The default is + * NO. + * + * @discussion When the user of an event doesn't contain an IP address, the SDK sets it to + * {{auto}} to instruct the server to use the connection IP address as the user + * address. + */ +@property (nonatomic, assign) BOOL sendDefaultPii; + +/** + * Indicates the percentage of the tracing data that is collected. + * Setting this to 0 or NIL discards all trace data, 1.0 collects all trace data, + * 0.01 collects 1% of all trace data. + */ +@property (nullable, nonatomic, strong) NSNumber *tracesSampleRate; + +/** + * A callback to a user defined traces sampler function. + * Returning 0 or NIL discards all trace data, 1.0 collects all trace data, + * 0.01 collects 1% of all trace data. + */ +@property (nullable, nonatomic) SentryTracesSamplerCallback tracesSampler; + +/** + * A list of string prefixes of framework names that belong to the app. This option takes precedence + * over inAppExcludes. Per default this contains CFBundleExecutable to mark it as inApp. + */ +@property (nonatomic, readonly, copy) NSArray *inAppIncludes; + +/** + * Adds an item to the list of inAppIncludes. + * + * @param inAppInclude The prefix of the framework name. + */ +- (void)addInAppInclude:(NSString *)inAppInclude; + +/** + * A list of string prefixes of framework names that do not belong to the app, but rather to + * third-party frameworks. Frameworks considered not part of the app will be hidden from stack + * traces by default. + * + * This option can be overridden using inAppIncludes. + */ +@property (nonatomic, readonly, copy) NSArray *inAppExcludes; + +/** + * Adds an item to the list of inAppExcludes. + * + * @param inAppExclude The prefix of the frameworks name. + */ +- (void)addInAppExclude:(NSString *)inAppExclude; + +/** + * Set as delegate on the NSURLSession used for all network data-transfer tasks performed by Sentry. + */ +@property (nullable, nonatomic, weak) id urlSessionDelegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySDK.h b/Pods/Sentry/Sources/Sentry/Public/SentrySDK.h new file mode 100644 index 00000000..84fc9e92 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySDK.h @@ -0,0 +1,311 @@ +#import + +#import "SentryDefines.h" + +@protocol SentrySpan; + +@class SentryHub, SentryOptions, SentryEvent, SentryBreadcrumb, SentryScope, SentryUser, SentryId, + SentryUserFeedback, SentryTransactionContext; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The main entry point for the SentrySDK. + * + * We recommend using `[Sentry startWithConfigureOptions]` to initialize Sentry. + */ +@interface SentrySDK : NSObject +SENTRY_NO_INIT + +/** + * The current active transaction or span bound to the scope. + */ +@property (nullable, class, nonatomic, readonly) id span; + +/** + * Inits and configures Sentry (SentryHub, SentryClient) and sets up all integrations. + */ ++ (void)startWithOptions:(NSDictionary *)optionsDict + NS_SWIFT_NAME(start(options:)); + +/** + * Inits and configures Sentry (SentryHub, SentryClient) and sets up all integrations. + */ ++ (void)startWithOptionsObject:(SentryOptions *)options NS_SWIFT_NAME(start(options:)); + +/** + * Inits and configures Sentry (SentryHub, SentryClient) and sets up all integrations. Make sure to + * set a valid DSN. + */ ++ (void)startWithConfigureOptions:(void (^)(SentryOptions *options))configureOptions + NS_SWIFT_NAME(start(configureOptions:)); + +/** + * Captures a manually created event and sends it to Sentry. + * + * @param event The event to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); + +/** + * Captures a manually created event and sends it to Sentry. Only the data in this scope object will + * be added to the event. The global scope will be ignored. + * + * @param event The event to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureEvent:(SentryEvent *)event + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(event:scope:)); + +/** + * Captures a manually created event and sends it to Sentry. Maintains the global scope but mutates + * scope data for only this call. + * + * @param event The event to send to Sentry. + * @param block The block mutating the scope only for this call. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureEvent:(SentryEvent *)event + withScopeBlock:(void (^)(SentryScope *scope))block + NS_SWIFT_NAME(capture(event:block:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param name The transaction name. + * @param operation Short code identifying the type of operation the span is measuring. + * + * @return The created transaction. + */ ++ (id)startTransactionWithName:(NSString *)name + operation:(NSString *)operation + NS_SWIFT_NAME(startTransaction(name:operation:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param name The transaction name. + * @param operation Short code identifying the type of operation the span is measuring. + * @param bindToScope Indicates whether the new transaction should be bind to the scope. + * + * @return The created transaction. + */ ++ (id)startTransactionWithName:(NSString *)name + operation:(NSString *)operation + bindToScope:(BOOL)bindToScope + NS_SWIFT_NAME(startTransaction(name:operation:bindToScope:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param transactionContext The transaction context. + * + * @return The created transaction. + */ ++ (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + NS_SWIFT_NAME(startTransaction(transactionContext:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param transactionContext The transaction context. + * @param bindToScope Indicates whether the new transaction should be bind to the scope. + * + * @return The created transaction. + */ ++ (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + bindToScope:(BOOL)bindToScope + NS_SWIFT_NAME(startTransaction(transactionContext:bindToScope:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param transactionContext The transaction context. + * @param bindToScope Indicates whether the new transaction should be bind to the scope. + * @param customSamplingContext Additional information about the sampling context. + * + * @return The created transaction. + */ ++ (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + bindToScope:(BOOL)bindToScope + customSamplingContext:(NSDictionary *)customSamplingContext + NS_SWIFT_NAME(startTransaction(transactionContext:bindToScope:customSamplingContext:)); + +/** + * Creates a transaction, binds it to the hub and returns the instance. + * + * @param transactionContext The transaction context. + * @param customSamplingContext Additional information about the sampling context. + * + * @return The created transaction. + */ ++ (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + customSamplingContext:(NSDictionary *)customSamplingContext + NS_SWIFT_NAME(startTransaction(transactionContext:customSamplingContext:)); + +/** + * Captures an error event and sends it to Sentry. + * + * @param error The error to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); + +/** + * Captures an error event and sends it to Sentry. Only the data in this scope object will be added + * to the event. The global scope will be ignored. + * + * @param error The error to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureError:(NSError *)error + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); + +/** + * Captures an error event and sends it to Sentry. Maintains the global scope but mutates scope data + * for only this call. + * + * @param error The error to send to Sentry. + * @param block The block mutating the scope only for this call. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureError:(NSError *)error + withScopeBlock:(void (^)(SentryScope *scope))block + NS_SWIFT_NAME(capture(error:block:)); + +/** + * Captures an exception event and sends it to Sentry. + * + * @param exception The exception to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); + +/** + * Captures an exception event and sends it to Sentry. Only the data in this scope object will be + * added to the event. The global scope will be ignored. + * + * @param exception The exception to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureException:(NSException *)exception + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); + +/** + * Captures an exception event and sends it to Sentry. Maintains the global scope but mutates scope + * data for only this call. + * + * @param exception The exception to send to Sentry. + * @param block The block mutating the scope only for this call. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureException:(NSException *)exception + withScopeBlock:(void (^)(SentryScope *scope))block + NS_SWIFT_NAME(capture(exception:block:)); + +/** + * Captures a message event and sends it to Sentry. + * + * @param message The message to send to Sentry. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); + +/** + * Captures a message event and sends it to Sentry. Only the data in this scope object will be added + * to the event. The global scope will be ignored. + * + * @param message The message to send to Sentry. + * @param scope The scope containing event metadata. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureMessage:(NSString *)message + withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); + +/** + * Captures a message event and sends it to Sentry. Maintains the global scope but mutates scope + * data for only this call. + * + * @param message The message to send to Sentry. + * @param block The block mutating the scope only for this call. + * + * @return The SentryId of the event or SentryId.empty if the event is not sent. + */ ++ (SentryId *)captureMessage:(NSString *)message + withScopeBlock:(void (^)(SentryScope *scope))block + NS_SWIFT_NAME(capture(message:block:)); + +/** + * Captures a manually created user feedback and sends it to Sentry. + * + * @param userFeedback The user feedback to send to Sentry. + */ ++ (void)captureUserFeedback:(SentryUserFeedback *)userFeedback + NS_SWIFT_NAME(capture(userFeedback:)); + +/** + * Adds a Breadcrumb to the current Scope of the current Hub. If the total number of breadcrumbs + * exceeds the `SentryOptions.maxBreadcrumbs`, the SDK removes the oldest breadcrumb. + * + * @param crumb The Breadcrumb to add to the current Scope of the current Hub. + */ ++ (void)addBreadcrumb:(SentryBreadcrumb *)crumb NS_SWIFT_NAME(addBreadcrumb(crumb:)); + +/** + * Use this method to modify the current Scope of the current Hub. The SDK uses the Scope to attach + * contextual data to events. + * + * @param callback The callback for configuring the current Scope of the current Hub. + */ ++ (void)configureScope:(void (^)(SentryScope *scope))callback; + +/** + * Checks if the last program execution terminated with a crash. + */ +@property (nonatomic, class, readonly) BOOL crashedLastRun; + +/** + * Set user to the current Scope of the current Hub. + * + * @param user The user to set to the current Scope. + */ ++ (void)setUser:(SentryUser *_Nullable)user; + +/** + * Starts a new session. If there's a running session, it ends it before starting the new one. + */ ++ (void)startSession; + +/** + * Ends the current session. + */ ++ (void)endSession; + +/** + * This forces a crash, useful to test the SentryCrash integration + */ ++ (void)crash; + +/** + * Closes the SDK and uninstalls all the integrations. + */ ++ (void)close; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySampleDecision.h b/Pods/Sentry/Sources/Sentry/Public/SentrySampleDecision.h new file mode 100644 index 00000000..92c70758 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySampleDecision.h @@ -0,0 +1,22 @@ +#import +/** + * Trace sample decision flag. + */ +typedef NS_ENUM(NSUInteger, SentrySampleDecision) { + /** + * Used when the decision to sample a trace should be postponed. + */ + kSentrySampleDecisionUndecided, + + /** + * The trace should be sampled. + */ + kSentrySampleDecisionYes, + + /** + * The trace should not be sampled. + */ + kSentrySampleDecisionNo +}; + +static NSString *_Nonnull const SentrySampleDecisionNames[] = { @"undecided", @"true", @"false" }; diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySamplingContext.h b/Pods/Sentry/Sources/Sentry/Public/SentrySamplingContext.h new file mode 100644 index 00000000..dd16e714 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySamplingContext.h @@ -0,0 +1,38 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@class SentryTransactionContext; + +NS_SWIFT_NAME(SamplingContext) +@interface SentrySamplingContext : NSObject + +/** + * Transaction context. + */ +@property (nonatomic, readonly) SentryTransactionContext *transactionContext; + +/** + * Custom data used for sampling. + */ +@property (nullable, nonatomic, readonly) NSDictionary *customSamplingContext; + +/** + * Init a SentryTransactionSamplingContext. + * + * @param transactionContext The context of the transaction being sampled. + */ +- (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext; + +/** + * Init a SentryTransactionSamplingContext. + * + * @param transactionContext The context of the transaction being sampled. + * @param customSamplingContext Custom data used for sampling. + */ +- (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext + customSamplingContext:(NSDictionary *)customSamplingContext; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryScope.h b/Pods/Sentry/Sources/Sentry/Public/SentryScope.h new file mode 100644 index 00000000..04806bf7 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryScope.h @@ -0,0 +1,138 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" +#import "SentrySpanProtocol.h" + +@class SentryUser, SentrySession, SentryOptions, SentryBreadcrumb, SentryAttachment; + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(Scope) +@interface SentryScope : NSObject + +/** + * Returns current Span or Transaction. + * + * @return current Span or Transaction or null if transaction has not been set. + */ +@property (nullable, nonatomic, strong) id span; + +- (instancetype)initWithMaxBreadcrumbs:(NSInteger)maxBreadcrumbs NS_DESIGNATED_INITIALIZER; +- (instancetype)init; +- (instancetype)initWithScope:(SentryScope *)scope; + +/** + * Set global user -> thus will be sent with every event + */ +- (void)setUser:(SentryUser *_Nullable)user; + +/** + * Set a global tag. Tags are searchable key/value string pairs attached to + * every event. + */ +- (void)setTagValue:(NSString *)value forKey:(NSString *)key NS_SWIFT_NAME(setTag(value:key:)); + +/** + * Remove the tag for the specified key. + */ +- (void)removeTagForKey:(NSString *)key NS_SWIFT_NAME(removeTag(key:)); + +/** + * Set global tags. Tags are searchable key/value string pairs attached to every + * event. + */ +- (void)setTags:(NSDictionary *_Nullable)tags; + +/** + * Set global extra -> these will be sent with every event + */ +- (void)setExtras:(NSDictionary *_Nullable)extras; + +/** + * Set global extra -> these will be sent with every event + */ +- (void)setExtraValue:(id _Nullable)value + forKey:(NSString *)key NS_SWIFT_NAME(setExtra(value:key:)); + +/** + * Remove the extra for the specified key. + */ +- (void)removeExtraForKey:(NSString *)key NS_SWIFT_NAME(removeExtra(key:)); + +/** + * Set dist in the scope + */ +- (void)setDist:(NSString *_Nullable)dist; + +/** + * Set environment in the scope + */ +- (void)setEnvironment:(NSString *_Nullable)environment; + +/** + * Sets the fingerprint in the scope + */ +- (void)setFingerprint:(NSArray *_Nullable)fingerprint; + +/** + * Sets the level in the scope + */ +- (void)setLevel:(enum SentryLevel)level; + +/** + * Add a breadcrumb to the scope + */ +- (void)addBreadcrumb:(SentryBreadcrumb *)crumb; + +/** + * Clears all breadcrumbs in the scope + */ +- (void)clearBreadcrumbs; + +/** + * Serializes the Scope to JSON + */ +- (NSDictionary *)serialize; + +/** + * Adds the Scope to the event + */ +- (SentryEvent *__nullable)applyToEvent:(SentryEvent *)event + maxBreadcrumb:(NSUInteger)maxBreadcrumbs; + +- (void)applyToSession:(SentrySession *)session; + +/** + * Sets context values which will overwrite SentryEvent.context when event is + * "enriched" with scope before sending event. + */ +- (void)setContextValue:(NSDictionary *)value + forKey:(NSString *)key NS_SWIFT_NAME(setContext(value:key:)); + +/** + * Remove the context for the specified key. + */ +- (void)removeContextForKey:(NSString *)key NS_SWIFT_NAME(removeContext(key:)); + +/** + * Adds an attachment to the Scope's list of attachments. The SDK adds the attachment to every event + * sent to Sentry. + * + * @param attachment The attachment to add to the Scope's list of attachments. + */ +- (void)addAttachment:(SentryAttachment *)attachment; + +/** + * Clears the current Scope + */ +- (void)clear; + +/** + * Mutates the current transaction atomically. + * + * @param callback the SentrySpanCallback. + */ +- (void)useSpan:(SentrySpanCallback)callback; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySdkInfo.h b/Pods/Sentry/Sources/Sentry/Public/SentrySdkInfo.h new file mode 100644 index 00000000..3c8af3f2 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySdkInfo.h @@ -0,0 +1,38 @@ +#import "SentrySerializable.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Describes the Sentry SDK and its configuration used to capture and transmit an event. + * + * Both name and version are required. + * + * For more info checkout: https://develop.sentry.dev/sdk/event-payloads/sdk/ + */ +@interface SentrySdkInfo : NSObject +SENTRY_NO_INIT + +/** + * The name of the SDK. + * + * Examples: sentry.cocoa, sentry.cocoa.vapor, ... + */ +@property (nonatomic, readonly, copy) NSString *name; + +/** + * The version of the SDK. It should have the Semantic Versioning format MAJOR.MINOR.PATCH, without + * any prefix (no v or anything else in front of the major version number). + * + * Examples: 0.1.0, 1.0.0, 2.0.0-beta0 + */ +@property (nonatomic, readonly, copy) NSString *version; + +- (instancetype)initWithName:(NSString *)name + andVersion:(NSString *)version NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithDict:(NSDictionary *)dict; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySerializable.h b/Pods/Sentry/Sources/Sentry/Public/SentrySerializable.h new file mode 100644 index 00000000..4e092d9a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySerializable.h @@ -0,0 +1,18 @@ +#import + +#import "SentryDefines.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol SentrySerializable +SENTRY_NO_INIT + +/** + * Serialize the contents of the object into an NSDictionary. Make to copy all properties of the + * original object so modifications to it don't have an impact on the serialized NSDictionary. + */ +- (NSDictionary *)serialize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySession.h b/Pods/Sentry/Sources/Sentry/Public/SentrySession.h new file mode 100644 index 00000000..570591c8 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySession.h @@ -0,0 +1,56 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" + +@class SentryUser; + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, SentrySessionStatus) { + kSentrySessionStatusOk = 0, + kSentrySessionStatusExited = 1, + kSentrySessionStatusCrashed = 2, + kSentrySessionStatusAbnormal = 3, +}; + +@interface SentrySession : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithReleaseName:(NSString *)releaseName; + +/** + * Initializes SentrySession from a JSON object. + * + * @param jsonObject The jsonObject containing the session. + * + * @return The SentrySession or nil if the JSONObject contains an error. + */ +- (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject; + +- (void)endSessionExitedWithTimestamp:(NSDate *)timestamp; +- (void)endSessionCrashedWithTimestamp:(NSDate *)timestamp; +- (void)endSessionAbnormalWithTimestamp:(NSDate *)timestamp; + +- (void)incrementErrors; + +@property (nonatomic, readonly, strong) NSUUID *sessionId; +@property (nonatomic, readonly, strong) NSDate *started; +@property (nonatomic, readonly) enum SentrySessionStatus status; +@property (nonatomic, readonly) NSUInteger errors; +@property (nonatomic, readonly) NSUInteger sequence; +@property (nonatomic, readonly, strong) NSString *distinctId; +/** + We can't use init because it overlaps with NSObject.init + */ +@property (nonatomic, readonly, copy) NSNumber *_Nullable flagInit; +@property (nonatomic, readonly, strong) NSDate *_Nullable timestamp; +@property (nonatomic, readonly, strong) NSNumber *_Nullable duration; + +@property (nonatomic, readonly, copy) NSString *_Nullable releaseName; +@property (nonatomic, copy) NSString *_Nullable environment; +@property (nonatomic, copy) SentryUser *_Nullable user; + +- (NSDictionary *)serialize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySpanContext.h b/Pods/Sentry/Sources/Sentry/Public/SentrySpanContext.h new file mode 100644 index 00000000..db0d3107 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySpanContext.h @@ -0,0 +1,107 @@ +#import "SentryDefines.h" +#import "SentrySampleDecision.h" +#import "SentrySerializable.h" +#import "SentrySpanStatus.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryId, SentrySpanId; + +NS_SWIFT_NAME(SpanContext) +@interface SentrySpanContext : NSObject +SENTRY_NO_INIT + +/** + * Determines which trace the Span belongs to. + */ +@property (nonatomic, readonly) SentryId *traceId; + +/** + * Span id. + */ +@property (nonatomic, readonly) SentrySpanId *spanId; + +/** + * Id of a parent span. + */ +@property (nullable, nonatomic, readonly) SentrySpanId *parentSpanId; + +/** + * If trace is sampled. + */ +@property (nonatomic) SentrySampleDecision sampled; + +/** + * Short code identifying the type of operation the span is measuring. + */ +@property (nonatomic, copy) NSString *operation; + +/** + * Longer description of the span's operation, which uniquely identifies the span but is + * consistent across instances of the span. + */ +@property (nullable, nonatomic, copy) NSString *spanDescription; + +/** + * Describes the status of the Transaction. + */ +@property (nonatomic) SentrySpanStatus status; + +/** + * A map or list of tags for this event. Each tag must be less than 200 characters. + */ +@property (nonatomic, readonly) NSDictionary *tags; + +/** + * Init a SentryContext with an operation code, + * traceId and spanId with be randomly created, + * sampled by default is false. + * + * @return SentryContext + */ +- (instancetype)initWithOperation:(NSString *)operation; + +/** + * Init a SentryContext with an operation code and mark it as sampled or not. + * TraceId and SpanId with be randomly created. + * + * @param operation The operation this span is measuring. + * @param sampled Determines whether the trace should be sampled. + * + * @return SentryContext + */ + +- (instancetype)initWithOperation:(NSString *)operation sampled:(SentrySampleDecision)sampled; + +/** + * Init a SentryContext with given traceId, spanId and parentId. + * + * @param traceId Determines which trace the Span belongs to. + * @param spanId The Span Id + * @param operation The operation this span is measuring. + * @param parentId Id of a parent span. + * @param sampled Determines whether the trace should be sampled. + * + * @return SentryContext + */ +- (instancetype)initWithTraceId:(SentryId *)traceId + spanId:(SentrySpanId *)spanId + parentId:(nullable SentrySpanId *)parentId + operation:(NSString *)operation + sampled:(SentrySampleDecision)sampled; + +/** + * Sets a tag with given value. + */ +- (void)setTagValue:(NSString *)value forKey:(NSString *)key NS_SWIFT_NAME(setTag(value:key:)); + +/** + * Removes a tag. + */ +- (void)removeTagForKey:(NSString *)key NS_SWIFT_NAME(removeTag(key:)); + +@property (class, nonatomic, readonly, copy) NSString *type; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySpanId.h b/Pods/Sentry/Sources/Sentry/Public/SentrySpanId.h new file mode 100644 index 00000000..9ecc514b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySpanId.h @@ -0,0 +1,40 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A 16 character Id. + */ + +NS_SWIFT_NAME(SpanId) +@interface SentrySpanId : NSObject + +/** + * Creates a SentrySpanId with a random 16 character Id. + */ +- (instancetype)init; + +/** + * Creates a SentrySpanId with the first 16 characters of the given UUID. + */ +- (instancetype)initWithUUID:(NSUUID *)uuid; + +/** + * Creates a SentrySpanId from a 16 character string. + * Returns a empty SentrySpanId with the input is invalid. + */ +- (instancetype)initWithValue:(NSString *)value; + +/** + * Returns the Span Id Value + */ +@property (readonly, copy) NSString *sentrySpanIdString; + +/** + * A SentrySpanId with an empty Id "0000000000000000". + */ +@property (class, nonatomic, readonly, strong) SentrySpanId *empty; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySpanProtocol.h b/Pods/Sentry/Sources/Sentry/Public/SentrySpanProtocol.h new file mode 100644 index 00000000..33233d40 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySpanProtocol.h @@ -0,0 +1,79 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" +#import "SentrySpanContext.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentrySpanId, SentryId; + +NS_SWIFT_NAME(Span) +@protocol SentrySpan + +/** + * The context information of the span. + */ +@property (nonatomic, readonly) SentrySpanContext *context; + +/** + * The timestamp of which the span ended. + */ +@property (nullable, nonatomic, strong) NSDate *timestamp; + +/** + * The start time of the span. + */ +@property (nullable, nonatomic, strong) NSDate *startTimestamp; + +/** + * An arbitrary mapping of additional metadata of the span. + */ +@property (nullable, readonly) NSDictionary *data; + +/** + * Whether the span is finished. + */ +@property (readonly) BOOL isFinished; + +/** + * Starts a child span. + * + * @param operation Short code identifying the type of operation the span is measuring. + * + * @return SentrySpan + */ +- (id)startChildWithOperation:(NSString *)operation + NS_SWIFT_NAME(startChild(operation:)); + +/** + * Starts a child span. + * + * @param operation Defines the child span operation. + * @param description Define the child span description. + * + * @return SentrySpan + */ +- (id)startChildWithOperation:(NSString *)operation + description:(nullable NSString *)description + NS_SWIFT_NAME(startChild(operation:description:)); + +/** + * Sets an extra. + */ +- (void)setDataValue:(nullable id)value + forKey:(NSString *)key NS_SWIFT_NAME(setExtra(value:key:)); + +/** + * Finishes the span by setting the end time. + */ +- (void)finish; + +/** + * Finishes the span by setting the end time and span status. + * + * @param status The status of this span + * */ +- (void)finishWithStatus:(SentrySpanStatus)status NS_SWIFT_NAME(finish(status:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentrySpanStatus.h b/Pods/Sentry/Sources/Sentry/Public/SentrySpanStatus.h new file mode 100644 index 00000000..6dd8a7bf --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentrySpanStatus.h @@ -0,0 +1,103 @@ +#import + +/** + * Describes the status of the Span/Transaction. + */ +typedef NS_ENUM(NSUInteger, SentrySpanStatus) { + /** + * An undefined status. + */ + kSentrySpanStatusUndefined, + + /** + * Not an error, returned on success. + */ + kSentrySpanStatusOk, + + /** + * The deadline expired before the operation could succeed. + */ + kSentrySpanStatusDeadlineExceeded, + + /** + * The requester doesn't have valid authentication credentials for the operation. + */ + kSentrySpanStatusUnauthenticated, + + /** + * The caller doesn't have permission to execute the specified operation. + */ + kSentrySpanStatusPermissionDenied, + + /** + * Content was not found or request was denied for an entire class of users. + */ + kSentrySpanStatusNotFound, + + /** + * The resource has been exhausted e.g. per-user quota exhausted, file system out of space. + */ + kSentrySpanStatusResourceExhausted, + + /** + * The client specified an invalid argument. + */ + kSentrySpanStatusInvalidArgument, + + /** + * 501 Not Implemented. + */ + kSentrySpanStatusUnimplemented, + + /** + * The operation is not implemented or is not supported/enabled for this operation. + */ + kSentrySpanStatusUnavailable, + + /** + * Some invariants expected by the underlying system have been broken. This code is reserved for + * serious errors. + */ + kSentrySpanStatusInternalError, + + /** + * An unknown error raised by APIs that don't return enough error information. + */ + kSentrySpanStatusUnknownError, + + /** + * The operation was cancelled, typically by the caller. + */ + kSentrySpanStatusCancelled, + + /** + * The entity attempted to be created already exists. + */ + kSentrySpanStatusAlreadyExists, + + /** + * The client shouldn't retry until the system state has been explicitly handled. + */ + kSentrySpanStatusFailedPrecondition, + + /** + * The operation was aborted. + */ + kSentrySpanStatusAborted, + + /** + * The operation was attempted past the valid range e.g. seeking past the end of a file. + */ + kSentrySpanStatusOutOfRange, + + /** + * Unrecoverable data loss or corruption. + */ + kSentrySpanStatusDataLoss, +}; + +static NSString *_Nonnull const SentrySpanStatusNames[] + = { @"undefined", @"ok", @"deadline_exceeded", @"unauthenticated", @"permission_denied", + @"not_found", @"resource_exhausted", @"invalid_argument", @"unimplemented", + @"unavailable", @"internal_error", @"unknown_error", @"cancelled", @"already_exists", + @"failed_precondition", @"aborted", @"out_of_range", @"data_loss" }; diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryStacktrace.h b/Pods/Sentry/Sources/Sentry/Public/SentryStacktrace.h new file mode 100644 index 00000000..e8c67d83 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryStacktrace.h @@ -0,0 +1,41 @@ +#import + +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryFrame; + +NS_SWIFT_NAME(Stacktrace) +@interface SentryStacktrace : NSObject +SENTRY_NO_INIT + +/** + * Array of all SentryFrame in the stacktrace + */ +@property (nonatomic, strong) NSArray *frames; + +/** + * Registers of the thread for additional information used on the server + */ +@property (nonatomic, strong) NSDictionary *registers; + +/** + * Initialize a SentryStacktrace with frames and registers + * @param frames NSArray + * @param registers NSArray + * @return SentryStacktrace + */ +- (instancetype)initWithFrames:(NSArray *)frames + registers:(NSDictionary *)registers; + +/** + * This will be called internally, is used to remove duplicated frames for + * certain crashes. + */ +- (void)fixDuplicateFrames; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryThread.h b/Pods/Sentry/Sources/Sentry/Public/SentryThread.h new file mode 100644 index 00000000..7546e419 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryThread.h @@ -0,0 +1,46 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryStacktrace; + +NS_SWIFT_NAME(Thread) +@interface SentryThread : NSObject +SENTRY_NO_INIT + +/** + * Number of the thread + */ +@property (nonatomic, copy) NSNumber *threadId; + +/** + * Name (if available) of the thread + */ +@property (nonatomic, copy) NSString *_Nullable name; + +/** + * SentryStacktrace of the SentryThread + */ +@property (nonatomic, strong) SentryStacktrace *_Nullable stacktrace; + +/** + * Did this thread crash? + */ +@property (nonatomic, copy) NSNumber *_Nullable crashed; + +/** + * Was it the current thread. + */ +@property (nonatomic, copy) NSNumber *_Nullable current; + +/** + * Initializes a SentryThread with its id + * @param threadId NSNumber + * @return SentryThread + */ +- (instancetype)initWithThreadId:(NSNumber *)threadId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryTransactionContext.h b/Pods/Sentry/Sources/Sentry/Public/SentryTransactionContext.h new file mode 100644 index 00000000..1dabf41e --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryTransactionContext.h @@ -0,0 +1,67 @@ +#import "SentrySampleDecision.h" +#import "SentrySpanContext.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentrySpanId; + +NS_SWIFT_NAME(TransactionContext) +@interface SentryTransactionContext : SentrySpanContext +SENTRY_NO_INIT + +/** + * Transaction name + */ +@property (nonatomic, readonly) NSString *name; + +/** + * Parent sampled + */ +@property (nonatomic) SentrySampleDecision parentSampled; + +/** + * Init a SentryTransactionContext with given name and set other fields by default + * + * @param name Transaction name + * @param operation The operation this span is measuring. + * + * @return SentryTransactionContext + */ +- (instancetype)initWithName:(NSString *)name operation:(NSString *)operation; + +/** + * Init a SentryTransactionContext with given name and set other fields by default + * + * @param name Transaction name + * @param operation The operation this span is measuring. + * @param sampled Determines whether the trace should be sampled. + * + * @return SentryTransactionContext + */ +- (instancetype)initWithName:(NSString *)name + operation:(NSString *)operation + sampled:(SentrySampleDecision)sampled; + +/** + * Init a SentryTransactionContext with given name, traceId, SpanId, parentSpanId and whether the + * parent is sampled. + * + * @param name Transaction name + * @param operation The operation this span is measuring. + * @param traceId Trace Id + * @param spanId Span Id + * @param parentSpanId Parent span id + * @param parentSampled Whether the parent is sampled + * + * @return SentryTransactionContext + */ +- (instancetype)initWithName:(NSString *)name + operation:(NSString *)operation + traceId:(SentryId *)traceId + spanId:(SentrySpanId *)spanId + parentSpanId:(nullable SentrySpanId *)parentSpanId + parentSampled:(SentrySampleDecision)parentSampled; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryUser.h b/Pods/Sentry/Sources/Sentry/Public/SentryUser.h new file mode 100644 index 00000000..ed5503b6 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryUser.h @@ -0,0 +1,52 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(User) +@interface SentryUser : NSObject + +/** + * Optional: Id of the user + */ +@property (atomic, copy) NSString *userId; + +/** + * Optional: Email of the user + */ +@property (atomic, copy) NSString *_Nullable email; + +/** + * Optional: Username + */ +@property (atomic, copy) NSString *_Nullable username; + +/** + * Optional: IP Address + */ +@property (atomic, copy) NSString *_Nullable ipAddress; + +/** + * Optional: Additional data + */ +@property (atomic, strong) NSDictionary *_Nullable data; + +/** + * Initializes a SentryUser with the id + * @param userId NSString + * @return SentryUser + */ +- (instancetype)initWithUserId:(NSString *)userId; + +- (instancetype)init; ++ (instancetype)new NS_UNAVAILABLE; + +- (BOOL)isEqual:(id _Nullable)other; + +- (BOOL)isEqualToUser:(SentryUser *)user; + +- (NSUInteger)hash; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/Public/SentryUserFeedback.h b/Pods/Sentry/Sources/Sentry/Public/SentryUserFeedback.h new file mode 100644 index 00000000..1878c369 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/Public/SentryUserFeedback.h @@ -0,0 +1,44 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryId; + +/** + * Adds additional information about what happened to an event. + */ +NS_SWIFT_NAME(UserFeedback) +@interface SentryUserFeedback : NSObject +SENTRY_NO_INIT + +/** + * Initializes SentryUserFeedback and sets the required eventId. + * + * @param eventId The eventId of the event to which the user feedback is associated. + */ +- (instancetype)initWithEventId:(SentryId *)eventId; + +/** + * The eventId of the event to which the user feedback is associated. + */ +@property (readonly, nonatomic, strong) SentryId *eventId; + +/** + * The name of the user. + */ +@property (nonatomic, copy) NSString *name; + +/** + * The email of the user. + */ +@property (nonatomic, copy) NSString *email; + +/** + * Comments of the user about what happened. + */ +@property (nonatomic, copy) NSString *comments; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryAppState.m b/Pods/Sentry/Sources/Sentry/SentryAppState.m new file mode 100644 index 00000000..b14884a6 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryAppState.m @@ -0,0 +1,74 @@ +#import +#import + +@implementation SentryAppState + +- (instancetype)initWithReleaseName:(NSString *)releaseName + osVersion:(NSString *)osVersion + isDebugging:(BOOL)isDebugging +{ + if (self = [super init]) { + _releaseName = releaseName; + _osVersion = osVersion; + _isDebugging = isDebugging; + _isActive = NO; + _wasTerminated = NO; + } + return self; +} + +- (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject +{ + if (self = [super init]) { + id releaseName = [jsonObject valueForKey:@"release_name"]; + if (releaseName == nil || ![releaseName isKindOfClass:[NSString class]]) { + return nil; + } else { + _releaseName = releaseName; + } + + id osVersion = [jsonObject valueForKey:@"os_version"]; + if (osVersion == nil || ![osVersion isKindOfClass:[NSString class]]) { + return nil; + } else { + _osVersion = osVersion; + } + + id isDebugging = [jsonObject valueForKey:@"is_debugging"]; + if (isDebugging == nil || ![isDebugging isKindOfClass:[NSNumber class]]) { + return nil; + } else { + _isDebugging = [isDebugging boolValue]; + } + + id isActive = [jsonObject valueForKey:@"is_active"]; + if (isActive == nil || ![isActive isKindOfClass:[NSNumber class]]) { + return nil; + } else { + _isActive = [isActive boolValue]; + } + + id wasTerminated = [jsonObject valueForKey:@"was_terminated"]; + if (wasTerminated == nil || ![wasTerminated isKindOfClass:[NSNumber class]]) { + return nil; + } else { + _wasTerminated = [wasTerminated boolValue]; + } + } + return self; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; + + [data setValue:self.releaseName forKey:@"release_name"]; + [data setValue:self.osVersion forKey:@"os_version"]; + [data setValue:@(self.isDebugging) forKey:@"is_debugging"]; + [data setValue:@(self.isActive) forKey:@"is_active"]; + [data setValue:@(self.wasTerminated) forKey:@"was_terminated"]; + + return data; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryAsynchronousOperation.m b/Pods/Sentry/Sources/Sentry/SentryAsynchronousOperation.m new file mode 100644 index 00000000..feade86b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryAsynchronousOperation.m @@ -0,0 +1,119 @@ +#import "SentryAsynchronousOperation.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryAsynchronousOperation () + +@property (nonatomic, getter=isCancelled, readwrite) BOOL cancelled; +@property (nonatomic, getter=isFinished, readwrite) BOOL finished; +@property (nonatomic, getter=isExecuting, readwrite) BOOL executing; + +@end + +@implementation SentryAsynchronousOperation + +@synthesize cancelled = _cancelled; +@synthesize finished = _finished; +@synthesize executing = _executing; + +- (id)init +{ + self = [super init]; + if (self) { + _finished = NO; + _executing = NO; + _cancelled = NO; + } + return self; +} + +- (void)start +{ + if ([self isCancelled]) { + self.finished = YES; + return; + } + + self.executing = YES; + + [self main]; +} + +- (void)cancel +{ + self.executing = NO; + self.finished = YES; + self.cancelled = YES; +} + +- (void)completeOperation +{ + self.executing = NO; + self.finished = YES; +} + +#pragma mark - NSOperation methods + +- (BOOL)isAsynchronous +{ + return YES; +} + +- (BOOL)isExecuting +{ + @synchronized(self) { + return _executing; + } +} + +- (BOOL)isFinished +{ + @synchronized(self) { + return _finished; + } +} + +- (BOOL)isCancelled +{ + @synchronized(self) { + return _cancelled; + } +} + +- (void)setCancelled:(BOOL)cancelled +{ + if (_cancelled != cancelled) { + [self willChangeValueForKey:@"isCancelled"]; + @synchronized(self) { + _cancelled = cancelled; + } + [self didChangeValueForKey:@"isCancelled"]; + } +} + +- (void)setExecuting:(BOOL)executing +{ + if (_executing != executing) { + [self willChangeValueForKey:@"isExecuting"]; + @synchronized(self) { + _executing = executing; + } + [self didChangeValueForKey:@"isExecuting"]; + } +} + +- (void)setFinished:(BOOL)finished +{ + [self willChangeValueForKey:@"isFinished"]; + @synchronized(self) { + if (_finished != finished) { + _finished = finished; + } + } + [self didChangeValueForKey:@"isFinished"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryAttachment.m b/Pods/Sentry/Sources/Sentry/SentryAttachment.m new file mode 100644 index 00000000..7c92dd7f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryAttachment.m @@ -0,0 +1,52 @@ +#import "SentryAttachment.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +NSString *const DefaultContentType = @"application/octet-stream"; + +@implementation SentryAttachment + +- (instancetype)initWithData:(NSData *)data filename:(NSString *)filename +{ + return [self initWithData:data filename:filename contentType:DefaultContentType]; +} + +- (instancetype)initWithData:(NSData *)data + filename:(NSString *)filename + contentType:(NSString *)contentType +{ + + if (self = [super init]) { + _data = data; + _filename = filename; + _contentType = contentType; + } + return self; +} + +- (instancetype)initWithPath:(NSString *)path +{ + return [self initWithPath:path filename:[path lastPathComponent]]; +} + +- (instancetype)initWithPath:(NSString *)path filename:(NSString *)filename +{ + return [self initWithPath:path filename:filename contentType:DefaultContentType]; +} + +- (instancetype)initWithPath:(NSString *)path + filename:(NSString *)filename + contentType:(NSString *)contentType +{ + if (self = [super init]) { + _path = path; + _filename = filename; + _contentType = contentType; + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryAutoBreadcrumbTrackingIntegration.m b/Pods/Sentry/Sources/Sentry/SentryAutoBreadcrumbTrackingIntegration.m new file mode 100644 index 00000000..7629576a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryAutoBreadcrumbTrackingIntegration.m @@ -0,0 +1,44 @@ +#import "SentryAutoBreadcrumbTrackingIntegration.h" +#import "SentryBreadcrumbTracker.h" +#import "SentryEvent.h" +#import "SentryLog.h" +#import "SentryOptions.h" +#import "SentrySystemEventsBreadcrumbs.h" + +@interface +SentryAutoBreadcrumbTrackingIntegration () + +@property (nonatomic, weak) SentryOptions *options; + +@property (nonatomic, strong) SentryBreadcrumbTracker *tracker; +@property (nonatomic, strong) SentrySystemEventsBreadcrumbs *system_events; + +@end + +@implementation SentryAutoBreadcrumbTrackingIntegration + +- (void)installWithOptions:(nonnull SentryOptions *)options +{ + self.options = options; + [self enableAutomaticBreadcrumbTracking]; +} + +- (void)uninstall +{ + if (nil != self.tracker) { + [self.tracker stop]; + } + if (nil != self.system_events) { + [self.system_events stop]; + } +} + +- (void)enableAutomaticBreadcrumbTracking +{ + self.tracker = [SentryBreadcrumbTracker alloc]; + [self.tracker start]; + self.system_events = [SentrySystemEventsBreadcrumbs alloc]; + [self.system_events start]; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryAutoSessionTrackingIntegration.m b/Pods/Sentry/Sources/Sentry/SentryAutoSessionTrackingIntegration.m new file mode 100644 index 00000000..0f8fc3aa --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryAutoSessionTrackingIntegration.m @@ -0,0 +1,46 @@ +#import "SentryAutoSessionTrackingIntegration.h" +#import "SentryDefaultCurrentDateProvider.h" +#import "SentryLog.h" +#import "SentryOptions.h" +#import "SentrySDK.h" +#import "SentrySessionTracker.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryAutoSessionTrackingIntegration () + +@property (nonatomic, strong) SentrySessionTracker *tracker; + +@end + +@implementation SentryAutoSessionTrackingIntegration + +- (void)installWithOptions:(SentryOptions *)options +{ + if (options.enableAutoSessionTracking) { + id currentDateProvider = + [[SentryDefaultCurrentDateProvider alloc] init]; + SentrySessionTracker *tracker = + [[SentrySessionTracker alloc] initWithOptions:options + currentDateProvider:currentDateProvider]; + [tracker start]; + self.tracker = tracker; + } +} + +- (void)uninstall +{ + [self stop]; +} + +- (void)stop +{ + if (nil != self.tracker) { + [self.tracker stop]; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryBreadcrumb.m b/Pods/Sentry/Sources/Sentry/SentryBreadcrumb.m new file mode 100644 index 00000000..00dd678f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryBreadcrumb.m @@ -0,0 +1,82 @@ +#import "SentryBreadcrumb.h" +#import "NSDate+SentryExtras.h" +#import "NSDictionary+SentrySanitize.h" + +@implementation SentryBreadcrumb + +- (instancetype)initWithLevel:(enum SentryLevel)level category:(NSString *)category +{ + self = [super init]; + if (self) { + self.level = level; + self.category = category; + self.timestamp = [NSDate date]; + } + return self; +} + +- (instancetype)init +{ + return [self initWithLevel:kSentryLevelInfo category:@"default"]; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = [NSMutableDictionary new]; + + [serializedData setValue:SentryLevelNames[self.level] forKey:@"level"]; + [serializedData setValue:[self.timestamp sentry_toIso8601String] forKey:@"timestamp"]; + [serializedData setValue:self.category forKey:@"category"]; + [serializedData setValue:self.type forKey:@"type"]; + [serializedData setValue:self.message forKey:@"message"]; + [serializedData setValue:[self.data sentry_sanitize] forKey:@"data"]; + + return serializedData; +} + +- (BOOL)isEqual:(id _Nullable)other +{ + if (other == self) + return YES; + if (!other || ![[other class] isEqual:[self class]]) + return NO; + + return [self isEqualToBreadcrumb:other]; +} + +- (BOOL)isEqualToBreadcrumb:(SentryBreadcrumb *)breadcrumb +{ + if (self == breadcrumb) + return YES; + if (breadcrumb == nil) + return NO; + if (self.level != breadcrumb.level) + return NO; + if (self.category != breadcrumb.category + && ![self.category isEqualToString:breadcrumb.category]) + return NO; + if (self.timestamp != breadcrumb.timestamp + && ![self.timestamp isEqualToDate:breadcrumb.timestamp]) + return NO; + if (self.type != breadcrumb.type && ![self.type isEqualToString:breadcrumb.type]) + return NO; + if (self.message != breadcrumb.message && ![self.message isEqualToString:breadcrumb.message]) + return NO; + if (self.data != breadcrumb.data && ![self.data isEqualToDictionary:breadcrumb.data]) + return NO; + return YES; +} + +- (NSUInteger)hash +{ + NSUInteger hash = 17; + hash = hash * 23 + (NSUInteger)self.level; + hash = hash * 23 + [self.category hash]; + hash = hash * 23 + [self.timestamp hash]; + hash = hash * 23 + [self.type hash]; + hash = hash * 23 + [self.message hash]; + hash = hash * 23 + [self.data hash]; + return hash; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryBreadcrumbTracker.m b/Pods/Sentry/Sources/Sentry/SentryBreadcrumbTracker.m new file mode 100644 index 00000000..a1efe40d --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryBreadcrumbTracker.m @@ -0,0 +1,221 @@ +#import "SentryBreadcrumbTracker.h" +#import "SentryBreadcrumb.h" +#import "SentryClient.h" +#import "SentryDefines.h" +#import "SentryHub.h" +#import "SentryLog.h" +#import "SentrySDK+Private.h" +#import "SentryScope.h" +#import "SentrySwizzle.h" + +#if SENTRY_HAS_UIKIT +# import +#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST +# import +#endif + +@implementation SentryBreadcrumbTracker + +- (void)start +{ + [self addEnabledCrumb]; + [self swizzleSendAction]; + [self swizzleViewDidAppear]; + [self trackApplicationUIKitNotifications]; +} + +- (void)stop +{ + // This is a noop because the notifications are registered via blocks and monkey patching + // which are both super hard to clean up. + // Either way, all these are guarded by checking the client of the current hub, which + // we remove when uninstalling the SDK. +} + +- (void)trackApplicationUIKitNotifications +{ +#if SENTRY_HAS_UIKIT + NSNotificationName foregroundNotificationName = UIApplicationDidBecomeActiveNotification; + NSNotificationName backgroundNotificationName = UIApplicationDidEnterBackgroundNotification; +#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST + NSNotificationName foregroundNotificationName = NSApplicationDidBecomeActiveNotification; + // Will resign Active notification is the nearest one to + // UIApplicationDidEnterBackgroundNotification + NSNotificationName backgroundNotificationName = NSApplicationWillResignActiveNotification; +#else + [SentryLog logWithMessage:@"NO UIKit, OSX and Catalyst -> [SentryBreadcrumbTracker " + @"trackApplicationUIKitNotifications] does nothing." + andLevel:kSentryLevelDebug]; +#endif + + // not available for macOS +#if SENTRY_HAS_UIKIT + [NSNotificationCenter.defaultCenter + addObserverForName:UIApplicationDidReceiveMemoryWarningNotification + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { + if (nil != [SentrySDK.currentHub getClient]) { + SentryBreadcrumb *crumb = + [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelWarning + category:@"device.event"]; + crumb.type = @"system"; + crumb.data = @ { @"action" : @"LOW_MEMORY" }; + crumb.message = @"Low memory"; + [SentrySDK addBreadcrumb:crumb]; + } + }]; +#endif + +#if SENTRY_HAS_UIKIT || TARGET_OS_OSX || TARGET_OS_MACCATALYST + [NSNotificationCenter.defaultCenter addObserverForName:backgroundNotificationName + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { + [self addBreadcrumbWithType:@"navigation" + withCategory:@"app.lifecycle" + withLevel:kSentryLevelInfo + withDataKey:@"state" + withDataValue:@"background"]; + }]; + + [NSNotificationCenter.defaultCenter addObserverForName:foregroundNotificationName + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { + [self addBreadcrumbWithType:@"navigation" + withCategory:@"app.lifecycle" + withLevel:kSentryLevelInfo + withDataKey:@"state" + withDataValue:@"foreground"]; + }]; +#endif +} + +- (void)addBreadcrumbWithType:(NSString *)type + withCategory:(NSString *)category + withLevel:(SentryLevel)level + withDataKey:(NSString *)key + withDataValue:(NSString *)value +{ + if (nil != [SentrySDK.currentHub getClient]) { + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:level category:category]; + crumb.type = type; + crumb.data = @{ key : value }; + [SentrySDK addBreadcrumb:crumb]; + } +} + +- (void)addEnabledCrumb +{ + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelInfo + category:@"started"]; + crumb.type = @"debug"; + crumb.message = @"Breadcrumb Tracking"; + [SentrySDK addBreadcrumb:crumb]; +} + +- (void)swizzleSendAction +{ +#if SENTRY_HAS_UIKIT + + // SentrySwizzleInstanceMethod declaration shadows a local variable. The swizzling is working + // fine and we accept this warning. +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wshadow" + + static const void *swizzleSendActionKey = &swizzleSendActionKey; + SEL selector = NSSelectorFromString(@"sendAction:to:from:forEvent:"); + SentrySwizzleInstanceMethod(UIApplication.class, selector, SentrySWReturnType(BOOL), + SentrySWArguments(SEL action, id target, id sender, UIEvent * event), SentrySWReplacement({ + if (nil != [SentrySDK.currentHub getClient]) { + NSDictionary *data = nil; + for (UITouch *touch in event.allTouches) { + if (touch.phase == UITouchPhaseCancelled || touch.phase == UITouchPhaseEnded) { + data = @ { @"view" : [NSString stringWithFormat:@"%@", touch.view] }; + } + } + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelInfo + category:@"touch"]; + crumb.type = @"user"; + crumb.message = [NSString stringWithFormat:@"%s", sel_getName(action)]; + crumb.data = data; + [SentrySDK addBreadcrumb:crumb]; + } + return SentrySWCallOriginal(action, target, sender, event); + }), + SentrySwizzleModeOncePerClassAndSuperclasses, swizzleSendActionKey); +# pragma clang diagnostic pop +#else + [SentryLog logWithMessage:@"NO UIKit -> [SentryBreadcrumbTracker " + @"swizzleSendAction] does nothing." + andLevel:kSentryLevelDebug]; +#endif +} + +- (void)swizzleViewDidAppear +{ +#if SENTRY_HAS_UIKIT + + // SentrySwizzleInstanceMethod declaration shadows a local variable. The swizzling is working + // fine and we accept this warning. +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wshadow" + + static const void *swizzleViewDidAppearKey = &swizzleViewDidAppearKey; + SEL selector = NSSelectorFromString(@"viewDidAppear:"); + SentrySwizzleInstanceMethod(UIViewController.class, selector, SentrySWReturnType(void), + SentrySWArguments(BOOL animated), SentrySWReplacement({ + if (nil != [SentrySDK.currentHub getClient]) { + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelInfo + category:@"ui.lifecycle"]; + crumb.type = @"navigation"; + NSString *viewControllerName = [SentryBreadcrumbTracker + sanitizeViewControllerName:[NSString stringWithFormat:@"%@", self]]; + crumb.data = @ { @"screen" : viewControllerName }; + + // Adding crumb via the SDK calls SentryBeforeBreadcrumbCallback + [SentrySDK addBreadcrumb:crumb]; + [SentrySDK.currentHub configureScope:^(SentryScope *_Nonnull scope) { + [scope setExtraValue:viewControllerName forKey:@"__sentry_transaction"]; + }]; + } + SentrySWCallOriginal(animated); + }), + SentrySwizzleModeOncePerClassAndSuperclasses, swizzleViewDidAppearKey); +# pragma clang diagnostic pop +#else + [SentryLog logWithMessage:@"NO UIKit -> [SentryBreadcrumbTracker " + @"swizzleViewDidAppear] does nothing." + andLevel:kSentryLevelDebug]; +#endif +} + ++ (NSRegularExpression *)viewControllerRegex +{ + static dispatch_once_t onceTokenRegex; + static NSRegularExpression *regex = nil; + dispatch_once(&onceTokenRegex, ^{ + NSString *pattern = @"[<.](\\w+)"; + regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil]; + }); + return regex; +} + ++ (NSString *)sanitizeViewControllerName:(NSString *)controller +{ + NSRange searchedRange = NSMakeRange(0, [controller length]); + NSArray *matches = [[self.class viewControllerRegex] matchesInString:controller + options:0 + range:searchedRange]; + NSMutableArray *strings = [NSMutableArray array]; + for (NSTextCheckingResult *match in matches) { + [strings addObject:[controller substringWithRange:[match rangeAtIndex:1]]]; + } + if ([strings count] > 0) { + return [strings componentsJoinedByString:@"."]; + } + return controller; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryClient.m b/Pods/Sentry/Sources/Sentry/SentryClient.m new file mode 100644 index 00000000..57d90d32 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryClient.m @@ -0,0 +1,536 @@ +#import "SentryClient.h" +#import "NSDictionary+SentrySanitize.h" +#import "SentryCrashDefaultBinaryImageProvider.h" +#import "SentryCrashDefaultMachineContextWrapper.h" +#import "SentryCrashIntegration.h" +#import "SentryCrashStackEntryMapper.h" +#import "SentryDebugMetaBuilder.h" +#import "SentryDefaultCurrentDateProvider.h" +#import "SentryDsn.h" +#import "SentryEnvelope.h" +#import "SentryEvent.h" +#import "SentryException.h" +#import "SentryFileManager.h" +#import "SentryFrameInAppLogic.h" +#import "SentryFrameRemover.h" +#import "SentryGlobalEventProcessor.h" +#import "SentryId.h" +#import "SentryInstallation.h" +#import "SentryLog.h" +#import "SentryMechanism.h" +#import "SentryMechanismMeta.h" +#import "SentryMessage.h" +#import "SentryMeta.h" +#import "SentryNSError.h" +#import "SentryOptions.h" +#import "SentryOutOfMemoryTracker.h" +#import "SentrySDK+Private.h" +#import "SentryScope+Private.h" +#import "SentryScope.h" +#import "SentryStacktraceBuilder.h" +#import "SentryThreadInspector.h" +#import "SentryTransaction.h" +#import "SentryTransport.h" +#import "SentryTransportFactory.h" +#import "SentryUser.h" +#import "SentryUserFeedback.h" + +#if SENTRY_HAS_UIKIT +# import +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryClient () + +@property (nonatomic, strong) id transport; +@property (nonatomic, strong) SentryFileManager *fileManager; +@property (nonatomic, strong) SentryDebugMetaBuilder *debugMetaBuilder; +@property (nonatomic, strong) SentryThreadInspector *threadInspector; + +@end + +NSString *const DropSessionLogMessage = @"Session has no release name. Won't send it."; + +@implementation SentryClient + +- (_Nullable instancetype)initWithOptions:(SentryOptions *)options +{ + if (self = [super init]) { + self.options = options; + + SentryCrashDefaultBinaryImageProvider *provider = + [[SentryCrashDefaultBinaryImageProvider alloc] init]; + + self.debugMetaBuilder = + [[SentryDebugMetaBuilder alloc] initWithBinaryImageProvider:provider]; + + SentryFrameInAppLogic *frameInAppLogic = + [[SentryFrameInAppLogic alloc] initWithInAppIncludes:options.inAppIncludes + inAppExcludes:options.inAppExcludes]; + SentryCrashStackEntryMapper *crashStackEntryMapper = + [[SentryCrashStackEntryMapper alloc] initWithFrameInAppLogic:frameInAppLogic]; + SentryStacktraceBuilder *stacktraceBuilder = + [[SentryStacktraceBuilder alloc] initWithCrashStackEntryMapper:crashStackEntryMapper]; + id machineContextWrapper = + [[SentryCrashDefaultMachineContextWrapper alloc] init]; + + self.threadInspector = + [[SentryThreadInspector alloc] initWithStacktraceBuilder:stacktraceBuilder + andMachineContextWrapper:machineContextWrapper]; + + NSError *error = nil; + + self.fileManager = [[SentryFileManager alloc] + initWithOptions:self.options + andCurrentDateProvider:[[SentryDefaultCurrentDateProvider alloc] init] + error:&error]; + if (nil != error) { + [SentryLog logWithMessage:error.localizedDescription andLevel:kSentryLevelError]; + return nil; + } + + self.transport = [SentryTransportFactory initTransport:self.options + sentryFileManager:self.fileManager]; + } + return self; +} + +/** Internal constructor for testing */ +- (instancetype)initWithOptions:(SentryOptions *)options + andTransport:(id)transport + andFileManager:(SentryFileManager *)fileManager +{ + self = [self initWithOptions:options]; + + self.transport = transport; + self.fileManager = fileManager; + + return self; +} + +- (SentryFileManager *)fileManager +{ + return _fileManager; +} + +- (SentryId *)captureMessage:(NSString *)message +{ + return [self captureMessage:message withScope:[[SentryScope alloc] init]]; +} + +- (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope +{ + SentryEvent *event = [[SentryEvent alloc] initWithLevel:kSentryLevelInfo]; + event.message = [[SentryMessage alloc] initWithFormatted:message]; + return [self sendEvent:event withScope:scope alwaysAttachStacktrace:NO]; +} + +- (SentryId *)captureException:(NSException *)exception +{ + return [self captureException:exception withScope:[[SentryScope alloc] init]]; +} + +- (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope +{ + SentryEvent *event = [self buildExceptionEvent:exception]; + return [self sendEvent:event withScope:scope alwaysAttachStacktrace:YES]; +} + +- (SentryId *)captureException:(NSException *)exception + withSession:(SentrySession *)session + withScope:(SentryScope *)scope +{ + SentryEvent *event = [self buildExceptionEvent:exception]; + event = [self prepareEvent:event withScope:scope alwaysAttachStacktrace:YES]; + return [self sendEvent:event withSession:session withScope:scope]; +} + +- (SentryEvent *)buildExceptionEvent:(NSException *)exception +{ + SentryEvent *event = [[SentryEvent alloc] initWithLevel:kSentryLevelError]; + SentryException *sentryException = [[SentryException alloc] initWithValue:exception.reason + type:exception.name]; + event.exceptions = @[ sentryException ]; + [self setUserInfo:exception.userInfo withEvent:event]; + return event; +} + +- (SentryId *)captureError:(NSError *)error +{ + return [self captureError:error withScope:[[SentryScope alloc] init]]; +} + +- (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope +{ + SentryEvent *event = [self buildErrorEvent:error]; + return [self sendEvent:event withScope:scope alwaysAttachStacktrace:YES]; +} + +- (SentryId *)captureError:(NSError *)error + withSession:(SentrySession *)session + withScope:(SentryScope *)scope +{ + SentryEvent *event = [self buildErrorEvent:error]; + event = [self prepareEvent:event withScope:scope alwaysAttachStacktrace:YES]; + return [self sendEvent:event withSession:session withScope:scope]; +} + +- (SentryEvent *)buildErrorEvent:(NSError *)error +{ + SentryEvent *event = [[SentryEvent alloc] initWithError:error]; + + NSString *exceptionValue = [NSString stringWithFormat:@"Code: %ld", (long)error.code]; + SentryException *exception = [[SentryException alloc] initWithValue:exceptionValue + type:error.domain]; + + // Sentry uses the error domain and code on the mechanism for gouping + SentryMechanism *mechanism = [[SentryMechanism alloc] initWithType:@"NSError"]; + SentryMechanismMeta *mechanismMeta = [[SentryMechanismMeta alloc] init]; + mechanismMeta.error = [[SentryNSError alloc] initWithDomain:error.domain code:error.code]; + mechanism.meta = mechanismMeta; + // The description of the error can be especially useful for error from swift that + // use a simple enum. + mechanism.desc = error.description; + + NSDictionary *userInfo = [error.userInfo sentry_sanitize]; + mechanism.data = userInfo; + exception.mechanism = mechanism; + event.exceptions = @[ exception ]; + + // Once the UI displays the mechanism data we can the userInfo from the event.context. + [self setUserInfo:userInfo withEvent:event]; + + return event; +} + +- (SentryId *)captureCrashEvent:(SentryEvent *)event withScope:(SentryScope *)scope +{ + return [self sendEvent:event withScope:scope alwaysAttachStacktrace:NO isCrashEvent:YES]; +} + +- (SentryId *)captureCrashEvent:(SentryEvent *)event + withSession:(SentrySession *)session + withScope:(SentryScope *)scope +{ + SentryEvent *preparedEvent = [self prepareEvent:event + withScope:scope + alwaysAttachStacktrace:NO + isCrashEvent:YES]; + return [self sendEvent:preparedEvent withSession:session withScope:scope]; +} + +- (SentryId *)captureEvent:(SentryEvent *)event +{ + return [self captureEvent:event withScope:[[SentryScope alloc] init]]; +} + +- (SentryId *)captureEvent:(SentryEvent *)event withScope:(SentryScope *)scope +{ + return [self sendEvent:event withScope:scope alwaysAttachStacktrace:NO]; +} + +- (SentryId *)sendEvent:(SentryEvent *)event + withScope:(SentryScope *)scope + alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace +{ + return [self sendEvent:event + withScope:scope + alwaysAttachStacktrace:alwaysAttachStacktrace + isCrashEvent:NO]; +} + +- (SentryId *)sendEvent:(SentryEvent *)event + withScope:(SentryScope *)scope + alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace + isCrashEvent:(BOOL)isCrashEvent +{ + SentryEvent *preparedEvent = [self prepareEvent:event + withScope:scope + alwaysAttachStacktrace:alwaysAttachStacktrace + isCrashEvent:isCrashEvent]; + + if (nil != preparedEvent) { + [self.transport sendEvent:preparedEvent attachments:scope.attachments]; + return preparedEvent.eventId; + } + + return SentryId.empty; +} + +- (SentryId *)sendEvent:(SentryEvent *)event + withSession:(SentrySession *)session + withScope:(SentryScope *)scope +{ + if (nil != event) { + if (nil == session.releaseName || [session.releaseName length] == 0) { + [SentryLog logWithMessage:DropSessionLogMessage andLevel:kSentryLevelDebug]; + [self.transport sendEvent:event attachments:scope.attachments]; + return event.eventId; + } + + [self.transport sendEvent:event withSession:session attachments:scope.attachments]; + return event.eventId; + } else { + [self captureSession:session]; + return SentryId.empty; + } +} + +- (void)captureSession:(SentrySession *)session +{ + if (nil == session.releaseName || [session.releaseName length] == 0) { + [SentryLog logWithMessage:DropSessionLogMessage andLevel:kSentryLevelDebug]; + return; + } + + SentryEnvelope *envelope = [[SentryEnvelope alloc] initWithSession:session]; + [self captureEnvelope:envelope]; +} + +- (void)captureEnvelope:(SentryEnvelope *)envelope +{ + // TODO: What is about beforeSend + + if ([self isDisabled]) { + [self logDisabledMessage]; + return; + } + + [self.transport sendEnvelope:envelope]; +} + +- (void)captureUserFeedback:(SentryUserFeedback *)userFeedback +{ + if ([self isDisabled]) { + [self logDisabledMessage]; + return; + } + + if ([SentryId.empty isEqual:userFeedback.eventId]) { + [SentryLog logWithMessage:@"Capturing UserFeedback with an empty event id. Won't send it." + andLevel:kSentryLevelDebug]; + return; + } + + [self.transport sendUserFeedback:userFeedback]; +} + +- (void)storeEnvelope:(SentryEnvelope *)envelope +{ + [self.fileManager storeEnvelope:envelope]; +} + +/** + * returns BOOL chance of YES is defined by sampleRate. + * if sample rate isn't within 0.0 - 1.0 it returns YES (like if sampleRate + * is 1.0) + */ +- (BOOL)checkSampleRate:(NSNumber *)sampleRate +{ + if (nil == sampleRate || [sampleRate floatValue] < 0 || [sampleRate floatValue] > 1) { + return YES; + } + return ([sampleRate floatValue] >= ((double)arc4random() / 0x100000000)); +} + +- (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event + withScope:(SentryScope *)scope + alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace +{ + return [self prepareEvent:event + withScope:scope + alwaysAttachStacktrace:alwaysAttachStacktrace + isCrashEvent:NO]; +} + +- (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event + withScope:(SentryScope *)scope + alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace + isCrashEvent:(BOOL)isCrashEvent +{ + NSParameterAssert(event); + if ([self isDisabled]) { + [self logDisabledMessage]; + return nil; + } + + if (NO == [self checkSampleRate:self.options.sampleRate]) { + [SentryLog logWithMessage:@"Event got sampled, will not send the event" + andLevel:kSentryLevelDebug]; + return nil; + } + + NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; + if (nil != infoDict && nil == event.dist) { + event.dist = infoDict[@"CFBundleVersion"]; + } + + // Use the values from SentryOptions as a fallback, + // in case not yet set directly in the event nor in the scope: + NSString *releaseName = self.options.releaseName; + if (nil == event.releaseName && nil != releaseName) { + // If no release was already set (i.e: crashed on an older version) use + // current release name + event.releaseName = releaseName; + } + + NSString *dist = self.options.dist; + if (nil != dist) { + event.dist = dist; + } + + NSString *environment = self.options.environment; + if (nil != environment && nil == event.environment) { + // Set the environment from option to the event before Scope is applied + event.environment = environment; + } + + NSMutableDictionary *sdk = + @{ @"name" : SentryMeta.sdkName, @"version" : SentryMeta.versionString }.mutableCopy; + if (nil != sdk && nil == event.sdk) { + if (event.extra[@"__sentry_sdk_integrations"]) { + [sdk setValue:event.extra[@"__sentry_sdk_integrations"] forKey:@"integrations"]; + } + event.sdk = sdk; + } + + BOOL shouldAttachStacktrace = alwaysAttachStacktrace || self.options.attachStacktrace + || (nil != event.exceptions && [event.exceptions count] > 0); + + BOOL debugMetaNotAttached = !(nil != event.debugMeta && event.debugMeta.count > 0); + if (!isCrashEvent && shouldAttachStacktrace && debugMetaNotAttached) { + event.debugMeta = [self.debugMetaBuilder buildDebugMeta]; + } + + BOOL threadsNotAttached = !(nil != event.threads && event.threads.count > 0); + if (!isCrashEvent && shouldAttachStacktrace && threadsNotAttached) { + event.threads = [self.threadInspector getCurrentThreads]; + } + + event = [scope applyToEvent:event maxBreadcrumb:self.options.maxBreadcrumbs]; + + // Remove free_memory if OOM as free_memory stems from the current run and not of the time of + // the OOM. + if ([self isOOM:event isCrashEvent:isCrashEvent]) { + [self removeFreeMemoryFromDeviceContext:event]; + } + + // With scope applied, before running callbacks run: + if (nil == event.environment) { + // We default to environment 'production' if nothing was set + event.environment = @"production"; + } + + // Need to do this after the scope is applied cause this sets the user if there is any + [self setUserIdIfNoUserSet:event]; + + // User can't be nil as setUserIdIfNoUserSet sets it. + if (self.options.sendDefaultPii && nil == event.user.ipAddress) { + // Let Sentry infer the IP address from the connection. + event.user.ipAddress = @"{{auto}}"; + } + + event = [self callEventProcessors:event]; + + if (nil != self.options.beforeSend) { + event = self.options.beforeSend(event); + } + + if (isCrashEvent && nil != self.options.onCrashedLastRun && !SentrySDK.crashedLastRunCalled) { + // We only want to call the callback once. It can occur that multiple crash events are + // about to be sent. + self.options.onCrashedLastRun(event); + SentrySDK.crashedLastRunCalled = YES; + } + + return event; +} + +- (BOOL)isDisabled +{ + return !self.options.enabled || nil == self.options.parsedDsn; +} + +- (void)logDisabledMessage +{ + [SentryLog logWithMessage:@"SDK disabled or no DSN set. Won't do anyting." + andLevel:kSentryLevelDebug]; +} + +- (SentryEvent *_Nullable)callEventProcessors:(SentryEvent *)event +{ + SentryEvent *newEvent = event; + + for (SentryEventProcessor processor in SentryGlobalEventProcessor.shared.processors) { + newEvent = processor(newEvent); + if (nil == newEvent) { + [SentryLog logWithMessage:@"SentryScope callEventProcessors: An event " + @"processor decided to remove this event." + andLevel:kSentryLevelDebug]; + break; + } + } + return newEvent; +} + +- (void)setUserInfo:(NSDictionary *)userInfo withEvent:(SentryEvent *)event +{ + if (nil != event && nil != userInfo && userInfo.count > 0) { + NSMutableDictionary *context; + if (nil == event.context) { + context = [[NSMutableDictionary alloc] init]; + event.context = context; + } else { + context = [event.context mutableCopy]; + } + + [context setValue:[userInfo sentry_sanitize] forKey:@"user info"]; + } +} + +- (void)setUserIdIfNoUserSet:(SentryEvent *)event +{ + // We only want to set the id if the customer didn't set a user so we at least set something to + // identify the user. + if (nil == event.user) { + SentryUser *user = [[SentryUser alloc] init]; + user.userId = [SentryInstallation id]; + event.user = user; + } +} + +- (BOOL)isOOM:(SentryEvent *)event isCrashEvent:(BOOL)isCrashEvent +{ + if (!isCrashEvent) { + return NO; + } + + if (nil == event.exceptions || event.exceptions.count != 1) { + return NO; + } + + SentryException *exception = event.exceptions[0]; + return nil != exception.mechanism && + [exception.mechanism.type isEqualToString:SentryOutOfMemoryMechanismType]; +} + +- (void)removeFreeMemoryFromDeviceContext:(SentryEvent *)event +{ + if (nil == event.context || event.context.count == 0 || nil == event.context[@"device"]) { + return; + } + + NSMutableDictionary *context = [[NSMutableDictionary alloc] initWithDictionary:event.context]; + NSMutableDictionary *device = + [[NSMutableDictionary alloc] initWithDictionary:context[@"device"]]; + [device removeObjectForKey:SentryDeviceContextFreeMemoryKey]; + context[@"device"] = device; + + event.context = context; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryConcurrentRateLimitsDictionary.m b/Pods/Sentry/Sources/Sentry/SentryConcurrentRateLimitsDictionary.m new file mode 100644 index 00000000..7f79386a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryConcurrentRateLimitsDictionary.m @@ -0,0 +1,36 @@ +#import "SentryConcurrentRateLimitsDictionary.h" +#import + +@interface +SentryConcurrentRateLimitsDictionary () + +/* Key is the type and value is valid until date */ +@property (nonatomic, strong) NSMutableDictionary *rateLimits; + +@end + +@implementation SentryConcurrentRateLimitsDictionary + +- (instancetype)init +{ + if (self = [super init]) { + self.rateLimits = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void)addRateLimit:(SentryRateLimitCategory)category validUntil:(NSDate *)date +{ + @synchronized(self.rateLimits) { + self.rateLimits[@(category)] = date; + } +} + +- (NSDate *)getRateLimitForCategory:(SentryRateLimitCategory)category +{ + @synchronized(self.rateLimits) { + return self.rateLimits[@(category)]; + } +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashAdapter.m b/Pods/Sentry/Sources/Sentry/SentryCrashAdapter.m new file mode 100644 index 00000000..a5fe31f8 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashAdapter.m @@ -0,0 +1,27 @@ +#import "SentryCrashAdapter.h" +#import "SentryCrash.h" +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryCrashAdapter + +- (BOOL)crashedLastLaunch +{ + return SentryCrash.sharedInstance.crashedLastLaunch; +} + +- (NSTimeInterval)activeDurationSinceLastCrash +{ + return SentryCrash.sharedInstance.activeDurationSinceLastCrash; +} + +- (BOOL)isBeingTraced +{ + return sentrycrashdebug_isBeingTraced(); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashDefaultBinaryImageProvider.m b/Pods/Sentry/Sources/Sentry/SentryCrashDefaultBinaryImageProvider.m new file mode 100644 index 00000000..4159a499 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashDefaultBinaryImageProvider.m @@ -0,0 +1,20 @@ +#import "SentryCrashDefaultBinaryImageProvider.h" +#import "SentryCrashBinaryImageProvider.h" +#import "SentryCrashDynamicLinker.h" +#import + +@implementation SentryCrashDefaultBinaryImageProvider + +- (NSInteger)getImageCount +{ + return sentrycrashdl_imageCount(); +} + +- (SentryCrashBinaryImage)getBinaryImage:(NSInteger)index +{ + SentryCrashBinaryImage image = { 0 }; + sentrycrashdl_getBinaryImage((int)index, &image); + return image; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashDefaultMachineContextWrapper.m b/Pods/Sentry/Sources/Sentry/SentryCrashDefaultMachineContextWrapper.m new file mode 100644 index 00000000..77001bbb --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashDefaultMachineContextWrapper.m @@ -0,0 +1,45 @@ +#import "SentryCrashDefaultMachineContextWrapper.h" +#import "SentryCrashDynamicLinker.h" +#import "SentryCrashMachineContext.h" +#import "SentryCrashMachineContextWrapper.h" +#import "SentryCrashStackCursor.h" +#import "SentryCrashStackCursor_SelfThread.h" +#import "SentryCrashThread.h" +#import "SentryFrame.h" +#import "SentryHexAddressFormatter.h" +#import "SentryStacktrace.h" +#import "SentryStacktraceBuilder.h" +#import "SentryThread.h" +#import +#include + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryCrashDefaultMachineContextWrapper + +- (void)fillContextForCurrentThread:(struct SentryCrashMachineContext *)context +{ + sentrycrashmc_getContextForThread(sentrycrashthread_self(), context, true); +} + +- (int)getThreadCount:(struct SentryCrashMachineContext *)context +{ + return sentrycrashmc_getThreadCount(context); +} + +- (SentryCrashThread)getThread:(struct SentryCrashMachineContext *)context withIndex:(int)index +{ + SentryCrashThread thread = sentrycrashmc_getThreadAtIndex(context, index); + return thread; +} + +- (void)getThreadName:(const SentryCrashThread)thread + andBuffer:(char *const)buffer + andBufLength:(int)bufLength; +{ + sentrycrashthread_getThreadName(thread, buffer, bufLength); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashExceptionApplication.m b/Pods/Sentry/Sources/Sentry/SentryCrashExceptionApplication.m new file mode 100644 index 00000000..3ec83729 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashExceptionApplication.m @@ -0,0 +1,28 @@ +#import "SentryCrashExceptionApplication.h" +#import "SentryCrash.h" +#import "SentryDefines.h" +#import "SentrySDK.h" + +@implementation SentryCrashExceptionApplication + +#if TARGET_OS_OSX + +- (void)reportException:(NSException *)exception +{ + [[NSUserDefaults standardUserDefaults] + registerDefaults:@{ @"NSApplicationCrashOnExceptions" : @YES }]; + if (nil != SentryCrash.sharedInstance.uncaughtExceptionHandler && nil != exception) { + SentryCrash.sharedInstance.uncaughtExceptionHandler(exception); + } + [super reportException:exception]; +} + +- (void)_crashOnException:(NSException *)exception +{ + [SentrySDK captureException:exception]; + abort(); +} + +#endif + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashInstallationReporter.m b/Pods/Sentry/Sources/Sentry/SentryCrashInstallationReporter.m new file mode 100644 index 00000000..5f67cdc7 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashInstallationReporter.m @@ -0,0 +1,55 @@ +#import "SentryCrashInstallationReporter.h" +#import "SentryCrash.h" +#import "SentryCrashInstallation+Private.h" +#import "SentryCrashReportSink.h" +#import "SentryDefines.h" +#import "SentryLog.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryCrashInstallationReporter () + +@property (nonatomic, strong) SentryFrameInAppLogic *frameInAppLogic; + +@end + +@implementation SentryCrashInstallationReporter + +- (instancetype)initWithFrameInAppLogic:(SentryFrameInAppLogic *)frameInAppLogic +{ + if (self = [super initWithRequiredProperties:[NSArray new]]) { + self.frameInAppLogic = frameInAppLogic; + } + return self; +} + +- (id)sink +{ + return [[SentryCrashReportSink alloc] initWithFrameInAppLogic:self.frameInAppLogic]; +} + +- (void)sendAllReports +{ + [self sendAllReportsWithCompletion:NULL]; +} + +- (void)sendAllReportsWithCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + [super + sendAllReportsWithCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + if (nil != error) { + [SentryLog logWithMessage:error.localizedDescription andLevel:kSentryLevelError]; + } + [SentryLog logWithMessage:[NSString stringWithFormat:@"Sent %lu crash report(s)", + (unsigned long)filteredReports.count] + andLevel:kSentryLevelDebug]; + if (completed && onCompletion) { + onCompletion(filteredReports, completed, error); + } + }]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashIntegration.m b/Pods/Sentry/Sources/Sentry/SentryCrashIntegration.m new file mode 100644 index 00000000..16a8e717 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashIntegration.m @@ -0,0 +1,239 @@ +#import "SentryCrashIntegration.h" +#import "SentryCrashAdapter.h" +#import "SentryCrashInstallationReporter.h" +#import "SentryDispatchQueueWrapper.h" +#import "SentryEvent.h" +#import "SentryFrameInAppLogic.h" +#import "SentryHook.h" +#import "SentryHub.h" +#import "SentryOutOfMemoryLogic.h" +#import "SentrySDK+Private.h" +#import "SentryScope+Private.h" +#import "SentrySessionCrashedHandler.h" + +#if SENTRY_HAS_UIKIT +# import +#endif + +static dispatch_once_t installationToken = 0; +static SentryCrashInstallationReporter *installation = nil; + +@interface +SentryCrashIntegration () + +@property (nonatomic, weak) SentryOptions *options; +@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueueWrapper; +@property (nonatomic, strong) SentryCrashAdapter *crashAdapter; +@property (nonatomic, strong) SentrySessionCrashedHandler *crashedSessionHandler; + +@end + +@implementation SentryCrashIntegration + +- (instancetype)init +{ + if (self = [super init]) { + self.crashAdapter = [[SentryCrashAdapter alloc] init]; + self.dispatchQueueWrapper = [[SentryDispatchQueueWrapper alloc] init]; + } + return self; +} + +/** Internal constructor for testing */ +- (instancetype)initWithCrashAdapter:(SentryCrashAdapter *)crashAdapter + andDispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper +{ + self = [self init]; + self.crashAdapter = crashAdapter; + self.dispatchQueueWrapper = dispatchQueueWrapper; + + return self; +} + +/** + * Wrapper for `SentryCrash.sharedInstance.systemInfo`, to cash the result. + * + * @return NSDictionary system info. + */ ++ (NSDictionary *)systemInfo +{ + static NSDictionary *sharedInfo = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ sharedInfo = SentryCrash.sharedInstance.systemInfo; }); + return sharedInfo; +} + +- (void)installWithOptions:(nonnull SentryOptions *)options +{ + self.options = options; + + SentryOutOfMemoryLogic *logic = + [[SentryOutOfMemoryLogic alloc] initWithOptions:options crashAdapter:self.crashAdapter]; + self.crashedSessionHandler = + [[SentrySessionCrashedHandler alloc] initWithCrashWrapper:self.crashAdapter + outOfMemoryLogic:logic]; + + [self startCrashHandler]; + sentrycrash_install_async_hooks(); + [self configureScope]; +} + +- (void)startCrashHandler +{ + void (^block)(void) = ^{ + SentryFrameInAppLogic *frameInAppLogic = + [[SentryFrameInAppLogic alloc] initWithInAppIncludes:self.options.inAppIncludes + inAppExcludes:self.options.inAppExcludes]; + installation = + [[SentryCrashInstallationReporter alloc] initWithFrameInAppLogic:frameInAppLogic]; + [installation install]; + + // We need to send the crashed event together with the crashed session in the same envelope + // to have proper statistics in release health. To achieve this we need both synchronously + // in the hub. The crashed event is converted from a SentryCrashReport to an event in + // SentryCrashReportSink and then passed to the SDK on a background thread. This process is + // started with installing this integration. We need to end and delete the previous session + // before being able to start a new session for the AutoSessionTrackingIntegration. The + // SentryCrashIntegration is installed before the AutoSessionTrackingIntegration so there is + // no guarantee if the crashed event is created before or after the + // AutoSessionTrackingIntegration. By ending the previous session and storing it as crashed + // in here we have the guarantee once the crashed event is sent to the hub it is already + // there and the AutoSessionTrackingIntegration can work properly. + // + // This is a pragmatic and not the most optimal place for this logic. + [self.crashedSessionHandler endCurrentSessionAsCrashedWhenCrashOrOOM]; + + [installation sendAllReports]; + }; + [self.dispatchQueueWrapper dispatchOnce:&installationToken block:block]; +} + +- (void)uninstall +{ + if (nil != installation) { + // Its not really possible to uninstall SentryCrash. Best we can do is to deactivate + // all the monitors and clear the `onCrash` callback installed on the global handler. + SentryCrash *handler = [SentryCrash sharedInstance]; + @synchronized(handler) { + [handler setMonitoring:SentryCrashMonitorTypeNone]; + handler.onCrash = NULL; + } + installation = nil; + installationToken = 0; + } + sentrycrash_deactivate_async_hooks(); +} + +- (void)configureScope +{ + // We need to make sure to set always the scope to KSCrash so we have it in + // case of a crash + NSString *integrationName = NSStringFromClass(SentryCrashIntegration.class); + if (nil != [SentrySDK.currentHub getIntegration:integrationName]) { + [SentrySDK.currentHub configureScope:^(SentryScope *_Nonnull outerScope) { + // OS + NSMutableDictionary *osData = [NSMutableDictionary new]; + +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST + [osData setValue:@"macOS" forKey:@"name"]; +#elif TARGET_OS_IOS + [osData setValue:@"iOS" forKey:@"name"]; +#elif TARGET_OS_TV + [osData setValue:@"tvOS" forKey:@"name"]; +#elif TARGET_OS_WATCH + [osData setValue:@"watchOS" forKey:@"name"]; +#endif + + // For MacCatalyst the UIDevice returns the current version of MacCatalyst and not the + // macOSVersion. Therefore we have to use NSProcessInfo. +#if SENTRY_HAS_UIDEVICE && !TARGET_OS_MACCATALYST + [osData setValue:[UIDevice currentDevice].systemVersion forKey:@"version"]; +#else + NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion; + NSString *systemVersion = + [NSString stringWithFormat:@"%d.%d.%d", (int)version.majorVersion, + (int)version.minorVersion, (int)version.patchVersion]; + [osData setValue:systemVersion forKey:@"version"]; + +#endif + + NSDictionary *systemInfo = [SentryCrashIntegration systemInfo]; + [osData setValue:systemInfo[@"osVersion"] forKey:@"build"]; + [osData setValue:systemInfo[@"kernelVersion"] forKey:@"kernel_version"]; + [osData setValue:systemInfo[@"isJailbroken"] forKey:@"rooted"]; + + [outerScope setContextValue:osData forKey:@"os"]; + + // DEVICE + + NSMutableDictionary *deviceData = [NSMutableDictionary new]; + +#if TARGET_OS_SIMULATOR + [deviceData setValue:@(YES) forKey:@"simulator"]; +#endif + + NSString *family = [[systemInfo[@"systemName"] + componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] + firstObject]; + +#if TARGET_OS_MACCATALYST + // This would be iOS. Set it to macOS instead. + family = @"macOS"; +#endif + + [deviceData setValue:family forKey:@"family"]; + [deviceData setValue:systemInfo[@"cpuArchitecture"] forKey:@"arch"]; + [deviceData setValue:systemInfo[@"machine"] forKey:@"model"]; + [deviceData setValue:systemInfo[@"model"] forKey:@"model_id"]; + [deviceData setValue:systemInfo[@"freeMemory"] forKey:SentryDeviceContextFreeMemoryKey]; + [deviceData setValue:systemInfo[@"usableMemory"] forKey:@"usable_memory"]; + [deviceData setValue:systemInfo[@"memorySize"] forKey:@"memory_size"]; + [deviceData setValue:systemInfo[@"storageSize"] forKey:@"storage_size"]; + [deviceData setValue:systemInfo[@"bootTime"] forKey:@"boot_time"]; + [deviceData setValue:systemInfo[@"timezone"] forKey:@"timezone"]; + + [outerScope setContextValue:deviceData forKey:@"device"]; + + // APP + + NSMutableDictionary *appData = [NSMutableDictionary new]; + NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; + + [appData setValue:infoDict[@"CFBundleIdentifier"] forKey:@"app_identifier"]; + [appData setValue:infoDict[@"CFBundleName"] forKey:@"app_name"]; + [appData setValue:infoDict[@"CFBundleVersion"] forKey:@"app_build"]; + [appData setValue:infoDict[@"CFBundleShortVersionString"] forKey:@"app_version"]; + + [appData setValue:systemInfo[@"appStartTime"] forKey:@"app_start_time"]; + [appData setValue:systemInfo[@"deviceAppHash"] forKey:@"device_app_hash"]; + [appData setValue:systemInfo[@"appID"] forKey:@"app_id"]; + [appData setValue:systemInfo[@"buildType"] forKey:@"build_type"]; + + [outerScope setContextValue:appData forKey:@"app"]; + + [outerScope addScopeListener:^(SentryScope *_Nonnull scope) { + // The serialization of the scope and synching it to SentryCrash can use quite some + // CPU time. We want to make sure that this doesn't happen on the main thread. We + // accept the tradeoff that in case of a crash the scope might not be 100% up to + // date over blocking the main thread. + [self.dispatchQueueWrapper dispatchAsyncWithBlock:^{ + NSMutableDictionary *userInfo = + [[NSMutableDictionary alloc] initWithDictionary:[scope serialize]]; + + // SentryCrashReportConverter.convertReportToEvent needs the release name and + // the dist of the SentryOptions in the UserInfo. When SentryCrash records a + // crash it writes the UserInfo into SentryCrashField_User of the report. + // SentryCrashReportConverter.initWithReport loads the contents of + // SentryCrashField_User into self.userContext and convertReportToEvent can map + // the release name and dist to the SentryEvent. Fixes GH-581 + userInfo[@"release"] = self.options.releaseName; + userInfo[@"dist"] = self.options.dist; + + [SentryCrash.sharedInstance setUserInfo:userInfo]; + }]; + }]; + }]; + } +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashReportConverter.m b/Pods/Sentry/Sources/Sentry/SentryCrashReportConverter.m new file mode 100644 index 00000000..0c19ca08 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashReportConverter.m @@ -0,0 +1,462 @@ +#import "SentryCrashReportConverter.h" +#import "NSDate+SentryExtras.h" +#import "SentryBreadcrumb.h" +#import "SentryDebugMeta.h" +#import "SentryEvent.h" +#import "SentryException.h" +#import "SentryFrame.h" +#import "SentryFrameInAppLogic.h" +#import "SentryHexAddressFormatter.h" +#import "SentryLog.h" +#import "SentryMechanism.h" +#import "SentryMechanismMeta.h" +#import "SentryStacktrace.h" +#import "SentryThread.h" +#import "SentryUser.h" + +@interface +SentryCrashReportConverter () + +@property (nonatomic, strong) NSDictionary *report; +@property (nonatomic, assign) NSInteger crashedThreadIndex; +@property (nonatomic, strong) NSDictionary *exceptionContext; +@property (nonatomic, strong) NSArray *binaryImages; +@property (nonatomic, strong) NSArray *threads; +@property (nonatomic, strong) NSDictionary *systemContext; +@property (nonatomic, strong) NSString *diagnosis; +@property (nonatomic, strong) SentryFrameInAppLogic *frameInAppLogic; + +@end + +@implementation SentryCrashReportConverter + +- (instancetype)initWithReport:(NSDictionary *)report + frameInAppLogic:(SentryFrameInAppLogic *)frameInAppLogic +{ + self = [super init]; + if (self) { + self.report = report; + self.frameInAppLogic = frameInAppLogic; + self.systemContext = report[@"system"]; + self.userContext = report[@"user"]; + + NSDictionary *crashContext; + // This is an incomplete crash report + if (nil != report[@"recrash_report"][@"crash"]) { + crashContext = report[@"recrash_report"][@"crash"]; + } else { + crashContext = report[@"crash"]; + } + + if (nil != report[@"recrash_report"][@"binary_images"]) { + self.binaryImages = report[@"recrash_report"][@"binary_images"]; + } else { + self.binaryImages = report[@"binary_images"]; + } + + self.diagnosis = crashContext[@"diagnosis"]; + self.exceptionContext = crashContext[@"error"]; + [self initThreads:crashContext[@"threads"]]; + } + return self; +} + +- (void)initThreads:(NSArray *)threads +{ + if (nil != threads && [threads isKindOfClass:[NSArray class]]) { + // SentryCrash sometimes produces recrash_reports where an element of threads is a + // NSString instead of a NSDictionary. When this happens we can't read the details of + // the thread, but we have to discard it. Otherwise we would crash. + NSPredicate *onlyNSDictionary = [NSPredicate predicateWithBlock:^BOOL(id object, + NSDictionary *bindings) { return [object isKindOfClass:[NSDictionary class]]; }]; + self.threads = [threads filteredArrayUsingPredicate:onlyNSDictionary]; + + for (NSUInteger i = 0; i < self.threads.count; i++) { + NSDictionary *thread = self.threads[i]; + if ([thread[@"crashed"] boolValue]) { + self.crashedThreadIndex = (NSInteger)i; + break; + } + } + } +} + +- (SentryEvent *_Nullable)convertReportToEvent +{ + @try { + SentryEvent *event = [[SentryEvent alloc] initWithLevel:kSentryLevelFatal]; + if ([self.report[@"report"][@"timestamp"] isKindOfClass:NSNumber.class]) { + event.timestamp = [NSDate + dateWithTimeIntervalSince1970:[self.report[@"report"][@"timestamp"] integerValue]]; + } else { + event.timestamp = + [NSDate sentry_fromIso8601String:self.report[@"report"][@"timestamp"]]; + } + event.debugMeta = [self convertDebugMeta]; + event.threads = [self convertThreads]; + event.exceptions = [self convertExceptions]; + + event.dist = self.userContext[@"dist"]; + event.environment = self.userContext[@"environment"]; + event.context = self.userContext[@"context"]; + event.extra = self.userContext[@"extra"]; + event.tags = self.userContext[@"tags"]; + // event.level we do not set the level here since this always resulted + // from a fatal crash + + event.user = [self convertUser]; + event.breadcrumbs = [self convertBreadcrumbs]; + + // The releaseName must be set on the userInfo of SentryCrash.sharedInstance + event.releaseName = self.userContext[@"release"]; + + // We want to set the release and dist to the version from the crash report + // itself otherwise it can happend that we have two different version when + // the app crashes right before an app update #218 #219 + NSDictionary *appContext = event.context[@"app"]; + if (nil == event.releaseName && appContext[@"app_identifier"] && appContext[@"app_version"] + && appContext[@"app_build"]) { + event.releaseName = + [NSString stringWithFormat:@"%@@%@+%@", appContext[@"app_identifier"], + appContext[@"app_version"], appContext[@"app_build"]]; + } + + if (nil == event.dist && appContext[@"app_build"]) { + event.dist = appContext[@"app_build"]; + } + + return event; + } @catch (NSException *exception) { + NSString *errorMessage = + [NSString stringWithFormat:@"Could not convert report:%@", exception.description]; + [SentryLog logWithMessage:errorMessage andLevel:kSentryLevelError]; + } + + return nil; +} + +- (SentryUser *_Nullable)convertUser +{ + SentryUser *user = nil; + if (nil != self.userContext[@"user"]) { + NSDictionary *storedUser = self.userContext[@"user"]; + user = [[SentryUser alloc] init]; + user.userId = storedUser[@"id"]; + user.email = storedUser[@"email"]; + user.username = storedUser[@"username"]; + user.data = storedUser[@"data"]; + } + return user; +} + +- (NSMutableArray *)convertBreadcrumbs +{ + NSMutableArray *breadcrumbs = [NSMutableArray new]; + if (nil != self.userContext[@"breadcrumbs"]) { + NSArray *storedBreadcrumbs = self.userContext[@"breadcrumbs"]; + for (NSDictionary *storedCrumb in storedBreadcrumbs) { + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] + initWithLevel:[self sentryLevelFromString:storedCrumb[@"level"]] + category:storedCrumb[@"category"]]; + crumb.message = storedCrumb[@"message"]; + crumb.type = storedCrumb[@"type"]; + crumb.timestamp = [NSDate sentry_fromIso8601String:storedCrumb[@"timestamp"]]; + crumb.data = storedCrumb[@"data"]; + [breadcrumbs addObject:crumb]; + } + } + return breadcrumbs; +} + +- (SentryLevel)sentryLevelFromString:(NSString *)level +{ + if ([level isEqualToString:@"fatal"]) { + return kSentryLevelFatal; + } else if ([level isEqualToString:@"warning"]) { + return kSentryLevelWarning; + } else if ([level isEqualToString:@"info"] || [level isEqualToString:@"log"]) { + return kSentryLevelInfo; + } else if ([level isEqualToString:@"debug"]) { + return kSentryLevelDebug; + } else if ([level isEqualToString:@"error"]) { + return kSentryLevelError; + } + return kSentryLevelError; +} + +- (NSArray *)rawStackTraceForThreadIndex:(NSInteger)threadIndex +{ + NSDictionary *thread = self.threads[threadIndex]; + return thread[@"backtrace"][@"contents"]; +} + +- (NSDictionary *)registersForThreadIndex:(NSInteger)threadIndex +{ + NSDictionary *thread = self.threads[threadIndex]; + NSMutableDictionary *registers = [NSMutableDictionary new]; + for (NSString *key in [thread[@"registers"][@"basic"] allKeys]) { + [registers setValue:sentry_formatHexAddress(thread[@"registers"][@"basic"][key]) + forKey:key]; + } + return registers; +} + +- (NSDictionary *)binaryImageForAddress:(uintptr_t)address +{ + NSDictionary *result = nil; + for (NSDictionary *binaryImage in self.binaryImages) { + uintptr_t imageStart = (uintptr_t)[binaryImage[@"image_addr"] unsignedLongLongValue]; + uintptr_t imageEnd + = imageStart + (uintptr_t)[binaryImage[@"image_size"] unsignedLongLongValue]; + if (address >= imageStart && address < imageEnd) { + result = binaryImage; + break; + } + } + return result; +} + +- (SentryThread *_Nullable)threadAtIndex:(NSInteger)threadIndex + stripCrashedStacktrace:(BOOL)stripCrashedStacktrace +{ + if (threadIndex >= [self.threads count]) { + return nil; + } + NSDictionary *threadDictionary = self.threads[threadIndex]; + + SentryThread *thread = [[SentryThread alloc] initWithThreadId:threadDictionary[@"index"]]; + // We only want to add the stacktrace if this thread hasn't crashed + thread.stacktrace = [self stackTraceForThreadIndex:threadIndex]; + if (thread.stacktrace.frames.count == 0) { + // If we don't have any frames, we discard the whole frame + thread.stacktrace = nil; + } + thread.crashed = threadDictionary[@"crashed"]; + thread.current = threadDictionary[@"current_thread"]; + thread.name = threadDictionary[@"name"]; + if (nil == thread.name) { + thread.name = threadDictionary[@"dispatch_queue"]; + } + return thread; +} + +- (SentryFrame *)stackFrameAtIndex:(NSInteger)frameIndex inThreadIndex:(NSInteger)threadIndex +{ + NSDictionary *frameDictionary = [self rawStackTraceForThreadIndex:threadIndex][frameIndex]; + uintptr_t instructionAddress + = (uintptr_t)[frameDictionary[@"instruction_addr"] unsignedLongLongValue]; + NSDictionary *binaryImage = [self binaryImageForAddress:instructionAddress]; + SentryFrame *frame = [[SentryFrame alloc] init]; + frame.symbolAddress = sentry_formatHexAddress(frameDictionary[@"symbol_addr"]); + frame.instructionAddress = sentry_formatHexAddress(frameDictionary[@"instruction_addr"]); + frame.imageAddress = sentry_formatHexAddress(binaryImage[@"image_addr"]); + frame.package = binaryImage[@"name"]; + BOOL isInApp = [self.frameInAppLogic isInApp:binaryImage[@"name"]]; + frame.inApp = @(isInApp); + if (frameDictionary[@"symbol_name"]) { + frame.function = frameDictionary[@"symbol_name"]; + } + return frame; +} + +// We already get all the frames in the right order +- (NSArray *)stackFramesForThreadIndex:(NSInteger)threadIndex +{ + NSUInteger frameCount = [self rawStackTraceForThreadIndex:threadIndex].count; + if (frameCount <= 0) { + return [NSArray new]; + } + + NSMutableArray *frames = [NSMutableArray arrayWithCapacity:frameCount]; + for (NSInteger i = frameCount - 1; i >= 0; i--) { + [frames addObject:[self stackFrameAtIndex:i inThreadIndex:threadIndex]]; + } + return frames; +} + +- (SentryStacktrace *)stackTraceForThreadIndex:(NSInteger)threadIndex +{ + NSArray *frames = [self stackFramesForThreadIndex:threadIndex]; + SentryStacktrace *stacktrace = + [[SentryStacktrace alloc] initWithFrames:frames + registers:[self registersForThreadIndex:threadIndex]]; + [stacktrace fixDuplicateFrames]; + return stacktrace; +} + +- (SentryThread *_Nullable)crashedThread +{ + return [self threadAtIndex:self.crashedThreadIndex stripCrashedStacktrace:NO]; +} + +- (NSArray *)convertDebugMeta +{ + NSMutableArray *result = [NSMutableArray new]; + for (NSDictionary *sourceImage in self.binaryImages) { + SentryDebugMeta *debugMeta = [[SentryDebugMeta alloc] init]; + debugMeta.uuid = sourceImage[@"uuid"]; + debugMeta.type = @"apple"; + // We default to 0 on the server if not sent + if ([sourceImage[@"image_vmaddr"] integerValue] > 0) { + debugMeta.imageVmAddress = sentry_formatHexAddress(sourceImage[@"image_vmaddr"]); + } + debugMeta.imageAddress = sentry_formatHexAddress(sourceImage[@"image_addr"]); + debugMeta.imageSize = sourceImage[@"image_size"]; + debugMeta.name = sourceImage[@"name"]; + [result addObject:debugMeta]; + } + return result; +} + +- (NSArray *_Nullable)convertExceptions +{ + if (nil == self.exceptionContext) { + return nil; + } + NSString *const exceptionType = self.exceptionContext[@"type"] ?: @"Unknown Exception"; + SentryException *exception = nil; + if ([exceptionType isEqualToString:@"nsexception"]) { + exception = [self parseNSException]; + } else if ([exceptionType isEqualToString:@"cpp_exception"]) { + exception = + [[SentryException alloc] initWithValue:self.exceptionContext[@"cpp_exception"][@"name"] + type:@"C++ Exception"]; + } else if ([exceptionType isEqualToString:@"mach"]) { + exception = [[SentryException alloc] + initWithValue:[NSString stringWithFormat:@"Exception %@, Code %@, Subcode %@", + self.exceptionContext[@"mach"][@"exception"], + self.exceptionContext[@"mach"][@"code"], + self.exceptionContext[@"mach"][@"subcode"]] + type:self.exceptionContext[@"mach"][@"exception_name"]]; + } else if ([exceptionType isEqualToString:@"signal"]) { + exception = [[SentryException alloc] + initWithValue:[NSString stringWithFormat:@"Signal %@, Code %@", + self.exceptionContext[@"signal"][@"signal"], + self.exceptionContext[@"signal"][@"code"]] + type:self.exceptionContext[@"signal"][@"name"]]; + } else if ([exceptionType isEqualToString:@"user"]) { + NSString *exceptionReason = + [NSString stringWithFormat:@"%@", self.exceptionContext[@"reason"]]; + exception = [[SentryException alloc] + initWithValue:exceptionReason + type:self.exceptionContext[@"user_reported"][@"name"]]; + + NSRange match = [exceptionReason rangeOfString:@":"]; + if (match.location != NSNotFound) { + exception = [[SentryException alloc] + initWithValue:[[exceptionReason + substringWithRange:NSMakeRange(match.location + match.length, + (exceptionReason.length - match.location) + - match.length)] + stringByTrimmingCharactersInSet:[NSCharacterSet + whitespaceCharacterSet]] + type:[exceptionReason substringWithRange:NSMakeRange(0, match.location)]]; + } + } else { + exception = [[SentryException alloc] initWithValue:@"Unknown Exception" type:exceptionType]; + } + + [self enhanceValueFromNotableAddresses:exception]; + exception.mechanism = [self extractMechanismOfType:exceptionType]; + + SentryThread *crashedThread = [self crashedThread]; + exception.threadId = crashedThread.threadId; + exception.stacktrace = crashedThread.stacktrace; + + if (nil != self.diagnosis && self.diagnosis.length > 0 + && ![self.diagnosis containsString:exception.value]) { + exception.value = [exception.value + stringByAppendingString:[NSString stringWithFormat:@" >\n%@", self.diagnosis]]; + } + return @[ exception ]; +} + +- (SentryException *)parseNSException +{ + NSString *reason = @""; + if (nil != self.exceptionContext[@"nsexception"][@"reason"]) { + reason = self.exceptionContext[@"nsexception"][@"reason"]; + } else if (nil != self.exceptionContext[@"reason"]) { + reason = self.exceptionContext[@"reason"]; + } + + return [[SentryException alloc] initWithValue:[NSString stringWithFormat:@"%@", reason] + type:self.exceptionContext[@"nsexception"][@"name"]]; +} + +- (void)enhanceValueFromNotableAddresses:(SentryException *)exception +{ + // Gatekeeper fixes https://github.com/getsentry/sentry-cocoa/issues/231 + if ([self.threads count] == 0 || self.crashedThreadIndex >= [self.threads count]) { + return; + } + NSDictionary *crashedThread = self.threads[self.crashedThreadIndex]; + NSDictionary *notableAddresses = crashedThread[@"notable_addresses"]; + NSMutableOrderedSet *reasons = [[NSMutableOrderedSet alloc] init]; + if (nil != notableAddresses) { + for (id key in notableAddresses) { + NSDictionary *content = notableAddresses[key]; + if ([content[@"type"] isEqualToString:@"string"] && nil != content[@"value"]) { + // if there are less than 3 slashes it shouldn't be a filepath + if ([[content[@"value"] componentsSeparatedByString:@"/"] count] < 3) { + [reasons addObject:content[@"value"]]; + } + } + } + } + if (reasons.count > 0) { + exception.value = + [[[reasons array] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] + componentsJoinedByString:@" > "]; + } +} + +- (SentryMechanism *_Nullable)extractMechanismOfType:(nonnull NSString *)type +{ + SentryMechanism *mechanism = [[SentryMechanism alloc] initWithType:type]; + if (nil != self.exceptionContext[@"mach"]) { + mechanism.handled = @(NO); + + SentryMechanismMeta *meta = [[SentryMechanismMeta alloc] init]; + + NSMutableDictionary *machException = [NSMutableDictionary new]; + [machException setValue:self.exceptionContext[@"mach"][@"exception_name"] forKey:@"name"]; + [machException setValue:self.exceptionContext[@"mach"][@"exception"] forKey:@"exception"]; + [machException setValue:self.exceptionContext[@"mach"][@"subcode"] forKey:@"subcode"]; + [machException setValue:self.exceptionContext[@"mach"][@"code"] forKey:@"code"]; + meta.machException = machException; + + if (nil != self.exceptionContext[@"signal"]) { + NSMutableDictionary *signal = [NSMutableDictionary new]; + [signal setValue:self.exceptionContext[@"signal"][@"signal"] forKey:@"number"]; + [signal setValue:self.exceptionContext[@"signal"][@"code"] forKey:@"code"]; + [signal setValue:self.exceptionContext[@"signal"][@"code_name"] forKey:@"code_name"]; + [signal setValue:self.exceptionContext[@"signal"][@"name"] forKey:@"name"]; + meta.signal = signal; + } + + mechanism.meta = meta; + + if (nil != self.exceptionContext[@"address"] && + [self.exceptionContext[@"address"] integerValue] > 0) { + mechanism.data = @{ + @"relevant_address" : sentry_formatHexAddress(self.exceptionContext[@"address"]) + }; + } + } + return mechanism; +} + +- (NSArray *)convertThreads +{ + NSMutableArray *result = [NSMutableArray new]; + for (NSInteger threadIndex = 0; threadIndex < (NSInteger)self.threads.count; threadIndex++) { + SentryThread *thread = [self threadAtIndex:threadIndex stripCrashedStacktrace:YES]; + if (thread && nil != thread.stacktrace) { + [result addObject:thread]; + } + } + return result; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashReportSink.m b/Pods/Sentry/Sources/Sentry/SentryCrashReportSink.m new file mode 100644 index 00000000..5bf0a249 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashReportSink.m @@ -0,0 +1,70 @@ +#import "SentryCrashReportSink.h" +#import "SentryClient.h" +#import "SentryCrash.h" +#import "SentryCrashReportConverter.h" +#import "SentryDefines.h" +#import "SentryEvent.h" +#import "SentryException.h" +#import "SentryHub.h" +#import "SentryLog.h" +#import "SentrySDK+Private.h" +#import "SentrySDK.h" +#import "SentryThread.h" + +@interface +SentryCrashReportSink () + +@property (nonatomic, strong) SentryFrameInAppLogic *frameInAppLogic; + +@end + +@implementation SentryCrashReportSink + +- (instancetype)initWithFrameInAppLogic:(SentryFrameInAppLogic *)frameInAppLogic +{ + if (self = [super init]) { + self.frameInAppLogic = frameInAppLogic; + } + return self; +} + +- (void)handleConvertedEvent:(SentryEvent *)event + report:(NSDictionary *)report + sentReports:(NSMutableArray *)sentReports +{ + [sentReports addObject:report]; + [SentrySDK captureCrashEvent:event]; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); + dispatch_async(queue, ^{ + NSMutableArray *sentReports = [NSMutableArray new]; + for (NSDictionary *report in reports) { + SentryCrashReportConverter *reportConverter = + [[SentryCrashReportConverter alloc] initWithReport:report + frameInAppLogic:self.frameInAppLogic]; + if (nil != [SentrySDK.currentHub getClient]) { + SentryEvent *event = [reportConverter convertReportToEvent]; + if (nil != event) { + [self handleConvertedEvent:event report:report sentReports:sentReports]; + } + } else { + [SentryLog logWithMessage:@"Crash reports were found but no " + @"[SentrySDK.currentHub getClient] is set. Cannot send " + @"crash reports to Sentry. This is probably a " + @"misconfiguration, make sure you set the client with " + @"[SentrySDK.currentHub bindClient] before calling " + @"startCrashHandlerWithError:." + andLevel:kSentryLevelError]; + } + } + if (onCompletion) { + onCompletion(sentReports, TRUE, nil); + } + }); +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryCrashStackEntryMapper.m b/Pods/Sentry/Sources/Sentry/SentryCrashStackEntryMapper.m new file mode 100644 index 00000000..5500d252 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCrashStackEntryMapper.m @@ -0,0 +1,56 @@ +#import "SentryCrashStackEntryMapper.h" +#import "SentryFrame.h" +#import "SentryFrameInAppLogic.h" +#import "SentryHexAddressFormatter.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryCrashStackEntryMapper () + +@property (nonatomic, strong) SentryFrameInAppLogic *frameInAppLogic; + +@end + +@implementation SentryCrashStackEntryMapper + +- (instancetype)initWithFrameInAppLogic:(SentryFrameInAppLogic *)frameInAppLogic +{ + if (self = [super init]) { + self.frameInAppLogic = frameInAppLogic; + } + return self; +} + +- (SentryFrame *)mapStackEntryWithCursor:(SentryCrashStackCursor)stackCursor +{ + SentryFrame *frame = [[SentryFrame alloc] init]; + + NSNumber *symbolAddress = @(stackCursor.stackEntry.symbolAddress); + frame.symbolAddress = sentry_formatHexAddress(symbolAddress); + + NSNumber *instructionAddress = @(stackCursor.stackEntry.address); + frame.instructionAddress = sentry_formatHexAddress(instructionAddress); + + NSNumber *imageAddress = @(stackCursor.stackEntry.imageAddress); + frame.imageAddress = sentry_formatHexAddress(imageAddress); + + if (stackCursor.stackEntry.symbolName != NULL) { + frame.function = [NSString stringWithCString:stackCursor.stackEntry.symbolName + encoding:NSUTF8StringEncoding]; + } + + if (stackCursor.stackEntry.imageName != NULL) { + NSString *imageName = [NSString stringWithCString:stackCursor.stackEntry.imageName + encoding:NSUTF8StringEncoding]; + frame.package = imageName; + frame.inApp = @([self.frameInAppLogic isInApp:imageName]); + } + + return frame; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryCurrentDate.m b/Pods/Sentry/Sources/Sentry/SentryCurrentDate.m new file mode 100644 index 00000000..519b8132 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryCurrentDate.m @@ -0,0 +1,32 @@ +#import "SentryCurrentDate.h" +#import "SentryCurrentDateProvider.h" +#import "SentryDefaultCurrentDateProvider.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryCurrentDate () + +@end + +@implementation SentryCurrentDate + +static id currentDateProvider; + ++ (NSDate *_Nonnull)date +{ + if (nil == currentDateProvider) { + currentDateProvider = [[SentryDefaultCurrentDateProvider alloc] init]; + } + return [currentDateProvider date]; +} + ++ (void)setCurrentDateProvider:(id)value +{ + currentDateProvider = value; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryDateUtil.m b/Pods/Sentry/Sources/Sentry/SentryDateUtil.m new file mode 100644 index 00000000..6c87f397 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryDateUtil.m @@ -0,0 +1,42 @@ +#import "SentryDateUtil.h" +#import "SentryCurrentDate.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryDateUtil () + +@end + +@implementation SentryDateUtil + ++ (BOOL)isInFuture:(NSDate *_Nullable)date +{ + if (nil == date) + return NO; + + NSComparisonResult result = [[SentryCurrentDate date] compare:date]; + return result == NSOrderedAscending; +} + ++ (NSDate *_Nullable)getMaximumDate:(NSDate *_Nullable)first andOther:(NSDate *_Nullable)second +{ + if (nil == first && nil == second) + return nil; + if (nil == first) + return second; + if (nil == second) + return first; + + NSComparisonResult result = [first compare:second]; + if (result == NSOrderedDescending) { + return first; + } else { + return second; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryDebugMeta.m b/Pods/Sentry/Sources/Sentry/SentryDebugMeta.m new file mode 100644 index 00000000..420ed048 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryDebugMeta.m @@ -0,0 +1,28 @@ +#import "SentryDebugMeta.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryDebugMeta + +- (instancetype)init +{ + return [super init]; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = [NSMutableDictionary new]; + + [serializedData setValue:self.uuid forKey:@"uuid"]; + [serializedData setValue:self.type forKey:@"type"]; + [serializedData setValue:self.imageAddress forKey:@"image_addr"]; + [serializedData setValue:self.imageSize forKey:@"image_size"]; + [serializedData setValue:[self.name lastPathComponent] forKey:@"name"]; + [serializedData setValue:self.imageVmAddress forKey:@"image_vmaddr"]; + + return serializedData; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryDebugMetaBuilder.m b/Pods/Sentry/Sources/Sentry/SentryDebugMetaBuilder.m new file mode 100644 index 00000000..4154da99 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryDebugMetaBuilder.m @@ -0,0 +1,74 @@ +#import "SentryDebugMetaBuilder.h" +#import "SentryCrashDynamicLinker.h" +#import "SentryCrashUUIDConversion.h" +#import "SentryDebugMeta.h" +#import "SentryHexAddressFormatter.h" +#import "SentryLog.h" +#import + +@interface +SentryDebugMetaBuilder () + +@property (nonatomic, strong) id binaryImageProvider; + +@end + +@implementation SentryDebugMetaBuilder + +- (id)initWithBinaryImageProvider:(id)binaryImageProvider +{ + if (self = [super init]) { + self.binaryImageProvider = binaryImageProvider; + } + return self; +} + +- (NSArray *)buildDebugMeta +{ + NSMutableArray *debugMetaArray = [NSMutableArray new]; + + NSInteger imageCount = [self.binaryImageProvider getImageCount]; + for (NSInteger i = 0; i < imageCount; i++) { + SentryCrashBinaryImage image = [self.binaryImageProvider getBinaryImage:i]; + SentryDebugMeta *debugMeta = [self fillDebugMetaFrom:image]; + [debugMetaArray addObject:debugMeta]; + } + + return debugMetaArray; +} + +- (SentryDebugMeta *)fillDebugMetaFrom:(SentryCrashBinaryImage)image +{ + SentryDebugMeta *debugMeta = [[SentryDebugMeta alloc] init]; + debugMeta.uuid = [SentryDebugMetaBuilder convertUUID:image.uuid]; + debugMeta.type = @"apple"; + + if (image.vmAddress > 0) { + NSNumber *imageVmAddress = [NSNumber numberWithUnsignedLongLong:image.vmAddress]; + debugMeta.imageVmAddress = sentry_formatHexAddress(imageVmAddress); + } + + NSNumber *imageAddress = [NSNumber numberWithUnsignedLongLong:image.address]; + debugMeta.imageAddress = sentry_formatHexAddress(imageAddress); + + debugMeta.imageSize = @(image.size); + + if (nil != image.name) { + debugMeta.name = [[NSString alloc] initWithUTF8String:image.name]; + } + + return debugMeta; +} + ++ (NSString *_Nullable)convertUUID:(const unsigned char *const)value +{ + if (nil == value) { + return nil; + } + + char uuidBuffer[37]; + sentrycrashdl_convertBinaryImageUUID(value, uuidBuffer); + return [[NSString alloc] initWithCString:uuidBuffer encoding:NSASCIIStringEncoding]; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryDefaultCurrentDateProvider.m b/Pods/Sentry/Sources/Sentry/SentryDefaultCurrentDateProvider.m new file mode 100644 index 00000000..3ab7b1ea --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryDefaultCurrentDateProvider.m @@ -0,0 +1,20 @@ +#import "SentryDefaultCurrentDateProvider.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryDefaultCurrentDateProvider () + +@end + +@implementation SentryDefaultCurrentDateProvider + +- (NSDate *_Nonnull)date +{ + return [NSDate date]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryDefaultRateLimits.m b/Pods/Sentry/Sources/Sentry/SentryDefaultRateLimits.m new file mode 100644 index 00000000..c624d3c4 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryDefaultRateLimits.m @@ -0,0 +1,86 @@ +#import "SentryDefaultRateLimits.h" +#import "SentryConcurrentRateLimitsDictionary.h" +#import "SentryCurrentDate.h" +#import "SentryDateUtil.h" +#import "SentryLog.h" +#import "SentryRateLimitCategoryMapper.h" +#import "SentryRateLimitParser.h" +#import "SentryRetryAfterHeaderParser.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryDefaultRateLimits () + +@property (nonatomic, strong) SentryConcurrentRateLimitsDictionary *rateLimits; +@property (nonatomic, strong) SentryRetryAfterHeaderParser *retryAfterHeaderParser; +@property (nonatomic, strong) SentryRateLimitParser *rateLimitParser; + +@end + +@implementation SentryDefaultRateLimits + +- (instancetype)initWithRetryAfterHeaderParser: + (SentryRetryAfterHeaderParser *)retryAfterHeaderParser + andRateLimitParser:(SentryRateLimitParser *)rateLimitParser +{ + if (self = [super init]) { + self.rateLimits = [[SentryConcurrentRateLimitsDictionary alloc] init]; + self.retryAfterHeaderParser = retryAfterHeaderParser; + self.rateLimitParser = rateLimitParser; + } + return self; +} + +- (BOOL)isRateLimitActive:(SentryRateLimitCategory)category +{ + NSDate *categoryDate = [self.rateLimits getRateLimitForCategory:category]; + NSDate *allCategoriesDate = + [self.rateLimits getRateLimitForCategory:kSentryRateLimitCategoryAll]; + + BOOL isActiveForCategory = [SentryDateUtil isInFuture:categoryDate]; + BOOL isActiveForCategories = [SentryDateUtil isInFuture:allCategoriesDate]; + + if (isActiveForCategory || isActiveForCategories) { + return YES; + } else { + return NO; + } +} + +- (void)update:(NSHTTPURLResponse *)response +{ + NSString *rateLimitsHeader = response.allHeaderFields[@"X-Sentry-Rate-Limits"]; + if (nil != rateLimitsHeader) { + NSDictionary *limits = [self.rateLimitParser parse:rateLimitsHeader]; + + for (NSNumber *categoryAsNumber in limits.allKeys) { + SentryRateLimitCategory category = [SentryRateLimitCategoryMapper + mapIntegerToCategory:(NSUInteger)[categoryAsNumber integerValue]]; + + [self updateRateLimit:category withDate:limits[categoryAsNumber]]; + } + } else if (response.statusCode == 429) { + NSDate *retryAfterHeaderDate = + [self.retryAfterHeaderParser parse:response.allHeaderFields[@"Retry-After"]]; + + if (nil == retryAfterHeaderDate) { + // parsing failed use default value + retryAfterHeaderDate = [[SentryCurrentDate date] dateByAddingTimeInterval:60]; + } + + [self updateRateLimit:kSentryRateLimitCategoryAll withDate:retryAfterHeaderDate]; + } +} + +- (void)updateRateLimit:(SentryRateLimitCategory)category withDate:(NSDate *)newDate +{ + NSDate *existingDate = [self.rateLimits getRateLimitForCategory:category]; + NSDate *longerRateLimitDate = [SentryDateUtil getMaximumDate:existingDate andOther:newDate]; + [self.rateLimits addRateLimit:category validUntil:longerRateLimitDate]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryDispatchQueueWrapper.m b/Pods/Sentry/Sources/Sentry/SentryDispatchQueueWrapper.m new file mode 100644 index 00000000..dde08019 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryDispatchQueueWrapper.m @@ -0,0 +1,48 @@ +#import "SentryDispatchQueueWrapper.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryDispatchQueueWrapper () + +@property (nonatomic, strong) dispatch_queue_t queue; + +@end + +@implementation SentryDispatchQueueWrapper + +- (instancetype)init +{ + // DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL is requires iOS 10. Since we are targeting + // iOS 9 we need to manually add the autoreleasepool. + dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + self = [self initWithName:"sentry-default" attributes:attributes]; + return self; +} + +- (instancetype)initWithName:(const char *)name attributes:(dispatch_queue_attr_t)attributes; +{ + if (self = [super init]) { + self.queue = dispatch_queue_create(name, attributes); + } + return self; +} + +- (void)dispatchAsyncWithBlock:(void (^)(void))block +{ + dispatch_async(self.queue, ^{ + @autoreleasepool { + block(); + } + }); +} + +- (void)dispatchOnce:(dispatch_once_t *)predicate block:(void (^)(void))block +{ + dispatch_once(predicate, block); +} +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryDsn.m b/Pods/Sentry/Sources/Sentry/SentryDsn.m new file mode 100644 index 00000000..cf0ba4a5 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryDsn.m @@ -0,0 +1,131 @@ +#import + +#import "SentryDsn.h" +#import "SentryError.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryDsn () + +@end + +@implementation SentryDsn { + NSURL *_storeEndpoint; + NSURL *_envelopeEndpoint; +} + +- (_Nullable instancetype)initWithString:(NSString *)dsnString + didFailWithError:(NSError *_Nullable *_Nullable)error +{ + self = [super init]; + if (self) { + _url = [self convertDsnString:dsnString didFailWithError:error]; + if (nil != error && nil != *error) { + return nil; + } + } + return self; +} + +- (NSString *)getHash +{ + NSData *data = [[self.url absoluteString] dataUsingEncoding:NSUTF8StringEncoding]; + uint8_t digest[CC_SHA1_DIGEST_LENGTH]; + CC_SHA1(data.bytes, (CC_LONG)data.length, digest); + NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; + for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { + [output appendFormat:@"%02x", digest[i]]; + } + return output; +} + +- (NSURL *)getStoreEndpoint +{ + if (nil == _storeEndpoint) { + @synchronized(self) { + if (nil == _storeEndpoint) { + _storeEndpoint = [[self getBaseEndpoint] URLByAppendingPathComponent:@"store/"]; + } + } + } + return _storeEndpoint; +} + +- (NSURL *)getEnvelopeEndpoint +{ + if (nil == _envelopeEndpoint) { + @synchronized(self) { + if (nil == _envelopeEndpoint) { + _envelopeEndpoint = + [[self getBaseEndpoint] URLByAppendingPathComponent:@"envelope/"]; + } + } + } + return _envelopeEndpoint; +} + +- (NSURL *)getBaseEndpoint +{ + NSURL *url = self.url; + NSString *projectId = url.lastPathComponent; + NSMutableArray *paths = [url.pathComponents mutableCopy]; + // [0] = / + // [1] = projectId + // If there are more than two, that means someone wants to have an + // additional path ref: https://github.com/getsentry/sentry-cocoa/issues/236 + NSString *path = @""; + if ([paths count] > 2) { + [paths removeObjectAtIndex:0]; // We remove the leading / + [paths removeLastObject]; // We remove projectId since we add it later + path = [NSString stringWithFormat:@"/%@", + [paths componentsJoinedByString:@"/"]]; // We put together the path + } + NSURLComponents *components = [NSURLComponents new]; + components.scheme = url.scheme; + components.host = url.host; + components.port = url.port; + components.path = [NSString stringWithFormat:@"%@/api/%@/", path, projectId]; + return components.URL; +} + +- (NSURL *_Nullable)convertDsnString:(NSString *)dsnString + didFailWithError:(NSError *_Nullable *_Nullable)error +{ + NSString *trimmedDsnString = [dsnString + stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + NSSet *allowedSchemes = [NSSet setWithObjects:@"http", @"https", nil]; + NSURL *url = [NSURL URLWithString:trimmedDsnString]; + NSString *errorMessage = nil; + if (nil == url.scheme) { + errorMessage = @"URL scheme of DSN is missing"; + url = nil; + } + if (![allowedSchemes containsObject:url.scheme]) { + errorMessage = @"Unrecognized URL scheme in DSN"; + url = nil; + } + if (nil == url.host || url.host.length == 0) { + errorMessage = @"Host component of DSN is missing"; + url = nil; + } + if (nil == url.user) { + errorMessage = @"User component of DSN is missing"; + url = nil; + } + if (url.pathComponents.count < 2) { + errorMessage = @"Project ID path component of DSN is missing"; + url = nil; + } + if (nil == url) { + if (nil != error) { + *error = NSErrorFromSentryError(kSentryErrorInvalidDsnError, errorMessage); + } + return nil; + } + return url; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryEnvelope.m b/Pods/Sentry/Sources/Sentry/SentryEnvelope.m new file mode 100644 index 00000000..240a7dc4 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryEnvelope.m @@ -0,0 +1,296 @@ +#import "SentryEnvelope.h" +#import "SentryAttachment.h" +#import "SentryBreadcrumb.h" +#import "SentryEnvelopeItemType.h" +#import "SentryEvent.h" +#import "SentryLog.h" +#import "SentryMessage.h" +#import "SentryMeta.h" +#import "SentrySdkInfo.h" +#import "SentrySerialization.h" +#import "SentrySession.h" +#import "SentryTransaction.h" +#import "SentryUserFeedback.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryEnvelopeHeader + +// id can be null if no event in the envelope or attachment related to event +- (instancetype)initWithId:(SentryId *_Nullable)eventId +{ + SentrySdkInfo *sdkInfo = [[SentrySdkInfo alloc] initWithName:SentryMeta.sdkName + andVersion:SentryMeta.versionString]; + self = [self initWithId:eventId andSdkInfo:sdkInfo]; + + return self; +} + +- (instancetype)initWithId:(SentryId *_Nullable)eventId andSdkInfo:(SentrySdkInfo *_Nullable)sdkInfo +{ + if (self = [super init]) { + _eventId = eventId; + _sdkInfo = sdkInfo; + } + + return self; +} + +@end + +@implementation SentryEnvelopeItemHeader + +- (instancetype)initWithType:(NSString *)type length:(NSUInteger)length +{ + if (self = [super init]) { + _type = type; + _length = length; + } + return self; +} + +- (instancetype)initWithType:(NSString *)type + length:(NSUInteger)length + filenname:(NSString *)filename + contentType:(NSString *)contentType +{ + if (self = [self initWithType:type length:length]) { + _filename = filename; + _contentType = contentType; + } + return self; +} + +@end + +@implementation SentryEnvelopeItem + +- (instancetype)initWithHeader:(SentryEnvelopeItemHeader *)header data:(NSData *)data +{ + if (self = [super init]) { + _header = header; + _data = data; + } + return self; +} + +- (instancetype)initWithEvent:(SentryEvent *)event +{ + NSError *error; + NSData *json = [SentrySerialization dataWithJSONObject:[event serialize] error:&error]; + + if (nil != error) { + // It could be the user added something to the context or the sdk that can't serialized. + event.context = nil; + event.sdk = nil; + error = nil; + json = [SentrySerialization dataWithJSONObject:[event serialize] error:&error]; + + // The context or the sdk was the problem for serialization. Add a breadcrumb that we are + // dropping the context and the sdk. + if (nil == error) { + NSMutableArray *breadcrumbs = [event.breadcrumbs mutableCopy]; + if (nil == breadcrumbs) { + breadcrumbs = [[NSMutableArray alloc] init]; + } + + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelError + category:@"sentry.event"]; + crumb.message = @"A value set to the context or sdk is not serializable. Dropping " + @"context and sdk."; + crumb.type = @"error"; + [breadcrumbs addObject:crumb]; + event.breadcrumbs = breadcrumbs; + + json = [SentrySerialization dataWithJSONObject:[event serialize] error:nil]; + } else { + // We don't know what caused the serialization to fail. + SentryEvent *errorEvent = [[SentryEvent alloc] initWithLevel:kSentryLevelWarning]; + + // Add some context to the event. We can only set simple properties otherwise we + // risk that the conversion fails again. + NSString *message = + [NSString stringWithFormat:@"JSON conversion error for event with message: '%@'", + event.message]; + + errorEvent.message = [[SentryMessage alloc] initWithFormatted:message]; + errorEvent.releaseName = event.releaseName; + errorEvent.environment = event.environment; + errorEvent.platform = event.platform; + errorEvent.timestamp = event.timestamp; + + // We accept the risk that this simple serialization fails. Therefore we ignore the + // error on purpose. + json = [SentrySerialization dataWithJSONObject:[errorEvent serialize] error:nil]; + } + } + + // event.type can be nil and the server infers error if there's a stack trace, otherwise + // default. In any case in the envelope type it should be event. Except for transactions + NSString *envelopeType = [event.type isEqualToString:SentryEnvelopeItemTypeTransaction] + ? SentryEnvelopeItemTypeTransaction + : SentryEnvelopeItemTypeEvent; + + return [self initWithHeader:[[SentryEnvelopeItemHeader alloc] initWithType:envelopeType + length:json.length] + data:json]; +} + +- (instancetype)initWithSession:(SentrySession *)session +{ + NSData *json = [NSJSONSerialization dataWithJSONObject:[session serialize] + options:0 + // TODO: handle error + error:nil]; + return [self + initWithHeader:[[SentryEnvelopeItemHeader alloc] initWithType:SentryEnvelopeItemTypeSession + length:json.length] + data:json]; +} + +- (instancetype)initWithUserFeedback:(SentryUserFeedback *)userFeedback +{ + + NSError *error = nil; + NSData *json = [NSJSONSerialization dataWithJSONObject:[userFeedback serialize] + options:0 + error:&error]; + + if (nil != error) { + [SentryLog logWithMessage:@"Couldn't serialize user feedback." andLevel:kSentryLevelError]; + json = [NSData new]; + } + + return [self initWithHeader:[[SentryEnvelopeItemHeader alloc] + initWithType:SentryEnvelopeItemTypeUserFeedback + length:json.length] + data:json]; +} + +- (_Nullable instancetype)initWithAttachment:(SentryAttachment *)attachment + maxAttachmentSize:(NSUInteger)maxAttachmentSize +{ + NSData *data = nil; + if (nil != attachment.data) { + if (attachment.data.length > maxAttachmentSize) { + NSString *message = + [NSString stringWithFormat:@"Dropping attachment with filename '%@', because the " + @"size of the passed data with %lu bytes is bigger than " + @"the maximum allowed attachment size of %lu bytes.", + attachment.filename, (unsigned long)attachment.data.length, + (unsigned long)maxAttachmentSize]; + [SentryLog logWithMessage:message andLevel:kSentryLevelDebug]; + + return nil; + } + + data = attachment.data; + } else if (nil != attachment.path) { + + NSError *error = nil; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSDictionary *attr = + [fileManager attributesOfItemAtPath:attachment.path error:&error]; + + if (nil != error) { + NSString *message = [NSString + stringWithFormat:@"Couldn't check file size of attachment with path: %@. Error: %@", + attachment.path, error.localizedDescription]; + [SentryLog logWithMessage:message andLevel:kSentryLevelError]; + + return nil; + } + + unsigned long long fileSize = [attr fileSize]; + + if (fileSize > maxAttachmentSize) { + NSString *message = [NSString + stringWithFormat: + @"Dropping attachment, because the size of the it located at '%@' with %llu " + @"bytes is bigger than the maximum allowed attachment size of %lu bytes.", + attachment.path, fileSize, (unsigned long)maxAttachmentSize]; + [SentryLog logWithMessage:message andLevel:kSentryLevelDebug]; + return nil; + } + + data = [[NSFileManager defaultManager] contentsAtPath:attachment.path]; + } + + if (nil == data) { + [SentryLog logWithMessage:@"Couldn't init Attachment." andLevel:kSentryLevelError]; + return nil; + } + + SentryEnvelopeItemHeader *itemHeader = + [[SentryEnvelopeItemHeader alloc] initWithType:SentryEnvelopeItemTypeAttachment + length:data.length + filenname:attachment.filename + contentType:attachment.contentType]; + + return [self initWithHeader:itemHeader data:data]; +} + +@end + +@implementation SentryEnvelope + +- (instancetype)initWithSession:(SentrySession *)session +{ + SentryEnvelopeItem *item = [[SentryEnvelopeItem alloc] initWithSession:session]; + return [self initWithHeader:[[SentryEnvelopeHeader alloc] initWithId:nil] singleItem:item]; +} + +- (instancetype)initWithSessions:(NSArray *)sessions +{ + NSMutableArray *envelopeItems = [[NSMutableArray alloc] initWithCapacity:sessions.count]; + for (int i = 0; i < sessions.count; ++i) { + SentryEnvelopeItem *item = + [[SentryEnvelopeItem alloc] initWithSession:[sessions objectAtIndex:i]]; + [envelopeItems addObject:item]; + } + return [self initWithHeader:[[SentryEnvelopeHeader alloc] initWithId:nil] items:envelopeItems]; +} + +- (instancetype)initWithEvent:(SentryEvent *)event +{ + SentryEnvelopeItem *item = [[SentryEnvelopeItem alloc] initWithEvent:event]; + return [self initWithHeader:[[SentryEnvelopeHeader alloc] initWithId:event.eventId] + singleItem:item]; +} + +- (instancetype)initWithUserFeedback:(SentryUserFeedback *)userFeedback +{ + SentryEnvelopeItem *item = [[SentryEnvelopeItem alloc] initWithUserFeedback:userFeedback]; + + return [self initWithHeader:[[SentryEnvelopeHeader alloc] initWithId:userFeedback.eventId] + singleItem:item]; +} + +- (instancetype)initWithId:(SentryId *_Nullable)id singleItem:(SentryEnvelopeItem *)item +{ + return [self initWithHeader:[[SentryEnvelopeHeader alloc] initWithId:id] singleItem:item]; +} + +- (instancetype)initWithId:(SentryId *_Nullable)id items:(NSArray *)items +{ + return [self initWithHeader:[[SentryEnvelopeHeader alloc] initWithId:id] items:items]; +} + +- (instancetype)initWithHeader:(SentryEnvelopeHeader *)header singleItem:(SentryEnvelopeItem *)item +{ + return [self initWithHeader:header items:@[ item ]]; +} + +- (instancetype)initWithHeader:(SentryEnvelopeHeader *)header + items:(NSArray *)items +{ + if (self = [super init]) { + _header = header; + _items = items; + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryEnvelopeRateLimit.m b/Pods/Sentry/Sources/Sentry/SentryEnvelopeRateLimit.m new file mode 100644 index 00000000..ac47fd7a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryEnvelopeRateLimit.m @@ -0,0 +1,78 @@ +#import "SentryEnvelopeRateLimit.h" +#import "SentryEnvelope.h" +#import "SentryRateLimitCategoryMapper.h" +#import "SentryRateLimits.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryEnvelopeRateLimit () + +@property (nonatomic, strong) id rateLimits; + +@end + +@implementation SentryEnvelopeRateLimit + +- (instancetype)initWithRateLimits:(id)sentryRateLimits +{ + if (self = [super init]) { + self.rateLimits = sentryRateLimits; + } + return self; +} + +- (SentryEnvelope *)removeRateLimitedItems:(SentryEnvelope *)envelope +{ + if (nil == envelope) { + return envelope; + } + + SentryEnvelope *result = envelope; + + NSArray *itemsToDrop = [self getEnvelopeItemsToDrop:envelope.items]; + + if (itemsToDrop.count > 0) { + NSArray *itemsToSend = [self getItemsToSend:envelope.items + withItemsToDrop:itemsToDrop]; + + result = [[SentryEnvelope alloc] initWithHeader:envelope.header items:itemsToSend]; + } + + return result; +} + +- (NSArray *)getEnvelopeItemsToDrop:(NSArray *)items +{ + NSMutableArray *itemsToDrop = [NSMutableArray new]; + + for (SentryEnvelopeItem *item in items) { + SentryRateLimitCategory rateLimitCategory = + [SentryRateLimitCategoryMapper mapEnvelopeItemTypeToCategory:item.header.type]; + if ([self.rateLimits isRateLimitActive:rateLimitCategory]) { + [itemsToDrop addObject:item]; + } + } + + return itemsToDrop; +} + +- (NSArray *)getItemsToSend:(NSArray *)allItems + withItemsToDrop: + (NSArray *_Nonnull)itemsToDrop +{ + NSMutableArray *itemsToSend = [NSMutableArray new]; + + for (SentryEnvelopeItem *item in allItems) { + if (![itemsToDrop containsObject:item]) { + [itemsToSend addObject:item]; + } + } + + return itemsToSend; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryError.m b/Pods/Sentry/Sources/Sentry/SentryError.m new file mode 100644 index 00000000..ba1b7b46 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryError.m @@ -0,0 +1,14 @@ +#import "SentryError.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString *const SentryErrorDomain = @"SentryErrorDomain"; + +NSError *_Nullable NSErrorFromSentryError(SentryError error, NSString *description) +{ + NSMutableDictionary *userInfo = [NSMutableDictionary new]; + [userInfo setValue:description forKey:NSLocalizedDescriptionKey]; + return [NSError errorWithDomain:SentryErrorDomain code:error userInfo:userInfo]; +} + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryEvent.m b/Pods/Sentry/Sources/Sentry/SentryEvent.m new file mode 100644 index 00000000..c7b16cbf --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryEvent.m @@ -0,0 +1,167 @@ +#import "SentryEvent.h" +#import "NSDate+SentryExtras.h" +#import "NSDictionary+SentrySanitize.h" +#import "SentryBreadcrumb.h" +#import "SentryClient.h" +#import "SentryCurrentDate.h" +#import "SentryDebugMeta.h" +#import "SentryException.h" +#import "SentryId.h" +#import "SentryMessage.h" +#import "SentryMeta.h" +#import "SentryStacktrace.h" +#import "SentryThread.h" +#import "SentryUser.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryEvent + +- (instancetype)init +{ + return [self initWithLevel:kSentryLevelNone]; +} + +- (instancetype)initWithLevel:(enum SentryLevel)level +{ + self = [super init]; + if (self) { + self.eventId = [[SentryId alloc] init]; + self.level = level; + self.platform = @"cocoa"; + } + return self; +} + +- (instancetype)initWithError:(NSError *)error +{ + self = [self initWithLevel:kSentryLevelError]; + self.error = error; + return self; +} + +- (NSDictionary *)serialize +{ + if (nil == self.timestamp) { + self.timestamp = [SentryCurrentDate date]; + } + + NSMutableDictionary *serializedData = @{ + @"event_id" : self.eventId.sentryIdString, + @"timestamp" : [self.timestamp sentry_toIso8601String], + @"platform" : @"cocoa", + } + .mutableCopy; + + if (self.level != kSentryLevelNone) { + [serializedData setValue:SentryLevelNames[self.level] forKey:@"level"]; + } + + [self addSimpleProperties:serializedData]; + [self addOptionalListProperties:serializedData]; + + // This is important here, since we probably use __sentry internal extras + // before + [serializedData setValue:[self.extra sentry_sanitize] forKey:@"extra"]; + [serializedData setValue:self.tags forKey:@"tags"]; + + return serializedData; +} + +- (void)addOptionalListProperties:(NSMutableDictionary *)serializedData +{ + [self addThreads:serializedData]; + [self addExceptions:serializedData]; + [self addDebugImages:serializedData]; +} + +- (void)addDebugImages:(NSMutableDictionary *)serializedData +{ + NSMutableArray *debugImages = [NSMutableArray new]; + for (SentryDebugMeta *debugImage in self.debugMeta) { + [debugImages addObject:[debugImage serialize]]; + } + if (debugImages.count > 0) { + [serializedData setValue:@{ @"images" : debugImages } forKey:@"debug_meta"]; + } +} + +- (void)addExceptions:(NSMutableDictionary *)serializedData +{ + NSMutableArray *exceptions = [NSMutableArray new]; + for (SentryException *exception in self.exceptions) { + [exceptions addObject:[exception serialize]]; + } + if (exceptions.count > 0) { + [serializedData setValue:@{ @"values" : exceptions } forKey:@"exception"]; + } +} + +- (void)addThreads:(NSMutableDictionary *)serializedData +{ + NSMutableArray *threads = [NSMutableArray new]; + for (SentryThread *thread in self.threads) { + [threads addObject:[thread serialize]]; + } + if (threads.count > 0) { + [serializedData setValue:@{ @"values" : threads } forKey:@"threads"]; + } +} + +- (void)addSimpleProperties:(NSMutableDictionary *)serializedData +{ + [serializedData setValue:self.sdk forKey:@"sdk"]; + [serializedData setValue:self.releaseName forKey:@"release"]; + [serializedData setValue:self.dist forKey:@"dist"]; + [serializedData setValue:self.environment forKey:@"environment"]; + + if (self.transaction) { + [serializedData setValue:self.transaction forKey:@"transaction"]; + } else if (self.extra[@"__sentry_transaction"]) { + [serializedData setValue:self.extra[@"__sentry_transaction"] forKey:@"transaction"]; + } + + [serializedData setValue:self.fingerprint forKey:@"fingerprint"]; + + [serializedData setValue:[self.user serialize] forKey:@"user"]; + [serializedData setValue:self.modules forKey:@"modules"]; + + [serializedData setValue:[self.stacktrace serialize] forKey:@"stacktrace"]; + + [serializedData setValue:[self serializeBreadcrumbs] forKey:@"breadcrumbs"]; + + [serializedData setValue:self.context forKey:@"contexts"]; + + if (nil != self.message) { + [serializedData setValue:[self.message serialize] forKey:@"message"]; + } + [serializedData setValue:self.logger forKey:@"logger"]; + [serializedData setValue:self.serverName forKey:@"server_name"]; + [serializedData setValue:self.type forKey:@"type"]; + if (nil != self.type && [self.type isEqualToString:@"transaction"]) { + if (nil != self.startTimestamp) { + [serializedData setValue:[self.startTimestamp sentry_toIso8601String] + forKey:@"start_timestamp"]; + } else { + // start timestamp should never be empty + [serializedData setValue:[self.timestamp sentry_toIso8601String] + forKey:@"start_timestamp"]; + } + } +} + +- (NSArray *_Nullable)serializeBreadcrumbs +{ + NSMutableArray *crumbs = [NSMutableArray new]; + for (SentryBreadcrumb *crumb in self.breadcrumbs) { + [crumbs addObject:[crumb serialize]]; + } + if (crumbs.count <= 0) { + return nil; + } + return crumbs; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryException.m b/Pods/Sentry/Sources/Sentry/SentryException.m new file mode 100644 index 00000000..6fdc4143 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryException.m @@ -0,0 +1,36 @@ +#import "SentryException.h" +#import "SentryMechanism.h" +#import "SentryStacktrace.h" +#import "SentryThread.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryException + +- (instancetype)initWithValue:(NSString *)value type:(NSString *)type +{ + self = [super init]; + if (self) { + self.value = value; + self.type = type; + } + return self; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = [NSMutableDictionary new]; + + [serializedData setValue:self.value forKey:@"value"]; + [serializedData setValue:self.type forKey:@"type"]; + [serializedData setValue:[self.mechanism serialize] forKey:@"mechanism"]; + [serializedData setValue:self.module forKey:@"module"]; + [serializedData setValue:self.threadId forKey:@"thread_id"]; + [serializedData setValue:[self.stacktrace serialize] forKey:@"stacktrace"]; + + return serializedData; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryFileContents.m b/Pods/Sentry/Sources/Sentry/SentryFileContents.m new file mode 100644 index 00000000..f18bb61d --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryFileContents.m @@ -0,0 +1,20 @@ +#import "SentryFileContents.h" +#import + +@interface +SentryFileContents () + +@end + +@implementation SentryFileContents + +- (instancetype)initWithPath:(NSString *)path andContents:(NSData *)contents +{ + if (self = [super init]) { + _path = path; + _contents = contents; + } + return self; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryFileManager.m b/Pods/Sentry/Sources/Sentry/SentryFileManager.m new file mode 100644 index 00000000..61a87c9d --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryFileManager.m @@ -0,0 +1,439 @@ +#import "SentryFileManager.h" +#import "NSDate+SentryExtras.h" +#import "SentryAppState.h" +#import "SentryDefaultCurrentDateProvider.h" +#import "SentryDsn.h" +#import "SentryEnvelope.h" +#import "SentryEnvelopeItemType.h" +#import "SentryError.h" +#import "SentryEvent.h" +#import "SentryFileContents.h" +#import "SentryLog.h" +#import "SentryMigrateSessionInit.h" +#import "SentryOptions.h" +#import "SentrySerialization.h" +#import "SentrySession+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryFileManager () + +@property (nonatomic, strong) id currentDateProvider; +@property (nonatomic, copy) NSString *sentryPath; +@property (nonatomic, copy) NSString *eventsPath; +@property (nonatomic, copy) NSString *envelopesPath; +@property (nonatomic, copy) NSString *currentSessionFilePath; +@property (nonatomic, copy) NSString *crashedSessionFilePath; +@property (nonatomic, copy) NSString *lastInForegroundFilePath; +@property (nonatomic, copy) NSString *appStateFilePath; +@property (nonatomic, assign) NSUInteger currentFileCounter; +@property (nonatomic, assign) NSUInteger maxEnvelopes; + +@end + +@implementation SentryFileManager + +- (nullable instancetype)initWithOptions:(SentryOptions *)options + andCurrentDateProvider:(id)currentDateProvider + error:(NSError **)error +{ + self = [super init]; + if (self) { + self.currentDateProvider = currentDateProvider; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *cachePath + = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) + .firstObject; + + self.sentryPath = [cachePath stringByAppendingPathComponent:@"io.sentry"]; + self.sentryPath = + [self.sentryPath stringByAppendingPathComponent:[options.parsedDsn getHash]]; + + if (![fileManager fileExistsAtPath:self.sentryPath]) { + [self.class createDirectoryAtPath:self.sentryPath withError:error]; + } + + self.currentSessionFilePath = + [self.sentryPath stringByAppendingPathComponent:@"session.current"]; + + self.crashedSessionFilePath = + [self.sentryPath stringByAppendingPathComponent:@"session.crashed"]; + + self.lastInForegroundFilePath = + [self.sentryPath stringByAppendingPathComponent:@"lastInForeground.timestamp"]; + + self.appStateFilePath = [self.sentryPath stringByAppendingPathComponent:@"app.state"]; + + // Remove old cached events for versions before 6.0.0 + self.eventsPath = [self.sentryPath stringByAppendingPathComponent:@"events"]; + [fileManager removeItemAtPath:self.eventsPath error:nil]; + + self.envelopesPath = [self.sentryPath stringByAppendingPathComponent:@"envelopes"]; + [self createDirectoryIfNotExists:self.envelopesPath didFailWithError:error]; + + self.currentFileCounter = 0; + self.maxEnvelopes = options.maxCacheItems; + } + return self; +} + +- (void)deleteAllFolders +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + [fileManager removeItemAtPath:self.envelopesPath error:nil]; + [fileManager removeItemAtPath:self.sentryPath error:nil]; +} + +- (NSString *)uniqueAcendingJsonName +{ + // %f = double + // %05lu = unsigned with always 5 digits and leading zeros if number is too small. We + // need this because otherwise 10 would be sorted before 2 for example. + // %@ = NSString + // For example 978307200.000000-00001-3FE8C3AE-EB9C-4BEB-868C-14B8D47C33DD.json + return [NSString stringWithFormat:@"%f-%05lu-%@.json", + [[self.currentDateProvider date] timeIntervalSince1970], + (unsigned long)self.currentFileCounter++, [NSUUID UUID].UUIDString]; +} + +- (NSArray *)getAllEnvelopes +{ + return [self allFilesContentInFolder:self.envelopesPath]; +} + +- (SentryFileContents *_Nullable)getOldestEnvelope +{ + NSArray *pathsOfAllEnvelopes; + @synchronized(self) { + pathsOfAllEnvelopes = [self allFilesInFolder:self.envelopesPath]; + } + + if (pathsOfAllEnvelopes.count > 0) { + NSString *filePath = pathsOfAllEnvelopes[0]; + return [self getFileContents:self.envelopesPath filePath:filePath]; + } + + return nil; +} + +- (NSArray *)allFilesContentInFolder:(NSString *)path +{ + @synchronized(self) { + NSMutableArray *contents = [NSMutableArray new]; + for (NSString *filePath in [self allFilesInFolder:path]) { + SentryFileContents *fileContents = [self getFileContents:path filePath:filePath]; + + if (nil != fileContents) { + [contents addObject:fileContents]; + } + } + return contents; + } +} + +- (SentryFileContents *_Nullable)getFileContents:(NSString *)folderPath + filePath:(NSString *)filePath +{ + + NSString *finalPath = [folderPath stringByAppendingPathComponent:filePath]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSData *content = [fileManager contentsAtPath:finalPath]; + if (nil != content) { + return [[SentryFileContents alloc] initWithPath:finalPath andContents:content]; + } else { + return nil; + } +} + +- (void)deleteAllEnvelopes +{ + for (NSString *path in [self allFilesInFolder:self.envelopesPath]) { + [self removeFileAtPath:[self.envelopesPath stringByAppendingPathComponent:path]]; + } +} + +- (NSArray *)allFilesInFolder:(NSString *)path +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error = nil; + NSArray *storedFiles = [fileManager contentsOfDirectoryAtPath:path error:&error]; + if (nil != error) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Couldn't load files in folder %@: %@", path, + error] + andLevel:kSentryLevelError]; + return [NSArray new]; + } + return [storedFiles sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; +} + +- (BOOL)removeFileAtPath:(NSString *)path +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error = nil; + @synchronized(self) { + [fileManager removeItemAtPath:path error:&error]; + if (nil != error) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Couldn't delete file %@: %@", + path, error] + andLevel:kSentryLevelError]; + return NO; + } + } + return YES; +} + +- (NSString *)storeEnvelope:(SentryEnvelope *)envelope +{ + @synchronized(self) { + NSString *result = [self storeData:[SentrySerialization dataWithEnvelope:envelope error:nil] + toPath:self.envelopesPath]; + [self handleEnvelopesLimit]; + return result; + } +} + +- (void)handleEnvelopesLimit +{ + NSArray *envelopeFilePaths = [self allFilesInFolder:self.envelopesPath]; + NSInteger numberOfEnvelopesToRemove = envelopeFilePaths.count - self.maxEnvelopes; + if (numberOfEnvelopesToRemove <= 0) { + return; + } + + for (NSUInteger i = 0; i < numberOfEnvelopesToRemove; i++) { + NSString *envelopeFilePath = + [self.envelopesPath stringByAppendingPathComponent:envelopeFilePaths[i]]; + + // Remove current envelope path + NSMutableArray *envelopePathsCopy = + [[NSMutableArray alloc] initWithArray:[envelopeFilePaths copy]]; + [envelopePathsCopy removeObjectAtIndex:i]; + + [SentryMigrateSessionInit migrateSessionInit:envelopeFilePath + envelopesDirPath:self.envelopesPath + envelopeFilePaths:envelopePathsCopy]; + + [self removeFileAtPath:envelopeFilePath]; + } + + [SentryLog logWithMessage:[NSString stringWithFormat:@"Removed %ld file(s) from <%@>", + (long)numberOfEnvelopesToRemove, + [self.envelopesPath lastPathComponent]] + andLevel:kSentryLevelDebug]; +} + +- (void)storeCurrentSession:(SentrySession *)session +{ + [self storeSession:session sessionFilePath:self.currentSessionFilePath]; +} + +- (void)storeCrashedSession:(SentrySession *)session +{ + [self storeSession:session sessionFilePath:self.crashedSessionFilePath]; +} + +- (void)storeSession:(SentrySession *)session sessionFilePath:(NSString *)sessionFilePath +{ + NSData *sessionData = [SentrySerialization dataWithSession:session error:nil]; + [SentryLog logWithMessage:[NSString stringWithFormat:@"Writing session: %@", sessionFilePath] + andLevel:kSentryLevelDebug]; + @synchronized(self.currentSessionFilePath) { + [sessionData writeToFile:sessionFilePath options:NSDataWritingAtomic error:nil]; + } +} + +- (void)deleteCurrentSession +{ + [self deleteSession:self.currentSessionFilePath]; +} + +- (void)deleteCrashedSession +{ + [self deleteSession:self.crashedSessionFilePath]; +} + +- (void)deleteSession:(NSString *)sessionFilePath +{ + [SentryLog logWithMessage:[NSString stringWithFormat:@"Deleting session: %@", sessionFilePath] + andLevel:kSentryLevelDebug]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + @synchronized(self.currentSessionFilePath) { + [fileManager removeItemAtPath:sessionFilePath error:nil]; + } +} + +- (SentrySession *_Nullable)readCurrentSession +{ + return [self readSession:self.currentSessionFilePath]; +} + +- (SentrySession *_Nullable)readCrashedSession +{ + return [self readSession:self.crashedSessionFilePath]; +} + +- (SentrySession *)readSession:(NSString *)sessionFilePath +{ + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Reading from session: %@", sessionFilePath] + andLevel:kSentryLevelDebug]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSData *currentData = nil; + @synchronized(self.currentSessionFilePath) { + currentData = [fileManager contentsAtPath:sessionFilePath]; + if (nil == currentData) { + return nil; + } + } + SentrySession *currentSession = [SentrySerialization sessionWithData:currentData]; + if (nil == currentSession) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Data stored in session: " + @"'%@' was not parsed as session.", + sessionFilePath] + andLevel:kSentryLevelError]; + return nil; + } + return currentSession; +} + +- (void)storeTimestampLastInForeground:(NSDate *)timestamp +{ + NSString *timestampString = [timestamp sentry_toIso8601String]; + NSString *logMessage = + [NSString stringWithFormat:@"Persisting lastInForeground: %@", timestampString]; + [SentryLog logWithMessage:logMessage andLevel:kSentryLevelDebug]; + @synchronized(self.lastInForegroundFilePath) { + [[timestampString dataUsingEncoding:NSUTF8StringEncoding] + writeToFile:self.lastInForegroundFilePath + options:NSDataWritingAtomic + error:nil]; + } +} + +- (void)deleteTimestampLastInForeground +{ + [SentryLog logWithMessage:[NSString stringWithFormat:@"Deleting LastInForeground at: %@", + self.lastInForegroundFilePath] + andLevel:kSentryLevelDebug]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + @synchronized(self.lastInForegroundFilePath) { + [fileManager removeItemAtPath:self.lastInForegroundFilePath error:nil]; + } +} + +- (NSDate *_Nullable)readTimestampLastInForeground +{ + [SentryLog logWithMessage:[NSString stringWithFormat:@"Reading timestamp of last " + @"in foreground at: %@", + self.lastInForegroundFilePath] + andLevel:kSentryLevelDebug]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSData *lastInForegroundData = nil; + @synchronized(self.lastInForegroundFilePath) { + lastInForegroundData = [fileManager contentsAtPath:self.lastInForegroundFilePath]; + } + if (nil == lastInForegroundData) { + [SentryLog logWithMessage:@"No lastInForeground found." andLevel:kSentryLevelDebug]; + return nil; + } + NSString *timestampString = [[NSString alloc] initWithData:lastInForegroundData + encoding:NSUTF8StringEncoding]; + return [NSDate sentry_fromIso8601String:timestampString]; +} + +- (NSString *)storeData:(NSData *)data toPath:(NSString *)path +{ + @synchronized(self) { + NSString *finalPath = [path stringByAppendingPathComponent:[self uniqueAcendingJsonName]]; + [SentryLog logWithMessage:[NSString stringWithFormat:@"Writing to file: %@", finalPath] + andLevel:kSentryLevelDebug]; + [data writeToFile:finalPath options:NSDataWritingAtomic error:nil]; + return finalPath; + } +} + +- (NSString *)storeDictionary:(NSDictionary *)dictionary toPath:(NSString *)path +{ + NSData *saveData = [SentrySerialization dataWithJSONObject:dictionary error:nil]; + return nil != saveData ? [self storeData:saveData toPath:path] + : path; // TODO: Should we return null instead? Whoever is using this + // return value is being tricked. +} + +- (void)storeAppState:(SentryAppState *)appState +{ + NSError *error = nil; + NSData *data = [SentrySerialization dataWithJSONObject:[appState serialize] error:&error]; + + if (nil != error) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Failed to store app state, because " + @"of an error in serialization: %@", + error] + andLevel:kSentryLevelError]; + return; + } + + @synchronized(self.appStateFilePath) { + [data writeToFile:self.appStateFilePath options:NSDataWritingAtomic error:&error]; + if (nil != error) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Failed to store app state %@", error] + andLevel:kSentryLevelError]; + } + } +} + +- (SentryAppState *_Nullable)readAppState +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSData *currentData = nil; + @synchronized(self.appStateFilePath) { + currentData = [fileManager contentsAtPath:self.appStateFilePath]; + if (nil == currentData) { + return nil; + } + } + return [SentrySerialization appStateWithData:currentData]; +} + +- (void)deleteAppState +{ + NSError *error = nil; + NSFileManager *fileManager = [NSFileManager defaultManager]; + @synchronized(self.appStateFilePath) { + [fileManager removeItemAtPath:self.appStateFilePath error:&error]; + + // We don't want to log an error if the file doesn't exist. + if (nil != error && error.code != NSFileNoSuchFileError) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Failed to delete app state %@", error] + andLevel:kSentryLevelError]; + } + } +} + ++ (BOOL)createDirectoryAtPath:(NSString *)path withError:(NSError **)error +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + return [fileManager createDirectoryAtPath:path + withIntermediateDirectories:YES + attributes:nil + error:error]; +} + +#pragma mark private methods + +- (BOOL)createDirectoryIfNotExists:(NSString *)path didFailWithError:(NSError **)error +{ + return [[NSFileManager defaultManager] createDirectoryAtPath:path + withIntermediateDirectories:YES + attributes:nil + error:error]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryFrame.m b/Pods/Sentry/Sources/Sentry/SentryFrame.m new file mode 100644 index 00000000..5dee3585 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryFrame.m @@ -0,0 +1,37 @@ +#import "SentryFrame.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryFrame + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.function = @""; + } + return self; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = [NSMutableDictionary new]; + + [serializedData setValue:self.symbolAddress forKey:@"symbol_addr"]; + [serializedData setValue:self.fileName forKey:@"filename"]; + [serializedData setValue:self.function forKey:@"function"]; + [serializedData setValue:self.module forKey:@"module"]; + [serializedData setValue:self.lineNumber forKey:@"lineno"]; + [serializedData setValue:self.columnNumber forKey:@"colno"]; + [serializedData setValue:self.package forKey:@"package"]; + [serializedData setValue:self.imageAddress forKey:@"image_addr"]; + [serializedData setValue:self.instructionAddress forKey:@"instruction_addr"]; + [serializedData setValue:self.platform forKey:@"platform"]; + [serializedData setValue:self.inApp forKey:@"in_app"]; + + return serializedData; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryFrameInAppLogic.m b/Pods/Sentry/Sources/Sentry/SentryFrameInAppLogic.m new file mode 100644 index 00000000..39461dcd --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryFrameInAppLogic.m @@ -0,0 +1,48 @@ +#import "SentryFrameInAppLogic.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryFrameInAppLogic () + +@property (nonatomic, copy, readonly) NSArray *inAppIncludes; +@property (nonatomic, copy, readonly) NSArray *inAppExcludes; + +@end + +@implementation SentryFrameInAppLogic + +- (instancetype)initWithInAppIncludes:(NSArray *)inAppIncludes + inAppExcludes:(NSArray *)inAppExcludes +{ + if (self = [super init]) { + _inAppIncludes = inAppIncludes; + _inAppExcludes = inAppExcludes; + } + + return self; +} + +- (BOOL)isInApp:(nullable NSString *)imageName +{ + if (nil == imageName) { + return NO; + } + + for (NSString *inAppInclude in self.inAppIncludes) { + if ([imageName.lastPathComponent.lowercaseString hasPrefix:inAppInclude.lowercaseString]) + return YES; + } + + for (NSString *inAppExlude in self.inAppExcludes) { + if ([imageName.lastPathComponent.lowercaseString hasPrefix:inAppExlude.lowercaseString]) + return NO; + } + + return NO; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryFrameRemover.m b/Pods/Sentry/Sources/Sentry/SentryFrameRemover.m new file mode 100644 index 00000000..13d88138 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryFrameRemover.m @@ -0,0 +1,22 @@ +#import "SentryFrameRemover.h" +#import "SentryFrame.h" +#import + +@implementation SentryFrameRemover + ++ (NSArray *)removeNonSdkFrames:(NSArray *)frames +{ + NSUInteger indexOfFirstNonSentryFrame = [frames indexOfObjectPassingTest:^BOOL( + SentryFrame *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { + return ![[obj.package lowercaseString] containsString:@"sentry"]; + }]; + + if (indexOfFirstNonSentryFrame == NSNotFound) { + return frames; + } else { + return [frames subarrayWithRange:NSMakeRange(indexOfFirstNonSentryFrame, + frames.count - indexOfFirstNonSentryFrame)]; + } +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryGlobalEventProcessor.m b/Pods/Sentry/Sources/Sentry/SentryGlobalEventProcessor.m new file mode 100644 index 00000000..d779b95d --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryGlobalEventProcessor.m @@ -0,0 +1,27 @@ +#import "SentryGlobalEventProcessor.h" +#import "SentryLog.h" + +@implementation SentryGlobalEventProcessor + ++ (instancetype)shared +{ + static SentryGlobalEventProcessor *instance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ instance = [[self alloc] initPrivate]; }); + return instance; +} + +- (instancetype)initPrivate +{ + if (self = [super init]) { + self.processors = [NSMutableArray new]; + } + return self; +} + +- (void)addEventProcessor:(SentryEventProcessor)newProcessor +{ + [self.processors addObject:newProcessor]; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryHttpDateParser.m b/Pods/Sentry/Sources/Sentry/SentryHttpDateParser.m new file mode 100644 index 00000000..5b971710 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryHttpDateParser.m @@ -0,0 +1,40 @@ +#import "SentryHttpDateParser.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryHttpDateParser () + +@property (nonatomic, strong) NSDateFormatter *dateFormatter; + +@end + +/** + * According to + * https://developer.apple.com/documentation/foundation/nsdateformatter + * NSDateFormatter is not guaranteed to be thread safe on all macOS + * applications yet. Therefore it must not be mutated from multiple threads. As + * we only modify NSDateFormatter during init we don't need any locks. + */ +@implementation SentryHttpDateParser + +- (instancetype)init +{ + if (self = [super init]) { + self.dateFormatter = [[NSDateFormatter alloc] init]; + [self.dateFormatter setDateFormat:@"EEE',' dd' 'MMM' 'yyyy HH':'mm':'ss zzz"]; + // Http dates are always expressed in GMT, never in local time. + [self.dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]]; + } + return self; +} + +- (NSDate *_Nullable)dateFromString:(NSString *)string +{ + return [self.dateFormatter dateFromString:string]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryHttpTransport.m b/Pods/Sentry/Sources/Sentry/SentryHttpTransport.m new file mode 100644 index 00000000..ee397c6b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryHttpTransport.m @@ -0,0 +1,201 @@ +#import "SentryHttpTransport.h" +#import "SentryDispatchQueueWrapper.h" +#import "SentryDsn.h" +#import "SentryEnvelope.h" +#import "SentryEnvelopeItemType.h" +#import "SentryEnvelopeRateLimit.h" +#import "SentryEvent.h" +#import "SentryFileContents.h" +#import "SentryFileManager.h" +#import "SentryLog.h" +#import "SentryNSURLRequest.h" +#import "SentryOptions.h" +#import "SentryRateLimitCategoryMapper.h" +#import "SentrySerialization.h" + +@interface +SentryHttpTransport () + +@property (nonatomic, strong) SentryFileManager *fileManager; +@property (nonatomic, strong) id requestManager; +@property (nonatomic, strong) SentryOptions *options; +@property (nonatomic, strong) id rateLimits; +@property (nonatomic, strong) SentryEnvelopeRateLimit *envelopeRateLimit; +@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueue; + +/** + * Synching with a dispatch queue to have concurrent reads and writes as barrier blocks is roughly + * 30% slower than using atomic here. + */ +@property (atomic) BOOL isSending; + +@end + +@implementation SentryHttpTransport + +- (id)initWithOptions:(SentryOptions *)options + fileManager:(SentryFileManager *)fileManager + requestManager:(id)requestManager + rateLimits:(id)rateLimits + envelopeRateLimit:(SentryEnvelopeRateLimit *)envelopeRateLimit + dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper +{ + if (self = [super init]) { + self.options = options; + self.requestManager = requestManager; + self.fileManager = fileManager; + self.rateLimits = rateLimits; + self.envelopeRateLimit = envelopeRateLimit; + self.dispatchQueue = dispatchQueueWrapper; + _isSending = NO; + + [self sendAllCachedEnvelopes]; + } + return self; +} + +- (void)sendEvent:(SentryEvent *)event attachments:(NSArray *)attachments +{ + NSMutableArray *items = [self buildEnvelopeItems:event + attachments:attachments]; + SentryEnvelope *envelope = [[SentryEnvelope alloc] initWithId:event.eventId items:items]; + + [self sendEnvelope:envelope]; +} + +- (void)sendEvent:(SentryEvent *)event + withSession:(SentrySession *)session + attachments:(NSArray *)attachments +{ + NSMutableArray *items = [self buildEnvelopeItems:event + attachments:attachments]; + [items addObject:[[SentryEnvelopeItem alloc] initWithSession:session]]; + + SentryEnvelope *envelope = [[SentryEnvelope alloc] initWithId:event.eventId items:items]; + + [self sendEnvelope:envelope]; +} + +- (NSMutableArray *)buildEnvelopeItems:(SentryEvent *)event + attachments: + (NSArray *)attachments +{ + NSMutableArray *items = [NSMutableArray new]; + [items addObject:[[SentryEnvelopeItem alloc] initWithEvent:event]]; + + for (SentryAttachment *attachment in attachments) { + SentryEnvelopeItem *item = + [[SentryEnvelopeItem alloc] initWithAttachment:attachment + maxAttachmentSize:self.options.maxAttachmentSize]; + // The item is nil, when creating the envelopeItem failed. + if (nil != item) { + [items addObject:item]; + } + } + + return items; +} + +- (void)sendUserFeedback:(SentryUserFeedback *)userFeedback +{ + SentryEnvelope *envelope = [[SentryEnvelope alloc] initWithUserFeedback:userFeedback]; + [self sendEnvelope:envelope]; +} + +- (void)sendEnvelope:(SentryEnvelope *)envelope +{ + envelope = [self.envelopeRateLimit removeRateLimitedItems:envelope]; + + if (envelope.items.count == 0) { + [SentryLog logWithMessage:@"RateLimit is active for all envelope items." + andLevel:kSentryLevelDebug]; + return; + } + + // With this we accept the a tradeoff. We might loose some envelopes when a hard crash happens, + // because this being done on a background thread, but instead we don't block the calling + // thread, which could be the main thread. + [self.dispatchQueue dispatchAsyncWithBlock:^{ + [self.fileManager storeEnvelope:envelope]; + [self sendAllCachedEnvelopes]; + }]; +} + +#pragma mark private methods + +// TODO: This has to move somewhere else, we are missing the whole beforeSend flow +- (void)sendAllCachedEnvelopes +{ + @synchronized(self) { + if (self.isSending || ![self.requestManager isReady]) { + return; + } + self.isSending = YES; + } + + SentryFileContents *envelopeFileContents = [self.fileManager getOldestEnvelope]; + if (nil == envelopeFileContents) { + self.isSending = NO; + return; + } + + SentryEnvelope *envelope = [SentrySerialization envelopeWithData:envelopeFileContents.contents]; + if (nil == envelope) { + [self deleteEnvelopeAndSendNext:envelopeFileContents.path]; + return; + } + + SentryEnvelope *rateLimitedEnvelope = [self.envelopeRateLimit removeRateLimitedItems:envelope]; + if (rateLimitedEnvelope.items.count == 0) { + [self deleteEnvelopeAndSendNext:envelopeFileContents.path]; + return; + } + + NSError *requestError = nil; + NSURLRequest *request = [self createEnvelopeRequest:rateLimitedEnvelope + didFailWithError:requestError]; + + if (nil != requestError) { + [self deleteEnvelopeAndSendNext:envelopeFileContents.path]; + return; + } else { + [self sendEnvelope:envelopeFileContents.path request:request]; + } +} + +- (void)deleteEnvelopeAndSendNext:(NSString *)envelopePath +{ + [self.fileManager removeFileAtPath:envelopePath]; + self.isSending = NO; + [self sendAllCachedEnvelopes]; +} + +- (NSURLRequest *)createEnvelopeRequest:(SentryEnvelope *)envelope + didFailWithError:(NSError *_Nullable)error +{ + return [[SentryNSURLRequest alloc] + initEnvelopeRequestWithDsn:self.options.parsedDsn + andData:[SentrySerialization dataWithEnvelope:envelope error:&error] + didFailWithError:&error]; +} + +- (void)sendEnvelope:(NSString *)envelopePath request:(NSURLRequest *)request +{ + __block SentryHttpTransport *_self = self; + [self.requestManager + addRequest:request + completionHandler:^(NSHTTPURLResponse *_Nullable response, NSError *_Nullable error) { + // TODO: How does beforeSend work here + + // If the response is not nil we had an internet connection. + // We don't worry about errors here. + if (nil != response) { + [_self.rateLimits update:response]; + [_self deleteEnvelopeAndSendNext:envelopePath]; + } else { + _self.isSending = NO; + } + }]; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryHub.m b/Pods/Sentry/Sources/Sentry/SentryHub.m new file mode 100644 index 00000000..6ab90a2a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryHub.m @@ -0,0 +1,481 @@ +#import "SentryHub.h" +#import "SentryClient+Private.h" +#import "SentryCrashAdapter.h" +#import "SentryCurrentDate.h" +#import "SentryEnvelope.h" +#import "SentryEnvelopeItemType.h" +#import "SentryFileManager.h" +#import "SentryId.h" +#import "SentryLog.h" +#import "SentrySDK+Private.h" +#import "SentrySamplingContext.h" +#import "SentryScope.h" +#import "SentrySerialization.h" +#import "SentryTracer.h" +#import "SentryTransactionContext.h" +#import "TracesSampler.h" + +@interface +SentryHub () + +@property (nonatomic, strong) SentryClient *_Nullable client; +@property (nonatomic, strong) SentryScope *_Nullable scope; +@property (nonatomic, strong) SentryCrashAdapter *crashAdapter; +@property (nonatomic, strong) TracesSampler *sampler; + +@end + +@implementation SentryHub { + NSObject *_sessionLock; +} + +- (instancetype)initWithClient:(SentryClient *_Nullable)client + andScope:(SentryScope *_Nullable)scope +{ + if (self = [super init]) { + _client = client; + _scope = scope; + _sessionLock = [[NSObject alloc] init]; + _installedIntegrations = [[NSMutableArray alloc] init]; + _crashAdapter = [[SentryCrashAdapter alloc] init]; + _sampler = [[TracesSampler alloc] initWithOptions:client.options]; + } + return self; +} + +/** Internal constructor for testing */ +- (instancetype)initWithClient:(SentryClient *_Nullable)client + andScope:(SentryScope *_Nullable)scope + andCrashAdapter:(SentryCrashAdapter *)crashAdapter +{ + self = [self initWithClient:client andScope:scope]; + _crashAdapter = crashAdapter; + + return self; +} + +- (void)startSession +{ + SentrySession *lastSession = nil; + SentryScope *scope = self.scope; + SentryOptions *options = [_client options]; + if (nil == options || nil == options.releaseName) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"No option or release to start a session."] + andLevel:kSentryLevelError]; + return; + } + @synchronized(_sessionLock) { + if (nil != _session) { + lastSession = _session; + } + _session = [[SentrySession alloc] initWithReleaseName:options.releaseName]; + + NSString *environment = options.environment; + if (nil != environment) { + _session.environment = environment; + } + + [scope applyToSession:_session]; + + [self storeCurrentSession:_session]; + // TODO: Capture outside the lock. Not the reference in the scope. + [self captureSession:_session]; + } + [lastSession endSessionExitedWithTimestamp:[SentryCurrentDate date]]; + [self captureSession:lastSession]; +} + +- (void)endSession +{ + [self endSessionWithTimestamp:[SentryCurrentDate date]]; +} + +- (void)endSessionWithTimestamp:(NSDate *)timestamp +{ + SentrySession *currentSession = nil; + @synchronized(_sessionLock) { + currentSession = _session; + _session = nil; + [self deleteCurrentSession]; + } + + if (nil == currentSession) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"No session to end with timestamp."] + andLevel:kSentryLevelDebug]; + return; + } + + [currentSession endSessionExitedWithTimestamp:timestamp]; + [self captureSession:currentSession]; +} + +- (void)storeCurrentSession:(SentrySession *)session +{ + [[_client fileManager] storeCurrentSession:session]; +} + +- (void)deleteCurrentSession +{ + [[_client fileManager] deleteCurrentSession]; +} + +- (void)closeCachedSessionWithTimestamp:(NSDate *_Nullable)timestamp +{ + SentryFileManager *fileManager = [_client fileManager]; + SentrySession *session = [fileManager readCurrentSession]; + if (nil == session) { + [SentryLog logWithMessage:@"No cached session to close." andLevel:kSentryLevelDebug]; + return; + } + [SentryLog logWithMessage:@"A cached session was found." andLevel:kSentryLevelDebug]; + + // Make sure there's a client bound. + SentryClient *client = _client; + if (nil == client) { + [SentryLog logWithMessage:@"No client bound." andLevel:kSentryLevelDebug]; + return; + } + + // The crashed session is handled in SentryCrashIntegration. Checkout the comments there to find + // out more. + if (!self.crashAdapter.crashedLastLaunch) { + if (nil == timestamp) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"No timestamp to close session " + @"was provided. Closing as abnormal. " + "Using session's start time %@", + session.started] + andLevel:kSentryLevelDebug]; + timestamp = session.started; + [session endSessionAbnormalWithTimestamp:timestamp]; + } else { + [SentryLog logWithMessage:@"Closing cached session as exited." + andLevel:kSentryLevelDebug]; + [session endSessionExitedWithTimestamp:timestamp]; + } + [self deleteCurrentSession]; + [client captureSession:session]; + } +} + +- (void)captureSession:(SentrySession *)session +{ + if (nil != session) { + SentryClient *client = _client; + + if (client.options.diagnosticLevel == kSentryLevelDebug) { + NSData *sessionData = [NSJSONSerialization dataWithJSONObject:[session serialize] + options:0 + error:nil]; + NSString *sessionString = [[NSString alloc] initWithData:sessionData + encoding:NSUTF8StringEncoding]; + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Capturing session with status: %@", + sessionString] + andLevel:kSentryLevelDebug]; + } + [client captureSession:session]; + } +} + +- (SentrySession *)incrementSessionErrors +{ + SentrySession *sessionCopy = nil; + @synchronized(_sessionLock) { + if (nil != _session) { + [_session incrementErrors]; + [self storeCurrentSession:_session]; + sessionCopy = [_session copy]; + } + } + + return sessionCopy; +} + +/** + * If autoSessionTracking is enabled we want to send the crash and the event together to get proper + * numbers for release health statistics. If there are multiple crash events to be sent on the start + * of the SDK there is currently no way to know which one belongs to the crashed session so we just + * send the session with the first crashed event we receive. + */ +- (void)captureCrashEvent:(SentryEvent *)event +{ + SentryClient *client = _client; + if (nil == client) { + return; + } + + // Check this condition first to avoid unnecessary I/O + if (client.options.enableAutoSessionTracking) { + SentryFileManager *fileManager = [client fileManager]; + SentrySession *crashedSession = [fileManager readCrashedSession]; + + // It can be that there is no session yet, because autoSessionTracking was just enabled and + // there is a previous crash on disk. In this case we just send the crash event. + if (nil != crashedSession) { + [client captureCrashEvent:event withSession:crashedSession withScope:self.scope]; + [fileManager deleteCrashedSession]; + return; + } + } + + [client captureCrashEvent:event withScope:self.scope]; +} + +- (SentryId *)captureEvent:(SentryEvent *)event +{ + return [self captureEvent:event withScope:[[SentryScope alloc] init]]; +} + +- (SentryId *)captureEvent:(SentryEvent *)event withScope:(SentryScope *)scope +{ + SentryClient *client = _client; + if (nil != client) { + return [client captureEvent:event withScope:scope]; + } + return SentryId.empty; +} + +- (id)startTransactionWithName:(NSString *)name operation:(NSString *)operation +{ + return [self + startTransactionWithContext:[[SentryTransactionContext alloc] initWithName:name + operation:operation]]; +} + +- (id)startTransactionWithName:(NSString *)name + operation:(NSString *)operation + bindToScope:(BOOL)bindToScope +{ + return + [self startTransactionWithContext:[[SentryTransactionContext alloc] initWithName:name + operation:operation] + bindToScope:bindToScope]; +} + +- (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext +{ + return [self startTransactionWithContext:transactionContext customSamplingContext:@{}]; +} + +- (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + bindToScope:(BOOL)bindToScope +{ + return [self startTransactionWithContext:transactionContext + bindToScope:bindToScope + customSamplingContext:@{}]; +} + +- (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + customSamplingContext:(NSDictionary *)customSamplingContext +{ + return [self startTransactionWithContext:transactionContext + bindToScope:false + customSamplingContext:customSamplingContext]; +} + +- (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + bindToScope:(BOOL)bindToScope + customSamplingContext:(NSDictionary *)customSamplingContext +{ + SentrySamplingContext *samplingContext = + [[SentrySamplingContext alloc] initWithTransactionContext:transactionContext + customSamplingContext:customSamplingContext]; + + transactionContext.sampled = [_sampler sample:samplingContext]; + + id tracer = [[SentryTracer alloc] initWithTransactionContext:transactionContext + hub:self]; + if (bindToScope) + _scope.span = tracer; + + return tracer; +} + +- (SentryId *)captureMessage:(NSString *)message +{ + return [self captureMessage:message withScope:[[SentryScope alloc] init]]; +} + +- (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope +{ + SentryClient *client = _client; + if (nil != client) { + return [client captureMessage:message withScope:scope]; + } + return SentryId.empty; +} + +- (SentryId *)captureError:(NSError *)error +{ + return [self captureError:error withScope:[[SentryScope alloc] init]]; +} + +- (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope +{ + SentrySession *currentSession = [self incrementSessionErrors]; + SentryClient *client = _client; + if (nil != client) { + if (nil != currentSession) { + return [client captureError:error withSession:currentSession withScope:scope]; + } else { + return [client captureError:error withScope:scope]; + } + } + return SentryId.empty; +} + +- (SentryId *)captureException:(NSException *)exception +{ + return [self captureException:exception withScope:[[SentryScope alloc] init]]; +} + +- (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope +{ + SentrySession *currentSession = [self incrementSessionErrors]; + + SentryClient *client = _client; + if (nil != client) { + if (nil != currentSession) { + return [client captureException:exception withSession:currentSession withScope:scope]; + } else { + return [client captureException:exception withScope:scope]; + } + } + return SentryId.empty; +} + +- (void)captureUserFeedback:(SentryUserFeedback *)userFeedback +{ + SentryClient *client = _client; + if (nil != client) { + [client captureUserFeedback:userFeedback]; + } +} + +- (void)addBreadcrumb:(SentryBreadcrumb *)crumb +{ + SentryBeforeBreadcrumbCallback callback = [[[self client] options] beforeBreadcrumb]; + if (nil != callback) { + crumb = callback(crumb); + } + if (nil == crumb) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Discarded Breadcrumb " + @"in `beforeBreadcrumb`"] + andLevel:kSentryLevelDebug]; + return; + } + [self.scope addBreadcrumb:crumb]; +} + +- (SentryClient *_Nullable)getClient +{ + return _client; +} + +- (void)bindClient:(SentryClient *_Nullable)client +{ + self.client = client; +} + +- (SentryScope *)scope +{ + @synchronized(self) { + if (_scope == nil) { + SentryClient *client = _client; + if (nil != client) { + _scope = [[SentryScope alloc] initWithMaxBreadcrumbs:client.options.maxBreadcrumbs]; + } else { + _scope = [[SentryScope alloc] init]; + } + } + return _scope; + } +} + +- (void)configureScope:(void (^)(SentryScope *scope))callback +{ + SentryScope *scope = self.scope; + SentryClient *client = _client; + if (nil != client && nil != scope) { + callback(scope); + } +} + +/** + * Checks if a specific Integration (`integrationClass`) has been installed. + * @return BOOL If instance of `integrationClass` exists within + * `SentryHub.installedIntegrations`. + */ +- (BOOL)isIntegrationInstalled:(Class)integrationClass +{ + for (id item in SentrySDK.currentHub.installedIntegrations) { + if ([item isKindOfClass:integrationClass]) { + return YES; + } + } + return NO; +} + +- (id _Nullable)getIntegration:(NSString *)integrationName +{ + NSArray *integrations = _client.options.integrations; + if (![integrations containsObject:integrationName]) { + return nil; + } + return [integrations objectAtIndex:[integrations indexOfObject:integrationName]]; +} + +- (void)setUser:(SentryUser *_Nullable)user +{ + SentryScope *scope = self.scope; + if (nil != scope) { + [scope setUser:user]; + } +} + +- (void)captureEnvelope:(SentryEnvelope *)envelope +{ + SentryClient *client = _client; + if (nil == client) { + return; + } + + [client captureEnvelope:[self updateSessionState:envelope]]; +} + +- (SentryEnvelope *)updateSessionState:(SentryEnvelope *)envelope +{ + if ([self envelopeContainsEventWithErrorOrHigher:envelope.items]) { + SentrySession *currentSession = [self incrementSessionErrors]; + + if (nil != currentSession) { + // Create a new envelope with the session update + NSMutableArray *itemsToSend = + [[NSMutableArray alloc] initWithArray:envelope.items]; + [itemsToSend addObject:[[SentryEnvelopeItem alloc] initWithSession:currentSession]]; + + return [[SentryEnvelope alloc] initWithHeader:envelope.header items:itemsToSend]; + } + } + + return envelope; +} + +- (BOOL)envelopeContainsEventWithErrorOrHigher:(NSArray *)items +{ + for (SentryEnvelopeItem *item in items) { + if ([item.header.type isEqualToString:SentryEnvelopeItemTypeEvent]) { + // If there is no level the default is error + SentryLevel level = [SentrySerialization levelFromData:item.data]; + if (level >= kSentryLevelError) { + return YES; + } + } + } + + return NO; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryId.m b/Pods/Sentry/Sources/Sentry/SentryId.m new file mode 100644 index 00000000..61805420 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryId.m @@ -0,0 +1,95 @@ +#import "SentryId.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const emptyUUIDString = @"00000000-0000-0000-0000-000000000000"; + +@interface +SentryId () + +@property (nonatomic, strong) NSUUID *uuid; + +@end + +@implementation SentryId + +static SentryId *_empty = nil; + +- (instancetype)init +{ + return [self initWithUUID:[NSUUID UUID]]; +} + +- (instancetype)initWithUUID:(NSUUID *)uuid +{ + if (self = [super init]) { + self.uuid = uuid; + } + return self; +} + +- (instancetype)initWithUUIDString:(NSString *)string +{ + NSUUID *uuid; + if (string.length == 36) { + uuid = [[NSUUID alloc] initWithUUIDString:string]; + } else if (string.length == 32) { + NSMutableString *mutableString = [[NSMutableString alloc] initWithString:string]; + [mutableString insertString:@"-" atIndex:8]; + [mutableString insertString:@"-" atIndex:13]; + [mutableString insertString:@"-" atIndex:18]; + [mutableString insertString:@"-" atIndex:23]; + + uuid = [[NSUUID alloc] initWithUUIDString:mutableString]; + } + + if (nil != uuid) { + return [self initWithUUID:uuid]; + } else { + return [self initWithUUIDString:emptyUUIDString]; + } +} + +- (NSString *)sentryIdString; +{ + NSString *sentryIdString = [self.uuid.UUIDString stringByReplacingOccurrencesOfString:@"-" + withString:@""]; + return [sentryIdString lowercaseString]; +} + +- (NSString *)description +{ + return [self sentryIdString]; +} + +- (BOOL)isEqual:(id _Nullable)object +{ + if (object == self) { + return YES; + } + if ([self class] != [object class]) { + return NO; + } + + SentryId *otherSentryID = (SentryId *)object; + + return [self.uuid isEqual:otherSentryID.uuid]; +} + +- (NSUInteger)hash +{ + return [self.uuid hash]; +} + ++ (SentryId *)empty +{ + if (nil == _empty) { + _empty = [[SentryId alloc] initWithUUIDString:emptyUUIDString]; + } + return _empty; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryInstallation.m b/Pods/Sentry/Sources/Sentry/SentryInstallation.m new file mode 100644 index 00000000..1f4b4aac --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryInstallation.m @@ -0,0 +1,46 @@ +#import "SentryInstallation.h" +#import "SentryDefines.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryInstallation + +static NSString *volatile installationString; + ++ (NSString *)id +{ + if (nil != installationString) { + return installationString; + } + @synchronized(self) { + if (nil != installationString) { + return installationString; + } + NSString *cachePath + = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) + .firstObject; + + NSString *installationFilePath = [cachePath stringByAppendingPathComponent:@"INSTALLATION"]; + + NSData *installationData = [NSData dataWithContentsOfFile:installationFilePath]; + + if (nil == installationData) { + installationString = [NSUUID UUID].UUIDString; + NSData *installationStringData = + [installationString dataUsingEncoding:NSUTF8StringEncoding]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + [fileManager createFileAtPath:installationFilePath + contents:installationStringData + attributes:nil]; + } else { + installationString = [[NSString alloc] initWithData:installationData + encoding:NSUTF8StringEncoding]; + } + + return installationString; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryLevelMapper.m b/Pods/Sentry/Sources/Sentry/SentryLevelMapper.m new file mode 100644 index 00000000..101b4104 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryLevelMapper.m @@ -0,0 +1,35 @@ +#import "SentryLevelMapper.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryLevelMapper + ++ (SentryLevel)levelWithString:(NSString *)string +{ + if ([string isEqualToString:SentryLevelNames[kSentryLevelNone]]) { + return kSentryLevelNone; + } + if ([string isEqualToString:SentryLevelNames[kSentryLevelDebug]]) { + return kSentryLevelDebug; + } + if ([string isEqualToString:SentryLevelNames[kSentryLevelInfo]]) { + return kSentryLevelInfo; + } + if ([string isEqualToString:SentryLevelNames[kSentryLevelWarning]]) { + return kSentryLevelWarning; + } + if ([string isEqualToString:SentryLevelNames[kSentryLevelError]]) { + return kSentryLevelError; + } + if ([string isEqualToString:SentryLevelNames[kSentryLevelFatal]]) { + return kSentryLevelFatal; + } + + // Default is error, see https://develop.sentry.dev/sdk/event-payloads/#optional-attributes + return kSentryLevelError; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryLog.m b/Pods/Sentry/Sources/Sentry/SentryLog.m new file mode 100644 index 00000000..cbc22f17 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryLog.m @@ -0,0 +1,43 @@ +#import "SentryLog.h" +#import "SentryLogOutput.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryLog + +/** + * Enable per default to log initialization errors. + */ +static BOOL isDebug = YES; +static SentryLevel diagnosticLevel = kSentryLevelError; +static SentryLogOutput *logOutput; + ++ (void)configure:(BOOL)debug diagnosticLevel:(SentryLevel)level +{ + isDebug = debug; + diagnosticLevel = level; +} + ++ (void)logWithMessage:(NSString *)message andLevel:(SentryLevel)level +{ + if (nil == logOutput) { + logOutput = [[SentryLogOutput alloc] init]; + } + + if (isDebug && level != kSentryLevelNone && level >= diagnosticLevel) { + [logOutput + log:[NSString stringWithFormat:@"Sentry - %@:: %@", SentryLevelNames[level], message]]; + } +} + +/** + * Internal and only needed for testing. + */ ++ (void)setLogOutput:(nullable SentryLogOutput *)output +{ + logOutput = output; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryLogOutput.m b/Pods/Sentry/Sources/Sentry/SentryLogOutput.m new file mode 100644 index 00000000..8ae34227 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryLogOutput.m @@ -0,0 +1,15 @@ +#import "SentryLogOutput.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryLogOutput + +- (void)log:(NSString *)message +{ + NSLog(@"%@", message); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryMechanism.m b/Pods/Sentry/Sources/Sentry/SentryMechanism.m new file mode 100644 index 00000000..12fbe4e7 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryMechanism.m @@ -0,0 +1,37 @@ +#import "SentryMechanism.h" +#import "NSDictionary+SentrySanitize.h" +#import "SentryMechanismMeta.h" +#import "SentryNSError.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryMechanism + +- (instancetype)initWithType:(NSString *)type +{ + self = [super init]; + if (self) { + self.type = type; + } + return self; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = @{ @"type" : self.type }.mutableCopy; + + [serializedData setValue:self.handled forKey:@"handled"]; + [serializedData setValue:self.desc forKey:@"description"]; + [serializedData setValue:[self.data sentry_sanitize] forKey:@"data"]; + [serializedData setValue:self.helpLink forKey:@"help_link"]; + + if (nil != self.meta) { + [serializedData setValue:[self.meta serialize] forKey:@"meta"]; + } + + return serializedData; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryMechanismMeta.m b/Pods/Sentry/Sources/Sentry/SentryMechanismMeta.m new file mode 100644 index 00000000..c5451a8d --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryMechanismMeta.m @@ -0,0 +1,28 @@ +#import "SentryMechanismMeta.h" +#import "NSDictionary+SentrySanitize.h" +#import "SentryNSError.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryMechanismMeta + +- (instancetype)init +{ + self = [super init]; + return self; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *data = [NSMutableDictionary new]; + + data[@"signal"] = [self.signal sentry_sanitize]; + data[@"mach_exception"] = [self.machException sentry_sanitize]; + data[@"ns_error"] = [self.error serialize]; + + return data; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryMessage.m b/Pods/Sentry/Sources/Sentry/SentryMessage.m new file mode 100644 index 00000000..c4aa518c --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryMessage.m @@ -0,0 +1,44 @@ +#import "SentryMessage.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +const NSUInteger MAX_STRING_LENGTH = 8192; + +@implementation SentryMessage + +- (instancetype)initWithFormatted:(NSString *)formatted +{ + if (self = [super init]) { + if (nil != formatted && formatted.length > MAX_STRING_LENGTH) { + _formatted = [formatted substringToIndex:MAX_STRING_LENGTH]; + } else { + _formatted = formatted; + } + } + return self; +} + +- (void)setMessage:(NSString *_Nullable)message +{ + if (nil != message && message.length > MAX_STRING_LENGTH) { + _message = [message substringToIndex:MAX_STRING_LENGTH]; + } else { + _message = message; + } +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = [[NSMutableDictionary alloc] init]; + + [serializedData setValue:self.formatted forKey:@"formatted"]; + [serializedData setValue:self.message forKey:@"message"]; + [serializedData setValue:self.params forKey:@"params"]; + + return serializedData; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryMeta.m b/Pods/Sentry/Sources/Sentry/SentryMeta.m new file mode 100644 index 00000000..f743ab9f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryMeta.m @@ -0,0 +1,21 @@ +#import "SentryMeta.h" + +@implementation SentryMeta + +// Don't remove the static keyword. If you do the compiler adds the constant name to the global +// symbol table and it might clash with other constants. When keeping the static keyword the +// compiler replaces all occurrences with the value. +static NSString *const versionString = @"7.0.0-beta.0"; +static NSString *const sdkName = @"sentry.cocoa"; + ++ (NSString *)versionString +{ + return versionString; +} + ++ (NSString *)sdkName +{ + return sdkName; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryMigrateSessionInit.m b/Pods/Sentry/Sources/Sentry/SentryMigrateSessionInit.m new file mode 100644 index 00000000..8ac86b20 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryMigrateSessionInit.m @@ -0,0 +1,130 @@ +#import + +#import "SentryEnvelope.h" +#import "SentryEnvelopeItemType.h" +#import "SentryLog.h" +#import "SentryMigrateSessionInit.h" +#import "SentrySerialization.h" +#import "SentrySession+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryMigrateSessionInit + ++ (void)migrateSessionInit:(NSString *)envelopeFilePath + envelopesDirPath:(NSString *)envelopesDirPath + envelopeFilePaths:(NSArray *)envelopeFilePaths; +{ + NSData *envelopeData = [[NSFileManager defaultManager] contentsAtPath:envelopeFilePath]; + SentryEnvelope *envelope = [SentrySerialization envelopeWithData:envelopeData]; + if (nil == envelope) { + return; + } + + for (SentryEnvelopeItem *item in envelope.items) { + if ([item.header.type isEqualToString:SentryEnvelopeItemTypeSession]) { + SentrySession *session = [SentrySerialization sessionWithData:item.data]; + if (nil != session && [session.flagInit boolValue]) { + [self setInitFlagOnNextEnvelopeWithSameSessionId:session + envelopesDirPath:envelopesDirPath + envelopeFilePaths:envelopeFilePaths]; + } + } + } +} + ++ (void)setInitFlagOnNextEnvelopeWithSameSessionId:(SentrySession *)session + envelopesDirPath:(NSString *)envelopesDirPath + envelopeFilePaths:(NSArray *)envelopeFilePaths +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + + for (NSString *envelopeFilePath in envelopeFilePaths) { + NSString *envelopePath = [envelopesDirPath stringByAppendingPathComponent:envelopeFilePath]; + NSData *envelopeData = [fileManager contentsAtPath:envelopePath]; + + // Some error occured while getting the envelopeData + if (nil == envelopeData) { + continue; + } + + SentryEnvelope *envelope = [SentrySerialization envelopeWithData:envelopeData]; + + if (nil != envelope) { + BOOL didSetInitFlag = [self setInitFlagIfContainsSameSessionId:session.sessionId + envelope:envelope + envelopeFilePath:envelopePath]; + + if (didSetInitFlag) { + break; + } + } + } +} + ++ (BOOL)setInitFlagIfContainsSameSessionId:(NSUUID *)sessionId + envelope:(SentryEnvelope *)envelope + envelopeFilePath:(NSString *)envelopeFilePath +{ + for (SentryEnvelopeItem *item in envelope.items) { + if ([item.header.type isEqualToString:SentryEnvelopeItemTypeSession]) { + SentrySession *localSession = [SentrySerialization sessionWithData:item.data]; + + if (nil != localSession && [localSession.sessionId isEqual:sessionId]) { + [localSession setFlagInit]; + + [self storeSessionInit:envelope session:localSession path:envelopeFilePath]; + return YES; + } + } + } + + return NO; +} + ++ (void)storeSessionInit:(SentryEnvelope *)originalEnvelope + session:(SentrySession *)session + path:(NSString *)envelopeFilePath +{ + NSArray *envelopeItemsWithUpdatedSession = + [self replaceSessionEnvelopeItem:session onEnvelope:originalEnvelope]; + SentryEnvelope *envelopeWithInitFlag = + [[SentryEnvelope alloc] initWithHeader:originalEnvelope.header + items:envelopeItemsWithUpdatedSession]; + + NSError *error; + NSData *envelopeWithInitFlagData = [SentrySerialization dataWithEnvelope:envelopeWithInitFlag + error:&error]; + [envelopeWithInitFlagData writeToFile:envelopeFilePath + options:NSDataWritingAtomic + error:&error]; + + if (nil != error) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Could not migrate session init, because " + @"storing the updated envelope failed: %@", + error.description] + andLevel:kSentryLevelError]; + } +} + ++ (NSArray *)replaceSessionEnvelopeItem:(SentrySession *)session + onEnvelope:(SentryEnvelope *)envelope +{ + NSPredicate *noSessionEnvelopeItems = + [NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) { + SentryEnvelopeItem *item = object; + return ![item.header.type isEqualToString:SentryEnvelopeItemTypeSession]; + }]; + NSMutableArray *itemsWithoutSession + = (NSMutableArray *)[[envelope.items + filteredArrayUsingPredicate:noSessionEnvelopeItems] mutableCopy]; + + SentryEnvelopeItem *sessionEnvelopeItem = [[SentryEnvelopeItem alloc] initWithSession:session]; + [itemsWithoutSession addObject:sessionEnvelopeItem]; + return itemsWithoutSession; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryNSError.m b/Pods/Sentry/Sources/Sentry/SentryNSError.m new file mode 100644 index 00000000..783dd88c --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryNSError.m @@ -0,0 +1,24 @@ +#import "SentryNSError.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryNSError + +- (instancetype)initWithDomain:(NSString *)domain code:(NSInteger)code +{ + if (self = [super init]) { + _domain = domain; + _code = code; + } + return self; +} + +- (NSDictionary *)serialize +{ + return @{ @"domain" : self.domain, @"code" : @(self.code) }; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryNSURLRequest.m b/Pods/Sentry/Sources/Sentry/SentryNSURLRequest.m new file mode 100644 index 00000000..f52c088c --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryNSURLRequest.m @@ -0,0 +1,136 @@ +#import "SentryNSURLRequest.h" +#import "NSData+SentryCompression.h" +#import "SentryClient.h" +#import "SentryDsn.h" +#import "SentryError.h" +#import "SentryEvent.h" +#import "SentryHub.h" +#import "SentryLog.h" +#import "SentryMeta.h" +#import "SentrySDK+Private.h" +#import "SentrySerialization.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString *const SentryServerVersionString = @"7"; +NSTimeInterval const SentryRequestTimeout = 15; + +@interface +SentryNSURLRequest () + +@property (nonatomic, strong) SentryDsn *dsn; + +@end + +@implementation SentryNSURLRequest + +- (_Nullable instancetype)initStoreRequestWithDsn:(SentryDsn *)dsn + andEvent:(SentryEvent *)event + didFailWithError:(NSError *_Nullable *_Nullable)error +{ + NSDictionary *serialized = [event serialize]; + NSData *jsonData = [SentrySerialization dataWithJSONObject:serialized error:error]; + if (nil == jsonData) { + if (error) { + // TODO: We're possibly overriding an error set by the actual + // code that failed ^ + *error = NSErrorFromSentryError( + kSentryErrorJsonConversionError, @"Event cannot be converted to JSON"); + } + return nil; + } + + if ([SentrySDK.currentHub getClient].options.debug == YES) { + [SentryLog logWithMessage:@"Sending JSON -------------------------------" + andLevel:kSentryLevelDebug]; + [SentryLog logWithMessage:[NSString stringWithFormat:@"%@", + [[NSString alloc] initWithData:jsonData + encoding:NSUTF8StringEncoding]] + andLevel:kSentryLevelDebug]; + [SentryLog logWithMessage:@"--------------------------------------------" + andLevel:kSentryLevelDebug]; + } + return [self initStoreRequestWithDsn:dsn andData:jsonData didFailWithError:error]; +} + +- (_Nullable instancetype)initStoreRequestWithDsn:(SentryDsn *)dsn + andData:(NSData *)data + didFailWithError:(NSError *_Nullable *_Nullable)error +{ + NSURL *apiURL = [dsn getStoreEndpoint]; + self = [super initWithURL:apiURL + cachePolicy:NSURLRequestReloadIgnoringLocalCacheData + timeoutInterval:SentryRequestTimeout]; + if (self) { + NSString *authHeader = newAuthHeader(dsn.url); + + self.HTTPMethod = @"POST"; + [self setValue:authHeader forHTTPHeaderField:@"X-Sentry-Auth"]; + [self setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + [self setValue:SentryMeta.sdkName forHTTPHeaderField:@"User-Agent"]; + [self setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; + self.HTTPBody = [data sentry_gzippedWithCompressionLevel:-1 error:error]; + } + return self; +} + +// TODO: Get refactored out to be a single init method +- (_Nullable instancetype)initEnvelopeRequestWithDsn:(SentryDsn *)dsn + andData:(NSData *)data + didFailWithError:(NSError *_Nullable *_Nullable)error +{ + NSURL *apiURL = [dsn getEnvelopeEndpoint]; + self = [super initWithURL:apiURL + cachePolicy:NSURLRequestReloadIgnoringLocalCacheData + timeoutInterval:SentryRequestTimeout]; + if (self) { + NSString *authHeader = newAuthHeader(dsn.url); + + self.HTTPMethod = @"POST"; + [self setValue:authHeader forHTTPHeaderField:@"X-Sentry-Auth"]; + [self setValue:@"application/x-sentry-envelope" forHTTPHeaderField:@"Content-Type"]; + [self setValue:SentryMeta.sdkName forHTTPHeaderField:@"User-Agent"]; + [self setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; + self.HTTPBody = [data sentry_gzippedWithCompressionLevel:-1 error:error]; + } + + // TODO: When the SDK inits, Client is created, then hub, then hub assigned + // to SentrySDK. That means there's no hub set yet on SentrySDK when this + // code runs (hub init closes pending sessions) + if ([SentrySDK.currentHub getClient].options.debug == YES) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Envelope request with data: %@", + [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]] + andLevel:kSentryLevelDebug]; + } + return self; +} + +static NSString * +newHeaderPart(NSString *key, id value) +{ + return [NSString stringWithFormat:@"%@=%@", key, value]; +} + +static NSString * +newAuthHeader(NSURL *url) +{ + NSMutableString *string = [NSMutableString stringWithString:@"Sentry "]; + [string appendFormat:@"%@,", newHeaderPart(@"sentry_version", SentryServerVersionString)]; + [string + appendFormat:@"%@,", + newHeaderPart(@"sentry_client", + [NSString stringWithFormat:@"%@/%@", SentryMeta.sdkName, SentryMeta.versionString])]; + [string + appendFormat:@"%@,", + newHeaderPart(@"sentry_timestamp", @((NSInteger)[[NSDate date] timeIntervalSince1970]))]; + [string appendFormat:@"%@", newHeaderPart(@"sentry_key", url.user)]; + if (nil != url.password) { + [string appendFormat:@",%@", newHeaderPart(@"sentry_secret", url.password)]; + } + return string; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryOptions.m b/Pods/Sentry/Sources/Sentry/SentryOptions.m new file mode 100644 index 00000000..01bd62b8 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryOptions.m @@ -0,0 +1,233 @@ +#import "SentryOptions.h" +#import "SentryDsn.h" +#import "SentryError.h" +#import "SentryLog.h" +#import "SentryMeta.h" +#import "SentrySDK.h" +#import "SentrySdkInfo.h" + +@implementation SentryOptions + ++ (NSArray *)defaultIntegrations +{ + return @[ + @"SentryCrashIntegration", @"SentryAutoBreadcrumbTrackingIntegration", + @"SentryAutoSessionTrackingIntegration", @"SentryOutOfMemoryTrackingIntegration" + ]; +} + +- (instancetype)init +{ + if (self = [super init]) { + self.enabled = YES; + self.diagnosticLevel = kSentryLevelDebug; + self.debug = NO; + self.maxBreadcrumbs = defaultMaxBreadcrumbs; + self.maxCacheItems = 30; + self.integrations = SentryOptions.defaultIntegrations; + self.sampleRate = @1; + self.enableAutoSessionTracking = YES; + self.enableOutOfMemoryTracking = YES; + self.sessionTrackingIntervalMillis = [@30000 unsignedIntValue]; + self.attachStacktrace = YES; + self.maxAttachmentSize = 20 * 1024 * 1024; + self.sendDefaultPii = NO; + self.tracesSampleRate = @0; + + // Use the name of the bundle’s executable file as inAppInclude, so SentryFrameInAppLogic + // marks frames coming from there as inApp. With this approach, the SDK marks public + // frameworks such as UIKitCore, CoreFoundation, GraphicsServices, and so forth, as not + // inApp. For private frameworks, such as Sentry, dynamic and static frameworks differ. + // Suppose you use dynamic frameworks inside your app. In that case, the SDK marks these as + // not inApp as these frameworks are located in the application bundle, but their location + // is different from the main executable. In case you have a private framework that should + // be inApp you can add it to inAppInclude. When using static frameworks, the frameworks end + // up in the main executable. Therefore, the SDK currently can't detect if a frame of the + // main executable originates from the application or a private framework and marks all of + // them as inApp. To fix this, the user can use stack trace rules on Sentry. + NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; + NSString *bundleExecutable = infoDict[@"CFBundleExecutable"]; + if (nil == bundleExecutable) { + _inAppIncludes = [NSArray new]; + } else { + _inAppIncludes = @[ bundleExecutable ]; + } + + _inAppExcludes = [NSArray new]; + _sdkInfo = [[SentrySdkInfo alloc] initWithName:SentryMeta.sdkName + andVersion:SentryMeta.versionString]; + + // Set default release name + if (nil != infoDict) { + self.releaseName = + [NSString stringWithFormat:@"%@@%@+%@", infoDict[@"CFBundleIdentifier"], + infoDict[@"CFBundleShortVersionString"], infoDict[@"CFBundleVersion"]]; + } + } + return self; +} + +- (_Nullable instancetype)initWithDict:(NSDictionary *)options + didFailWithError:(NSError *_Nullable *_Nullable)error +{ + if (self = [self init]) { + [self validateOptions:options didFailWithError:error]; + if (nil != error && nil != *error) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Failed to initialize: %@", *error] + andLevel:kSentryLevelError]; + return nil; + } + } + return self; +} + +- (void)setDsn:(NSString *)dsn +{ + NSError *error = nil; + self.parsedDsn = [[SentryDsn alloc] initWithString:dsn didFailWithError:&error]; + + if (nil == error) { + _dsn = dsn; + } else { + NSString *errorMessage = [NSString stringWithFormat:@"Could not parse the DSN: %@.", error]; + [SentryLog logWithMessage:errorMessage andLevel:kSentryLevelError]; + } +} + +/** + * Populates all `SentryOptions` values from `options` dict using fallbacks/defaults if needed. + */ +- (void)validateOptions:(NSDictionary *)options + didFailWithError:(NSError *_Nullable *_Nullable)error +{ + if (nil != options[@"debug"]) { + self.debug = [options[@"debug"] boolValue]; + } + + if ([options[@"diagnosticLevel"] isKindOfClass:[NSString class]]) { + for (SentryLevel level = 0; level <= kSentryLevelFatal; level++) { + if ([SentryLevelNames[level] isEqualToString:options[@"diagnosticLevel"]]) { + self.diagnosticLevel = level; + break; + } + } + } + + NSString *dsn = @""; + if (nil != [options valueForKey:@"dsn"] && + [[options valueForKey:@"dsn"] isKindOfClass:[NSString class]]) { + dsn = [options valueForKey:@"dsn"]; + } + + self.parsedDsn = [[SentryDsn alloc] initWithString:dsn didFailWithError:error]; + + if ([options[@"release"] isKindOfClass:[NSString class]]) { + self.releaseName = options[@"release"]; + } + + if ([options[@"environment"] isKindOfClass:[NSString class]]) { + self.environment = options[@"environment"]; + } + + if ([options[@"dist"] isKindOfClass:[NSString class]]) { + self.dist = options[@"dist"]; + } + + if (nil != options[@"enabled"]) { + self.enabled = [options[@"enabled"] boolValue]; + } + + if ([options[@"maxBreadcrumbs"] isKindOfClass:[NSNumber class]]) { + self.maxBreadcrumbs = [options[@"maxBreadcrumbs"] unsignedIntValue]; + } + + if ([options[@"maxCacheItems"] isKindOfClass:[NSNumber class]]) { + self.maxCacheItems = [options[@"maxCacheItems"] unsignedIntValue]; + } + + if (nil != options[@"beforeSend"]) { + self.beforeSend = options[@"beforeSend"]; + } + + if (nil != options[@"beforeBreadcrumb"]) { + self.beforeBreadcrumb = options[@"beforeBreadcrumb"]; + } + + if (nil != options[@"onCrashedLastRun"]) { + self.onCrashedLastRun = options[@"onCrashedLastRun"]; + } + + if (nil != options[@"integrations"]) { + self.integrations = options[@"integrations"]; + } + + NSNumber *sampleRate = options[@"sampleRate"]; + if (nil != sampleRate && [sampleRate floatValue] >= 0 && [sampleRate floatValue] <= 1.0) { + self.sampleRate = sampleRate; + } + + if (nil != options[@"enableAutoSessionTracking"]) { + self.enableAutoSessionTracking = [options[@"enableAutoSessionTracking"] boolValue]; + } + + if (nil != options[@"enableOutOfMemoryTracking"]) { + self.enableOutOfMemoryTracking = [options[@"enableOutOfMemoryTracking"] boolValue]; + } + + if (nil != options[@"sessionTrackingIntervalMillis"]) { + self.sessionTrackingIntervalMillis = + [options[@"sessionTrackingIntervalMillis"] unsignedIntValue]; + } + + if (nil != options[@"attachStacktrace"]) { + self.attachStacktrace = [options[@"attachStacktrace"] boolValue]; + } + + if (nil != options[@"maxAttachmentSize"]) { + self.maxAttachmentSize = [options[@"maxAttachmentSize"] unsignedIntValue]; + } + + if (nil != options[@"sendDefaultPii"]) { + self.sendDefaultPii = [options[@"sendDefaultPii"] boolValue]; + } + + NSNumber *tracesSampleRate = options[@"tracesSampleRate"]; + if (nil != tracesSampleRate && [tracesSampleRate floatValue] >= 0 && + [tracesSampleRate floatValue] <= 1.0) { + self.tracesSampleRate = tracesSampleRate; + } + + if (nil != options[@"tracesSampler"]) { + self.tracesSampler = options[@"tracesSampler"]; + } + + NSPredicate *isNSString = [NSPredicate predicateWithBlock:^BOOL( + id object, NSDictionary *bindings) { return [object isKindOfClass:[NSString class]]; }]; + + if ([options[@"inAppIncludes"] isKindOfClass:[NSArray class]]) { + NSArray *inAppIncludes = + [options[@"inAppIncludes"] filteredArrayUsingPredicate:isNSString]; + _inAppIncludes = [_inAppIncludes arrayByAddingObjectsFromArray:inAppIncludes]; + } + + if ([options[@"inAppExcludes"] isKindOfClass:[NSArray class]]) { + _inAppExcludes = [options[@"inAppExcludes"] filteredArrayUsingPredicate:isNSString]; + } + + if ([options[@"urlSessionDelegate"] conformsToProtocol:@protocol(NSURLSessionDelegate)]) { + self.urlSessionDelegate = options[@"urlSessionDelegate"]; + } +} + +- (void)addInAppInclude:(NSString *)inAppInclude +{ + _inAppIncludes = [self.inAppIncludes arrayByAddingObject:inAppInclude]; +} + +- (void)addInAppExclude:(NSString *)inAppExclude +{ + _inAppExcludes = [self.inAppExcludes arrayByAddingObject:inAppExclude]; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryLogic.m b/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryLogic.m new file mode 100644 index 00000000..07481da3 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryLogic.m @@ -0,0 +1,104 @@ +#import "SentrySDK+Private.h" +#import +#import +#import +#import +#import +#import +#import +#import + +#if SENTRY_HAS_UIKIT +# import +#endif + +@interface +SentryOutOfMemoryLogic () + +@property (nonatomic, strong) SentryOptions *options; +@property (nonatomic, strong) SentryCrashAdapter *crashAdapter; + +@end + +@implementation SentryOutOfMemoryLogic : NSObject + +- (instancetype)initWithOptions:(SentryOptions *)options + crashAdapter:(SentryCrashAdapter *)crashAdatper +{ + if (self = [super init]) { + self.options = options; + self.crashAdapter = crashAdatper; + } + return self; +} + +- (BOOL)isOOM +{ + if (!self.options.enableOutOfMemoryTracking) { + return NO; + } + +#if SENTRY_HAS_UIKIT + SentryFileManager *fileManager = [[[SentrySDK currentHub] getClient] fileManager]; + SentryAppState *previousAppState = [fileManager readAppState]; + + SentryAppState *currentAppState = [self buildCurrentAppState]; + + // If there is no previous app state, we can't do anything. + if (nil == previousAppState) { + return NO; + } + + // If the release name is different we assume it's an upgrade + if (![currentAppState.releaseName isEqualToString:previousAppState.releaseName]) { + return NO; + } + + // The OS was upgraded + if (![currentAppState.osVersion isEqualToString:previousAppState.osVersion]) { + return NO; + } + + // Restarting the app in development is a termination we can't catch and would falsely + // report OOMs. + if (previousAppState.isDebugging) { + return NO; + } + + // The app was terminated normally + if (previousAppState.wasTerminated) { + return NO; + } + + // The app crashed on the previous run. No OOM. + if (self.crashAdapter.crashedLastLaunch) { + return NO; + } + + // Was the app in foreground/active ? + // If the app was in background we can't reliably tell if it was an OOM or not. + if (!previousAppState.isActive) { + return NO; + } + + return YES; +#else + // We can only track OOMs for iOS, tvOS and macCatalyst. Therefore we return NO for other + // platforms. + return NO; +#endif +} + +#if SENTRY_HAS_UIKIT +- (SentryAppState *)buildCurrentAppState +{ + // Is the current process being traced or not? If it is a debugger is attached. + bool isDebugging = self.crashAdapter.isBeingTraced; + + return [[SentryAppState alloc] initWithReleaseName:self.options.releaseName + osVersion:UIDevice.currentDevice.systemVersion + isDebugging:isDebugging]; +} +#endif + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryTracker.m b/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryTracker.m new file mode 100644 index 00000000..37932809 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryTracker.m @@ -0,0 +1,143 @@ +#import "SentryFileManager.h" +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#if SENTRY_HAS_UIKIT +# import +#endif + +@interface +SentryOutOfMemoryTracker () + +@property (nonatomic, strong) SentryOptions *options; +@property (nonatomic, strong) SentryOutOfMemoryLogic *outOfMemoryLogic; +@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueue; + +@end + +@implementation SentryOutOfMemoryTracker : NSObject + +- (instancetype)initWithOptions:(SentryOptions *)options + outOfMemoryLogic:(SentryOutOfMemoryLogic *)outOfMemoryLogic + dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper +{ + if (self = [super init]) { + self.options = options; + self.outOfMemoryLogic = outOfMemoryLogic; + self.dispatchQueue = dispatchQueueWrapper; + } + return self; +} + +- (void)start +{ +#if SENTRY_HAS_UIKIT + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(didBecomeActive) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(didBecomeActive) + name:SentryHybridSdkDidBecomeActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(willResignActive) + name:UIApplicationWillResignActiveNotification + object:nil]; + + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(willTerminate) + name:UIApplicationWillTerminateNotification + object:nil]; + + [self.dispatchQueue dispatchAsyncWithBlock:^{ + if ([self.outOfMemoryLogic isOOM]) { + SentryEvent *event = [[SentryEvent alloc] initWithLevel:kSentryLevelFatal]; + // Set to empty list so no breadcrumbs of the current scope are added + event.breadcrumbs = @[]; + + SentryException *exception = + [[SentryException alloc] initWithValue:SentryOutOfMemoryExceptionValue + type:SentryOutOfMemoryExceptionType]; + SentryMechanism *mechanism = + [[SentryMechanism alloc] initWithType:SentryOutOfMemoryMechanismType]; + mechanism.handled = @(NO); + exception.mechanism = mechanism; + event.exceptions = @[ exception ]; + + // We don't need to upate the releaseName of the event to the previous app state as we + // assume it's not an OOM when the releaseName changed between app starts. + [SentrySDK captureCrashEvent:event]; + } + + SentryFileManager *fileManager = [[[SentrySDK currentHub] getClient] fileManager]; + [fileManager storeAppState:[self.outOfMemoryLogic buildCurrentAppState]]; + }]; + +#else + [SentryLog logWithMessage:@"NO UIKit -> SentryOutOfMemoryTracker will not track OOM." + andLevel:kSentryLevelInfo]; + return; +#endif +} + +- (void)stop +{ +#if SENTRY_HAS_UIKIT + [NSNotificationCenter.defaultCenter removeObserver:self]; +#endif +} + +/** + * It is called when an App. is receiving events / It is in the foreground and when we receive a + * SentryHybridSdkDidBecomeActiveNotification. + */ +- (void)didBecomeActive +{ + [self updateAppState:^(SentryAppState *appState) { appState.isActive = YES; }]; +} + +/** + * The app is about to lose focus / going to the background. This is only called when an app was + * receiving events / was is in the foreground. + */ +- (void)willResignActive +{ + [self updateAppState:^(SentryAppState *appState) { appState.isActive = NO; }]; +} + +- (void)willTerminate +{ + [self updateAppState:^(SentryAppState *appState) { appState.wasTerminated = YES; }]; +} + +- (void)updateAppState:(void (^)(SentryAppState *))block +{ + // We accept the tradeoff that the app state might not be 100% up to date over blocking the main + // thread. + [self.dispatchQueue dispatchAsyncWithBlock:^{ + SentryFileManager *fileManager = [[[SentrySDK currentHub] getClient] fileManager]; + SentryAppState *appState = [fileManager readAppState]; + if (nil != appState) { + block(appState); + [fileManager storeAppState:appState]; + } + }]; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryTrackingIntegration.m b/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryTrackingIntegration.m new file mode 100644 index 00000000..bbff3a2f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryOutOfMemoryTrackingIntegration.m @@ -0,0 +1,53 @@ +#import +#import +#import +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryOutOfMemoryTrackingIntegration () + +@property (nonatomic, strong) SentryOutOfMemoryTracker *tracker; + +@end + +@implementation SentryOutOfMemoryTrackingIntegration + +- (void)installWithOptions:(SentryOptions *)options +{ + if (options.enableOutOfMemoryTracking) { + dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_PRIORITY_HIGH, 0); + SentryDispatchQueueWrapper *dispatchQueueWrapper = + [[SentryDispatchQueueWrapper alloc] initWithName:"sentry-out-of-memory-tracker" + attributes:attributes]; + + SentryOutOfMemoryLogic *logic = + [[SentryOutOfMemoryLogic alloc] initWithOptions:options + crashAdapter:[[SentryCrashAdapter alloc] init]]; + + self.tracker = [[SentryOutOfMemoryTracker alloc] initWithOptions:options + outOfMemoryLogic:logic + dispatchQueueWrapper:dispatchQueueWrapper]; + [self.tracker start]; + } +} + +- (void)uninstall +{ + [self stop]; +} + +- (void)stop +{ + if (nil != self.tracker) { + [self.tracker stop]; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryQueueableRequestManager.m b/Pods/Sentry/Sources/Sentry/SentryQueueableRequestManager.m new file mode 100644 index 00000000..be591851 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryQueueableRequestManager.m @@ -0,0 +1,54 @@ +#import "SentryQueueableRequestManager.h" +#import "SentryLog.h" +#import "SentryRequestOperation.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryQueueableRequestManager () + +@property (nonatomic, strong) NSOperationQueue *queue; +@property (nonatomic, strong) NSURLSession *session; + +@end + +@implementation SentryQueueableRequestManager + +- (instancetype)initWithSession:(NSURLSession *)session +{ + self = [super init]; + if (self) { + self.session = session; + self.queue = [[NSOperationQueue alloc] init]; + self.queue.name = @"io.sentry.QueueableRequestManager.OperationQueue"; + self.queue.maxConcurrentOperationCount = 3; + } + return self; +} + +- (BOOL)isReady +{ + // We always have at least one operation in the queue when calling this + return self.queue.operationCount <= 1; +} + +- (void)addRequest:(NSURLRequest *)request + completionHandler:(_Nullable SentryRequestOperationFinished)completionHandler +{ + SentryRequestOperation *operation = [[SentryRequestOperation alloc] + initWithSession:self.session + request:request + completionHandler:^(NSHTTPURLResponse *_Nullable response, NSError *_Nullable error) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Queued requests: %@", + @(self.queue.operationCount - 1)] + andLevel:kSentryLevelDebug]; + if (completionHandler) { + completionHandler(response, error); + } + }]; + [self.queue addOperation:operation]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryRandom.m b/Pods/Sentry/Sources/Sentry/SentryRandom.m new file mode 100644 index 00000000..9847f303 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryRandom.m @@ -0,0 +1,18 @@ +#import "SentryRandom.h" + +@implementation SentryRandom + +- (instancetype)init +{ + if (self = [super init]) { + srand48(time(0)); // drand seed initializer + } + return self; +} + +- (double)nextNumber +{ + return drand48(); +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryRateLimitCategoryMapper.m b/Pods/Sentry/Sources/Sentry/SentryRateLimitCategoryMapper.m new file mode 100644 index 00000000..f921c430 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryRateLimitCategoryMapper.m @@ -0,0 +1,71 @@ +#import "SentryRateLimitCategoryMapper.h" +#import "SentryEnvelopeItemType.h" +#import "SentryRateLimitCategory.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryRateLimitCategoryMapper () + +@end + +@implementation SentryRateLimitCategoryMapper + ++ (SentryRateLimitCategory)mapEventTypeToCategory:(NSString *)eventType +{ + // Currently we classify every event type as error. + // This is going to change in the future. + return kSentryRateLimitCategoryError; +} + ++ (SentryRateLimitCategory)mapEnvelopeItemTypeToCategory:(NSString *)itemType +{ + SentryRateLimitCategory category = kSentryRateLimitCategoryDefault; + if ([itemType isEqualToString:SentryEnvelopeItemTypeEvent]) { + category = kSentryRateLimitCategoryError; + } + if ([itemType isEqualToString:SentryEnvelopeItemTypeSession]) { + category = kSentryRateLimitCategorySession; + } + if ([itemType isEqualToString:SentryEnvelopeItemTypeTransaction]) { + category = kSentryRateLimitCategoryTransaction; + } + if ([itemType isEqualToString:SentryEnvelopeItemTypeAttachment]) { + category = kSentryRateLimitCategoryAttachment; + } + return category; +} + ++ (SentryRateLimitCategory)mapIntegerToCategory:(NSUInteger)value +{ + SentryRateLimitCategory category = kSentryRateLimitCategoryUnknown; + + if (value == kSentryRateLimitCategoryAll) { + category = kSentryRateLimitCategoryAll; + } + if (value == kSentryRateLimitCategoryDefault) { + category = kSentryRateLimitCategoryDefault; + } + if (value == kSentryRateLimitCategoryError) { + category = kSentryRateLimitCategoryError; + } + if (value == kSentryRateLimitCategorySession) { + category = kSentryRateLimitCategorySession; + } + if (value == kSentryRateLimitCategoryTransaction) { + category = kSentryRateLimitCategoryTransaction; + } + if (value == kSentryRateLimitCategoryAttachment) { + category = kSentryRateLimitCategoryAttachment; + } + if (value == kSentryRateLimitCategoryUnknown) { + category = kSentryRateLimitCategoryUnknown; + } + + return category; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryRateLimitParser.m b/Pods/Sentry/Sources/Sentry/SentryRateLimitParser.m new file mode 100644 index 00000000..26072f61 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryRateLimitParser.m @@ -0,0 +1,112 @@ +#import "SentryRateLimitParser.h" +#import "SentryCurrentDate.h" +#import "SentryDateUtil.h" +#import "SentryRateLimitCategoryMapper.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryRateLimitParser () + +@end + +@implementation SentryRateLimitParser + +- (NSDictionary *)parse:(NSString *)header +{ + if ([header length] == 0) { + return @{}; + } + + NSMutableDictionary *rateLimits = [NSMutableDictionary new]; + + // The header might contain whitespaces and they must be ignored. + NSString *headerNoWhitespaces = [self removeAllWhitespaces:header]; + + // Each quotaLimit exists of retryAfter:categories:scope. The scope is + // ignored here as it can be ignored by SDKs. + for (NSString *quota in [headerNoWhitespaces componentsSeparatedByString:@","]) { + NSArray *parameters = [quota componentsSeparatedByString:@":"]; + + NSNumber *rateLimitInSeconds = [self parseRateLimitSeconds:parameters[0]]; + if (nil == rateLimitInSeconds || [rateLimitInSeconds intValue] <= 0) { + continue; + } + + for (NSNumber *category in [self parseCategories:parameters[1]]) { + rateLimits[category] = [self getLongerRateLimit:rateLimits[category] + andRateLimitInSeconds:rateLimitInSeconds]; + } + } + + return rateLimits; +} + +- (NSString *)removeAllWhitespaces:(NSString *)string +{ + NSArray *words = [string + componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + return [words componentsJoinedByString:@""]; +} + +- (NSNumber *)parseRateLimitSeconds:(NSString *)string +{ + NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; + numberFormatter.numberStyle = NSNumberFormatterNoStyle; + return [numberFormatter numberFromString:string]; +} + +- (SentryRateLimitCategory)mapStringToCategory:(NSString *)category +{ + SentryRateLimitCategory result = kSentryRateLimitCategoryUnknown; + if ([category isEqualToString:@""]) { + result = kSentryRateLimitCategoryAll; + } + if ([category isEqualToString:@"default"]) { + result = kSentryRateLimitCategoryDefault; + } + if ([category isEqualToString:@"error"]) { + result = kSentryRateLimitCategoryError; + } + if ([category isEqualToString:@"session"]) { + result = kSentryRateLimitCategorySession; + } + if ([category isEqualToString:@"transaction"]) { + result = kSentryRateLimitCategoryTransaction; + } + if ([category isEqualToString:@"attachment"]) { + result = kSentryRateLimitCategoryAttachment; + } + return result; +} + +- (NSArray *)parseCategories:(NSString *)categoriesAsString +{ + // The categories are a semicolon separated list. If this parameter is empty + // it stands for all categories. componentsSeparatedByString returns one + // category even if this parameter is empty. + NSMutableArray *categories = [NSMutableArray new]; + for (NSString *categoryAsString in [categoriesAsString componentsSeparatedByString:@";"]) { + SentryRateLimitCategory category = [self mapStringToCategory:categoryAsString]; + + // Unknown categories must be ignored + if (category != kSentryRateLimitCategoryUnknown) { + [categories addObject:@(category)]; + } + } + + return categories; +} + +- (NSDate *)getLongerRateLimit:(NSDate *)existingRateLimit + andRateLimitInSeconds:(NSNumber *)newRateLimitInSeconds +{ + NSDate *newDate = + [SentryCurrentDate.date dateByAddingTimeInterval:[newRateLimitInSeconds doubleValue]]; + return [SentryDateUtil getMaximumDate:newDate andOther:existingRateLimit]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryRequestOperation.m b/Pods/Sentry/Sources/Sentry/SentryRequestOperation.m new file mode 100644 index 00000000..c6324f92 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryRequestOperation.m @@ -0,0 +1,79 @@ +#import "SentryRequestOperation.h" +#import "SentryClient.h" +#import "SentryError.h" +#import "SentryHub.h" +#import "SentryLog.h" +#import "SentrySDK+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryRequestOperation () + +@property (nonatomic, strong) NSURLSessionTask *task; +@property (nonatomic, strong) NSURLRequest *request; + +@end + +@implementation SentryRequestOperation + +- (instancetype)initWithSession:(NSURLSession *)session + request:(NSURLRequest *)request + completionHandler:(_Nullable SentryRequestOperationFinished)completionHandler +{ + self = [super init]; + if (self) { + self.request = request; + self.task = [session + dataTaskWithRequest:self.request + completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, + NSError *_Nullable error) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + NSInteger statusCode = [httpResponse statusCode]; + + // We only have these if's here because of performance reasons + [SentryLog logWithMessage:[NSString stringWithFormat:@"Request status: %ld", + (long)statusCode] + andLevel:kSentryLevelDebug]; + if ([SentrySDK.currentHub getClient].options.debug == YES) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Request response: %@", + [[NSString alloc] + initWithData:data + encoding:NSUTF8StringEncoding]] + andLevel:kSentryLevelDebug]; + } + + if (nil != error) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Request failed: %@", error] + andLevel:kSentryLevelError]; + } + + if (completionHandler) { + completionHandler(httpResponse, error); + } + + [self completeOperation]; + }]; + } + return self; +} + +- (void)cancel +{ + if (nil != self.task) { + [self.task cancel]; + } + [super cancel]; +} + +- (void)main +{ + if (nil != self.task) { + [self.task resume]; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryRetryAfterHeaderParser.m b/Pods/Sentry/Sources/Sentry/SentryRetryAfterHeaderParser.m new file mode 100644 index 00000000..c5912703 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryRetryAfterHeaderParser.m @@ -0,0 +1,44 @@ +#import "SentryRetryAfterHeaderParser.h" +#import "SentryCurrentDate.h" +#import "SentryHttpDateParser.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryRetryAfterHeaderParser () + +@property (nonatomic, strong) SentryHttpDateParser *httpDateParser; + +@end + +@implementation SentryRetryAfterHeaderParser + +- (instancetype)initWithHttpDateParser:(SentryHttpDateParser *)httpDateParser +{ + if (self = [super init]) { + self.httpDateParser = httpDateParser; + } + return self; +} + +- (NSDate *_Nullable)parse:(NSString *_Nullable)retryAfterHeader +{ + if (nil == retryAfterHeader || 0 == [retryAfterHeader length]) { + return nil; + } + + NSInteger retryAfterSeconds = [retryAfterHeader integerValue]; + if (0 != retryAfterSeconds) { + return [[SentryCurrentDate date] dateByAddingTimeInterval:retryAfterSeconds]; + } + + // parsing as double/seconds failed, try to parse as date + NSDate *retryAfterDate = [self.httpDateParser dateFromString:retryAfterHeader]; + + return retryAfterDate; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySDK.m b/Pods/Sentry/Sources/Sentry/SentrySDK.m new file mode 100644 index 00000000..e6669c6b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySDK.m @@ -0,0 +1,330 @@ +#import "SentrySDK.h" +#import "SentryBreadcrumb.h" +#import "SentryClient+Private.h" +#import "SentryCrash.h" +#import "SentryHub+Private.h" +#import "SentryLog.h" +#import "SentryMeta.h" +#import "SentryScope.h" + +@interface +SentrySDK () + +@property (class) SentryHub *currentHub; + +@end + +NS_ASSUME_NONNULL_BEGIN +@implementation SentrySDK + +static SentryHub *currentHub; +static BOOL crashedLastRunCalled; + ++ (SentryHub *)currentHub +{ + @synchronized(self) { + if (nil == currentHub) { + currentHub = [[SentryHub alloc] initWithClient:nil andScope:nil]; + } + return currentHub; + } +} + +/** Internal, only needed for testing. */ ++ (void)setCurrentHub:(SentryHub *)hub +{ + @synchronized(self) { + currentHub = hub; + } +} + ++ (nullable id)span +{ + return currentHub.scope.span; +} + ++ (BOOL)crashedLastRunCalled +{ + return crashedLastRunCalled; +} + ++ (void)setCrashedLastRunCalled:(BOOL)value +{ + crashedLastRunCalled = value; +} + ++ (void)startWithOptions:(NSDictionary *)optionsDict +{ + NSError *error = nil; + SentryOptions *options = [[SentryOptions alloc] initWithDict:optionsDict + didFailWithError:&error]; + if (nil != error) { + [SentryLog logWithMessage:@"Error while initializing the SDK" andLevel:kSentryLevelError]; + [SentryLog logWithMessage:[NSString stringWithFormat:@"%@", error] + andLevel:kSentryLevelError]; + } else { + [SentrySDK startWithOptionsObject:options]; + } +} + ++ (void)startWithOptionsObject:(SentryOptions *)options +{ + [SentryLog configure:options.debug diagnosticLevel:options.diagnosticLevel]; + SentryClient *newClient = [[SentryClient alloc] initWithOptions:options]; + // The Hub needs to be initialized with a client so that closing a session + // can happen. + [SentrySDK setCurrentHub:[[SentryHub alloc] initWithClient:newClient andScope:nil]]; + [SentryLog logWithMessage:[NSString stringWithFormat:@"SDK initialized! Version: %@", + SentryMeta.versionString] + andLevel:kSentryLevelDebug]; + [SentrySDK installIntegrations]; +} + ++ (void)startWithConfigureOptions:(void (^)(SentryOptions *options))configureOptions +{ + SentryOptions *options = [[SentryOptions alloc] init]; + configureOptions(options); + [SentrySDK startWithOptionsObject:options]; +} + ++ (void)captureCrashEvent:(SentryEvent *)event +{ + [SentrySDK.currentHub captureCrashEvent:event]; +} + ++ (SentryId *)captureEvent:(SentryEvent *)event +{ + return [SentrySDK captureEvent:event withScope:SentrySDK.currentHub.scope]; +} + ++ (SentryId *)captureEvent:(SentryEvent *)event withScopeBlock:(void (^)(SentryScope *))block +{ + SentryScope *scope = [[SentryScope alloc] initWithScope:SentrySDK.currentHub.scope]; + block(scope); + return [SentrySDK captureEvent:event withScope:scope]; +} + ++ (SentryId *)captureEvent:(SentryEvent *)event withScope:(SentryScope *)scope +{ + return [SentrySDK.currentHub captureEvent:event withScope:scope]; +} + ++ (id)startTransactionWithName:(NSString *)name operation:(NSString *)operation +{ + return [SentrySDK.currentHub startTransactionWithName:name operation:operation]; +} + ++ (id)startTransactionWithName:(NSString *)name + operation:(NSString *)operation + bindToScope:(BOOL)bindToScope +{ + return [SentrySDK.currentHub startTransactionWithName:name + operation:operation + bindToScope:bindToScope]; +} + ++ (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext +{ + return [SentrySDK.currentHub startTransactionWithContext:transactionContext]; +} + ++ (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + bindToScope:(BOOL)bindToScope +{ + return [SentrySDK.currentHub startTransactionWithContext:transactionContext + bindToScope:bindToScope]; +} + ++ (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + bindToScope:(BOOL)bindToScope + customSamplingContext:(NSDictionary *)customSamplingContext +{ + return [SentrySDK.currentHub startTransactionWithContext:transactionContext + bindToScope:bindToScope + customSamplingContext:customSamplingContext]; +} + ++ (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext + customSamplingContext:(NSDictionary *)customSamplingContext +{ + return [SentrySDK.currentHub startTransactionWithContext:transactionContext + customSamplingContext:customSamplingContext]; +} + ++ (SentryId *)captureError:(NSError *)error +{ + return [SentrySDK captureError:error withScope:SentrySDK.currentHub.scope]; +} + ++ (SentryId *)captureError:(NSError *)error withScopeBlock:(void (^)(SentryScope *_Nonnull))block +{ + SentryScope *scope = [[SentryScope alloc] initWithScope:SentrySDK.currentHub.scope]; + block(scope); + return [SentrySDK captureError:error withScope:scope]; +} + ++ (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope +{ + return [SentrySDK.currentHub captureError:error withScope:scope]; +} + ++ (SentryId *)captureException:(NSException *)exception +{ + return [SentrySDK captureException:exception withScope:SentrySDK.currentHub.scope]; +} + ++ (SentryId *)captureException:(NSException *)exception + withScopeBlock:(void (^)(SentryScope *))block +{ + SentryScope *scope = [[SentryScope alloc] initWithScope:SentrySDK.currentHub.scope]; + block(scope); + return [SentrySDK captureException:exception withScope:scope]; +} + ++ (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope +{ + return [SentrySDK.currentHub captureException:exception withScope:scope]; +} + ++ (SentryId *)captureMessage:(NSString *)message +{ + return [SentrySDK captureMessage:message withScope:SentrySDK.currentHub.scope]; +} + ++ (SentryId *)captureMessage:(NSString *)message withScopeBlock:(void (^)(SentryScope *))block +{ + SentryScope *scope = [[SentryScope alloc] initWithScope:SentrySDK.currentHub.scope]; + block(scope); + return [SentrySDK captureMessage:message withScope:scope]; +} + ++ (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope +{ + return [SentrySDK.currentHub captureMessage:message withScope:scope]; +} + +/** + * Needed by hybrid SDKs as react-native to synchronously capture an envelope. + */ ++ (void)captureEnvelope:(SentryEnvelope *)envelope +{ + [SentrySDK.currentHub captureEnvelope:envelope]; +} + +/** + * Needed by hybrid SDKs as react-native to synchronously store an envelope to disk. + */ ++ (void)storeEnvelope:(SentryEnvelope *)envelope +{ + if (nil != [SentrySDK.currentHub getClient]) { + [[SentrySDK.currentHub getClient] storeEnvelope:envelope]; + } +} + ++ (void)captureUserFeedback:(SentryUserFeedback *)userFeedback +{ + [SentrySDK.currentHub captureUserFeedback:userFeedback]; +} + ++ (void)addBreadcrumb:(SentryBreadcrumb *)crumb +{ + [SentrySDK.currentHub addBreadcrumb:crumb]; +} + ++ (void)configureScope:(void (^)(SentryScope *scope))callback +{ + [SentrySDK.currentHub configureScope:callback]; +} + ++ (void)setUser:(SentryUser *_Nullable)user +{ + [SentrySDK.currentHub setUser:user]; +} + ++ (BOOL)crashedLastRun +{ + return SentryCrash.sharedInstance.crashedLastLaunch; +} + ++ (void)startSession +{ + [SentrySDK.currentHub startSession]; +} + ++ (void)endSession +{ + [SentrySDK.currentHub endSession]; +} + +/** + * Install integrations and keeps ref in `SentryHub.integrations` + */ ++ (void)installIntegrations +{ + if (nil == [SentrySDK.currentHub getClient]) { + // Gatekeeper + return; + } + SentryOptions *options = [SentrySDK.currentHub getClient].options; + for (NSString *integrationName in [SentrySDK.currentHub getClient].options.integrations) { + Class integrationClass = NSClassFromString(integrationName); + if (nil == integrationClass) { + NSString *logMessage = [NSString stringWithFormat:@"[SentryHub doInstallIntegrations] " + @"couldn't find \"%@\" -> skipping.", + integrationName]; + [SentryLog logWithMessage:logMessage andLevel:kSentryLevelError]; + continue; + } else if ([SentrySDK.currentHub isIntegrationInstalled:integrationClass]) { + NSString *logMessage = + [NSString stringWithFormat:@"[SentryHub doInstallIntegrations] already " + @"installed \"%@\" -> skipping.", + integrationName]; + [SentryLog logWithMessage:logMessage andLevel:kSentryLevelError]; + continue; + } + id integrationInstance = [[integrationClass alloc] init]; + [integrationInstance installWithOptions:options]; + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Integration installed: %@", integrationName] + andLevel:kSentryLevelDebug]; + [SentrySDK.currentHub.installedIntegrations addObject:integrationInstance]; + } +} + +/** + * Closes the SDK and uninstalls all the integrations. + */ ++ (void)close +{ + // pop the hub and unset + SentryHub *hub = SentrySDK.currentHub; + [SentrySDK setCurrentHub:nil]; + + // uninstall all the integrations + for (NSObject *integration in hub.installedIntegrations) { + if ([integration respondsToSelector:@selector(uninstall)]) { + [integration uninstall]; + } + } + [hub.installedIntegrations removeAllObjects]; + + // close the client + SentryClient *client = [hub getClient]; + client.options.enabled = NO; + [hub bindClient:nil]; + + [SentryLog logWithMessage:@"SDK closed!" andLevel:kSentryLevelDebug]; +} + +#ifndef __clang_analyzer__ +// Code not to be analyzed ++ (void)crash +{ + int *p = 0; + *p = 0; +} +#endif + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySamplingContext.m b/Pods/Sentry/Sources/Sentry/SentrySamplingContext.m new file mode 100644 index 00000000..e50344c7 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySamplingContext.m @@ -0,0 +1,21 @@ +#import "SentrySamplingContext.h" + +@implementation SentrySamplingContext + +- (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext +{ + if (self = [super init]) { + _transactionContext = transactionContext; + } + return self; +} + +- (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext + customSamplingContext:(NSDictionary *)customSamplingContext +{ + self = [self initWithTransactionContext:transactionContext]; + _customSamplingContext = customSamplingContext; + return self; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryScope+Private.m b/Pods/Sentry/Sources/Sentry/SentryScope+Private.m new file mode 100644 index 00000000..370dc1b0 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryScope+Private.m @@ -0,0 +1,31 @@ +#import "SentryScope+Private.h" +#import + +@implementation SentryScope (Private) + +@dynamic listeners, attachments; + +- (NSMutableArray *)listeners +{ + return objc_getAssociatedObject(self, @selector(listeners)); +} + +- (void)setListeners:(NSMutableArray *)listeners +{ + objc_setAssociatedObject( + self, @selector(listeners), listeners, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (void)addScopeListener:(SentryScopeListener)listener; +{ + [self.listeners addObject:listener]; +} + +- (void)notifyListeners +{ + for (SentryScopeListener listener in self.listeners) { + listener(self); + } +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryScope.m b/Pods/Sentry/Sources/Sentry/SentryScope.m new file mode 100644 index 00000000..f3e874c2 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryScope.m @@ -0,0 +1,474 @@ +#import "SentryScope.h" +#import "SentryAttachment.h" +#import "SentryBreadcrumb.h" +#import "SentryEvent.h" +#import "SentryGlobalEventProcessor.h" +#import "SentryLog.h" +#import "SentryScope+Private.h" +#import "SentrySession.h" +#import "SentrySpan.h" +#import "SentryTracer.h" +#import "SentryUser.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryScope () + +/** + * Set global user -> thus will be sent with every event + */ +@property (atomic, strong) SentryUser *_Nullable userObject; + +/** + * Set global tags -> these will be sent with every event + */ +@property (atomic, strong) NSMutableDictionary *tagDictionary; + +/** + * Set global extra -> these will be sent with every event + */ +@property (atomic, strong) NSMutableDictionary *extraDictionary; + +/** + * used to add values in event context. + */ +@property (atomic, strong) + NSMutableDictionary *> *contextDictionary; + +/** + * Contains the breadcrumbs which will be sent with the event + */ +@property (atomic, strong) NSMutableArray *breadcrumbArray; + +/** + * This distribution of the application. + */ +@property (atomic, copy) NSString *_Nullable distString; + +/** + * The environment used in this scope. + */ +@property (atomic, copy) NSString *_Nullable environmentString; + +/** + * Set the fingerprint of an event to determine the grouping + */ +@property (atomic, strong) NSMutableArray *fingerprintArray; + +/** + * SentryLevel of the event + */ +@property (atomic) enum SentryLevel levelEnum; + +@property (atomic) NSInteger maxBreadcrumbs; + +@property (atomic, strong) NSMutableArray *attachmentArray; + +@end + +@implementation SentryScope { + NSObject *_spanLock; +} + +#pragma mark Initializer + +- (instancetype)initWithMaxBreadcrumbs:(NSInteger)maxBreadcrumbs +{ + if (self = [super init]) { + self.listeners = [NSMutableArray new]; + self.maxBreadcrumbs = maxBreadcrumbs; + self.breadcrumbArray = [NSMutableArray new]; + self.tagDictionary = [NSMutableDictionary new]; + self.extraDictionary = [NSMutableDictionary new]; + self.contextDictionary = [NSMutableDictionary new]; + self.attachmentArray = [NSMutableArray new]; + self.fingerprintArray = [NSMutableArray new]; + _spanLock = [[NSObject alloc] init]; + } + return self; +} + +- (instancetype)init +{ + return [self initWithMaxBreadcrumbs:defaultMaxBreadcrumbs]; +} + +- (instancetype)initWithScope:(SentryScope *)scope +{ + if (self = [self init]) { + [_extraDictionary addEntriesFromDictionary:[scope extras]]; + [_tagDictionary addEntriesFromDictionary:[scope tags]]; + [_contextDictionary addEntriesFromDictionary:[scope context]]; + [_breadcrumbArray addObjectsFromArray:[scope breadcrumbs]]; + [_fingerprintArray addObjectsFromArray:[scope fingerprints]]; + [_attachmentArray addObjectsFromArray:[scope attachments]]; + + self.maxBreadcrumbs = scope.maxBreadcrumbs; + self.userObject = scope.userObject.copy; + self.distString = scope.distString; + self.environmentString = scope.environmentString; + self.levelEnum = scope.levelEnum; + } + return self; +} + +#pragma mark Global properties + +- (void)addBreadcrumb:(SentryBreadcrumb *)crumb +{ + [SentryLog logWithMessage:[NSString stringWithFormat:@"Add breadcrumb: %@", crumb] + andLevel:kSentryLevelDebug]; + @synchronized(_breadcrumbArray) { + [_breadcrumbArray addObject:crumb]; + if ([_breadcrumbArray count] > self.maxBreadcrumbs) { + [_breadcrumbArray removeObjectAtIndex:0]; + } + } + [self notifyListeners]; +} + +- (void)setSpan:(nullable id)span +{ + @synchronized(_spanLock) { + _span = span; + } +} + +- (void)useSpan:(SentrySpanCallback)callback +{ + @synchronized(_spanLock) { + callback(_span); + } +} + +- (void)clear +{ + // As we need to synchronize the accesses of the arrays and dictionaries and we use the + // references instead of self we remove all objects instead of creating new instances. Removing + // all objects is usually O(n). This is acceptable as we don't expect a huge amount of elements + // in the arrays or dictionaries, that would slow down the performance. + @synchronized(_breadcrumbArray) { + [_breadcrumbArray removeAllObjects]; + } + @synchronized(_tagDictionary) { + [_tagDictionary removeAllObjects]; + } + @synchronized(_extraDictionary) { + [_extraDictionary removeAllObjects]; + } + @synchronized(_contextDictionary) { + [_contextDictionary removeAllObjects]; + } + @synchronized(_fingerprintArray) { + [_fingerprintArray removeAllObjects]; + } + @synchronized(_attachmentArray) { + [_attachmentArray removeAllObjects]; + } + @synchronized(_spanLock) { + _span = nil; + } + + self.userObject = nil; + self.distString = nil; + self.environmentString = nil; + self.levelEnum = kSentryLevelNone; + + [self notifyListeners]; +} + +- (void)clearBreadcrumbs +{ + @synchronized(_breadcrumbArray) { + [_breadcrumbArray removeAllObjects]; + } + [self notifyListeners]; +} + +- (NSArray *)breadcrumbs +{ + @synchronized(_breadcrumbArray) { + return _breadcrumbArray.copy; + } +} + +- (void)setContextValue:(NSDictionary *)value forKey:(NSString *)key +{ + @synchronized(_contextDictionary) { + [_contextDictionary setValue:value forKey:key]; + } + [self notifyListeners]; +} + +- (void)removeContextForKey:(NSString *)key +{ + @synchronized(_contextDictionary) { + [_contextDictionary removeObjectForKey:key]; + } + [self notifyListeners]; +} + +- (NSDictionary *> *)context +{ + @synchronized(_contextDictionary) { + return _contextDictionary.copy; + } +} + +- (void)setExtraValue:(id _Nullable)value forKey:(NSString *)key +{ + @synchronized(_extraDictionary) { + [_extraDictionary setValue:value forKey:key]; + } + [self notifyListeners]; +} + +- (void)removeExtraForKey:(NSString *)key +{ + @synchronized(_extraDictionary) { + [_extraDictionary removeObjectForKey:key]; + } + [self notifyListeners]; +} + +- (void)setExtras:(NSDictionary *_Nullable)extras +{ + if (extras == nil) { + return; + } + @synchronized(_extraDictionary) { + [_extraDictionary addEntriesFromDictionary:extras]; + } + [self notifyListeners]; +} + +- (NSDictionary *)extras +{ + @synchronized(_extraDictionary) { + return _extraDictionary.copy; + } +} + +- (void)setTagValue:(NSString *)value forKey:(NSString *)key +{ + @synchronized(_tagDictionary) { + _tagDictionary[key] = value; + } + [self notifyListeners]; +} + +- (void)removeTagForKey:(NSString *)key +{ + @synchronized(_tagDictionary) { + [_tagDictionary removeObjectForKey:key]; + } + [self notifyListeners]; +} + +- (void)setTags:(NSDictionary *_Nullable)tags +{ + if (tags == nil) { + return; + } + @synchronized(_tagDictionary) { + [_tagDictionary addEntriesFromDictionary:tags]; + } + [self notifyListeners]; +} + +- (NSDictionary *)tags +{ + @synchronized(_tagDictionary) { + return _tagDictionary.copy; + } +} + +- (void)setUser:(SentryUser *_Nullable)user +{ + self.userObject = user; + [self notifyListeners]; +} + +- (void)setDist:(NSString *_Nullable)dist +{ + self.distString = dist; + [self notifyListeners]; +} + +- (void)setEnvironment:(NSString *_Nullable)environment +{ + self.environmentString = environment; + [self notifyListeners]; +} + +- (void)setFingerprint:(NSArray *_Nullable)fingerprint +{ + @synchronized(_fingerprintArray) { + [_fingerprintArray removeAllObjects]; + if (fingerprint != nil) { + [_fingerprintArray addObjectsFromArray:fingerprint]; + } + } + + [self notifyListeners]; +} + +- (NSArray *)fingerprints +{ + @synchronized(_fingerprintArray) { + return _fingerprintArray.copy; + } +} + +- (void)setLevel:(enum SentryLevel)level +{ + self.levelEnum = level; + [self notifyListeners]; +} + +- (void)addAttachment:(SentryAttachment *)attachment +{ + @synchronized(_attachmentArray) { + [_attachmentArray addObject:attachment]; + } +} + +- (NSArray *)attachments +{ + @synchronized(_attachmentArray) { + return _attachmentArray.copy; + } +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = [NSMutableDictionary new]; + [serializedData setValue:[self tags] forKey:@"tags"]; + [serializedData setValue:[self extras] forKey:@"extra"]; + [serializedData setValue:[self context] forKey:@"context"]; + [serializedData setValue:[self.userObject serialize] forKey:@"user"]; + [serializedData setValue:self.distString forKey:@"dist"]; + [serializedData setValue:self.environmentString forKey:@"environment"]; + [serializedData setValue:[self fingerprints] forKey:@"fingerprint"]; + + SentryLevel level = self.levelEnum; + if (level != kSentryLevelNone) { + [serializedData setValue:SentryLevelNames[level] forKey:@"level"]; + } + NSArray *crumbs = [self serializeBreadcrumbs]; + if (crumbs.count > 0) { + [serializedData setValue:crumbs forKey:@"breadcrumbs"]; + } + return serializedData; +} + +- (NSArray *)serializeBreadcrumbs +{ + NSMutableArray *serializedCrumbs = [NSMutableArray new]; + + NSArray *crumbs = [self breadcrumbs]; + for (SentryBreadcrumb *crumb in crumbs) { + [serializedCrumbs addObject:[crumb serialize]]; + } + + return serializedCrumbs; +} + +- (void)applyToSession:(SentrySession *)session +{ + SentryUser *userObject = self.userObject; + if (nil != userObject) { + session.user = userObject.copy; + } + + NSString *environment = self.environmentString; + if (nil != environment) { + // TODO: Make sure environment set on options is applied to the + // scope so it's available now + session.environment = environment; + } +} + +- (SentryEvent *__nullable)applyToEvent:(SentryEvent *)event + maxBreadcrumb:(NSUInteger)maxBreadcrumbs +{ + if (nil == event.tags) { + event.tags = [self tags]; + } else { + NSMutableDictionary *newTags = [NSMutableDictionary new]; + [newTags addEntriesFromDictionary:[self tags]]; + [newTags addEntriesFromDictionary:event.tags]; + event.tags = newTags; + } + + if (nil == event.extra) { + event.extra = [self extras]; + } else { + NSMutableDictionary *newExtra = [NSMutableDictionary new]; + [newExtra addEntriesFromDictionary:[self extras]]; + [newExtra addEntriesFromDictionary:event.extra]; + event.extra = newExtra; + } + + NSArray *fingerprints = [self fingerprints]; + if (fingerprints.count > 0 && nil == event.fingerprint) { + event.fingerprint = fingerprints; + } + + if (nil == event.breadcrumbs) { + NSArray *breadcrumbs = [self breadcrumbs]; + event.breadcrumbs = [breadcrumbs + subarrayWithRange:NSMakeRange(0, MIN(maxBreadcrumbs, [breadcrumbs count]))]; + } + + if (nil == event.context) { + event.context = [self context]; + } else { + NSMutableDictionary *newContext = [NSMutableDictionary new]; + [newContext addEntriesFromDictionary:[self context]]; + [newContext addEntriesFromDictionary:event.context]; + event.context = newContext; + } + + SentryUser *user = self.userObject.copy; + if (nil != user) { + event.user = user; + } + + NSString *dist = self.distString; + if (nil != dist && nil == event.dist) { + // dist can also be set via options but scope takes precedence. + event.dist = dist; + } + + NSString *environment = self.environmentString; + if (nil != environment && nil == event.environment) { + // environment can also be set via options but scope takes + // precedence. + event.environment = environment; + } + + SentryLevel level = self.levelEnum; + if (level != kSentryLevelNone) { + // We always want to set the level from the scope since this has + // been set on purpose + event.level = level; + } + + id span; + @synchronized(_spanLock) { + span = self.span; + } + + if (![event.type isEqualToString:SentryEnvelopeItemTypeTransaction] && + [span isKindOfClass:[SentryTracer class]]) { + event.transaction = [(SentryTracer *)span name]; + } + + return event; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySdkInfo.m b/Pods/Sentry/Sources/Sentry/SentrySdkInfo.m new file mode 100644 index 00000000..05ef13f0 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySdkInfo.m @@ -0,0 +1,54 @@ +#import "SentrySdkInfo.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentrySdkInfo + +- (instancetype)initWithName:(NSString *)name andVersion:(NSString *)version +{ + if (self = [super init]) { + + if (name.length == 0) { + _name = @""; + } else { + _name = name; + } + + if (version.length == 0) { + _version = @""; + } else { + _version = version; + } + } + + return self; +} + +- (instancetype)initWithDict:(NSDictionary *)dict +{ + NSString *name = @""; + NSString *version = @""; + + if (nil != dict[@"sdk"] && [dict[@"sdk"] isKindOfClass:[NSDictionary class]]) { + NSDictionary *sdkInfoDict = dict[@"sdk"]; + if ([sdkInfoDict[@"name"] isKindOfClass:[NSString class]]) { + name = sdkInfoDict[@"name"]; + } + + if ([sdkInfoDict[@"version"] isKindOfClass:[NSString class]]) { + version = sdkInfoDict[@"version"]; + } + } + + return [self initWithName:name andVersion:version]; +} + +- (NSDictionary *)serialize +{ + return @{ @"sdk" : @ { @"name" : self.name, @"version" : self.version } }; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySerialization.m b/Pods/Sentry/Sources/Sentry/SentrySerialization.m new file mode 100644 index 00000000..3dc56941 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySerialization.m @@ -0,0 +1,320 @@ +#import "SentrySerialization.h" +#import "SentryAppState.h" +#import "SentryDefines.h" +#import "SentryEnvelope.h" +#import "SentryEnvelopeItemType.h" +#import "SentryError.h" +#import "SentryId.h" +#import "SentryLevelMapper.h" +#import "SentryLog.h" +#import "SentrySdkInfo.h" +#import "SentrySession.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentrySerialization + ++ (NSData *_Nullable)dataWithJSONObject:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error +{ + + NSData *data = nil; + if ([NSJSONSerialization isValidJSONObject:dictionary] != NO) { + data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:error]; + } else { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Invalid JSON."] + andLevel:kSentryLevelError]; + if (error) { + *error = NSErrorFromSentryError( + kSentryErrorJsonConversionError, @"Event cannot be converted to JSON"); + } + } + + return data; +} + ++ (NSData *_Nullable)dataWithEnvelope:(SentryEnvelope *)envelope + error:(NSError *_Nullable *_Nullable)error +{ + + NSMutableData *envelopeData = [[NSMutableData alloc] init]; + NSMutableDictionary *serializedData = [NSMutableDictionary new]; + if (nil != envelope.header.eventId) { + [serializedData setValue:[envelope.header.eventId sentryIdString] forKey:@"event_id"]; + } + + SentrySdkInfo *sdkInfo = envelope.header.sdkInfo; + if (nil != sdkInfo) { + [serializedData addEntriesFromDictionary:[sdkInfo serialize]]; + } + + NSData *header = [SentrySerialization dataWithJSONObject:serializedData error:error]; + if (nil == header) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Envelope header cannot " + @"be converted to JSON."] + andLevel:kSentryLevelError]; + if (error) { + *error = NSErrorFromSentryError( + kSentryErrorJsonConversionError, @"Envelope header cannot be converted to JSON"); + } + return nil; + } + [envelopeData appendData:header]; + + for (int i = 0; i < envelope.items.count; ++i) { + [envelopeData appendData:[@"\n" dataUsingEncoding:NSUTF8StringEncoding]]; + NSMutableDictionary *serializedItemHeaderData = [NSMutableDictionary new]; + if (nil != envelope.items[i].header) { + if (nil != envelope.items[i].header.type) { + [serializedItemHeaderData setValue:envelope.items[i].header.type forKey:@"type"]; + } + + NSString *filename = envelope.items[i].header.filename; + if (nil != filename) { + [serializedItemHeaderData setValue:filename forKey:@"filename"]; + } + + NSString *contentType = envelope.items[i].header.contentType; + if (nil != contentType) { + [serializedItemHeaderData setValue:contentType forKey:@"content_type"]; + } + + [serializedItemHeaderData + setValue:[NSNumber numberWithUnsignedInteger:envelope.items[i].header.length] + forKey:@"length"]; + } + NSData *itemHeader = [SentrySerialization dataWithJSONObject:serializedItemHeaderData + error:error]; + if (nil == itemHeader) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Envelope item header cannot " + @"be converted to JSON."] + andLevel:kSentryLevelError]; + if (error) { + *error = NSErrorFromSentryError(kSentryErrorJsonConversionError, + @"Envelope item header cannot be converted to JSON"); + } + return nil; + } + [envelopeData appendData:itemHeader]; + [envelopeData appendData:[@"\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [envelopeData appendData:envelope.items[i].data]; + } + + return envelopeData; +} + ++ (SentryEnvelope *_Nullable)envelopeWithData:(NSData *)data +{ + SentryEnvelopeHeader *envelopeHeader = nil; + const unsigned char *bytes = [data bytes]; + int envelopeHeaderIndex = 0; + for (int i = 0; i < data.length; ++i) { + if (bytes[i] == '\n') { + envelopeHeaderIndex = i; + // Envelope header end + NSData *headerData = [NSData dataWithBytes:bytes length:i]; +#ifdef DEBUG + NSString *headerString = [[NSString alloc] initWithData:headerData + encoding:NSUTF8StringEncoding]; + [SentryLog logWithMessage:[NSString stringWithFormat:@"Header %@", headerString] + andLevel:kSentryLevelDebug]; +#endif + NSError *error = nil; + NSDictionary *headerDictionary = [NSJSONSerialization JSONObjectWithData:headerData + options:0 + error:&error]; + if (nil != error) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Failed to parse " + @"envelope header %@", + error] + andLevel:kSentryLevelError]; + } else { + SentryId *eventId = nil; + NSString *eventIdAsString = headerDictionary[@"event_id"]; + if (nil != eventIdAsString) { + eventId = [[SentryId alloc] initWithUUIDString:eventIdAsString]; + } + + SentrySdkInfo *sdkInfo = nil; + if (nil != headerDictionary[@"sdk"]) { + sdkInfo = [[SentrySdkInfo alloc] initWithDict:headerDictionary]; + } + envelopeHeader = [[SentryEnvelopeHeader alloc] initWithId:eventId + andSdkInfo:sdkInfo]; + } + break; + } + } + if (nil == envelopeHeader) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Invalid envelope. No header found."] + andLevel:kSentryLevelError]; + return nil; + } + NSAssert(envelopeHeaderIndex > 0, @"EnvelopeHeader was parsed, its index is expected."); + // Parse items + NSInteger itemHeaderStart = envelopeHeaderIndex + 1; + + NSMutableArray *items = [NSMutableArray new]; + NSUInteger endOfEnvelope = data.length - 1; + for (NSInteger i = itemHeaderStart; i <= endOfEnvelope; ++i) { + if (bytes[i] == '\n' || i == endOfEnvelope) { + if (endOfEnvelope == i) { + i++; // 0 byte attachment + } + + NSData *itemHeaderData = + [data subdataWithRange:NSMakeRange(itemHeaderStart, i - itemHeaderStart)]; +#ifdef DEBUG + NSString *itemHeaderString = [[NSString alloc] initWithData:itemHeaderData + encoding:NSUTF8StringEncoding]; + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Item Header %@", itemHeaderString] + andLevel:kSentryLevelDebug]; +#endif + NSError *error = nil; + NSDictionary *headerDictionary = [NSJSONSerialization JSONObjectWithData:itemHeaderData + options:0 + error:&error]; + if (nil != error) { + [SentryLog + logWithMessage:[NSString + stringWithFormat:@"Failed to parse envelope item header %@", + error] + andLevel:kSentryLevelError]; + return nil; + } + NSString *_Nullable type = [headerDictionary valueForKey:@"type"]; + if (nil == type) { + [SentryLog + logWithMessage:[NSString stringWithFormat:@"Envelope item type is required."] + andLevel:kSentryLevelError]; + break; + } + NSNumber *bodyLengthNumber = [headerDictionary valueForKey:@"length"]; + NSUInteger bodyLength = [bodyLengthNumber unsignedIntegerValue]; + if (endOfEnvelope == i && bodyLength != 0) { + [SentryLog + logWithMessage:[NSString + stringWithFormat:@"Envelope item has no data but header " + @"indicates it's length is %d.", + (int)bodyLength] + andLevel:kSentryLevelError]; + break; + } + + NSString *_Nullable filename = [headerDictionary valueForKey:@"filename"]; + NSString *_Nullable contentType = [headerDictionary valueForKey:@"content_type"]; + + SentryEnvelopeItemHeader *itemHeader; + if (nil != filename && nil != contentType) { + itemHeader = [[SentryEnvelopeItemHeader alloc] initWithType:type + length:bodyLength + filenname:filename + contentType:contentType]; + } else { + itemHeader = [[SentryEnvelopeItemHeader alloc] initWithType:type length:bodyLength]; + } + + NSData *itemBody = [data subdataWithRange:NSMakeRange(i + 1, bodyLength)]; +#ifdef DEBUG + if ([SentryEnvelopeItemTypeEvent isEqual:type] || + [SentryEnvelopeItemTypeSession isEqual:type]) { + NSString *event = [[NSString alloc] initWithData:itemBody + encoding:NSUTF8StringEncoding]; + [SentryLog logWithMessage:[NSString stringWithFormat:@"Event %@", event] + andLevel:kSentryLevelDebug]; + } +#endif + SentryEnvelopeItem *envelopeItem = [[SentryEnvelopeItem alloc] initWithHeader:itemHeader + data:itemBody]; + [items addObject:envelopeItem]; + i = itemHeaderStart = i + 1 + [bodyLengthNumber integerValue]; + } + } + + if (items.count == 0) { + [SentryLog logWithMessage:[NSString stringWithFormat:@"Envelope has no items."] + andLevel:kSentryLevelError]; + return nil; + } + + SentryEnvelope *envelope = [[SentryEnvelope alloc] initWithHeader:envelopeHeader items:items]; + return envelope; +} + ++ (NSData *_Nullable)dataWithSession:(SentrySession *)session + error:(NSError *_Nullable *_Nullable)error +{ + return [self dataWithJSONObject:[session serialize] error:error]; +} + ++ (SentrySession *_Nullable)sessionWithData:(NSData *)sessionData +{ + NSError *error = nil; + NSDictionary *sessionDictionary = [NSJSONSerialization JSONObjectWithData:sessionData + options:0 + error:&error]; + if (nil != error) { + [SentryLog + logWithMessage:[NSString + stringWithFormat:@"Failed to deserialize session data %@", error] + andLevel:kSentryLevelError]; + return nil; + } + SentrySession *session = [[SentrySession alloc] initWithJSONObject:sessionDictionary]; + + if (nil == session) { + [SentryLog logWithMessage:@"Failed to initialize session from dictionary. Dropping it." + andLevel:kSentryLevelError]; + return nil; + } + + if (nil == session.releaseName || [session.releaseName isEqualToString:@""]) { + [SentryLog + logWithMessage:@"Deserialized session doesn't contain a release name. Dropping it." + andLevel:kSentryLevelError]; + return nil; + } + + return session; +} + ++ (SentryAppState *_Nullable)appStateWithData:(NSData *)data +{ + NSError *error = nil; + NSDictionary *appSateDictionary = [NSJSONSerialization JSONObjectWithData:data + options:0 + error:&error]; + if (nil != error) { + [SentryLog + logWithMessage:[NSString + stringWithFormat:@"Failed to deserialize app state data %@", error] + andLevel:kSentryLevelError]; + return nil; + } + + return [[SentryAppState alloc] initWithJSONObject:appSateDictionary]; +} + ++ (SentryLevel)levelFromData:(NSData *)eventEnvelopeItemData +{ + NSError *error = nil; + NSDictionary *eventDictionary = [NSJSONSerialization JSONObjectWithData:eventEnvelopeItemData + options:0 + error:&error]; + if (nil != error) { + [SentryLog + logWithMessage: + [NSString + stringWithFormat:@"Failed to retrieve event level from envelope item data: %@", + error] + andLevel:kSentryLevelError]; + return kSentryLevelError; + } + + return [SentryLevelMapper levelWithString:eventDictionary[@"level"]]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySession.m b/Pods/Sentry/Sources/Sentry/SentrySession.m new file mode 100644 index 00000000..5f26d11d --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySession.m @@ -0,0 +1,269 @@ +#import "SentrySession.h" +#import "NSDate+SentryExtras.h" +#import "SentryCurrentDate.h" +#import "SentryInstallation.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentrySession + +@synthesize flagInit = _init; + +/** + * Default private constructor. We don't name it init to avoid the overlap with the default init of + * NSObject, which is not available as we specified in the header with SENTRY_NO_INIT. + */ +- (instancetype)initDefault +{ + if (self = [super init]) { + _sessionId = [NSUUID UUID]; + _started = [SentryCurrentDate date]; + _status = kSentrySessionStatusOk; + _sequence = 1; + _errors = 0; + _distinctId = [SentryInstallation id]; + } + + return self; +} + +- (instancetype)initWithReleaseName:(NSString *)releaseName +{ + if (self = [self initDefault]) { + _init = @YES; + _releaseName = releaseName; + } + return self; +} + +- (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject +{ + if (self = [super init]) { + + id sid = [jsonObject valueForKey:@"sid"]; + if (sid == nil || ![sid isKindOfClass:[NSString class]]) + return nil; + NSUUID *sessionId = [[NSUUID UUID] initWithUUIDString:sid]; + if (nil == sessionId) + return nil; + _sessionId = sessionId; + + id started = [jsonObject valueForKey:@"started"]; + if (started == nil || ![started isKindOfClass:[NSString class]]) + return nil; + NSDate *startedDate = [NSDate sentry_fromIso8601String:started]; + if (nil == startedDate) { + return nil; + } + _started = startedDate; + + id status = [jsonObject valueForKey:@"status"]; + if (status == nil || ![status isKindOfClass:[NSString class]]) + return nil; + if ([@"ok" isEqualToString:status]) { + _status = kSentrySessionStatusOk; + } else if ([@"exited" isEqualToString:status]) { + _status = kSentrySessionStatusExited; + } else if ([@"crashed" isEqualToString:status]) { + _status = kSentrySessionStatusCrashed; + } else if ([@"abnormal" isEqualToString:status]) { + _status = kSentrySessionStatusAbnormal; + } else { + return nil; + } + + id seq = [jsonObject valueForKey:@"seq"]; + if (seq == nil || ![seq isKindOfClass:[NSNumber class]]) + return nil; + _sequence = [seq unsignedIntegerValue]; + + id errors = [jsonObject valueForKey:@"errors"]; + if (errors == nil || ![errors isKindOfClass:[NSNumber class]]) + return nil; + _errors = [errors unsignedIntegerValue]; + + id did = [jsonObject valueForKey:@"did"]; + if (did == nil || ![did isKindOfClass:[NSString class]]) + return nil; + _distinctId = did; + + id init = [jsonObject valueForKey:@"init"]; + if ([init isKindOfClass:[NSNumber class]]) { + _init = init; + } + + id attrs = [jsonObject valueForKey:@"attrs"]; + if (nil != attrs) { + id releaseName = [attrs valueForKey:@"release"]; + if ([releaseName isKindOfClass:[NSString class]]) { + _releaseName = releaseName; + } + + id environment = [attrs valueForKey:@"environment"]; + if ([environment isKindOfClass:[NSString class]]) { + _environment = environment; + } + } + + id timestamp = [jsonObject valueForKey:@"timestamp"]; + if ([timestamp isKindOfClass:[NSString class]]) { + _timestamp = [NSDate sentry_fromIso8601String:timestamp]; + } + + id duration = [jsonObject valueForKey:@"duration"]; + if ([duration isKindOfClass:[NSNumber class]]) { + _duration = duration; + } + } + + return self; +} + +- (void)setFlagInit +{ + _init = @YES; +} + +- (void)endSessionExitedWithTimestamp:(NSDate *)timestamp +{ + @synchronized(self) { + [self changed]; + _status = kSentrySessionStatusExited; + [self endSessionWithTimestamp:timestamp]; + } +} + +- (void)endSessionCrashedWithTimestamp:(NSDate *)timestamp +{ + @synchronized(self) { + [self changed]; + _status = kSentrySessionStatusCrashed; + [self endSessionWithTimestamp:timestamp]; + } +} + +- (void)endSessionAbnormalWithTimestamp:(NSDate *)timestamp +{ + @synchronized(self) { + [self changed]; + _status = kSentrySessionStatusAbnormal; + [self endSessionWithTimestamp:timestamp]; + } +} + +- (void)endSessionWithTimestamp:(NSDate *)timestamp +{ + @synchronized(self) { + _timestamp = timestamp; + NSTimeInterval secondsBetween = [_timestamp timeIntervalSinceDate:_started]; + _duration = [NSNumber numberWithDouble:secondsBetween]; + } +} + +- (void)changed +{ + _init = nil; + _sequence++; +} + +- (void)incrementErrors +{ + @synchronized(self) { + [self changed]; + _errors++; + } +} + +- (NSDictionary *)serialize +{ + @synchronized(self) { + NSMutableDictionary *serializedData = @{ + @"sid" : _sessionId.UUIDString, + @"errors" : @(_errors), + @"started" : [_started sentry_toIso8601String], + } + .mutableCopy; + + if (nil != _init) { + [serializedData setValue:_init forKey:@"init"]; + } + + NSString *statusString = nil; + switch (_status) { + case kSentrySessionStatusOk: + statusString = @"ok"; + break; + case kSentrySessionStatusExited: + statusString = @"exited"; + break; + case kSentrySessionStatusCrashed: + statusString = @"crashed"; + break; + case kSentrySessionStatusAbnormal: + statusString = @"abnormal"; + break; + default: + // TODO: Log warning + break; + } + + if (nil != statusString) { + [serializedData setValue:statusString forKey:@"status"]; + } + + NSDate *timestamp = nil != _timestamp ? _timestamp : [SentryCurrentDate date]; + [serializedData setValue:[timestamp sentry_toIso8601String] forKey:@"timestamp"]; + + if (nil != _duration) { + [serializedData setValue:_duration forKey:@"duration"]; + } else if (nil == _init) { + NSTimeInterval secondsBetween = [_timestamp timeIntervalSinceDate:_started]; + [serializedData setValue:[NSNumber numberWithDouble:secondsBetween] forKey:@"duration"]; + } + + // TODO: seq to be just unix time in mills? + [serializedData setValue:@(_sequence) forKey:@"seq"]; + + if (nil != _releaseName || nil != _environment) { + NSMutableDictionary *attrs = [[NSMutableDictionary alloc] init]; + if (nil != _releaseName) { + [attrs setValue:_releaseName forKey:@"release"]; + } + + if (nil != _environment) { + [attrs setValue:_environment forKey:@"environment"]; + } + [serializedData setValue:attrs forKey:@"attrs"]; + } + + [serializedData setValue:_distinctId forKey:@"did"]; + + return serializedData; + } +} + +- (id)copyWithZone:(nullable NSZone *)zone +{ + SentrySession *copy = [[[self class] allocWithZone:zone] init]; + + if (copy != nil) { + copy->_sessionId = _sessionId; + copy->_started = _started; + copy->_status = _status; + copy->_errors = _errors; + copy->_sequence = _sequence; + copy->_distinctId = _distinctId; + copy->_timestamp = _timestamp; + copy->_duration = _duration; + copy->_releaseName = _releaseName; + copy.environment = self.environment; + copy.user = self.user; + copy->_init = _init; + } + + return copy; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySessionCrashedHandler.m b/Pods/Sentry/Sources/Sentry/SentrySessionCrashedHandler.m new file mode 100644 index 00000000..bb01cc29 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySessionCrashedHandler.m @@ -0,0 +1,53 @@ +#import "SentrySessionCrashedHandler.h" +#import "SentryClient+Private.h" +#import "SentryCrashAdapter.h" +#import "SentryCurrentDate.h" +#import "SentryFileManager.h" +#import "SentryHub.h" +#import "SentryOutOfMemoryLogic.h" +#import "SentrySDK+Private.h" + +@interface +SentrySessionCrashedHandler () + +@property (nonatomic, strong) SentryCrashAdapter *crashWrapper; +@property (nonatomic, strong) SentryOutOfMemoryLogic *outOfMemoryLogic; + +@end + +@implementation SentrySessionCrashedHandler + +- (instancetype)initWithCrashWrapper:(SentryCrashAdapter *)crashWrapper + outOfMemoryLogic:(SentryOutOfMemoryLogic *)outOfMemoryLogic; +{ + self = [self init]; + self.crashWrapper = crashWrapper; + self.outOfMemoryLogic = outOfMemoryLogic; + + return self; +} + +- (void)endCurrentSessionAsCrashedWhenCrashOrOOM +{ + if (self.crashWrapper.crashedLastLaunch || [self.outOfMemoryLogic isOOM]) { + SentryFileManager *fileManager = [[[SentrySDK currentHub] getClient] fileManager]; + + if (nil == fileManager) { + return; + } + + SentrySession *session = [fileManager readCurrentSession]; + if (nil == session) { + return; + } + + NSDate *timeSinceLastCrash = [[SentryCurrentDate date] + dateByAddingTimeInterval:-self.crashWrapper.activeDurationSinceLastCrash]; + + [session endSessionCrashedWithTimestamp:timeSinceLastCrash]; + [fileManager storeCrashedSession:session]; + [fileManager deleteCurrentSession]; + } +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentrySessionTracker.m b/Pods/Sentry/Sources/Sentry/SentrySessionTracker.m new file mode 100644 index 00000000..b3fad0d2 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySessionTracker.m @@ -0,0 +1,192 @@ +#import "SentrySessionTracker.h" +#import "SentryClient+Private.h" +#import "SentryClient.h" +#import "SentryFileManager.h" +#import "SentryHub+Private.h" +#import "SentryInternalNotificationNames.h" +#import "SentryLog.h" +#import "SentrySDK+Private.h" + +#if SENTRY_HAS_UIKIT +# import +#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST +# import +#endif + +@interface +SentrySessionTracker () + +@property (nonatomic, strong) SentryOptions *options; +@property (nonatomic, strong) id currentDateProvider; +@property (atomic, strong) NSDate *lastInForeground; +@property (nonatomic, assign) BOOL wasDidBecomeActiveCalled; + +@end + +@implementation SentrySessionTracker + +- (instancetype)initWithOptions:(SentryOptions *)options + currentDateProvider:(id)currentDateProvider +{ + if (self = [super init]) { + self.options = options; + self.currentDateProvider = currentDateProvider; + self.wasDidBecomeActiveCalled = NO; + } + return self; +} + +/** + * Can also be called when the system launches an app for a background task. We don't want to track + * sessions if an app is only in the background. Therefore we must not start a session in here. Such + * apps must do session tracking manually, see + * https://docs.sentry.io/workflow/releases/health/#session + */ +- (void)start +{ + // We don't want to use WillEnterForeground because tvOS doesn't call it when it launches an app + // the first time. It only calls it when the app was open and the user navigates back to it. + // DidEnterBackground is called when the app launches a background task so we would need to + // check if DidBecomeActive was called before to not track sessions in the background. + // DidBecomeActive and WillResignActive are not called when the app launches a background task. + // WillTerminate is called no matter if started from the background or launched into the + // foreground. + +#if SENTRY_HAS_UIKIT + NSNotificationName didBecomeActiveNotificationName = UIApplicationDidBecomeActiveNotification; + NSNotificationName willResignActiveNotificationName = UIApplicationWillResignActiveNotification; + NSNotificationName willTerminateNotificationName = UIApplicationWillTerminateNotification; +#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST + NSNotificationName didBecomeActiveNotificationName = NSApplicationDidBecomeActiveNotification; + NSNotificationName willResignActiveNotificationName = NSApplicationWillResignActiveNotification; + NSNotificationName willTerminateNotificationName = NSApplicationWillTerminateNotification; +#else + [SentryLog logWithMessage:@"NO UIKit -> SentrySessionTracker will not " + @"track sessions automatically." + andLevel:kSentryLevelDebug]; +#endif + +#if SENTRY_HAS_UIKIT || TARGET_OS_OSX || TARGET_OS_MACCATALYST + + // Call before subscribing to the notifications to avoid that didBecomeActive gets called before + // ending the cached session. + [self endCachedSession]; + + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(didBecomeActive) + name:didBecomeActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(didBecomeActive) + name:SentryHybridSdkDidBecomeActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(willResignActive) + name:willResignActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(willTerminate) + name:willTerminateNotificationName + object:nil]; +#endif +} + +- (void)stop +{ +#if SENTRY_HAS_UIKIT || TARGET_OS_OSX || TARGET_OS_MACCATALYST + [NSNotificationCenter.defaultCenter removeObserver:self]; +#endif +} + +/** + * End previously cached sessions. We never can be sure that WillResignActive or WillTerminate are + * called due to a crash or unexpected behavior. Still, we don't want to lose such sessions and end + * them. + */ +- (void)endCachedSession +{ + SentryHub *hub = [SentrySDK currentHub]; + NSDate *_Nullable lastInForeground = + [[[hub getClient] fileManager] readTimestampLastInForeground]; + if (nil != lastInForeground) { + [[[hub getClient] fileManager] deleteTimestampLastInForeground]; + } + + [hub closeCachedSessionWithTimestamp:lastInForeground]; +} + +/** + * It is called when an App. is receiving events / It is in the foreground and when we receive a + * SentryHybridSdkDidBecomeActiveNotification. There is no guarantee that this method is called once + * or twice. We need to ensure that we execute it only once. + * + * We can't start the session in this method because we don't know if a background task or a hybrid + * SDK initialized the SDK. Hybrid SDKs must only post this notification if they are running in the + * foreground because the auto session tracking logic doesn't support background tasks. Posting the + * notification from the background would mess up the session stats. + */ +- (void)didBecomeActive +{ + // We don't know if the hybrid SDKs post the notification from a background thread, so we + // synchronize to be safe. + @synchronized(self) { + if (self.wasDidBecomeActiveCalled) { + return; + } + self.wasDidBecomeActiveCalled = YES; + } + + SentryHub *hub = [SentrySDK currentHub]; + self.lastInForeground = [[[hub getClient] fileManager] readTimestampLastInForeground]; + + if (nil == self.lastInForeground) { + // Cause we don't want to track sessions if the app is in the background we need to wait + // until the app is in the foreground to start a session. + [hub startSession]; + } else { + // When the app was already in the foreground we have to decide whether it was long enough + // in the background to start a new session or to keep the session open. We don't want a new + // session if the user switches to another app for just a few seconds. + NSTimeInterval secondsInBackground = + [[self.currentDateProvider date] timeIntervalSinceDate:self.lastInForeground]; + + if (secondsInBackground * 1000 >= (double)(self.options.sessionTrackingIntervalMillis)) { + [hub endSessionWithTimestamp:self.lastInForeground]; + [hub startSession]; + } + } + [[[hub getClient] fileManager] deleteTimestampLastInForeground]; + self.lastInForeground = nil; +} + +/** + * The app is about to lose focus / going to the background. This is only called when an app was + * receiving events / was is in the foreground. We can't end a session here because we don't how + * long the app is going to be in the background. If it is just for a few seconds we want to keep + * the session open. + */ +- (void)willResignActive +{ + self.lastInForeground = [self.currentDateProvider date]; + SentryHub *hub = [SentrySDK currentHub]; + [[[hub getClient] fileManager] storeTimestampLastInForeground:self.lastInForeground]; + self.wasDidBecomeActiveCalled = NO; +} + +/** + * We always end the session when the app is terminated. + */ +- (void)willTerminate +{ + NSDate *sessionEnded + = nil == self.lastInForeground ? [self.currentDateProvider date] : self.lastInForeground; + SentryHub *hub = [SentrySDK currentHub]; + [hub endSessionWithTimestamp:sessionEnded]; + [[[hub getClient] fileManager] deleteTimestampLastInForeground]; + self.wasDidBecomeActiveCalled = NO; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentrySpan.m b/Pods/Sentry/Sources/Sentry/SentrySpan.m new file mode 100644 index 00000000..a8019030 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySpan.m @@ -0,0 +1,99 @@ +#import "SentrySpan.h" +#import "NSDate+SentryExtras.h" +#import "SentryCurrentDate.h" +#import "SentryTracer.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentrySpan () + +@property (nonatomic) SentryTracer *tracer; + +@end + +@implementation SentrySpan { + NSMutableDictionary *_extras; +} + +- (instancetype)initWithTracer:(SentryTracer *)tracer context:(SentrySpanContext *)context +{ + if ([self initWithContext:context]) { + self.tracer = tracer; + } + return self; +} + +- (instancetype)initWithContext:(SentrySpanContext *)context +{ + if ([super init]) { + _context = context; + self.startTimestamp = [SentryCurrentDate date]; + _extras = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (id)startChildWithOperation:(NSString *)operation +{ + return [self startChildWithOperation:operation description:nil]; +} + +- (id)startChildWithOperation:(NSString *)operation + description:(nullable NSString *)description +{ + return [self.tracer startChildWithParentId:[self.context spanId] + operation:operation + description:description]; +} + +- (void)setDataValue:(nullable NSString *)value forKey:(NSString *)key +{ + @synchronized(_extras) { + [_extras setValue:value forKey:key]; + } +} + +- (nullable NSDictionary *)data +{ + return _extras; +} + +- (BOOL)isFinished +{ + return self.timestamp != nil; +} + +- (void)finish +{ + self.timestamp = [SentryCurrentDate date]; +} + +- (void)finishWithStatus:(SentrySpanStatus)status +{ + self.context.status = status; + [self finish]; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *mutableDictionary = + [[NSMutableDictionary alloc] initWithDictionary:[self.context serialize]]; + + [mutableDictionary setValue:[self.timestamp sentry_toIso8601String] forKey:@"timestamp"]; + [mutableDictionary setValue:[self.startTimestamp sentry_toIso8601String] + forKey:@"start_timestamp"]; + + if (_extras != nil) { + @synchronized(_extras) { + [mutableDictionary setValue:_extras.copy forKey:@"data"]; + } + } + + return mutableDictionary; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySpanContext.m b/Pods/Sentry/Sources/Sentry/SentrySpanContext.m new file mode 100644 index 00000000..66cb0704 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySpanContext.m @@ -0,0 +1,104 @@ +#import "SentrySpanContext.h" +#import "SentryId.h" +#import "SentrySpanId.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentrySpanContext () { + NSMutableDictionary *_tags; +} + +@end + +@implementation SentrySpanContext + +- (instancetype)initWithOperation:(NSString *)operation +{ + return [self initWithOperation:operation sampled:false]; +} + +- (instancetype)initWithOperation:(NSString *)operation sampled:(SentrySampleDecision)sampled +{ + return [self initWithTraceId:[[SentryId alloc] init] + spanId:[[SentrySpanId alloc] init] + parentId:nil + operation:operation + sampled:sampled]; +} + +- (instancetype)initWithTraceId:(SentryId *)traceId + spanId:(SentrySpanId *)spanId + parentId:(nullable SentrySpanId *)parentId + operation:(NSString *)operation + sampled:(SentrySampleDecision)sampled +{ + if (self = [super init]) { + _traceId = traceId; + _spanId = spanId; + _parentSpanId = parentId; + self.sampled = sampled; + self.operation = operation; + self.status = kSentrySpanStatusUndefined; + _tags = [[NSMutableDictionary alloc] init]; + } + return self; +} + ++ (NSString *)type +{ + static NSString *type; + if (type == nil) + type = @"trace"; + return type; +} + +- (NSDictionary *)tags +{ + @synchronized(_tags) { + return _tags.copy; + } +} +- (void)setTagValue:(NSString *)value forKey:(NSString *)key +{ + @synchronized(_tags) { + [_tags setValue:value forKey:key]; + } +} + +- (void)removeTagForKey:(NSString *)key +{ + @synchronized(_tags) { + [_tags removeObjectForKey:key]; + } +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *mutabledictionary = @{ + @"type" : SentrySpanContext.type, + @"span_id" : self.spanId.sentrySpanIdString, + @"trace_id" : self.traceId.sentryIdString, + @"tags" : _tags.copy + } + .mutableCopy; + + // Since we guard for 'undecided', we'll + // either send it if it's 'true' or 'false'. + if (self.sampled != kSentrySampleDecisionUndecided) + [mutabledictionary setValue:SentrySampleDecisionNames[self.sampled] forKey:@"sampled"]; + + if (self.operation != nil) + [mutabledictionary setValue:self.operation forKey:@"op"]; + + if (self.parentSpanId != nil) + [mutabledictionary setValue:self.parentSpanId.sentrySpanIdString forKey:@"parent_span_id"]; + + if (self.status != kSentrySpanStatusUndefined) + [mutabledictionary setValue:SentrySpanStatusNames[self.status] forKey:@"status"]; + + return mutabledictionary; +} +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySpanId.m b/Pods/Sentry/Sources/Sentry/SentrySpanId.m new file mode 100644 index 00000000..b3d7a51f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySpanId.m @@ -0,0 +1,82 @@ +#import "SentrySpanId.h" + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const emptyUUIDString = @"0000000000000000"; + +@interface +SentrySpanId () + +@property (nonatomic, strong) NSString *value; + +@end + +@implementation SentrySpanId + +static SentrySpanId *_empty = nil; + +- (instancetype)init +{ + return [self initWithUUID:[NSUUID UUID]]; +} + +- (instancetype)initWithUUID:(NSUUID *)uuid +{ + return [self initWithValue:[[uuid.UUIDString.lowercaseString + stringByReplacingOccurrencesOfString:@"-" + withString:@""] substringToIndex:16]]; +} + +- (instancetype)initWithValue:(NSString *)value +{ + if (self = [super init]) { + if (value.length != 16) + return [SentrySpanId empty]; + value = value.lowercaseString; + + self.value = value; + } + + return self; +} + +- (NSString *)sentrySpanIdString; +{ + return self.value; +} + +- (NSString *)description +{ + return [self sentrySpanIdString]; +} + +- (BOOL)isEqual:(id _Nullable)object +{ + if (object == self) { + return YES; + } + if ([self class] != [object class]) { + return NO; + } + + SentrySpanId *otherSentryID = (SentrySpanId *)object; + + return [self.value isEqual:otherSentryID.value]; +} + +- (NSUInteger)hash +{ + return [self.value hash]; +} + ++ (SentrySpanId *)empty +{ + if (nil == _empty) { + _empty = [[SentrySpanId alloc] initWithValue:emptyUUIDString]; + } + return _empty; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryStacktrace.m b/Pods/Sentry/Sources/Sentry/SentryStacktrace.m new file mode 100644 index 00000000..f5d911a2 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryStacktrace.m @@ -0,0 +1,64 @@ +#import "SentryStacktrace.h" +#import "SentryFrame.h" +#import "SentryLog.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryStacktrace + +- (instancetype)initWithFrames:(NSArray *)frames + registers:(NSDictionary *)registers +{ + self = [super init]; + if (self) { + self.registers = registers; + self.frames = frames; + } + return self; +} + +/// This function fixes duplicate frames and removes the first duplicate +/// https://github.com/kstenerud/KSCrash/blob/05cdc801cfc578d256f85de2e72ec7877cbe79f8/Source/KSCrash/Recording/Tools/KSStackCursor_MachineContext.c#L84 +- (void)fixDuplicateFrames +{ + if (self.frames.count < 2 || nil == self.registers) { + return; + } + + SentryFrame *lastFrame = self.frames.lastObject; + SentryFrame *beforeLastFrame = [self.frames objectAtIndex:self.frames.count - 2]; + + if ([lastFrame.symbolAddress isEqualToString:beforeLastFrame.symbolAddress] && + [self.registers[@"lr"] isEqualToString:beforeLastFrame.instructionAddress]) { + NSMutableArray *copyFrames = self.frames.mutableCopy; + [copyFrames removeObjectAtIndex:self.frames.count - 2]; + self.frames = copyFrames; + [SentryLog logWithMessage:@"Found duplicate frame, removing one with link register" + andLevel:kSentryLevelDebug]; + } +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = [NSMutableDictionary new]; + + NSMutableArray *frames = [NSMutableArray new]; + for (SentryFrame *frame in self.frames) { + NSDictionary *serialized = [frame serialize]; + if (serialized.allKeys.count > 0) { + [frames addObject:[frame serialize]]; + } + } + if (frames.count > 0) { + [serializedData setValue:frames forKey:@"frames"]; + } + // This is here because we wanted to be conform with the old json + if (self.registers.count > 0) { + [serializedData setValue:self.registers forKey:@"registers"]; + } + return serializedData; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryStacktraceBuilder.m b/Pods/Sentry/Sources/Sentry/SentryStacktraceBuilder.m new file mode 100644 index 00000000..0c20404e --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryStacktraceBuilder.m @@ -0,0 +1,57 @@ +#import "SentryStacktraceBuilder.h" +#import "SentryCrashStackCursor.h" +#import "SentryCrashStackCursor_SelfThread.h" +#import "SentryCrashStackEntryMapper.h" +#import "SentryFrame.h" +#import "SentryFrameRemover.h" +#import "SentryStacktrace.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryStacktraceBuilder () + +@property (nonatomic, strong) SentryCrashStackEntryMapper *crashStackEntryMapper; + +@end + +@implementation SentryStacktraceBuilder + +- (id)initWithCrashStackEntryMapper:(SentryCrashStackEntryMapper *)crashStackEntryMapper +{ + if (self = [super init]) { + self.crashStackEntryMapper = crashStackEntryMapper; + } + return self; +} + +- (SentryStacktrace *)buildStacktraceForCurrentThread +{ + NSMutableArray *frames = [NSMutableArray new]; + + SentryCrashStackCursor stackCursor; + // We don't need to skip any frames, because we filter out non sentry frames below. + NSInteger framesToSkip = 0; + sentrycrashsc_initSelfThread(&stackCursor, (int)framesToSkip); + + while (stackCursor.advanceCursor(&stackCursor)) { + if (stackCursor.symbolicate(&stackCursor)) { + SentryFrame *frame = [self.crashStackEntryMapper mapStackEntryWithCursor:stackCursor]; + [frames addObject:frame]; + } + } + + NSArray *framesCleared = [SentryFrameRemover removeNonSdkFrames:frames]; + + // The frames must be ordered from caller to callee, or oldest to youngest + NSArray *framesReversed = [[framesCleared reverseObjectEnumerator] allObjects]; + + SentryStacktrace *stacktrace = [[SentryStacktrace alloc] initWithFrames:framesReversed + registers:@{}]; + + return stacktrace; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentrySwizzle.m b/Pods/Sentry/Sources/Sentry/SentrySwizzle.m new file mode 100644 index 00000000..8ed3bd79 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySwizzle.m @@ -0,0 +1,172 @@ +#import "SentrySwizzle.h" + +#import +#include + +#pragma mark - Swizzling + +#pragma mark └ SentrySwizzleInfo + +typedef IMP (^SentrySwizzleImpProvider)(void); + +@interface +SentrySwizzleInfo () +@property (nonatomic, copy) SentrySwizzleImpProvider impProviderBlock; +@property (nonatomic, readwrite) SEL selector; +@end + +@implementation SentrySwizzleInfo + +- (SentrySwizzleOriginalIMP)getOriginalImplementation +{ + NSAssert(_impProviderBlock, nil); + // Casting IMP to SentrySwizzleOriginalIMP to force user casting. + return (SentrySwizzleOriginalIMP)_impProviderBlock(); +} + +@end + +#pragma mark └ SentrySwizzle + +@implementation SentrySwizzle + +static void +swizzle(Class classToSwizzle, SEL selector, SentrySwizzleImpFactoryBlock factoryBlock) +{ + Method method = class_getInstanceMethod(classToSwizzle, selector); + + NSCAssert(NULL != method, @"Selector %@ not found in %@ methods of class %@.", + NSStringFromSelector(selector), class_isMetaClass(classToSwizzle) ? @"class" : @"instance", + classToSwizzle); + + static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER; + + // To keep things thread-safe, we fill in the originalIMP later, + // with the result of the class_replaceMethod call below. + __block IMP originalIMP = NULL; + + // This block will be called by the client to get original implementation + // and call it. + SentrySwizzleImpProvider originalImpProvider = ^IMP { + // It's possible that another thread can call the method between the + // call to class_replaceMethod and its return value being set. So to be + // sure originalIMP has the right value, we need a lock. + + pthread_mutex_lock(&gLock); + + IMP imp = originalIMP; + + pthread_mutex_unlock(&gLock); + + if (NULL == imp) { + // If the class does not implement the method + // we need to find an implementation in one of the superclasses. + Class superclass = class_getSuperclass(classToSwizzle); + imp = method_getImplementation(class_getInstanceMethod(superclass, selector)); + } + + return imp; + }; + + SentrySwizzleInfo *swizzleInfo = [SentrySwizzleInfo new]; + swizzleInfo.selector = selector; + swizzleInfo.impProviderBlock = originalImpProvider; + + // We ask the client for the new implementation block. + // We pass swizzleInfo as an argument to factory block, so the client can + // call original implementation from the new implementation. + id newIMPBlock = factoryBlock(swizzleInfo); + + const char *methodType = method_getTypeEncoding(method); + + IMP newIMP = imp_implementationWithBlock(newIMPBlock); + + // Atomically replace the original method with our new implementation. + // This will ensure that if someone else's code on another thread is messing + // with the class' method list too, we always have a valid method at all + // times. + // + // If the class does not implement the method itself then + // class_replaceMethod returns NULL and superclasses's implementation will + // be used. + // + // We need a lock to be sure that originalIMP has the right value in the + // originalImpProvider block above. + + pthread_mutex_lock(&gLock); + + originalIMP = class_replaceMethod(classToSwizzle, selector, newIMP, methodType); + + pthread_mutex_unlock(&gLock); +} + +static NSMutableDictionary * +swizzledClassesDictionary() +{ + static NSMutableDictionary *swizzledClasses; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ swizzledClasses = [NSMutableDictionary new]; }); + return swizzledClasses; +} + +static NSMutableSet * +swizzledClassesForKey(const void *key) +{ + NSMutableDictionary *classesDictionary = swizzledClassesDictionary(); + NSValue *keyValue = [NSValue valueWithPointer:key]; + NSMutableSet *swizzledClasses = [classesDictionary objectForKey:keyValue]; + if (!swizzledClasses) { + swizzledClasses = [NSMutableSet new]; + [classesDictionary setObject:swizzledClasses forKey:keyValue]; + } + return swizzledClasses; +} + ++ (BOOL)swizzleInstanceMethod:(SEL)selector + inClass:(Class)classToSwizzle + newImpFactory:(SentrySwizzleImpFactoryBlock)factoryBlock + mode:(SentrySwizzleMode)mode + key:(const void *)key +{ + NSAssert(!(NULL == key && SentrySwizzleModeAlways != mode), + @"Key may not be NULL if mode is not SentrySwizzleModeAlways."); + + @synchronized(swizzledClassesDictionary()) { + if (key) { + NSSet *swizzledClasses = swizzledClassesForKey(key); + if (mode == SentrySwizzleModeOncePerClass) { + if ([swizzledClasses containsObject:classToSwizzle]) { + return NO; + } + } else if (mode == SentrySwizzleModeOncePerClassAndSuperclasses) { + for (Class currentClass = classToSwizzle; nil != currentClass; + currentClass = class_getSuperclass(currentClass)) { + if ([swizzledClasses containsObject:currentClass]) { + return NO; + } + } + } + } + + swizzle(classToSwizzle, selector, factoryBlock); + + if (key) { + [swizzledClassesForKey(key) addObject:classToSwizzle]; + } + } + + return YES; +} + ++ (void)swizzleClassMethod:(SEL)selector + inClass:(Class)classToSwizzle + newImpFactory:(SentrySwizzleImpFactoryBlock)factoryBlock +{ + [self swizzleInstanceMethod:selector + inClass:object_getClass(classToSwizzle) + newImpFactory:factoryBlock + mode:SentrySwizzleModeAlways + key:NULL]; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentrySystemEventsBreadcrumbs.m b/Pods/Sentry/Sources/Sentry/SentrySystemEventsBreadcrumbs.m new file mode 100644 index 00000000..0aded136 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentrySystemEventsBreadcrumbs.m @@ -0,0 +1,182 @@ +#import "SentrySystemEventsBreadcrumbs.h" +#import "SentryBreadcrumb.h" +#import "SentryLog.h" +#import "SentrySDK.h" + +// all those notifications are not available for tvOS +#if TARGET_OS_IOS +# import +#endif + +@implementation SentrySystemEventsBreadcrumbs + +- (void)start +{ +#if TARGET_OS_IOS + UIDevice *currentDevice = [UIDevice currentDevice]; + [self start:currentDevice]; +#else + [SentryLog logWithMessage:@"NO iOS -> [SentrySystemEventsBreadcrumbs.start] does nothing." + andLevel:kSentryLevelDebug]; +#endif +} + +- (void)stop +{ +#if TARGET_OS_IOS + NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter removeObserver:self]; +#endif +} + +#if TARGET_OS_IOS +/** + * Only used for testing, call start() instead. + */ +- (void)start:(UIDevice *)currentDevice +{ + if (currentDevice != nil) { + [self initBatteryObserver:currentDevice]; + [self initOrientationObserver:currentDevice]; + } else { + [SentryLog logWithMessage:@"currentDevice is null, it won't be able to record breadcrumbs " + @"for device battery and orientation." + andLevel:kSentryLevelDebug]; + } + [self initKeyboardVisibilityObserver]; + [self initScreenshotObserver]; +} +#endif + +#if TARGET_OS_IOS +- (void)initBatteryObserver:(UIDevice *)currentDevice +{ + if (currentDevice.batteryMonitoringEnabled == NO) { + currentDevice.batteryMonitoringEnabled = YES; + } + + NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; + + // Posted when the battery level changes. + [defaultCenter addObserver:self + selector:@selector(batteryStateChanged:) + name:UIDeviceBatteryLevelDidChangeNotification + object:currentDevice]; + // Posted when battery state changes. + [defaultCenter addObserver:self + selector:@selector(batteryStateChanged:) + name:UIDeviceBatteryStateDidChangeNotification + object:currentDevice]; +} + +- (void)batteryStateChanged:(NSNotification *)notification +{ + // Notifications for battery level change are sent no more frequently than once per minute + NSMutableDictionary *batteryData = [self getBatteryStatus:notification.object]; + batteryData[@"action"] = @"BATTERY_STATE_CHANGE"; + + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelInfo + category:@"device.event"]; + crumb.type = @"system"; + crumb.data = batteryData; + [SentrySDK addBreadcrumb:crumb]; +} + +- (NSMutableDictionary *)getBatteryStatus:(UIDevice *)currentDevice +{ + // borrowed and adapted from + // https://github.com/apache/cordova-plugin-battery-status/blob/master/src/ios/CDVBattery.m + UIDeviceBatteryState currentState = [currentDevice batteryState]; + + BOOL isPlugged = NO; // UIDeviceBatteryStateUnknown or UIDeviceBatteryStateUnplugged + if ((currentState == UIDeviceBatteryStateCharging) + || (currentState == UIDeviceBatteryStateFull)) { + isPlugged = YES; + } + float currentLevel = [currentDevice batteryLevel]; + NSMutableDictionary *batteryData = [NSMutableDictionary new]; + + // W3C spec says level must be null if it is unknown + if ((currentState != UIDeviceBatteryStateUnknown) && (currentLevel != -1.0)) { + float w3cLevel = (currentLevel * 100); + batteryData[@"level"] = @(w3cLevel); + } else { + [SentryLog logWithMessage:@"batteryLevel is unknown." andLevel:kSentryLevelDebug]; + } + + batteryData[@"plugged"] = @(isPlugged); + return batteryData; +} + +- (void)initOrientationObserver:(UIDevice *)currentDevice +{ + if (currentDevice.isGeneratingDeviceOrientationNotifications == NO) { + [currentDevice beginGeneratingDeviceOrientationNotifications]; + } + + // Posted when the orientation of the device changes. + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(orientationChanged:) + name:UIDeviceOrientationDidChangeNotification + object:currentDevice]; +} + +- (void)orientationChanged:(NSNotification *)notification +{ + UIDevice *currentDevice = notification.object; + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelInfo + category:@"device.orientation"]; + + UIDeviceOrientation currentOrientation = currentDevice.orientation; + + // Ignore changes in device orientation if unknown, face up, or face down. + if (!UIDeviceOrientationIsValidInterfaceOrientation(currentOrientation)) { + [SentryLog logWithMessage:@"currentOrientation is unknown." andLevel:kSentryLevelDebug]; + return; + } + + if (UIDeviceOrientationIsLandscape(currentOrientation)) { + crumb.data = @{ @"position" : @"landscape" }; + } else { + crumb.data = @{ @"position" : @"portrait" }; + } + crumb.type = @"navigation"; + [SentrySDK addBreadcrumb:crumb]; +} + +- (void)initKeyboardVisibilityObserver +{ + NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; + // Posted immediately after the display of the keyboard. + [defaultCenter addObserver:self + selector:@selector(systemEventTriggered:) + name:UIKeyboardDidShowNotification + object:nil]; + + // Posted immediately after the dismissal of the keyboard. + [defaultCenter addObserver:self + selector:@selector(systemEventTriggered:) + name:UIKeyboardDidHideNotification + object:nil]; +} + +- (void)systemEventTriggered:(NSNotification *)notification +{ + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelInfo + category:@"device.event"]; + crumb.type = @"system"; + crumb.data = @{ @"action" : notification.name }; + [SentrySDK addBreadcrumb:crumb]; +} + +- (void)initScreenshotObserver +{ + // it's only about the action, but not the SS itself + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(systemEventTriggered:) + name:UIApplicationUserDidTakeScreenshotNotification + object:nil]; +} +#endif + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryThread.m b/Pods/Sentry/Sources/Sentry/SentryThread.m new file mode 100644 index 00000000..07f4441b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryThread.m @@ -0,0 +1,32 @@ +#import "SentryThread.h" +#import "SentryStacktrace.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryThread + +- (instancetype)initWithThreadId:(NSNumber *)threadId +{ + self = [super init]; + if (self) { + self.threadId = threadId; + } + return self; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = + @{ @"id" : self.threadId ? self.threadId : @(99) }.mutableCopy; + + [serializedData setValue:self.crashed forKey:@"crashed"]; + [serializedData setValue:self.current forKey:@"current"]; + [serializedData setValue:self.name forKey:@"name"]; + [serializedData setValue:[self.stacktrace serialize] forKey:@"stacktrace"]; + + return serializedData; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryThreadInspector.m b/Pods/Sentry/Sources/Sentry/SentryThreadInspector.m new file mode 100644 index 00000000..e338b226 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryThreadInspector.m @@ -0,0 +1,70 @@ +#import "SentryThreadInspector.h" +#import "SentryFrame.h" +#import "SentryStacktrace.h" +#import "SentryStacktraceBuilder.h" +#import "SentryThread.h" + +@interface +SentryThreadInspector () + +@property (nonatomic, strong) SentryStacktraceBuilder *stacktraceBuilder; +@property (nonatomic, strong) id machineContextWrapper; + +@end + +@implementation SentryThreadInspector + +- (id)initWithStacktraceBuilder:(SentryStacktraceBuilder *)stacktraceBuilder + andMachineContextWrapper:(id)machineContextWrapper +{ + if (self = [super init]) { + self.stacktraceBuilder = stacktraceBuilder; + self.machineContextWrapper = machineContextWrapper; + } + return self; +} + +- (NSArray *)getCurrentThreads +{ + NSMutableArray *threads = [NSMutableArray new]; + + SentryCrashMC_NEW_CONTEXT(context); + [self.machineContextWrapper fillContextForCurrentThread:context]; + + int threadCount = [self.machineContextWrapper getThreadCount:context]; + + for (int i = 0; i < threadCount; i++) { + SentryCrashThread thread = [self.machineContextWrapper getThread:context withIndex:i]; + SentryThread *sentryThread = [[SentryThread alloc] initWithThreadId:@(i)]; + + sentryThread.name = [self getThreadName:thread]; + + sentryThread.crashed = @NO; + bool isCurrent = thread == sentrycrashthread_self(); + sentryThread.current = @(isCurrent); + + // For now we can only retrieve the stack trace of the current thread. + if (isCurrent) { + sentryThread.stacktrace = [self.stacktraceBuilder buildStacktraceForCurrentThread]; + } + + [threads addObject:sentryThread]; + } + + return threads; +} + +- (NSString *)getThreadName:(SentryCrashThread)thread +{ + char buffer[128]; + char *const pBuffer = buffer; + [self.machineContextWrapper getThreadName:thread andBuffer:pBuffer andBufLength:128]; + + NSString *threadName = [NSString stringWithCString:pBuffer encoding:NSUTF8StringEncoding]; + if (nil == threadName) { + threadName = @""; + } + return threadName; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryTracer.m b/Pods/Sentry/Sources/Sentry/SentryTracer.m new file mode 100644 index 00000000..45522c4b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryTracer.m @@ -0,0 +1,138 @@ +#import "SentryTracer.h" +#import "SentrySpan.h" +#import "SentrySpanContext.h" +#import "SentrySpanId.h" +#import "SentryTransaction.h" + +@implementation SentryTracer { + SentrySpan *_rootSpan; + NSMutableArray> *_spans; + SentryHub *_hub; +} + +- (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext + hub:(nullable SentryHub *)hub +{ + if ([super init]) { + _rootSpan = [[SentrySpan alloc] initWithTracer:self context:transactionContext]; + self.name = transactionContext.name; + _spans = [[NSMutableArray alloc] init]; + _hub = hub; + } + + return self; +} + +- (id)startChildWithOperation:(NSString *)operation +{ + return [_rootSpan startChildWithOperation:operation]; +} + +- (id)startChildWithOperation:(NSString *)operation + description:(nullable NSString *)description +{ + return [_rootSpan startChildWithOperation:operation description:description]; +} + +- (id)startChildWithParentId:(SentrySpanId *)parentId + operation:(NSString *)operation + description:(nullable NSString *)description +{ + SentrySpanContext *context = + [[SentrySpanContext alloc] initWithTraceId:_rootSpan.context.traceId + spanId:[[SentrySpanId alloc] init] + parentId:parentId + operation:operation + sampled:_rootSpan.context.sampled]; + context.spanDescription = description; + + SentrySpan *span = [[SentrySpan alloc] initWithTracer:self context:context]; + @synchronized(_spans) { + [_spans addObject:span]; + } + return span; +} + +- (SentrySpanContext *)context +{ + return _rootSpan.context; +} + +- (NSDate *)timestamp +{ + return _rootSpan.timestamp; +} + +- (void)setTimestamp:(NSDate *)timestamp +{ + _rootSpan.timestamp = timestamp; +} + +- (NSDate *)startTimestamp +{ + return _rootSpan.startTimestamp; +} + +- (void)setStartTimestamp:(NSDate *)startTimestamp +{ + _rootSpan.startTimestamp = startTimestamp; +} + +- (NSDictionary *)data +{ + return _rootSpan.data; +} + +- (BOOL)isFinished +{ + return _rootSpan.isFinished; +} + +- (void)setDataValue:(nullable id)value forKey:(NSString *)key +{ + [_rootSpan setDataValue:value forKey:key]; +} + +- (void)finish +{ + [_rootSpan finish]; + [self captureTransaction]; +} + +- (void)finishWithStatus:(SentrySpanStatus)status +{ + [_rootSpan finishWithStatus:status]; + [self captureTransaction]; +} + +- (void)captureTransaction +{ + NSArray *spans; + @synchronized(_spans) { + // Make a new array with all finished child spans because if any of the transactions + // children is not finished the transaction is ignored by Sentry. + spans = [_spans + filteredArrayUsingPredicate:[NSPredicate + predicateWithBlock:^BOOL(id _Nullable span, + NSDictionary *_Nullable bindings) { + return span.isFinished; + }]]; + } + + SentryTransaction *transaction = [[SentryTransaction alloc] initWithTrace:self children:spans]; + transaction.transaction = self.name; + [_hub captureEvent:transaction withScope:_hub.scope]; + + [_hub.scope useSpan:^(id _Nullable span) { + if (span == self) { + [self->_hub.scope setSpan:nil]; + } + }]; +} + +- (NSDictionary *)serialize +{ + return [_rootSpan serialize]; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryTransaction.m b/Pods/Sentry/Sources/Sentry/SentryTransaction.m new file mode 100644 index 00000000..c05115a5 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryTransaction.m @@ -0,0 +1,40 @@ +#import "SentryTransaction.h" + +@implementation SentryTransaction { + id _trace; + NSArray> *_spans; +} + +- (instancetype)initWithTrace:(id)trace children:(NSArray> *)children +{ + if ([super init]) { + self.timestamp = trace.timestamp; + self.startTimestamp = trace.startTimestamp; + _trace = trace; + _spans = children; + self.type = SentryEnvelopeItemTypeTransaction; + } + return self; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = + [[NSMutableDictionary alloc] initWithDictionary:[super serialize]]; + + NSMutableArray *spans = [[NSMutableArray alloc] init]; + for (id span in _spans) { + [spans addObject:[span serialize]]; + } + serializedData[@"spans"] = spans; + + NSMutableDictionary *mutableContext = [[NSMutableDictionary alloc] init]; + if (serializedData[@"contexts"] != nil) { + [mutableContext addEntriesFromDictionary:serializedData[@"contexts"]]; + } + mutableContext[@"trace"] = [_trace serialize]; + [serializedData setValue:mutableContext forKey:@"contexts"]; + + return serializedData; +} +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryTransactionContext.m b/Pods/Sentry/Sources/Sentry/SentryTransactionContext.m new file mode 100644 index 00000000..12c5b09c --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryTransactionContext.m @@ -0,0 +1,43 @@ +#import "SentryTransactionContext.h" + +@implementation SentryTransactionContext + +- (instancetype)initWithName:(NSString *)name operation:(NSString *)operation +{ + if (self = [super initWithOperation:operation]) { + _name = [NSString stringWithString:name]; + self.parentSampled = false; + } + return self; +} + +- (instancetype)initWithName:(NSString *)name + operation:(NSString *)operation + sampled:(SentrySampleDecision)sampled +{ + if (self = [super initWithOperation:operation sampled:sampled]) { + _name = [NSString stringWithString:name]; + self.parentSampled = false; + } + return self; +} + +- (instancetype)initWithName:(NSString *)name + operation:(nonnull NSString *)operation + traceId:(SentryId *)traceId + spanId:(SentrySpanId *)spanId + parentSpanId:(SentrySpanId *)parentSpanId + parentSampled:(SentrySampleDecision)parentSampled +{ + if ([super initWithTraceId:traceId + spanId:spanId + parentId:parentSpanId + operation:operation + sampled:false]) { + _name = [NSString stringWithString:name]; + self.parentSampled = parentSampled; + } + return self; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/SentryTransportFactory.m b/Pods/Sentry/Sources/Sentry/SentryTransportFactory.m new file mode 100644 index 00000000..c552e03a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryTransportFactory.m @@ -0,0 +1,63 @@ +#import + +#import "SentryDefaultRateLimits.h" +#import "SentryDispatchQueueWrapper.h" +#import "SentryEnvelopeRateLimit.h" +#import "SentryHttpDateParser.h" +#import "SentryHttpTransport.h" +#import "SentryOptions.h" +#import "SentryQueueableRequestManager.h" +#import "SentryRateLimitParser.h" +#import "SentryRateLimits.h" +#import "SentryRetryAfterHeaderParser.h" +#import "SentryTransport.h" +#import "SentryTransportFactory.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface +SentryTransportFactory () + +@end + +@implementation SentryTransportFactory + ++ (id)initTransport:(SentryOptions *)options + sentryFileManager:(SentryFileManager *)sentryFileManager +{ + NSURLSessionConfiguration *configuration = + [NSURLSessionConfiguration ephemeralSessionConfiguration]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration + delegate:options.urlSessionDelegate + delegateQueue:nil]; + id requestManager = + [[SentryQueueableRequestManager alloc] initWithSession:session]; + + SentryHttpDateParser *httpDateParser = [[SentryHttpDateParser alloc] init]; + SentryRetryAfterHeaderParser *retryAfterHeaderParser = + [[SentryRetryAfterHeaderParser alloc] initWithHttpDateParser:httpDateParser]; + SentryRateLimitParser *rateLimitParser = [[SentryRateLimitParser alloc] init]; + id rateLimits = + [[SentryDefaultRateLimits alloc] initWithRetryAfterHeaderParser:retryAfterHeaderParser + andRateLimitParser:rateLimitParser]; + + SentryEnvelopeRateLimit *envelopeRateLimit = + [[SentryEnvelopeRateLimit alloc] initWithRateLimits:rateLimits]; + + dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_PRIORITY_LOW, 0); + SentryDispatchQueueWrapper *dispatchQueueWrapper = + [[SentryDispatchQueueWrapper alloc] initWithName:"sentry-http-transport" + attributes:attributes]; + + return [[SentryHttpTransport alloc] initWithOptions:options + fileManager:sentryFileManager + requestManager:requestManager + rateLimits:rateLimits + envelopeRateLimit:envelopeRateLimit + dispatchQueueWrapper:dispatchQueueWrapper]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryUser.m b/Pods/Sentry/Sources/Sentry/SentryUser.m new file mode 100644 index 00000000..66f5b50b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryUser.m @@ -0,0 +1,117 @@ +#import "SentryUser.h" +#import "NSDictionary+SentrySanitize.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryUser + +- (instancetype)initWithUserId:(NSString *)userId +{ + self = [super init]; + if (self) { + self.userId = userId; + } + return self; +} + +- (instancetype)init +{ + return [super init]; +} + +- (id)copyWithZone:(nullable NSZone *)zone +{ + SentryUser *copy = [[SentryUser allocWithZone:zone] init]; + + @synchronized(self) { + if (copy != nil) { + copy.userId = self.userId; + copy.email = self.email; + copy.username = self.username; + copy.ipAddress = self.ipAddress; + copy.data = self.data.copy; + } + } + + return copy; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *serializedData = [[NSMutableDictionary alloc] init]; + + @synchronized(self) { + [serializedData setValue:self.userId forKey:@"id"]; + [serializedData setValue:self.email forKey:@"email"]; + [serializedData setValue:self.username forKey:@"username"]; + [serializedData setValue:self.ipAddress forKey:@"ip_address"]; + [serializedData setValue:[self.data sentry_sanitize] forKey:@"data"]; + } + + return serializedData; +} + +- (BOOL)isEqual:(id _Nullable)other +{ + @synchronized(self) { + if (other == self) + return YES; + if (!other || ![[other class] isEqual:[self class]]) + return NO; + + return [self isEqualToUser:other]; + } +} + +- (BOOL)isEqualToUser:(SentryUser *)user +{ + @synchronized(self) { + // We need to get some local copies of the properties, because they could be modified during + // the if statements + + if (self == user) + return YES; + if (user == nil) + return NO; + + NSString *otherUserId = user.userId; + if (self.userId != otherUserId && ![self.userId isEqualToString:otherUserId]) + return NO; + + NSString *otherEmail = user.email; + if (self.email != otherEmail && ![self.email isEqualToString:otherEmail]) + return NO; + + NSString *otherUsername = user.username; + if (self.username != otherUsername && ![self.username isEqualToString:otherUsername]) + return NO; + + NSString *otherIpAdress = user.ipAddress; + if (self.ipAddress != otherIpAdress && ![self.ipAddress isEqualToString:otherIpAdress]) + return NO; + + NSDictionary *otherUserData = user.data; + if (self.data != otherUserData && ![self.data isEqualToDictionary:otherUserData]) + return NO; + return YES; + } +} + +- (NSUInteger)hash +{ + @synchronized(self) { + NSUInteger hash = 17; + + hash = hash * 23 + [self.userId hash]; + hash = hash * 23 + [self.email hash]; + hash = hash * 23 + [self.username hash]; + hash = hash * 23 + [self.ipAddress hash]; + hash = hash * 23 + [self.data hash]; + + return hash; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/SentryUserFeedback.m b/Pods/Sentry/Sources/Sentry/SentryUserFeedback.m new file mode 100644 index 00000000..521adcaa --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/SentryUserFeedback.m @@ -0,0 +1,27 @@ +#import "SentryUserFeedback.h" +#import "SentryId.h" +#import + +@implementation SentryUserFeedback + +- (instancetype)initWithEventId:(SentryId *)eventId +{ + if (self = [super init]) { + _eventId = eventId; + } + return self; +} + +- (NSDictionary *)serialize +{ + NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; + + [data setValue:self.eventId.sentryIdString forKey:@"event_id"]; + [data setValue:self.email forKey:@"email"]; + [data setValue:self.name forKey:@"name"]; + [data setValue:self.comments forKey:@"comments"]; + + return data; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/TracesSampler.m b/Pods/Sentry/Sources/Sentry/TracesSampler.m new file mode 100644 index 00000000..5f0e5e87 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/TracesSampler.m @@ -0,0 +1,50 @@ +#import "TracesSampler.h" +#import "SentryOptions.h" +#import "SentrySamplingContext.h" +#import "SentryTransactionContext.h" + +@implementation TracesSampler { + SentryOptions *_options; +} + +- (instancetype)initWithOptions:(SentryOptions *)options random:(id)random +{ + if (self = [super init]) { + _options = options; + self.random = random; + } + return self; +} + +- (instancetype)initWithOptions:(SentryOptions *)options +{ + return [self initWithOptions:options random:[[SentryRandom alloc] init]]; +} + +- (SentrySampleDecision)sample:(SentrySamplingContext *)context +{ + if (context.transactionContext.sampled != kSentrySampleDecisionUndecided) + return context.transactionContext.sampled; + + if (_options.tracesSampler != nil) { + NSNumber *callbackDecision = _options.tracesSampler(context); + if (callbackDecision != nil) + return [self calcSample:callbackDecision.doubleValue]; + } + + if (context.transactionContext.parentSampled != kSentrySampleDecisionUndecided) + return context.transactionContext.parentSampled; + + if (_options.tracesSampleRate != nil) + return [self calcSample:_options.tracesSampleRate.doubleValue]; + + return kSentrySampleDecisionNo; +} + +- (SentrySampleDecision)calcSample:(double)rate +{ + double r = [self.random nextNumber]; + return r <= rate ? kSentrySampleDecisionYes : kSentrySampleDecisionNo; +} + +@end diff --git a/Pods/Sentry/Sources/Sentry/include/NSArray+SentrySanitize.h b/Pods/Sentry/Sources/Sentry/include/NSArray+SentrySanitize.h new file mode 100644 index 00000000..517fd0fe --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/NSArray+SentrySanitize.h @@ -0,0 +1,11 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSArray (SentrySanitize) + +- (NSArray *)sentry_sanitize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/NSData+SentryCompression.h b/Pods/Sentry/Sources/Sentry/include/NSData+SentryCompression.h new file mode 100644 index 00000000..7042fc20 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/NSData+SentryCompression.h @@ -0,0 +1,12 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSData (SentryCompression) + +- (NSData *_Nullable)sentry_gzippedWithCompressionLevel:(NSInteger)compressionLevel + error:(NSError *_Nullable *_Nullable)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/NSDate+SentryExtras.h b/Pods/Sentry/Sources/Sentry/include/NSDate+SentryExtras.h new file mode 100644 index 00000000..44e10cd5 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/NSDate+SentryExtras.h @@ -0,0 +1,13 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSDate (SentryExtras) + ++ (NSDate *)sentry_fromIso8601String:(NSString *)string; + +- (NSString *)sentry_toIso8601String; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/NSDictionary+SentrySanitize.h b/Pods/Sentry/Sources/Sentry/include/NSDictionary+SentrySanitize.h new file mode 100644 index 00000000..eb7f9961 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/NSDictionary+SentrySanitize.h @@ -0,0 +1,11 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSDictionary (SentrySanitize) + +- (NSDictionary *)sentry_sanitize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/NSString+SentryUnsignedLongLongValue.h b/Pods/Sentry/Sources/Sentry/include/NSString+SentryUnsignedLongLongValue.h new file mode 100644 index 00000000..b9d2d6c4 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/NSString+SentryUnsignedLongLongValue.h @@ -0,0 +1,9 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSString (SentryUnsignedLongLongValue) +- (unsigned long long)unsignedLongLongValue; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryAppState.h b/Pods/Sentry/Sources/Sentry/include/SentryAppState.h new file mode 100644 index 00000000..6b26884b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryAppState.h @@ -0,0 +1,34 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryAppState : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithReleaseName:(NSString *)releaseName + osVersion:(NSString *)osVersion + isDebugging:(BOOL)isDebugging; + +/** + * Initializes SentryAppState from a JSON object. + * + * @param jsonObject The jsonObject containing the session. + * + * @return The SentrySession or nil if the JSONObject contains an error. + */ +- (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject; + +@property (readonly, nonatomic, copy) NSString *releaseName; + +@property (readonly, nonatomic, copy) NSString *osVersion; + +@property (readonly, nonatomic, assign) BOOL isDebugging; + +@property (nonatomic, assign) BOOL isActive; + +@property (nonatomic, assign) BOOL wasTerminated; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryAsynchronousOperation.h b/Pods/Sentry/Sources/Sentry/include/SentryAsynchronousOperation.h new file mode 100644 index 00000000..ab3c8a18 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryAsynchronousOperation.h @@ -0,0 +1,11 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryAsynchronousOperation : NSOperation + +- (void)completeOperation; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryAutoBreadcrumbTrackingIntegration.h b/Pods/Sentry/Sources/Sentry/include/SentryAutoBreadcrumbTrackingIntegration.h new file mode 100644 index 00000000..268c365a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryAutoBreadcrumbTrackingIntegration.h @@ -0,0 +1,13 @@ +#import "SentryIntegrationProtocol.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * This automatically adds breadcrumbs for different user actions. + */ +@interface SentryAutoBreadcrumbTrackingIntegration : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryAutoSessionTrackingIntegration.h b/Pods/Sentry/Sources/Sentry/include/SentryAutoSessionTrackingIntegration.h new file mode 100644 index 00000000..93fc4a4d --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryAutoSessionTrackingIntegration.h @@ -0,0 +1,15 @@ +#import "SentryIntegrationProtocol.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Automatically tracks session start and end. + */ +@interface SentryAutoSessionTrackingIntegration : NSObject + +- (void)stop; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryBreadcrumbTracker.h b/Pods/Sentry/Sources/Sentry/include/SentryBreadcrumbTracker.h new file mode 100644 index 00000000..4a8a7be6 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryBreadcrumbTracker.h @@ -0,0 +1,9 @@ +#import + +@interface SentryBreadcrumbTracker : NSObject + +- (void)start; + +- (void)stop; + +@end diff --git a/Pods/Sentry/Sources/Sentry/include/SentryClient+Private.h b/Pods/Sentry/Sources/Sentry/include/SentryClient+Private.h new file mode 100644 index 00000000..2f5e4e62 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryClient+Private.h @@ -0,0 +1,33 @@ +#import "SentryClient.h" +#import + +@class SentryId; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryClient (Private) + +- (SentryFileManager *)fileManager; + +- (SentryId *)captureError:(NSError *)error + withSession:(SentrySession *)session + withScope:(SentryScope *)scope; + +- (SentryId *)captureException:(NSException *)exception + withSession:(SentrySession *)session + withScope:(SentryScope *)scope; + +- (SentryId *)captureCrashEvent:(SentryEvent *)event withScope:(SentryScope *)scope; + +- (SentryId *)captureCrashEvent:(SentryEvent *)event + withSession:(SentrySession *)session + withScope:(SentryScope *)scope; + +/** + * Needed by hybrid SDKs as react-native to synchronously store an envelope to disk. + */ +- (void)storeEnvelope:(SentryEnvelope *)envelope; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryConcurrentRateLimitsDictionary.h b/Pods/Sentry/Sources/Sentry/include/SentryConcurrentRateLimitsDictionary.h new file mode 100644 index 00000000..d7de36c7 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryConcurrentRateLimitsDictionary.h @@ -0,0 +1,21 @@ +#import "SentryRateLimitCategory.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** A thread safe wrapper around a dictionary to store rate limits. + */ +@interface SentryConcurrentRateLimitsDictionary : NSObject + +/** + Adds the passed rate limit for the given category. If a rate limit already + exists it is overwritten. + */ +- (void)addRateLimit:(SentryRateLimitCategory)category validUntil:(NSDate *)date; + +/** Returns the date until the rate limit is active. */ +- (NSDate *)getRateLimitForCategory:(SentryRateLimitCategory)category; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashAdapter.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashAdapter.h new file mode 100644 index 00000000..060133c3 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashAdapter.h @@ -0,0 +1,17 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** A wrapper around SentryCrash for testability. + */ +@interface SentryCrashAdapter : NSObject + +- (BOOL)crashedLastLaunch; + +- (NSTimeInterval)activeDurationSinceLastCrash; + +- (BOOL)isBeingTraced; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashBinaryImageProvider.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashBinaryImageProvider.h new file mode 100644 index 00000000..56150bff --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashBinaryImageProvider.h @@ -0,0 +1,17 @@ +#import "SentryCrashDynamicLinker.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + A wrapper around SentryCrash for testability. + */ +@protocol SentryCrashBinaryImageProvider + +- (NSInteger)getImageCount; + +- (SentryCrashBinaryImage)getBinaryImage:(NSInteger)index; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashDefaultBinaryImageProvider.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashDefaultBinaryImageProvider.h new file mode 100644 index 00000000..343cec1a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashDefaultBinaryImageProvider.h @@ -0,0 +1,10 @@ +#import "SentryCrashBinaryImageProvider.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryCrashDefaultBinaryImageProvider : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashDefaultMachineContextWrapper.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashDefaultMachineContextWrapper.h new file mode 100644 index 00000000..881187d7 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashDefaultMachineContextWrapper.h @@ -0,0 +1,10 @@ +#import "SentryCrashMachineContextWrapper.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryCrashDefaultMachineContextWrapper : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashInstallationReporter.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashInstallationReporter.h new file mode 100644 index 00000000..b99b01e0 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashInstallationReporter.h @@ -0,0 +1,19 @@ +#import "SentryCrash.h" +#import "SentryCrashInstallation.h" +#import "SentryDefines.h" +#import + +@class SentryFrameInAppLogic; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryCrashInstallationReporter : SentryCrashInstallation +SENTRY_NO_INIT + +- (instancetype)initWithFrameInAppLogic:(SentryFrameInAppLogic *)frameInAppLogic; + +- (void)sendAllReports; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashIntegration.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashIntegration.h new file mode 100644 index 00000000..5bb20e1b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashIntegration.h @@ -0,0 +1,12 @@ +#import "SentryIntegrationProtocol.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const SentryDeviceContextFreeMemoryKey = @"free_memory"; + +@interface SentryCrashIntegration : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashIsAppImage.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashIsAppImage.h new file mode 100644 index 00000000..5b6a926f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashIsAppImage.h @@ -0,0 +1,9 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryCrashBinaryImageUtil : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashMachineContextWrapper.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashMachineContextWrapper.h new file mode 100644 index 00000000..96f8e5ad --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashMachineContextWrapper.h @@ -0,0 +1,23 @@ +#import "SentryCrashMachineContext.h" +#import "SentryCrashThread.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** A wrapper around SentryCrashMachineContext for testability. + */ +@protocol SentryCrashMachineContextWrapper + +- (void)fillContextForCurrentThread:(struct SentryCrashMachineContext *)context; + +- (int)getThreadCount:(struct SentryCrashMachineContext *)context; + +- (SentryCrashThread)getThread:(struct SentryCrashMachineContext *)context withIndex:(int)index; + +- (void)getThreadName:(const SentryCrashThread)thread + andBuffer:(char *const)buffer + andBufLength:(int)bufLength; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashReportConverter.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashReportConverter.h new file mode 100644 index 00000000..2f6de1ec --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashReportConverter.h @@ -0,0 +1,23 @@ +#import + +@class SentryEvent, SentryFrameInAppLogic; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryCrashReportConverter : NSObject + +@property (nonatomic, strong) NSDictionary *userContext; + +- (instancetype)initWithReport:(NSDictionary *)report + frameInAppLogic:(SentryFrameInAppLogic *)frameInAppLogic; + +/** + * Converts the report to an SentryEvent. + * + * @return The converted event or nil if an error occured during the conversion. + */ +- (SentryEvent *_Nullable)convertReportToEvent; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashReportSink.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashReportSink.h new file mode 100644 index 00000000..05521b96 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashReportSink.h @@ -0,0 +1,16 @@ +#import "SentryCrash.h" +#import "SentryDefines.h" +#import + +@class SentryFrameInAppLogic; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryCrashReportSink : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithFrameInAppLogic:(SentryFrameInAppLogic *)frameInAppLogic; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCrashStackEntryMapper.h b/Pods/Sentry/Sources/Sentry/include/SentryCrashStackEntryMapper.h new file mode 100644 index 00000000..e007f5ab --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCrashStackEntryMapper.h @@ -0,0 +1,25 @@ +#import "SentryCrashDynamicLinker.h" +#import "SentryCrashStackCursor.h" +#import "SentryDefines.h" +#import + +@class SentryFrame, SentryFrameInAppLogic; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryCrashStackEntryMapper : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithFrameInAppLogic:(SentryFrameInAppLogic *)frameInAppLogic; + +/** + * Maps the stackEntry of a SentryCrashStackCursor to SentryFrame. + * + * @param stackCursor An with SentryCrash initialized stackCursor. You can use for example + * sentrycrashsc_initSelfThread. + */ +- (SentryFrame *)mapStackEntryWithCursor:(SentryCrashStackCursor)stackCursor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCurrentDate.h b/Pods/Sentry/Sources/Sentry/include/SentryCurrentDate.h new file mode 100644 index 00000000..33245af1 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCurrentDate.h @@ -0,0 +1,19 @@ +#import "SentryCurrentDateProvider.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A static API to return the current date. This allows to change the current + * date, especially useful for testing. + */ +NS_SWIFT_NAME(CurrentDate) +@interface SentryCurrentDate : NSObject + ++ (NSDate *_Nonnull)date; + ++ (void)setCurrentDateProvider:(id)currentDateProvider; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryCurrentDateProvider.h b/Pods/Sentry/Sources/Sentry/include/SentryCurrentDateProvider.h new file mode 100644 index 00000000..a981e320 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryCurrentDateProvider.h @@ -0,0 +1,12 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(CurrentDateProvider) +@protocol SentryCurrentDateProvider + +- (NSDate *)date; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryDateUtil.h b/Pods/Sentry/Sources/Sentry/include/SentryDateUtil.h new file mode 100644 index 00000000..60c8fdb6 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryDateUtil.h @@ -0,0 +1,14 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(DateUtil) +@interface SentryDateUtil : NSObject + ++ (BOOL)isInFuture:(NSDate *_Nullable)date; + ++ (NSDate *_Nullable)getMaximumDate:(NSDate *_Nullable)first andOther:(NSDate *_Nullable)second; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryDebugMetaBuilder.h b/Pods/Sentry/Sources/Sentry/include/SentryDebugMetaBuilder.h new file mode 100644 index 00000000..4ad9886c --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryDebugMetaBuilder.h @@ -0,0 +1,18 @@ +#import "SentryCrashBinaryImageProvider.h" +#import "SentryDefines.h" +#import + +@class SentryDebugMeta; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryDebugMetaBuilder : NSObject +SENTRY_NO_INIT + +- (id)initWithBinaryImageProvider:(id)binaryImageProvider; + +- (NSArray *)buildDebugMeta; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryDefaultCurrentDateProvider.h b/Pods/Sentry/Sources/Sentry/include/SentryDefaultCurrentDateProvider.h new file mode 100644 index 00000000..4cd04843 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryDefaultCurrentDateProvider.h @@ -0,0 +1,11 @@ +#import "SentryCurrentDateProvider.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(DefaultCurrentDateProvider) +@interface SentryDefaultCurrentDateProvider : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryDefaultRateLimits.h b/Pods/Sentry/Sources/Sentry/include/SentryDefaultRateLimits.h new file mode 100644 index 00000000..170c4d08 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryDefaultRateLimits.h @@ -0,0 +1,24 @@ +#import "SentryRateLimits.h" +#import + +@class SentryRetryAfterHeaderParser; +@class SentryRateLimitParser; + +NS_ASSUME_NONNULL_BEGIN + +/** + Parses HTTP responses from the Sentry server for rate limits and stores them + in memory. The server can communicate a rate limit either through the 429 + status code with a "Retry-After" header or through any response with a custom + "X-Sentry-Rate-Limits" header. This class is thread safe. +*/ +NS_SWIFT_NAME(DefaultRateLimits) +@interface SentryDefaultRateLimits : NSObject + +- (instancetype)initWithRetryAfterHeaderParser: + (SentryRetryAfterHeaderParser *)retryAfterHeaderParser + andRateLimitParser:(SentryRateLimitParser *)rateLimitParser; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryDispatchQueueWrapper.h b/Pods/Sentry/Sources/Sentry/include/SentryDispatchQueueWrapper.h new file mode 100644 index 00000000..32883dce --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryDispatchQueueWrapper.h @@ -0,0 +1,18 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A wrapper around DispatchQueue functions for testability. + */ +@interface SentryDispatchQueueWrapper : NSObject + +- (instancetype)initWithName:(const char *)name attributes:(dispatch_queue_attr_t)attributes; + +- (void)dispatchAsyncWithBlock:(void (^)(void))block; + +- (void)dispatchOnce:(dispatch_once_t *)predicate block:(void (^)(void))block; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryEnvelopeRateLimit.h b/Pods/Sentry/Sources/Sentry/include/SentryEnvelopeRateLimit.h new file mode 100644 index 00000000..28c9b78c --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryEnvelopeRateLimit.h @@ -0,0 +1,20 @@ +#import "SentryRateLimits.h" +#import + +@class SentryEnvelope; + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(EnvelopeRateLimit) +@interface SentryEnvelopeRateLimit : NSObject + +- (instancetype)initWithRateLimits:(id)sentryRateLimits; + +/** + Removes SentryEnvelopItems for which a rate limit is active. + */ +- (SentryEnvelope *)removeRateLimitedItems:(SentryEnvelope *)envelope; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryFileContents.h b/Pods/Sentry/Sources/Sentry/include/SentryFileContents.h new file mode 100644 index 00000000..25184588 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryFileContents.h @@ -0,0 +1,14 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryFileContents : NSObject + +- (instancetype)initWithPath:(NSString *)path andContents:(NSData *)contents; + +@property (nonatomic, readonly, copy) NSString *path; +@property (nonatomic, readonly, strong) NSData *contents; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryFileManager.h b/Pods/Sentry/Sources/Sentry/include/SentryFileManager.h new file mode 100644 index 00000000..40632ad9 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryFileManager.h @@ -0,0 +1,63 @@ +#import + +#import "SentryCurrentDateProvider.h" +#import "SentryDefines.h" +#import "SentrySession.h" + +NS_ASSUME_NONNULL_BEGIN + +@class SentryEvent, SentryOptions, SentryEnvelope, SentryFileContents, SentryAppState; + +NS_SWIFT_NAME(SentryFileManager) +@interface SentryFileManager : NSObject +SENTRY_NO_INIT + +- (nullable instancetype)initWithOptions:(SentryOptions *)options + andCurrentDateProvider:(id)currentDateProvider + error:(NSError **)error NS_DESIGNATED_INITIALIZER; + +- (NSString *)storeEnvelope:(SentryEnvelope *)envelope; + +- (void)storeCurrentSession:(SentrySession *)session; +- (void)storeCrashedSession:(SentrySession *)session; +- (SentrySession *_Nullable)readCurrentSession; +- (SentrySession *_Nullable)readCrashedSession; +- (void)deleteCurrentSession; +- (void)deleteCrashedSession; + +- (void)storeTimestampLastInForeground:(NSDate *)timestamp; +- (NSDate *_Nullable)readTimestampLastInForeground; +- (void)deleteTimestampLastInForeground; + ++ (BOOL)createDirectoryAtPath:(NSString *)path withError:(NSError **)error; + +- (void)deleteAllEnvelopes; + +- (void)deleteAllFolders; + +/** + * Get all envelopes sorted ascending by the timeIntervalSince1970 the envelope was stored and if + * two envelopes are stored at the same time sorted by the order they were stored. + */ +- (NSArray *)getAllEnvelopes; + +/** + * Gets the oldest stored envelope. For the order see getAllEnvelopes. + * + * @return SentryFileContens if there is an envelope and nil if there are no envelopes. + */ +- (SentryFileContents *_Nullable)getOldestEnvelope; + +- (BOOL)removeFileAtPath:(NSString *)path; + +- (NSArray *)allFilesInFolder:(NSString *)path; + +- (NSString *)storeDictionary:(NSDictionary *)dictionary toPath:(NSString *)path; + +- (void)storeAppState:(SentryAppState *)appState; +- (SentryAppState *_Nullable)readAppState; +- (void)deleteAppState; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryFrameInAppLogic.h b/Pods/Sentry/Sources/Sentry/include/SentryFrameInAppLogic.h new file mode 100644 index 00000000..6ad8bc8a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryFrameInAppLogic.h @@ -0,0 +1,61 @@ +#import "SentryDefines.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class detects whether a framework belongs to the app or not. We differentiate between three + * different types of frameworks. + * + * First, the main executable of the app, which's name can be retrieved by CFBundleExecutable. To + * mark this framework as inApp the caller needs to pass in the CFBundleExecutable to InAppIncludes. + * + * Next, there are private frameworks embedded in the application bundle. Both app supporting + * frameworks as CocoaLumberJack, Sentry, RXSwift, etc., and frameworks written by the user fall + * into this category. These frameworks can be both inApp or not. As we expect most frameworks of + * this category to be supporting frameworks, we mark them not as inApp. If a user wants such a + * framework to be inApp, they need to pass the name into inAppInclude. For dynamic frameworks, the + * location is usually in the bundle under /Frameworks/FrameworkName.framework/FrameworkName. As for + * static frameworks, the location is the same as the main executable; this class marks all static + * frameworks as inApp. To remove static frameworks from being inApp, Sentry uses stack trace + * grouping rules on the server. + * + * Last, this class marks all public frameworks as not inApp. Such frameworks are bound dynamically + * and are usually located at /Library/Frameworks or ~/Library/Frameworks. For simulators, the + * location can be something like + * /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/... + * + */ +@interface SentryFrameInAppLogic : NSObject +SENTRY_NO_INIT + +/** + * Initializes SentryFrameInAppLogic with inAppIncludes and inAppExcludes. + * + * To work properly for Apple applications the inAppIncludes should contain the CFBundleExecutable, + * which is the name of the bundle’s executable file. + * + * @param inAppIncludes A list of string prefixes of framework names that belong to the app. This + * option takes precedence over inAppExcludes. + * @param inAppExcludes A list of string prefixes of framework names that do not belong to the app, + * but rather to third-party packages. Modules considered not part of the app will be hidden from + * stack traces by default. + */ +- (instancetype)initWithInAppIncludes:(NSArray *)inAppIncludes + inAppExcludes:(NSArray *)inAppExcludes; + +/** + * Determines if the framework belongs to the app by using inAppIncludes and inAppExcludes. Before + * checking this method lowercases the strings and uses only the lastPathComponent of the imagePath. + * + * @param imagePath the full path of the binary image. + * + * @return YES if the framework located at the imagePath starts with a prefix of inAppIncludes. NO + * if the framework located at the imagePath doesn't start with a prefix of inAppIncludes or start + * with a prefix of inAppExcludes. + */ +- (BOOL)isInApp:(nullable NSString *)imagePath; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryFrameRemover.h b/Pods/Sentry/Sources/Sentry/include/SentryFrameRemover.h new file mode 100644 index 00000000..77b87083 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryFrameRemover.h @@ -0,0 +1,22 @@ +#import + +@class SentryFrame; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryFrameRemover : NSObject + +/** + * Removes Sentry SDK frames until a frame from a different package is found. + * + * When a user includes Sentry as a static library, the package is the same as the application. + * Therefore removing frames with a package containing "sentry" doesn't work. We can't look into the + * function name as in release builds, the function name can be obfuscated, or we remove functions + * that are not from this SDK and contain "sentry". Therefore this logic only works for apps + * including Sentry dynamically. + */ ++ (NSArray *)removeNonSdkFrames:(NSArray *)frames; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryGlobalEventProcessor.h b/Pods/Sentry/Sources/Sentry/include/SentryGlobalEventProcessor.h new file mode 100644 index 00000000..c2571f29 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryGlobalEventProcessor.h @@ -0,0 +1,20 @@ +#import "SentryDefines.h" + +@class SentryEvent; + +typedef SentryEvent *__nullable (^SentryEventProcessor)(SentryEvent *_Nonnull event); + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryGlobalEventProcessor : NSObject +SENTRY_NO_INIT + +@property (nonatomic, strong) NSMutableArray *processors; + ++ (instancetype)shared; + +- (void)addEventProcessor:(SentryEventProcessor)newProcessor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryHexAddressFormatter.h b/Pods/Sentry/Sources/Sentry/include/SentryHexAddressFormatter.h new file mode 100644 index 00000000..37165aaa --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryHexAddressFormatter.h @@ -0,0 +1,7 @@ +#import + +static inline NSString * +sentry_formatHexAddress(NSNumber *value) +{ + return [NSString stringWithFormat:@"0x%016llx", [value unsignedLongLongValue]]; +} diff --git a/Pods/Sentry/Sources/Sentry/include/SentryHttpDateParser.h b/Pods/Sentry/Sources/Sentry/include/SentryHttpDateParser.h new file mode 100644 index 00000000..6e08e914 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryHttpDateParser.h @@ -0,0 +1,17 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Parses a string in the format of http date to NSDate. For more details see: + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date. + * SentryHttpDateParser is thread safe. + */ +NS_SWIFT_NAME(HttpDateParser) +@interface SentryHttpDateParser : NSObject + +- (NSDate *_Nullable)dateFromString:(NSString *)string; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryHttpTransport.h b/Pods/Sentry/Sources/Sentry/include/SentryHttpTransport.h new file mode 100644 index 00000000..82a14680 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryHttpTransport.h @@ -0,0 +1,24 @@ +#import + +#import "SentryDefines.h" +#import "SentryRateLimits.h" +#import "SentryRequestManager.h" +#import "SentryTransport.h" + +@class SentryEnvelopeRateLimit, SentryOptions, SentryFileManager, SentryDispatchQueueWrapper; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryHttpTransport : NSObject +SENTRY_NO_INIT + +- (id)initWithOptions:(SentryOptions *)options + fileManager:(SentryFileManager *)fileManager + requestManager:(id)requestManager + rateLimits:(id)rateLimits + envelopeRateLimit:(SentryEnvelopeRateLimit *)envelopeRateLimit + dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryHub+Private.h b/Pods/Sentry/Sources/Sentry/include/SentryHub+Private.h new file mode 100644 index 00000000..aa26d57e --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryHub+Private.h @@ -0,0 +1,17 @@ +#import "SentryHub.h" + +@class SentryId, SentryScope; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryHub (Private) + +- (void)captureCrashEvent:(SentryEvent *)event; + +- (void)setSampleRandomValue:(NSNumber *)value; + +- (void)closeCachedSessionWithTimestamp:(NSDate *_Nullable)timestamp; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryInstallation.h b/Pods/Sentry/Sources/Sentry/include/SentryInstallation.h new file mode 100644 index 00000000..d74f43bd --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryInstallation.h @@ -0,0 +1,13 @@ +#import + +#import "SentryDefines.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryInstallation : NSObject + ++ (NSString *)id; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryInternalNotificationNames.h b/Pods/Sentry/Sources/Sentry/include/SentryInternalNotificationNames.h new file mode 100644 index 00000000..7f2f0551 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryInternalNotificationNames.h @@ -0,0 +1,8 @@ +/** + * In hybrid SDKs, we might initialize the Cocoa SDK after the hybrid engine is ready. So, we may + * register the didBecomeActive notification after the OS posts it. Therefore the hybrid SDKs can + * post this internal notification after initializing the Cocoa SDK. Hybrid SDKs must only post this + * notification if they are running in the foreground. + */ +static NSString *const SentryHybridSdkDidBecomeActiveNotificationName + = @"SentryHybridSdkDidBecomeActive"; diff --git a/Pods/Sentry/Sources/Sentry/include/SentryLevelMapper.h b/Pods/Sentry/Sources/Sentry/include/SentryLevelMapper.h new file mode 100644 index 00000000..8f568571 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryLevelMapper.h @@ -0,0 +1,17 @@ +#import + +#import "SentryDefines.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryLevelMapper : NSObject + +/** + * Maps a string to a SentryLevel. If the passed string doesn't match any level this defaults to + * the 'error' level. See https://develop.sentry.dev/sdk/event-payloads/#optional-attributes + */ ++ (SentryLevel)levelWithString:(NSString *)string; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryLog.h b/Pods/Sentry/Sources/Sentry/include/SentryLog.h new file mode 100644 index 00000000..01111031 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryLog.h @@ -0,0 +1,17 @@ +#import "SentryDefines.h" +#import + +@class SentryLogOutput; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryLog : NSObject +SENTRY_NO_INIT + ++ (void)configure:(BOOL)debug diagnosticLevel:(SentryLevel)level; + ++ (void)logWithMessage:(NSString *)message andLevel:(SentryLevel)level; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryLogOutput.h b/Pods/Sentry/Sources/Sentry/include/SentryLogOutput.h new file mode 100644 index 00000000..c1671067 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryLogOutput.h @@ -0,0 +1,11 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryLogOutput : NSObject + +- (void)log:(NSString *)message; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryMeta.h b/Pods/Sentry/Sources/Sentry/include/SentryMeta.h new file mode 100644 index 00000000..21e66eeb --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryMeta.h @@ -0,0 +1,19 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryMeta : NSObject + +/** + * Return a version string e.g: 1.2.3 (3) + */ +@property (nonatomic, class, readonly, copy) NSString *versionString; + +/** + * Return a string sentry-cocoa + */ +@property (nonatomic, class, readonly, copy) NSString *sdkName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryMigrateSessionInit.h b/Pods/Sentry/Sources/Sentry/include/SentryMigrateSessionInit.h new file mode 100644 index 00000000..38321868 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryMigrateSessionInit.h @@ -0,0 +1,35 @@ +#import + +@class SentryEnvelope; + +NS_ASSUME_NONNULL_BEGIN + +/** + * For proper statistics in release health, we need to make sure we don't send session updates + without sending a session init first. In other words, we can't drop a session init. The +  SentryFileManager deletes an envelope once the maximum amount of envelopes is stored. When this + happens and the envelope to delete contains a session init we look for the next envelope containing + a session update for the same session. If such a session envelope is found we migrate the init + flag. If none is found we delete the envelope. We don't migrate other envelope items as events. + */ +@interface SentryMigrateSessionInit : NSObject +SENTRY_NO_INIT + +/** + * Checks if the envelope of the passed file path contains an envelope item with a session init. If + * it does it iterates over all envelopes and looks for a session with the same session id. If such + * a session is found the init flag is set to YES, the envelope is updated with keeping other + * envelope items and headers, and the updated envelope is stored to the disk keeping its path. + * + * @param envelopeFilePath The path of the envelope that was deleted. + * @param envelopesDirPath The path of the directory where the envelopes are stored. + * @param envelopeFilePaths An array containing the file paths of envelopes to check if they contain + * a session init. + */ ++ (void)migrateSessionInit:(NSString *)envelopeFilePath + envelopesDirPath:(NSString *)envelopesDirPath + envelopeFilePaths:(NSArray *)envelopeFilePaths; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryNSURLRequest.h b/Pods/Sentry/Sources/Sentry/include/SentryNSURLRequest.h new file mode 100644 index 00000000..7b42695f --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryNSURLRequest.h @@ -0,0 +1,23 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@class SentryDsn, SentryEvent; + +@interface SentryNSURLRequest : NSMutableURLRequest + +- (_Nullable instancetype)initStoreRequestWithDsn:(SentryDsn *)dsn + andEvent:(SentryEvent *)event + didFailWithError:(NSError *_Nullable *_Nullable)error; + +- (_Nullable instancetype)initStoreRequestWithDsn:(SentryDsn *)dsn + andData:(NSData *)data + didFailWithError:(NSError *_Nullable *_Nullable)error; + +- (_Nullable instancetype)initEnvelopeRequestWithDsn:(SentryDsn *)dsn + andData:(NSData *)data + didFailWithError:(NSError *_Nullable *_Nullable)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryLogic.h b/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryLogic.h new file mode 100644 index 00000000..7635e26e --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryLogic.h @@ -0,0 +1,21 @@ +#import "SentryDefines.h" + +@class SentryOptions, SentryCrashAdapter, SentryAppState, SentryFileManager; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryOutOfMemoryLogic : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithOptions:(SentryOptions *)options + crashAdapter:(SentryCrashAdapter *)crashAdatper; + +- (BOOL)isOOM; + +#if SENTRY_HAS_UIKIT +- (SentryAppState *)buildCurrentAppState; +#endif + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryTracker.h b/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryTracker.h new file mode 100644 index 00000000..9069cdde --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryTracker.h @@ -0,0 +1,29 @@ +#import "SentryDefines.h" + +@class SentryOptions, SentryOutOfMemoryLogic, SentryDispatchQueueWrapper; + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const SentryOutOfMemoryExceptionType = @"OutOfMemory"; +static NSString *const SentryOutOfMemoryExceptionValue + = @"The OS most likely terminated your app because it overused RAM."; +static NSString *const SentryOutOfMemoryMechanismType = @"out_of_memory"; + +/** + * Detect OOMs based on heuristics described in a blog post: + * https://engineering.fb.com/2015/08/24/ios/reducing-fooms-in-the-facebook-ios-app/ If a OOM is + * detected, the SDK sends it as crash event. Only works for iOS, tvOS and macCatalyst. + */ +@interface SentryOutOfMemoryTracker : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithOptions:(SentryOptions *)options + outOfMemoryLogic:(SentryOutOfMemoryLogic *)outOfMemoryLogic + dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper; + +- (void)start; +- (void)stop; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryTrackingIntegration.h b/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryTrackingIntegration.h new file mode 100644 index 00000000..4e32016a --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryOutOfMemoryTrackingIntegration.h @@ -0,0 +1,12 @@ +#import "SentryIntegrationProtocol.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryOutOfMemoryTrackingIntegration : NSObject + +- (void)stop; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryQueueableRequestManager.h b/Pods/Sentry/Sources/Sentry/include/SentryQueueableRequestManager.h new file mode 100644 index 00000000..0363391e --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryQueueableRequestManager.h @@ -0,0 +1,12 @@ +#import + +#import "SentryDefines.h" +#import "SentryRequestManager.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryQueueableRequestManager : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryRandom.h b/Pods/Sentry/Sources/Sentry/include/SentryRandom.h new file mode 100644 index 00000000..bdcc09a0 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryRandom.h @@ -0,0 +1,20 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol SentryRandom + +/** + * Returns a random number uniformly distributed over the interval [0.0 , 1.0]. + */ +- (double)nextNumber; + +@end + +@interface SentryRandom : NSObject + +- (double)nextNumber; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryRateLimitCategory.h b/Pods/Sentry/Sources/Sentry/include/SentryRateLimitCategory.h new file mode 100644 index 00000000..c288b283 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryRateLimitCategory.h @@ -0,0 +1,11 @@ +#import + +typedef NS_ENUM(NSUInteger, SentryRateLimitCategory) { + kSentryRateLimitCategoryAll, + kSentryRateLimitCategoryDefault, + kSentryRateLimitCategoryError, + kSentryRateLimitCategorySession, + kSentryRateLimitCategoryTransaction, + kSentryRateLimitCategoryAttachment, + kSentryRateLimitCategoryUnknown +}; diff --git a/Pods/Sentry/Sources/Sentry/include/SentryRateLimitCategoryMapper.h b/Pods/Sentry/Sources/Sentry/include/SentryRateLimitCategoryMapper.h new file mode 100644 index 00000000..d43ec011 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryRateLimitCategoryMapper.h @@ -0,0 +1,19 @@ +#import "SentryRateLimitCategory.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(RateLimitCategoryMapper) +@interface SentryRateLimitCategoryMapper : NSObject + +/** Maps an event type to the category for rate limiting. + */ ++ (SentryRateLimitCategory)mapEventTypeToCategory:(NSString *)eventType; + ++ (SentryRateLimitCategory)mapEnvelopeItemTypeToCategory:(NSString *)itemType; + ++ (SentryRateLimitCategory)mapIntegerToCategory:(NSUInteger)value; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryRateLimitParser.h b/Pods/Sentry/Sources/Sentry/include/SentryRateLimitParser.h new file mode 100644 index 00000000..a29e09b1 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryRateLimitParser.h @@ -0,0 +1,20 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** Parses the custom X-Sentry-Rate-Limits header. + + @discussion This header exists of a multiple quotaLimits seperated by ",". + Each quotaLimit exists of retry_after:categories:scope. + retry_after: seconds until the rate limit expires. + categories: semicolon separated list of categories. If empty, this limit + applies to all categories. scope: This can be ignored by SDKs. + */ +NS_SWIFT_NAME(RateLimitParser) +@interface SentryRateLimitParser : NSObject + +- (NSDictionary *)parse:(NSString *)header; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryRateLimits.h b/Pods/Sentry/Sources/Sentry/include/SentryRateLimits.h new file mode 100644 index 00000000..8119a10c --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryRateLimits.h @@ -0,0 +1,32 @@ +#import "SentryRateLimitCategory.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + Parses HTTP responses from the Sentry server for rate limits. + When a rate limit is reached the SDK should stop data transmission + until the rate limit has expired. +*/ +NS_SWIFT_NAME(RateLimits) +@protocol SentryRateLimits + +/** +Check if a data category has reached a rate limit. + @param category the type e.g. event, error, session, transaction, etc. + + @return BOOL YES if limit is reached, NO otherwise. + */ +- (BOOL)isRateLimitActive:(SentryRateLimitCategory)category; + +/** +Should be called for each HTTP response of the Sentry + server. It checks the response for any communicated rate limits. + + @param response The response from the server + */ +- (void)update:(NSHTTPURLResponse *)response; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryRequestManager.h b/Pods/Sentry/Sources/Sentry/include/SentryRequestManager.h new file mode 100644 index 00000000..6cc16dc8 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryRequestManager.h @@ -0,0 +1,17 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(RequestManager) +@protocol SentryRequestManager + +@property (nonatomic, readonly, getter=isReady) BOOL ready; + +- (instancetype)initWithSession:(NSURLSession *)session; + +- (void)addRequest:(NSURLRequest *)request + completionHandler:(_Nullable SentryRequestOperationFinished)completionHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryRequestOperation.h b/Pods/Sentry/Sources/Sentry/include/SentryRequestOperation.h new file mode 100644 index 00000000..33920c66 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryRequestOperation.h @@ -0,0 +1,16 @@ +#import + +#import "SentryAsynchronousOperation.h" +#import "SentryQueueableRequestManager.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryRequestOperation : SentryAsynchronousOperation + +- (instancetype)initWithSession:(NSURLSession *)session + request:(NSURLRequest *)request + completionHandler:(_Nullable SentryRequestOperationFinished)completionHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryRetryAfterHeaderParser.h b/Pods/Sentry/Sources/Sentry/include/SentryRetryAfterHeaderParser.h new file mode 100644 index 00000000..fc9c7f81 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryRetryAfterHeaderParser.h @@ -0,0 +1,27 @@ +#import + +@class SentryHttpDateParser; + +NS_ASSUME_NONNULL_BEGIN + +/** Parses value of HTTP header "Retry-After" which in most cases is sent in + combination with HTTP status 429 Too Many Requests. For more details see: + https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.37 +*/ +NS_SWIFT_NAME(RetryAfterHeaderParser) +@interface SentryRetryAfterHeaderParser : NSObject + +- (instancetype)initWithHttpDateParser:(SentryHttpDateParser *)httpDateParser; + +/** Parses the HTTP header into a NSDate. + + @param retryAfterHeader The header value. + + @return NSDate representation of Retry-After. If the date can't be parsed nil + is returned. +*/ +- (NSDate *_Nullable)parse:(NSString *_Nullable)retryAfterHeader; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentrySDK+Private.h b/Pods/Sentry/Sources/Sentry/include/SentrySDK+Private.h new file mode 100644 index 00000000..18406fdf --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentrySDK+Private.h @@ -0,0 +1,20 @@ +#import "SentrySDK.h" + +@class SentryId; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentrySDK (Private) + ++ (void)captureCrashEvent:(SentryEvent *)event; + +/** + * SDK private field to store the state if onCrashedLastRun was called. + */ +@property (nonatomic, class) BOOL crashedLastRunCalled; + ++ (SentryHub *)currentHub; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryScope+Private.h b/Pods/Sentry/Sources/Sentry/include/SentryScope+Private.h new file mode 100644 index 00000000..a6276a6b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryScope+Private.h @@ -0,0 +1,22 @@ +#import + +#import "SentryScope.h" + +@class SentryAttachment; + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^SentryScopeListener)(SentryScope *scope); + +@interface SentryScope (Private) + +@property (nonatomic, retain) NSMutableArray *listeners; + +- (void)addScopeListener:(SentryScopeListener)listener; +- (void)notifyListeners; + +@property (atomic, strong, readonly) NSArray *attachments; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentrySerialization.h b/Pods/Sentry/Sources/Sentry/include/SentrySerialization.h new file mode 100644 index 00000000..063bd189 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentrySerialization.h @@ -0,0 +1,36 @@ +#import + +#import "SentryDefines.h" + +@class SentrySession, SentryEnvelope, SentryAppState; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentrySerialization : NSObject + ++ (NSData *_Nullable)dataWithJSONObject:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error; + ++ (NSData *_Nullable)dataWithSession:(SentrySession *)session + error:(NSError *_Nullable *_Nullable)error; + ++ (SentrySession *_Nullable)sessionWithData:(NSData *)sessionData; + +// TODO: use (NSOutputStream *)outputStream ++ (NSData *_Nullable)dataWithEnvelope:(SentryEnvelope *)envelope + error:(NSError *_Nullable *_Nullable)error; + +// TODO: (NSInputStream *)inputStream ++ (SentryEnvelope *_Nullable)envelopeWithData:(NSData *)data; + ++ (SentryAppState *_Nullable)appStateWithData:(NSData *)sessionData; + +/** + * Extract the level from data of an envelopte item containing an event. Default is the 'error' + * level, see https://develop.sentry.dev/sdk/event-payloads/#optional-attributes + */ ++ (SentryLevel)levelFromData:(NSData *)eventEnvelopeItemData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentrySession+Private.h b/Pods/Sentry/Sources/Sentry/include/SentrySession+Private.h new file mode 100644 index 00000000..012d8906 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentrySession+Private.h @@ -0,0 +1,12 @@ +#import "SentrySession.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentrySession (Private) + +- (void)setFlagInit; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentrySessionCrashedHandler.h b/Pods/Sentry/Sources/Sentry/include/SentrySessionCrashedHandler.h new file mode 100644 index 00000000..97403a81 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentrySessionCrashedHandler.h @@ -0,0 +1,17 @@ +#import + +@class SentryCrashAdapter, SentryDispatchQueueWrapper, SentryOutOfMemoryLogic; + +@interface SentrySessionCrashedHandler : NSObject + +- (instancetype)initWithCrashWrapper:(SentryCrashAdapter *)crashWrapper + outOfMemoryLogic:(SentryOutOfMemoryLogic *)outOfMemoryLogic; + +/** + * When a crash happened the current session is ended as crashed, stored at a different + * location and the current session is deleted. Checkout SentryHub where most of the session logic + * is implemented for more details about sessions. + */ +- (void)endCurrentSessionAsCrashedWhenCrashOrOOM; + +@end diff --git a/Pods/Sentry/Sources/Sentry/include/SentrySessionTracker.h b/Pods/Sentry/Sources/Sentry/include/SentrySessionTracker.h new file mode 100644 index 00000000..08478ceb --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentrySessionTracker.h @@ -0,0 +1,19 @@ +#import "SentryCurrentDateProvider.h" +#import "SentryDefines.h" +#import + +@class SentryEvent, SentryOptions, SentryCurrentDateProvider; + +/** + * Tracks sessions for release health. For more info see: + * https://docs.sentry.io/workflow/releases/health/#session + */ +NS_SWIFT_NAME(SessionTracker) +@interface SentrySessionTracker : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithOptions:(SentryOptions *)options + currentDateProvider:(id)currentDateProvider; +- (void)start; +- (void)stop; +@end diff --git a/Pods/Sentry/Sources/Sentry/include/SentrySpan.h b/Pods/Sentry/Sources/Sentry/include/SentrySpan.h new file mode 100644 index 00000000..458137c0 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentrySpan.h @@ -0,0 +1,101 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" +#import "SentrySpanContext.h" +#import "SentrySpanProtocol.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@class SentryTracer; + +NS_SWIFT_NAME(Span) +@interface SentrySpan : NSObject +SENTRY_NO_INIT + +/** + * The context information of the span. + */ +@property (nonatomic, readonly) SentrySpanContext *context; + +/** + * The timestamp of which the span ended. + */ +@property (nullable, nonatomic, strong) NSDate *timestamp; + +/** + * The start time of the span. + */ +@property (nullable, nonatomic, strong) NSDate *startTimestamp; + +/** + * An arbitrary mapping of additional metadata of the span. + */ +@property (nullable, readonly) NSDictionary *data; + +/** + * Whether the span is finished. + */ +@property (readonly) BOOL isFinished; + +/** + * Init a SentrySpan with given tracer and context. + * + * @param tracer The tracer responsible for this span. + * @param context This span context information. + * + * @return SentrySpan + */ +- (instancetype)initWithTracer:(SentryTracer *)tracer context:(SentrySpanContext *)context; + +/** + * Init a SentrySpan with given context. + * + * @param context This span context information. + * + * @return SentrySpan + */ +- (instancetype)initWithContext:(SentrySpanContext *)context; + +/** + * Starts a child span. + * + * @param operation Short code identifying the type of operation the span is measuring. + * + * @return SentrySpan + */ +- (id)startChildWithOperation:(NSString *)operation + NS_SWIFT_NAME(startChild(operation:)); + +/** + * Starts a child span. + * + * @param operation Defines the child span operation. + * @param description Define the child span description. + * + * @return SentrySpan + */ +- (id)startChildWithOperation:(NSString *)operation + description:(nullable NSString *)description + NS_SWIFT_NAME(startChild(operation:description:)); + +/** + * Sets an extra. + */ +- (void)setDataValue:(nullable id)value + forKey:(NSString *)key NS_SWIFT_NAME(setExtra(value:key:)); + +/** + * Finishes the span by setting the end time. + */ +- (void)finish; + +/** + * Finishes the span by setting the end time and span status. + * + * @param status The status of this span + */ +- (void)finishWithStatus:(SentrySpanStatus)status NS_SWIFT_NAME(finish(status:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryStacktraceBuilder.h b/Pods/Sentry/Sources/Sentry/include/SentryStacktraceBuilder.h new file mode 100644 index 00000000..706ea505 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryStacktraceBuilder.h @@ -0,0 +1,25 @@ +#import "SentryDefines.h" +#import + +@class SentryStacktrace, SentryFrameRemover, SentryCrashStackEntryMapper; + +NS_ASSUME_NONNULL_BEGIN + +/** Uses SentryCrash internally to retrieve the stacktrace. + */ +@interface SentryStacktraceBuilder : NSObject +SENTRY_NO_INIT + +- (id)initWithCrashStackEntryMapper:(SentryCrashStackEntryMapper *)crashStackEntryMapper; + +/** + * Builds the stacktrace for the current thread removing frames from the SentrySDK until frames from + * a different package are found. When including Sentry via the Swift Package Manager the package is + * the same as the application that includes Sentry. In this case the full stacktrace is returned + * without skipping frames. + */ +- (SentryStacktrace *)buildStacktraceForCurrentThread; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentrySwizzle.h b/Pods/Sentry/Sources/Sentry/include/SentrySwizzle.h new file mode 100644 index 00000000..bb8f0019 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentrySwizzle.h @@ -0,0 +1,380 @@ +#import + +#pragma mark - Macros Based API + +/// A macro for wrapping the return type of the swizzled method. +#define SentrySWReturnType(type) type + +/// A macro for wrapping arguments of the swizzled method. +#define SentrySWArguments(arguments...) _SentrySWArguments(arguments) + +/// A macro for wrapping the replacement code for the swizzled method. +#define SentrySWReplacement(code...) code + +/// A macro for casting and calling original implementation. +/// May be used only in SentrySwizzleInstanceMethod or SentrySwizzleClassMethod +/// macros. +#define SentrySWCallOriginal(arguments...) _SentrySWCallOriginal(arguments) + +#pragma mark └ Swizzle Instance Method + +/** + Swizzles the instance method of the class with the new implementation. + + Example for swizzling `-(int)calculate:(int)number;` method: + + @code + + SentrySwizzleInstanceMethod(classToSwizzle, + @selector(calculate:), + SentrySWReturnType(int), + SentrySWArguments(int number), + SentrySWReplacement( + { + // Calling original implementation. + int res = SentrySWCallOriginal(number); + // Returning modified return value. + return res + 1; + }), 0, NULL); + + @endcode + + Swizzling frequently goes along with checking whether this particular class (or + one of its superclasses) has been already swizzled. Here the + `SentrySwizzleMode` and `key` parameters can help. See +[SentrySwizzle + swizzleInstanceMethod:inClass:newImpFactory:mode:key:] for details. + + Swizzling is fully thread-safe. + + @param classToSwizzle The class with the method that should be swizzled. + + @param selector Selector of the method that should be swizzled. + + @param SentrySWReturnType The return type of the swizzled method wrapped in the + SentrySWReturnType macro. + + @param SentrySWArguments The arguments of the swizzled method wrapped in the + SentrySWArguments macro. + + @param SentrySWReplacement The code of the new implementation of the swizzled + method wrapped in the SentrySWReplacement macro. + + @param SentrySwizzleMode The mode is used in combination with the key to + indicate whether the swizzling should be done for the given class. You can pass + 0 for SentrySwizzleModeAlways. + + @param key The key is used in combination with the mode to indicate whether the + swizzling should be done for the given class. May be NULL if the mode is + SentrySwizzleModeAlways. + + @return YES if successfully swizzled and NO if swizzling has been already done + for given key and class (or one of superclasses, depends on the mode). + + */ +#define SentrySwizzleInstanceMethod(classToSwizzle, selector, SentrySWReturnType, \ + SentrySWArguments, SentrySWReplacement, SentrySwizzleMode, key) \ + _SentrySwizzleInstanceMethod(classToSwizzle, selector, SentrySWReturnType, \ + _SentrySWWrapArg(SentrySWArguments), _SentrySWWrapArg(SentrySWReplacement), \ + SentrySwizzleMode, key) + +#pragma mark └ Swizzle Class Method + +/** + Swizzles the class method of the class with the new implementation. + + Example for swizzling `+(int)calculate:(int)number;` method: + + @code + + SentrySwizzleClassMethod(classToSwizzle, + @selector(calculate:), + SentrySWReturnType(int), + SentrySWArguments(int number), + SentrySWReplacement( + { + // Calling original implementation. + int res = SentrySWCallOriginal(number); + // Returning modified return value. + return res + 1; + })); + + @endcode + + Swizzling is fully thread-safe. + + @param classToSwizzle The class with the method that should be swizzled. + + @param selector Selector of the method that should be swizzled. + + @param SentrySWReturnType The return type of the swizzled method wrapped in the + SentrySWReturnType macro. + + @param SentrySWArguments The arguments of the swizzled method wrapped in the + SentrySWArguments macro. + + @param SentrySWReplacement The code of the new implementation of the swizzled + method wrapped in the SentrySWReplacement macro. + + */ +#define SentrySwizzleClassMethod( \ + classToSwizzle, selector, SentrySWReturnType, SentrySWArguments, SentrySWReplacement) \ + _SentrySwizzleClassMethod(classToSwizzle, selector, SentrySWReturnType, \ + _SentrySWWrapArg(SentrySWArguments), _SentrySWWrapArg(SentrySWReplacement)) + +#pragma mark - Main API + +/** + A function pointer to the original implementation of the swizzled method. + */ +typedef void (*SentrySwizzleOriginalIMP)(void /* id, SEL, ... */); + +/** + SentrySwizzleInfo is used in the new implementation block to get and call + original implementation of the swizzled method. + */ +@interface SentrySwizzleInfo : NSObject + +/** + Returns the original implementation of the swizzled method. + + It is actually either an original implementation if the swizzled class + implements the method itself; or a super implementation fetched from one of the + superclasses. + + @note You must always cast returned implementation to the appropriate function + pointer when calling. + + @return A function pointer to the original implementation of the swizzled + method. + */ +- (SentrySwizzleOriginalIMP)getOriginalImplementation; + +/// The selector of the swizzled method. +@property (nonatomic, readonly) SEL selector; + +@end + +/** + A factory block returning the block for the new implementation of the swizzled + method. + + You must always obtain original implementation with swizzleInfo and call it + from the new implementation. + + @param swizzleInfo An info used to get and call the original implementation of + the swizzled method. + + @return A block that implements a method. + Its signature should be: `method_return_type ^(id self, method_args...)`. + The selector is not available as a parameter to this block. + */ +typedef id (^SentrySwizzleImpFactoryBlock)(SentrySwizzleInfo *swizzleInfo); + +typedef NS_ENUM(NSUInteger, SentrySwizzleMode) { + /// SentrySwizzle always does swizzling. + SentrySwizzleModeAlways = 0, + /// SentrySwizzle does not do swizzling if the same class has been swizzled + /// earlier with the same key. + SentrySwizzleModeOncePerClass = 1, + /// SentrySwizzle does not do swizzling if the same class or one of its + /// superclasses have been swizzled earlier with the same key. + /// @note There is no guarantee that your implementation will be called only + /// once per method call. If the order of swizzling is: first inherited + /// class, second superclass, then both swizzlings will be done and the new + /// implementation will be called twice. + SentrySwizzleModeOncePerClassAndSuperclasses = 2 +}; + +@interface SentrySwizzle : NSObject + +#pragma mark └ Swizzle Instance Method + +/** + Swizzles the instance method of the class with the new implementation. + + Original implementation must always be called from the new implementation. And + because of the the fact that for safe and robust swizzling original + implementation must be dynamically fetched at the time of calling and not at + the time of swizzling, swizzling API is a little bit complicated. + + You should pass a factory block that returns the block for the new + implementation of the swizzled method. And use swizzleInfo argument to retrieve + and call original implementation. + + Example for swizzling `-(int)calculate:(int)number;` method: + + @code + + SEL selector = @selector(calculate:); + [SentrySwizzle + swizzleInstanceMethod:selector + inClass:classToSwizzle + newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + // This block will be used as the new implementation. + return ^int(__unsafe_unretained id self, int num){ + // You MUST always cast implementation to the correct function + pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = + (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; + // Calling original implementation. + int res = originalIMP(self,selector,num); + // Returning modified return value. + return res + 1; + }; + } + mode:SentrySwizzleModeAlways + key:NULL]; + + @endcode + + Swizzling frequently goes along with checking whether this particular class (or + one of its superclasses) has been already swizzled. Here the `mode` and `key` + parameters can help. + + Here is an example of swizzling `-(void)dealloc;` only in case when neither + class and no one of its superclasses has been already swizzled with our key. + However "Deallocating ..." message still may be logged multiple times per + method call if swizzling was called primarily for an inherited class and later + for one of its superclasses. + + @code + + static const void *key = &key; + SEL selector = NSSelectorFromString(@"dealloc"); + [SentrySwizzle + swizzleInstanceMethod:selector + inClass:classToSwizzle + newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + return ^void(__unsafe_unretained id self){ + NSLog(@"Deallocating %@.",self); + + void (*originalIMP)(__unsafe_unretained id, SEL); + originalIMP = (__typeof(originalIMP))[swizzleInfo + getOriginalImplementation]; originalIMP(self,selector); + }; + } + mode:SentrySwizzleModeOncePerClassAndSuperclasses + key:key]; + + @endcode + + Swizzling is fully thread-safe. + + @param selector Selector of the method that should be swizzled. + + @param classToSwizzle The class with the method that should be swizzled. + + @param factoryBlock The factory block returning the block for the new + implementation of the swizzled method. + + @param mode The mode is used in combination with the key to indicate whether + the swizzling should be done for the given class. + + @param key The key is used in combination with the mode to indicate whether the + swizzling should be done for the given class. May be NULL if the mode is + SentrySwizzleModeAlways. + + @return YES if successfully swizzled and NO if swizzling has been already done + for given key and class (or one of superclasses, depends on the mode). + */ ++ (BOOL)swizzleInstanceMethod:(SEL)selector + inClass:(Class)classToSwizzle + newImpFactory:(SentrySwizzleImpFactoryBlock)factoryBlock + mode:(SentrySwizzleMode)mode + key:(const void *)key; + +#pragma mark └ Swizzle Class method + +/** + Swizzles the class method of the class with the new implementation. + + Original implementation must always be called from the new implementation. And + because of the the fact that for safe and robust swizzling original + implementation must be dynamically fetched at the time of calling and not at + the time of swizzling, swizzling API is a little bit complicated. + + You should pass a factory block that returns the block for the new + implementation of the swizzled method. And use swizzleInfo argument to retrieve + and call original implementation. + + Example for swizzling `+(int)calculate:(int)number;` method: + + @code + + SEL selector = @selector(calculate:); + [SentrySwizzle + swizzleClassMethod:selector + inClass:classToSwizzle + newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + // This block will be used as the new implementation. + return ^int(__unsafe_unretained id self, int num){ + // You MUST always cast implementation to the correct function + pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = + (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; + // Calling original implementation. + int res = originalIMP(self,selector,num); + // Returning modified return value. + return res + 1; + }; + }]; + + @endcode + + Swizzling is fully thread-safe. + + @param selector Selector of the method that should be swizzled. + + @param classToSwizzle The class with the method that should be swizzled. + + @param factoryBlock The factory block returning the block for the new + implementation of the swizzled method. + */ ++ (void)swizzleClassMethod:(SEL)selector + inClass:(Class)classToSwizzle + newImpFactory:(SentrySwizzleImpFactoryBlock)factoryBlock; + +@end + +#pragma mark - Implementation details +// Do not write code that depends on anything below this line. + +// Wrapping arguments to pass them as a single argument to another macro. +#define _SentrySWWrapArg(args...) args + +#define _SentrySWDel2Arg(a1, a2, args...) a1, ##args +#define _SentrySWDel3Arg(a1, a2, a3, args...) a1, a2, ##args + +// To prevent comma issues if there are no arguments we add one dummy argument +// and remove it later. +#define _SentrySWArguments(arguments...) DEL, ##arguments + +#define _SentrySwizzleInstanceMethod(classToSwizzle, selector, SentrySWReturnType, \ + SentrySWArguments, SentrySWReplacement, SentrySwizzleMode, KEY) \ + [SentrySwizzle \ + swizzleInstanceMethod:selector \ + inClass:[classToSwizzle class] \ + newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { \ + SentrySWReturnType (*originalImplementation_)( \ + _SentrySWDel3Arg(__unsafe_unretained id, SEL, SentrySWArguments)); \ + SEL selector_ = selector; \ + return ^SentrySWReturnType(_SentrySWDel2Arg( \ + __unsafe_unretained id self, SentrySWArguments)) { SentrySWReplacement }; \ + } \ + mode:SentrySwizzleMode \ + key:KEY]; + +#define _SentrySwizzleClassMethod( \ + classToSwizzle, selector, SentrySWReturnType, SentrySWArguments, SentrySWReplacement) \ + [SentrySwizzle \ + swizzleClassMethod:selector \ + inClass:[classToSwizzle class] \ + newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { \ + SentrySWReturnType (*originalImplementation_)( \ + _SentrySWDel3Arg(__unsafe_unretained id, SEL, SentrySWArguments)); \ + SEL selector_ = selector; \ + return ^SentrySWReturnType(_SentrySWDel2Arg( \ + __unsafe_unretained id self, SentrySWArguments)) { SentrySWReplacement }; \ + }]; + +#define _SentrySWCallOriginal(arguments...) \ + ((__typeof(originalImplementation_))[swizzleInfo getOriginalImplementation])( \ + self, selector_, ##arguments) diff --git a/Pods/Sentry/Sources/Sentry/include/SentrySystemEventsBreadcrumbs.h b/Pods/Sentry/Sources/Sentry/include/SentrySystemEventsBreadcrumbs.h new file mode 100644 index 00000000..8ce6474b --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentrySystemEventsBreadcrumbs.h @@ -0,0 +1,17 @@ +#import + +#if TARGET_OS_IOS +# import +#endif + +@interface SentrySystemEventsBreadcrumbs : NSObject + +- (void)start; + +#if TARGET_OS_IOS +- (void)start:(UIDevice *)currentDevice; +#endif + +- (void)stop; + +@end diff --git a/Pods/Sentry/Sources/Sentry/include/SentryThreadInspector.h b/Pods/Sentry/Sources/Sentry/include/SentryThreadInspector.h new file mode 100644 index 00000000..258421a9 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryThreadInspector.h @@ -0,0 +1,23 @@ +#import "SentryCrashMachineContextWrapper.h" +#import "SentryDefines.h" +#import + +@class SentryThread, SentryStacktraceBuilder; + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryThreadInspector : NSObject +SENTRY_NO_INIT + +- (id)initWithStacktraceBuilder:(SentryStacktraceBuilder *)stacktraceBuilder + andMachineContextWrapper:(id)machineContextWrapper; + +/** + * Gets current threads with the stacktrace only for the current thread. Frames from the SentrySDK + * are not included. For more details checkout SentryStacktraceBuilder. + */ +- (NSArray *)getCurrentThreads; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryTracer.h b/Pods/Sentry/Sources/Sentry/include/SentryTracer.h new file mode 100644 index 00000000..f360a3d0 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryTracer.h @@ -0,0 +1,107 @@ +#import "SentrySpanProtocol.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@class SentryHub, SentryTransactionContext; + +@interface SentryTracer : NSObject + +/** + *Span name. + */ +@property (nonatomic, copy) NSString *name; + +/** + * The context information of the span. + */ +@property (nonatomic, readonly) SentrySpanContext *context; + +/** + * The timestamp of which the span ended. + */ +@property (nullable, nonatomic, strong) NSDate *timestamp; + +/** + * The start time of the span. + */ +@property (nullable, nonatomic, strong) NSDate *startTimestamp; + +/** + * An arbitrary mapping of additional metadata of the span. + */ +@property (nullable, readonly) NSDictionary *data; + +/** + * Whether the span is finished. + */ +@property (readonly) BOOL isFinished; + +/** + * Init a SentryTransaction with given transaction context and hub and set other fields by default + * + * @param transactionContext Transaction context + * @param hub A hub to bind this transaction + * + * @return SentryTransaction + */ +- (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext + hub:(nullable SentryHub *)hub; + +/** + * Starts a child span. + * + * @param operation Short code identifying the type of operation the span is measuring. + * + * @return SentrySpan + */ +- (id)startChildWithOperation:(NSString *)operation + NS_SWIFT_NAME(startChild(operation:)); + +/** + * Starts a child span. + * + * @param operation Defines the child span operation. + * @param description Define the child span description. + * + * @return SentrySpan + */ +- (id)startChildWithOperation:(NSString *)operation + description:(nullable NSString *)description + NS_SWIFT_NAME(startChild(operation:description:)); + +/** + * Starts a child span. + * + * @param parentId The child span parent id. + * @param operation The child span operation. + * @param description The child span description. + * + * @return SentrySpan + */ +- (id)startChildWithParentId:(SentrySpanId *)parentId + operation:(NSString *)operation + description:(nullable NSString *)description + NS_SWIFT_NAME(startChild(parentId:operation:description:)); + +/** + * Sets an extra. + */ +- (void)setDataValue:(nullable id)value + forKey:(NSString *)key NS_SWIFT_NAME(setExtra(value:key:)); + +/** + * Finishes the transaction by setting the end time and capturing the transaction with binded hub. + */ +- (void)finish; + +/** + * Finishes the span by setting the end time and span status. + * + * @param status The status of this span + */ +- (void)finishWithStatus:(SentrySpanStatus)status NS_SWIFT_NAME(finish(status:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryTransaction.h b/Pods/Sentry/Sources/Sentry/include/SentryTransaction.h new file mode 100644 index 00000000..2294916c --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryTransaction.h @@ -0,0 +1,13 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(Transaction) +@interface SentryTransaction : SentryEvent +SENTRY_NO_INIT + +- (instancetype)initWithTrace:(id)trace children:(NSArray> *)children; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryTransport.h b/Pods/Sentry/Sources/Sentry/include/SentryTransport.h new file mode 100644 index 00000000..c8db7580 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryTransport.h @@ -0,0 +1,25 @@ +#import + +@class SentryEnvelope, SentryEvent, SentrySession, SentryUserFeedback, SentryAttachment; + +NS_ASSUME_NONNULL_BEGIN + +// TODO: align with unified SDK api +NS_SWIFT_NAME(Transport) +@protocol SentryTransport + +- (void)sendEvent:(SentryEvent *)event + attachments:(NSArray *)attachments + NS_SWIFT_NAME(send(event:attachments:)); + +- (void)sendEvent:(SentryEvent *)event + withSession:(SentrySession *)session + attachments:(NSArray *)attachments; + +- (void)sendUserFeedback:(SentryUserFeedback *)userFeedback NS_SWIFT_NAME(send(userFeedback:)); + +- (void)sendEnvelope:(SentryEnvelope *)envelope NS_SWIFT_NAME(send(envelope:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/SentryTransportFactory.h b/Pods/Sentry/Sources/Sentry/include/SentryTransportFactory.h new file mode 100644 index 00000000..3170a2f0 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/SentryTransportFactory.h @@ -0,0 +1,17 @@ +#import + +#import "SentryTransport.h" + +@class SentryOptions, SentryFileManager; + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(TransportInitializer) +@interface SentryTransportFactory : NSObject + ++ (id)initTransport:(SentryOptions *)options + sentryFileManager:(SentryFileManager *)sentryFileManager; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/Sentry/include/TracesSampler.h b/Pods/Sentry/Sources/Sentry/include/TracesSampler.h new file mode 100644 index 00000000..841802b0 --- /dev/null +++ b/Pods/Sentry/Sources/Sentry/include/TracesSampler.h @@ -0,0 +1,36 @@ +#import "SentryRandom.h" +#import "SentrySampleDecision.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@class SentryOptions, SentrySamplingContext; + +@interface TracesSampler : NSObject + +/** + * A random number generator + */ +@property (nonatomic, strong) id random; + +/** + * Init a TracesSampler with given options and random generator. + * @param options Sentry options with sampling configuration + * @param random A random number generator + */ +- (instancetype)initWithOptions:(SentryOptions *)options random:(id)random; + +/** + * Init a TracesSampler with given options and a default Random generator. + * @param options Sentry options with sampling configuration + */ +- (instancetype)initWithOptions:(SentryOptions *)options; + +/** + * Determines whether a trace should be sampled based on the context and options. + */ +- (SentrySampleDecision)sample:(SentrySamplingContext *)context; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation+Private.h b/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation+Private.h new file mode 100644 index 00000000..95da4946 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation+Private.h @@ -0,0 +1,87 @@ +// +// SentryCrashReportFieldProperties.h +// +// Created by Karl Stenerud on 2013-02-10. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashInstallation.h" + +/** Implement a property to be used as a "key". */ +#define IMPLEMENT_REPORT_KEY_PROPERTY(NAME, NAMEUPPER) \ + @synthesize NAME##Key = _##NAME##Key; \ + -(void)set##NAMEUPPER##Key : (NSString *)value \ + { \ + _##NAME##Key; \ + _##NAME##Key = value; \ + [self reportFieldForProperty:@ #NAME setKey:value]; \ + } + +/** Implement a property to be used as a "value". */ +#define IMPLEMENT_REPORT_VALUE_PROPERTY(NAME, NAMEUPPER, TYPE) \ + @synthesize NAME = _##NAME; \ + -(void)set##NAMEUPPER : (TYPE)value \ + { \ + _##NAME; \ + _##NAME = value; \ + [self reportFieldForProperty:@ #NAME setValue:value]; \ + } + +/** Implement a standard report property (with key and value properties) */ +#define IMPLEMENT_REPORT_PROPERTY(NAME, NAMEUPPER, TYPE) \ + IMPLEMENT_REPORT_VALUE_PROPERTY(NAME, NAMEUPPER, TYPE) \ + IMPLEMENT_REPORT_KEY_PROPERTY(NAME, NAMEUPPER) + +@interface +SentryCrashInstallation () + +/** Initializer. + * + * @param requiredProperties Properties that MUST be set when sending reports. + */ +- (id)initWithRequiredProperties:(NSArray *)requiredProperties; + +/** Set the key to be used for the specified report property. + * + * @param propertyName The name of the property. + * @param key The key to use. + */ +- (void)reportFieldForProperty:(NSString *)propertyName setKey:(id)key; + +/** Set the value of the specified report property. + * + * @param propertyName The name of the property. + * @param value The value to set. + */ +- (void)reportFieldForProperty:(NSString *)propertyName setValue:(id)value; + +/** Create a new sink. Subclasses must implement this. + */ +- (id)sink; + +/** Make an absolute key path if the specified path is not already absolute. */ +- (NSString *)makeKeyPath:(NSString *)keyPath; + +/** Make an absolute key paths from the specified paths. */ +- (NSArray *)makeKeyPaths:(NSArray *)keyPaths; + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation.h b/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation.h new file mode 100644 index 00000000..98f786b9 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation.h @@ -0,0 +1,71 @@ +// +// SentryCrashInstallation.h +// +// Created by Karl Stenerud on 2013-02-10. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashReportFilter.h" +#import "SentryCrashReportWriter.h" +#import + +/** + * Crash system installation which handles backend-specific details. + * + * Only one installation can be installed at a time. + * + * This is an abstract class. + */ +@interface SentryCrashInstallation : NSObject + +/** C Function to call during a crash report to give the callee an opportunity + * to add to the report. NULL = ignore. + * + * WARNING: Only call async-safe functions from this function! DO NOT call + * Objective-C methods!!! + */ +@property (atomic, readwrite, assign) SentryCrashReportWriteCallback onCrash; + +/** Install this installation. Call this instead of -[SentryCrash install] to + * install with everything needed for your particular backend. + */ +- (void)install; + +/** Convenience method to call -[SentryCrash sendAllReportsWithCompletion:]. + * This method will set the SentryCrash sink and then send all outstanding + * reports. + * + * Note: Pay special attention to SentryCrash's "deleteBehaviorAfterSendAll" + * property. + * + * @param onCompletion Called when sending is complete (nil = ignore). + */ +- (void)sendAllReportsWithCompletion:(SentryCrashReportFilterCompletion)onCompletion; + +/** Add a filter that gets executed before all normal filters. + * Prepended filters will be executed in the order in which they were added. + * + * @param filter the filter to prepend. + */ +- (void)addPreFilter:(id)filter; + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation.m b/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation.m new file mode 100644 index 00000000..6bc479ee --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Installations/SentryCrashInstallation.m @@ -0,0 +1,338 @@ +// +// SentryCrashInstallation.m +// +// Created by Karl Stenerud on 2013-02-10. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashInstallation.h" +#import "NSError+SentrySimpleConstructor.h" +#import "SentryCrash.h" +#import "SentryCrashCString.h" +#import "SentryCrashInstallation+Private.h" +#import "SentryCrashJSONCodecObjC.h" +#import "SentryCrashLogger.h" +#import "SentryCrashReportFilterBasic.h" +#import + +/** Max number of properties that can be defined for writing to the report */ +#define kMaxProperties 500 + +typedef struct { + const char *key; + const char *value; +} ReportField; + +typedef struct { + SentryCrashReportWriteCallback userCrashCallback; + int reportFieldsCount; + ReportField *reportFields[0]; +} CrashHandlerData; + +static CrashHandlerData *g_crashHandlerData; + +static void +crashCallback(const SentryCrashReportWriter *writer) +{ + for (int i = 0; i < g_crashHandlerData->reportFieldsCount; i++) { + ReportField *field = g_crashHandlerData->reportFields[i]; + if (field->key != NULL && field->value != NULL) { + writer->addJSONElement(writer, field->key, field->value, true); + } + } + if (g_crashHandlerData->userCrashCallback != NULL) { + g_crashHandlerData->userCrashCallback(writer); + } +} + +@interface SentryCrashInstReportField : NSObject + +@property (nonatomic, readonly, assign) int index; +@property (nonatomic, readonly, assign) ReportField *field; + +@property (nonatomic, readwrite, retain) NSString *key; +@property (nonatomic, readwrite, retain) id value; + +@property (nonatomic, readwrite, retain) NSMutableData *fieldBacking; +@property (nonatomic, readwrite, retain) SentryCrashCString *keyBacking; +@property (nonatomic, readwrite, retain) SentryCrashCString *valueBacking; + +@end + +@implementation SentryCrashInstReportField + +@synthesize index = _index; +@synthesize key = _key; +@synthesize value = _value; +@synthesize fieldBacking = _fieldBacking; +@synthesize keyBacking = _keyBacking; +@synthesize valueBacking = _valueBacking; + ++ (SentryCrashInstReportField *)fieldWithIndex:(int)index +{ + return [(SentryCrashInstReportField *)[self alloc] initWithIndex:index]; +} + +- (id)initWithIndex:(int)index +{ + if ((self = [super init])) { + _index = index; + self.fieldBacking = [NSMutableData dataWithLength:sizeof(*self.field)]; + } + return self; +} + +- (ReportField *)field +{ + return (ReportField *)self.fieldBacking.mutableBytes; +} + +- (void)setKey:(NSString *)key +{ + _key = key; + if (key == nil) { + self.keyBacking = nil; + } else { + self.keyBacking = [SentryCrashCString stringWithString:key]; + } + self.field->key = self.keyBacking.bytes; +} + +- (void)setValue:(id)value +{ + if (value == nil) { + _value = nil; + self.valueBacking = nil; + return; + } + + NSError *error = nil; + NSData *jsonData = [SentryCrashJSONCodec + encode:value + options:SentryCrashJSONEncodeOptionPretty | SentryCrashJSONEncodeOptionSorted + error:&error]; + if (jsonData == nil) { + SentryCrashLOG_ERROR(@"Could not set value %@ for property %@: %@", value, self.key, error); + } else { + _value = value; + self.valueBacking = [SentryCrashCString stringWithData:jsonData]; + self.field->value = self.valueBacking.bytes; + } +} + +@end + +@interface +SentryCrashInstallation () + +@property (nonatomic, readwrite, assign) int nextFieldIndex; +@property (nonatomic, readonly, assign) CrashHandlerData *crashHandlerData; +@property (nonatomic, readwrite, retain) NSMutableData *crashHandlerDataBacking; +@property (nonatomic, readwrite, retain) NSMutableDictionary *fields; +@property (nonatomic, readwrite, retain) NSArray *requiredProperties; +@property (nonatomic, readwrite, retain) SentryCrashReportFilterPipeline *prependedFilters; + +@end + +@implementation SentryCrashInstallation + +@synthesize nextFieldIndex = _nextFieldIndex; +@synthesize crashHandlerDataBacking = _crashHandlerDataBacking; +@synthesize fields = _fields; +@synthesize requiredProperties = _requiredProperties; +@synthesize prependedFilters = _prependedFilters; + +- (id)init +{ + [NSException raise:NSInternalInconsistencyException + format:@"%@ does not support init. Subclasses must call " + @"initWithMaxReportFieldCount:requiredProperties:", + [self class]]; + return nil; +} + +- (id)initWithRequiredProperties:(NSArray *)requiredProperties +{ + if ((self = [super init])) { + self.crashHandlerDataBacking = + [NSMutableData dataWithLength:sizeof(*self.crashHandlerData) + + sizeof(*self.crashHandlerData->reportFields) * kMaxProperties]; + self.fields = [NSMutableDictionary dictionary]; + self.requiredProperties = requiredProperties; + self.prependedFilters = [SentryCrashReportFilterPipeline filterWithFilters:nil]; + } + return self; +} + +- (void)dealloc +{ + SentryCrash *handler = [SentryCrash sharedInstance]; + @synchronized(handler) { + if (g_crashHandlerData == self.crashHandlerData) { + g_crashHandlerData = NULL; + handler.onCrash = NULL; + } + } +} + +- (CrashHandlerData *)crashHandlerData +{ + return (CrashHandlerData *)self.crashHandlerDataBacking.mutableBytes; +} + +- (SentryCrashInstReportField *)reportFieldForProperty:(NSString *)propertyName +{ + SentryCrashInstReportField *field = [self.fields objectForKey:propertyName]; + if (field == nil) { + field = [SentryCrashInstReportField fieldWithIndex:self.nextFieldIndex]; + self.nextFieldIndex++; + self.crashHandlerData->reportFieldsCount = self.nextFieldIndex; + self.crashHandlerData->reportFields[field.index] = field.field; + [self.fields setObject:field forKey:propertyName]; + } + return field; +} + +- (void)reportFieldForProperty:(NSString *)propertyName setKey:(id)key +{ + SentryCrashInstReportField *field = [self reportFieldForProperty:propertyName]; + field.key = key; +} + +- (void)reportFieldForProperty:(NSString *)propertyName setValue:(id)value +{ + SentryCrashInstReportField *field = [self reportFieldForProperty:propertyName]; + field.value = value; +} + +- (NSError *)validateProperties +{ + NSMutableString *errors = [NSMutableString string]; + for (NSString *propertyName in self.requiredProperties) { + NSString *nextError = nil; + @try { + id value = [self valueForKey:propertyName]; + if (value == nil) { + nextError = @"is nil"; + } + } @catch (NSException *exception) { + nextError = @"property not found"; + } + if (nextError != nil) { + if ([errors length] > 0) { + [errors appendString:@", "]; + } + [errors appendFormat:@"%@ (%@)", propertyName, nextError]; + } + } + if ([errors length] > 0) { + return [NSError + sentryErrorWithDomain:[[self class] description] + code:0 + description:@"Installation properties failed validation: %@", errors]; + } + return nil; +} + +- (NSString *)makeKeyPath:(NSString *)keyPath +{ + if ([keyPath length] == 0) { + return keyPath; + } + BOOL isAbsoluteKeyPath = [keyPath length] > 0 && [keyPath characterAtIndex:0] == '/'; + return isAbsoluteKeyPath ? keyPath : [@"user/" stringByAppendingString:keyPath]; +} + +- (NSArray *)makeKeyPaths:(NSArray *)keyPaths +{ + if ([keyPaths count] == 0) { + return keyPaths; + } + NSMutableArray *result = [NSMutableArray arrayWithCapacity:[keyPaths count]]; + for (NSString *keyPath in keyPaths) { + [result addObject:[self makeKeyPath:keyPath]]; + } + return result; +} + +- (SentryCrashReportWriteCallback)onCrash +{ + @synchronized(self) { + return self.crashHandlerData->userCrashCallback; + } +} + +- (void)setOnCrash:(SentryCrashReportWriteCallback)onCrash +{ + @synchronized(self) { + self.crashHandlerData->userCrashCallback = onCrash; + } +} + +- (void)install +{ + SentryCrash *handler = [SentryCrash sharedInstance]; + @synchronized(handler) { + g_crashHandlerData = self.crashHandlerData; + handler.onCrash = crashCallback; + [handler install]; + } +} + +- (void)sendAllReportsWithCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSError *error = [self validateProperties]; + if (error != nil) { + if (onCompletion != nil) { + onCompletion(nil, NO, error); + } + return; + } + + id sink = [self sink]; + if (sink == nil) { + onCompletion(nil, NO, + [NSError sentryErrorWithDomain:[[self class] description] + code:0 + description:@"Sink was nil (subclasses must implement " + @"method \"sink\")"]); + return; + } + + sink = [SentryCrashReportFilterPipeline filterWithFilters:self.prependedFilters, sink, nil]; + + SentryCrash *handler = [SentryCrash sharedInstance]; + handler.sink = sink; + [handler sendAllReportsWithCompletion:onCompletion]; +} + +- (void)addPreFilter:(id)filter +{ + [self.prependedFilters addFilter:filter]; +} + +- (id)sink +{ + return nil; +} + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c new file mode 100644 index 00000000..cb28136a --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c @@ -0,0 +1,251 @@ +// +// SentryCrashMonitor.c +// +// Created by Karl Stenerud on 2012-02-12. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMonitor.h" +#include "SentryCrashMonitorContext.h" +#include "SentryCrashMonitorType.h" + +#include "SentryCrashDebug.h" +#include "SentryCrashMonitor_AppState.h" +#include "SentryCrashMonitor_CPPException.h" +#include "SentryCrashMonitor_Deadlock.h" +#include "SentryCrashMonitor_MachException.h" +#include "SentryCrashMonitor_NSException.h" +#include "SentryCrashMonitor_Signal.h" +#include "SentryCrashMonitor_System.h" +#include "SentryCrashMonitor_User.h" +#include "SentryCrashMonitor_Zombie.h" +#include "SentryCrashSystemCapabilities.h" +#include "SentryCrashThread.h" + +#include + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +// ============================================================================ +#pragma mark - Globals - +// ============================================================================ + +typedef struct { + SentryCrashMonitorType monitorType; + SentryCrashMonitorAPI *(*getAPI)(void); +} Monitor; + +static Monitor g_monitors[] = { +#if SentryCrashCRASH_HAS_MACH + { + .monitorType = SentryCrashMonitorTypeMachException, + .getAPI = sentrycrashcm_machexception_getAPI, + }, +#endif +#if SentryCrashCRASH_HAS_SIGNAL + { + .monitorType = SentryCrashMonitorTypeSignal, + .getAPI = sentrycrashcm_signal_getAPI, + }, +#endif +#if SentryCrashCRASH_HAS_OBJC + { + .monitorType = SentryCrashMonitorTypeNSException, + .getAPI = sentrycrashcm_nsexception_getAPI, + }, + { + .monitorType = SentryCrashMonitorTypeMainThreadDeadlock, + .getAPI = sentrycrashcm_deadlock_getAPI, + }, + { + .monitorType = SentryCrashMonitorTypeZombie, + .getAPI = sentrycrashcm_zombie_getAPI, + }, +#endif + { + .monitorType = SentryCrashMonitorTypeCPPException, + .getAPI = sentrycrashcm_cppexception_getAPI, + }, + { + .monitorType = SentryCrashMonitorTypeUserReported, + .getAPI = sentrycrashcm_user_getAPI, + }, + { + .monitorType = SentryCrashMonitorTypeSystem, + .getAPI = sentrycrashcm_system_getAPI, + }, + { + .monitorType = SentryCrashMonitorTypeApplicationState, + .getAPI = sentrycrashcm_appstate_getAPI, + }, +}; +static int g_monitorsCount = sizeof(g_monitors) / sizeof(*g_monitors); + +static SentryCrashMonitorType g_activeMonitors = SentryCrashMonitorTypeNone; + +static bool g_handlingFatalException = false; +static bool g_crashedDuringExceptionHandling = false; +static bool g_requiresAsyncSafety = false; + +static void (*g_onExceptionEvent)(struct SentryCrash_MonitorContext *monitorContext); + +// ============================================================================ +#pragma mark - API - +// ============================================================================ + +static inline SentryCrashMonitorAPI * +getAPI(Monitor *monitor) +{ + if (monitor != NULL && monitor->getAPI != NULL) { + return monitor->getAPI(); + } + return NULL; +} + +static inline void +setMonitorEnabled(Monitor *monitor, bool isEnabled) +{ + SentryCrashMonitorAPI *api = getAPI(monitor); + if (api != NULL && api->setEnabled != NULL) { + api->setEnabled(isEnabled); + } +} + +static inline bool +isMonitorEnabled(Monitor *monitor) +{ + SentryCrashMonitorAPI *api = getAPI(monitor); + if (api != NULL && api->isEnabled != NULL) { + return api->isEnabled(); + } + return false; +} + +static inline void +addContextualInfoToEvent(Monitor *monitor, struct SentryCrash_MonitorContext *eventContext) +{ + SentryCrashMonitorAPI *api = getAPI(monitor); + if (api != NULL && api->addContextualInfoToEvent != NULL) { + api->addContextualInfoToEvent(eventContext); + } +} + +void +sentrycrashcm_setEventCallback(void (*onEvent)(struct SentryCrash_MonitorContext *monitorContext)) +{ + g_onExceptionEvent = onEvent; +} + +void +sentrycrashcm_setActiveMonitors(SentryCrashMonitorType monitorTypes) +{ + if (sentrycrashdebug_isBeingTraced() && (monitorTypes & SentryCrashMonitorTypeDebuggerUnsafe)) { + static bool hasWarned = false; + if (!hasWarned) { + hasWarned = true; + SentryCrashLOGBASIC_WARN(" ************************ Crash " + "Handler Notice ************************"); + SentryCrashLOGBASIC_WARN(" * App is running in a debugger. " + "Masking out unsafe monitors. *"); + SentryCrashLOGBASIC_WARN(" * This means that most crashes WILL " + "NOT BE RECORDED while debugging! *"); + SentryCrashLOGBASIC_WARN(" " + "*****************************************" + "*****************************"); + } + monitorTypes &= SentryCrashMonitorTypeDebuggerSafe; + } + if (g_requiresAsyncSafety && (monitorTypes & SentryCrashMonitorTypeAsyncUnsafe)) { + SentryCrashLOG_DEBUG("Async-safe environment detected. Masking out unsafe monitors."); + monitorTypes &= SentryCrashMonitorTypeAsyncSafe; + } + + SentryCrashLOG_DEBUG( + "Changing active monitors from 0x%x tp 0x%x.", g_activeMonitors, monitorTypes); + + SentryCrashMonitorType activeMonitors = SentryCrashMonitorTypeNone; + for (int i = 0; i < g_monitorsCount; i++) { + Monitor *monitor = &g_monitors[i]; + bool isEnabled = monitor->monitorType & monitorTypes; + setMonitorEnabled(monitor, isEnabled); + if (isMonitorEnabled(monitor)) { + activeMonitors |= monitor->monitorType; + } else { + activeMonitors &= ~monitor->monitorType; + } + } + + SentryCrashLOG_DEBUG("Active monitors are now 0x%x.", activeMonitors); + g_activeMonitors = activeMonitors; +} + +SentryCrashMonitorType +sentrycrashcm_getActiveMonitors() +{ + return g_activeMonitors; +} + +// ============================================================================ +#pragma mark - Private API - +// ============================================================================ + +bool +sentrycrashcm_notifyFatalExceptionCaptured(bool isAsyncSafeEnvironment) +{ + g_requiresAsyncSafety |= isAsyncSafeEnvironment; // Don't let it be unset. + if (g_handlingFatalException) { + g_crashedDuringExceptionHandling = true; + } + g_handlingFatalException = true; + if (g_crashedDuringExceptionHandling) { + SentryCrashLOG_INFO("Detected crash in the crash reporter. Uninstalling SentryCrash."); + sentrycrashcm_setActiveMonitors(SentryCrashMonitorTypeNone); + } + return g_crashedDuringExceptionHandling; +} + +void +sentrycrashcm_handleException(struct SentryCrash_MonitorContext *context) +{ + context->requiresAsyncSafety = g_requiresAsyncSafety; + if (g_crashedDuringExceptionHandling) { + context->crashedDuringCrashHandling = true; + } + for (int i = 0; i < g_monitorsCount; i++) { + Monitor *monitor = &g_monitors[i]; + if (isMonitorEnabled(monitor)) { + addContextualInfoToEvent(monitor, context); + } + } + + g_onExceptionEvent(context); + + if (context->currentSnapshotUserReported) { + g_handlingFatalException = false; + } else { + if (g_handlingFatalException && !g_crashedDuringExceptionHandling) { + SentryCrashLOG_DEBUG("Exception is fatal. Restoring original handlers."); + sentrycrashcm_setActiveMonitors(SentryCrashMonitorTypeNone); + } + } +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.h new file mode 100644 index 00000000..507068fb --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.h @@ -0,0 +1,93 @@ +// +// SentryCrashMonitor.h +// +// Created by Karl Stenerud on 2012-02-12. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/** Keeps watch for crashes and informs via callback when on occurs. + */ + +#ifndef HDR_SentryCrashMonitor_h +#define HDR_SentryCrashMonitor_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitorType.h" +#include "SentryCrashThread.h" + +#include + +struct SentryCrash_MonitorContext; + +// ============================================================================ +#pragma mark - External API - +// ============================================================================ + +/** Set which monitors are active. + * + * @param monitorTypes Which monitors should be active. + */ +void sentrycrashcm_setActiveMonitors(SentryCrashMonitorType monitorTypes); + +/** Get the currently active monitors. + */ +SentryCrashMonitorType sentrycrashcm_getActiveMonitors(void); + +/** Set the callback to call when an event is captured. + * + * @param onEvent Called whenever an event is captured. + */ +void sentrycrashcm_setEventCallback( + void (*onEvent)(struct SentryCrash_MonitorContext *monitorContext)); + +// ============================================================================ +#pragma mark - Internal API - +// ============================================================================ + +typedef struct { + void (*setEnabled)(bool isEnabled); + bool (*isEnabled)(void); + void (*addContextualInfoToEvent)(struct SentryCrash_MonitorContext *eventContext); +} SentryCrashMonitorAPI; + +/** Notify that a fatal exception has been captured. + * This allows the system to take appropriate steps in preparation. + * + * @oaram isAsyncSafeEnvironment If true, only async-safe functions are allowed + * from now on. + */ +bool sentrycrashcm_notifyFatalExceptionCaptured(bool isAsyncSafeEnvironment); + +/** Start general exception processing. + * + * @oaram context Contextual information about the exception. + */ +void sentrycrashcm_handleException(struct SentryCrash_MonitorContext *context); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitor_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h new file mode 100644 index 00000000..aad588ee --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorContext.h @@ -0,0 +1,231 @@ +// +// SentryCrashMonitorContext.h +// +// Created by Karl Stenerud on 2012-02-12. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashMonitorContext_h +#define HDR_SentryCrashMonitorContext_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMachineContext.h" +#include "SentryCrashMonitorType.h" + +#include +#include + +typedef struct SentryCrash_MonitorContext { + /** Unique identifier for this event. */ + const char *eventID; + /** + If true, so reported user exception will have the current snapshot. + */ + bool currentSnapshotUserReported; + + /** If true, the environment has crashed hard, and only async-safe + * functions should be used. + */ + bool requiresAsyncSafety; + + /** If true, the crash handling system is currently handling a crash. + * When false, all values below this field are considered invalid. + */ + bool handlingCrash; + + /** If true, a second crash occurred while handling a crash. */ + bool crashedDuringCrashHandling; + + /** If true, the registers contain valid information about the crash. */ + bool registersAreValid; + + /** True if the crash system has detected a stack overflow. */ + bool isStackOverflow; + + /** The machine context that generated the event. */ + struct SentryCrashMachineContext *offendingMachineContext; + + /** Address that caused the fault. */ + uintptr_t faultAddress; + + /** The type of crash that occurred. + * This determines which other fields are valid. */ + SentryCrashMonitorType crashType; + + /** The name of the exception that caused the crash, if any. */ + const char *exceptionName; + + /** Short description of why the crash occurred. */ + const char *crashReason; + + /** The stack cursor for the trace leading up to the crash. + * Note: Actual type is SentryCrashStackCursor* + */ + void *stackCursor; + + struct { + /** The mach exception type. */ + int type; + + /** The mach exception code. */ + int64_t code; + + /** The mach exception subcode. */ + int64_t subcode; + } mach; + + struct { + /** The exception name. */ + const char *name; + + /** The exception userInfo. */ + const char *userInfo; + } NSException; + + struct { + /** The exception name. */ + const char *name; + + } CPPException; + + struct { + /** User context information. */ + const void *userContext; + int signum; + int sigcode; + } signal; + + struct { + /** The exception name. */ + const char *name; + + /** The language the exception occured in. */ + const char *language; + + /** The line of code where the exception occurred. Can be NULL. */ + const char *lineOfCode; + + /** The user-supplied JSON encoded stack trace. */ + const char *customStackTrace; + } userException; + + struct { + /** Total active time elapsed since the last crash. */ + double activeDurationSinceLastCrash; + + /** Total time backgrounded elapsed since the last crash. */ + double backgroundDurationSinceLastCrash; + + /** Number of app launches since the last crash. */ + int launchesSinceLastCrash; + + /** Number of sessions (launch, resume from suspend) since last crash. + */ + int sessionsSinceLastCrash; + + /** Total active time elapsed since launch. */ + double activeDurationSinceLaunch; + + /** Total time backgrounded elapsed since launch. */ + double backgroundDurationSinceLaunch; + + /** Number of sessions (launch, resume from suspend) since app launch. + */ + int sessionsSinceLaunch; + + /** If true, the application crashed on the previous launch. */ + bool crashedLastLaunch; + + /** If true, the application crashed on this launch. */ + bool crashedThisLaunch; + + /** Timestamp for when the app state was last changed + * (active<->inactive, background<->foreground) */ + double appStateTransitionTime; + + /** If true, the application is currently active. */ + bool applicationIsActive; + + /** If true, the application is currently in the foreground. */ + bool applicationIsInForeground; + + } AppState; + + /* Misc system information */ + struct { + const char *systemName; + const char *systemVersion; + const char *machine; + const char *model; + const char *kernelVersion; + const char *osVersion; + bool isJailbroken; + const char *bootTime; + const char *appStartTime; + const char *executablePath; + const char *executableName; + const char *bundleID; + const char *bundleName; + const char *bundleVersion; + const char *bundleShortVersion; + const char *appID; + const char *cpuArchitecture; + int cpuType; + int cpuSubType; + int binaryCPUType; + int binaryCPUSubType; + const char *timezone; + const char *processName; + int processID; + int parentProcessID; + const char *deviceAppHash; + const char *buildType; + uint64_t storageSize; + uint64_t memorySize; + uint64_t freeMemory; + uint64_t usableMemory; + } System; + + struct { + /** Address of the last deallocated exception. */ + uintptr_t address; + + /** Name of the last deallocated exception. */ + const char *name; + + /** Reason field from the last deallocated exception. */ + const char *reason; + } ZombieException; + + /** Full path to the console log, if any. */ + const char *consoleLogPath; + +} SentryCrash_MonitorContext; + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitorContext_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c new file mode 100644 index 00000000..e5fbeecb --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c @@ -0,0 +1,58 @@ +// +// SentryCrashMonitorType.c +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMonitorType.h" + +#include + +static const struct { + const SentryCrashMonitorType type; + const char *const name; +} g_monitorTypes[] = { +#define MONITORTYPE(NAME) \ + { \ + NAME, #NAME \ + } + MONITORTYPE(SentryCrashMonitorTypeMachException), + MONITORTYPE(SentryCrashMonitorTypeSignal), + MONITORTYPE(SentryCrashMonitorTypeCPPException), + MONITORTYPE(SentryCrashMonitorTypeNSException), + MONITORTYPE(SentryCrashMonitorTypeMainThreadDeadlock), + MONITORTYPE(SentryCrashMonitorTypeUserReported), + MONITORTYPE(SentryCrashMonitorTypeSystem), + MONITORTYPE(SentryCrashMonitorTypeApplicationState), + MONITORTYPE(SentryCrashMonitorTypeZombie), +}; +static const int g_monitorTypesCount = sizeof(g_monitorTypes) / sizeof(*g_monitorTypes); + +const char * +sentrycrashmonitortype_name(const SentryCrashMonitorType monitorType) +{ + for (int i = 0; i < g_monitorTypesCount; i++) { + if (g_monitorTypes[i].type == monitorType) { + return g_monitorTypes[i].name; + } + } + return NULL; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h new file mode 100644 index 00000000..8f40788d --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h @@ -0,0 +1,126 @@ +// +// SentryCrashMonitorType.h +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashMonitorType_h +#define HDR_SentryCrashMonitorType_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** Various aspects of the system that can be monitored: + * - Mach kernel exception + * - Fatal signal + * - Uncaught C++ exception + * - Uncaught Objective-C NSException + * - Deadlock on the main thread + * - User reported custom exception + */ +typedef enum { + /* Captures and reports Mach exceptions. */ + SentryCrashMonitorTypeMachException = 0x01, + + /* Captures and reports POSIX signals. */ + SentryCrashMonitorTypeSignal = 0x02, + + /* Captures and reports C++ exceptions. + * Note: This will slightly slow down exception processing. + */ + SentryCrashMonitorTypeCPPException = 0x04, + + /* Captures and reports NSExceptions. */ + SentryCrashMonitorTypeNSException = 0x08, + + /* Detects and reports a deadlock in the main thread. */ + SentryCrashMonitorTypeMainThreadDeadlock = 0x10, + + /* Accepts and reports user-generated exceptions. */ + SentryCrashMonitorTypeUserReported = 0x20, + + /* Keeps track of and injects system information. */ + SentryCrashMonitorTypeSystem = 0x40, + + /* Keeps track of and injects application state. */ + SentryCrashMonitorTypeApplicationState = 0x80, + + /* Keeps track of zombies, and injects the last zombie NSException. */ + SentryCrashMonitorTypeZombie = 0x100, +} SentryCrashMonitorType; + +#define SentryCrashMonitorTypeAll \ + (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal \ + | SentryCrashMonitorTypeCPPException | SentryCrashMonitorTypeNSException \ + | SentryCrashMonitorTypeMainThreadDeadlock | SentryCrashMonitorTypeUserReported \ + | SentryCrashMonitorTypeSystem | SentryCrashMonitorTypeApplicationState \ + | SentryCrashMonitorTypeZombie) + +#define SentryCrashMonitorTypeExperimental (SentryCrashMonitorTypeMainThreadDeadlock) + +#define SentryCrashMonitorTypeDebuggerUnsafe \ + (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal \ + | SentryCrashMonitorTypeCPPException | SentryCrashMonitorTypeNSException) + +#define SentryCrashMonitorTypeAsyncSafe \ + (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal) + +#define SentryCrashMonitorTypeOptional (SentryCrashMonitorTypeZombie) + +#define SentryCrashMonitorTypeAsyncUnsafe \ + (SentryCrashMonitorTypeAll & (~SentryCrashMonitorTypeAsyncSafe)) + +/** Monitors that are safe to enable in a debugger. */ +#define SentryCrashMonitorTypeDebuggerSafe \ + (SentryCrashMonitorTypeAll & (~SentryCrashMonitorTypeDebuggerUnsafe)) + +/** Monitors that are safe to use in a production environment. + * All other monitors should be considered experimental. + */ +#define SentryCrashMonitorTypeProductionSafe \ + (SentryCrashMonitorTypeAll & (~SentryCrashMonitorTypeExperimental)) + +/** Production safe monitors, minus the optional ones. */ +#define SentryCrashMonitorTypeProductionSafeMinimal \ + (SentryCrashMonitorTypeProductionSafe & (~SentryCrashMonitorTypeOptional)) + +/** Monitors that are required for proper operation. + * These add essential information to the reports, but do not trigger reporting. + */ +#define SentryCrashMonitorTypeRequired \ + (SentryCrashMonitorTypeSystem | SentryCrashMonitorTypeApplicationState) + +/** Effectively disables automatica reporting. The only way to generate a report + * in this mode is by manually calling sentrycrash_reportUserException(). + */ +#define SentryCrashMonitorTypeManual \ + (SentryCrashMonitorTypeRequired | SentryCrashMonitorTypeUserReported) + +#define SentryCrashMonitorTypeNone 0 + +const char *sentrycrashmonitortype_name(SentryCrashMonitorType monitorType); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitorType_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.c b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.c new file mode 100644 index 00000000..02d25c2a --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.c @@ -0,0 +1,453 @@ +// +// SentryCrashMonitor_AppState.c +// +// Created by Karl Stenerud on 2012-02-05. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMonitor_AppState.h" + +#include "SentryCrashFileUtils.h" +#include "SentryCrashJSONCodec.h" +#include "SentryCrashMonitorContext.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include +#include +#include +#include + +// ============================================================================ +#pragma mark - Constants - +// ============================================================================ + +#define kFormatVersion 1 + +#define kKeyFormatVersion "version" +#define kKeyCrashedLastLaunch "crashedLastLaunch" +#define kKeyActiveDurationSinceLastCrash "activeDurationSinceLastCrash" +#define kKeyBackgroundDurationSinceLastCrash "backgroundDurationSinceLastCrash" +#define kKeyLaunchesSinceLastCrash "launchesSinceLastCrash" +#define kKeySessionsSinceLastCrash "sessionsSinceLastCrash" +#define kKeySessionsSinceLaunch "sessionsSinceLaunch" + +// ============================================================================ +#pragma mark - Globals - +// ============================================================================ + +/** Location where stat file is stored. */ +static const char *g_stateFilePath; + +/** Current state. */ +static SentryCrash_AppState g_state; + +static volatile bool g_isEnabled = false; + +// ============================================================================ +#pragma mark - JSON Encoding - +// ============================================================================ + +static int +onBooleanElement(const char *const name, const bool value, void *const userData) +{ + SentryCrash_AppState *state = userData; + + if (strcmp(name, kKeyCrashedLastLaunch) == 0) { + state->crashedLastLaunch = value; + } + + return SentryCrashJSON_OK; +} + +static int +onFloatingPointElement(const char *const name, const double value, void *const userData) +{ + SentryCrash_AppState *state = userData; + + if (strcmp(name, kKeyActiveDurationSinceLastCrash) == 0) { + state->activeDurationSinceLastCrash = value; + } + if (strcmp(name, kKeyBackgroundDurationSinceLastCrash) == 0) { + state->backgroundDurationSinceLastCrash = value; + } + + return SentryCrashJSON_OK; +} + +static int +onIntegerElement(const char *const name, const int64_t value, void *const userData) +{ + SentryCrash_AppState *state = userData; + + if (strcmp(name, kKeyFormatVersion) == 0) { + if (value != kFormatVersion) { + SentryCrashLOG_ERROR("Expected version 1 but got %" PRId64, value); + return SentryCrashJSON_ERROR_INVALID_DATA; + } + } else if (strcmp(name, kKeyLaunchesSinceLastCrash) == 0) { + state->launchesSinceLastCrash = (int)value; + } else if (strcmp(name, kKeySessionsSinceLastCrash) == 0) { + state->sessionsSinceLastCrash = (int)value; + } + + // FP value might have been written as a whole number. + return onFloatingPointElement(name, value, userData); +} + +static int +onNullElement(__unused const char *const name, __unused void *const userData) +{ + return SentryCrashJSON_OK; +} + +static int +onStringElement(__unused const char *const name, __unused const char *const value, + __unused void *const userData) +{ + return SentryCrashJSON_OK; +} + +static int +onBeginObject(__unused const char *const name, __unused void *const userData) +{ + return SentryCrashJSON_OK; +} + +static int +onBeginArray(__unused const char *const name, __unused void *const userData) +{ + return SentryCrashJSON_OK; +} + +static int +onEndContainer(__unused void *const userData) +{ + return SentryCrashJSON_OK; +} + +static int +onEndData(__unused void *const userData) +{ + return SentryCrashJSON_OK; +} + +/** Callback for adding JSON data. + */ +static int +addJSONData(const char *const data, const int length, void *const userData) +{ + const int fd = *((int *)userData); + const bool success = sentrycrashfu_writeBytesToFD(fd, data, length); + return success ? SentryCrashJSON_OK : SentryCrashJSON_ERROR_CANNOT_ADD_DATA; +} + +// ============================================================================ +#pragma mark - Utility - +// ============================================================================ + +static double +getCurentTime() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + (double)tv.tv_usec / 1000000.0; +} + +static double +timeSince(double timeInSeconds) +{ + return getCurentTime() - timeInSeconds; +} + +/** Load the persistent state portion of a crash context. + * + * @param path The path to the file to read. + * + * @return true if the operation was successful. + */ +static bool +loadState(const char *const path) +{ + // Stop if the file doesn't exist. + // This is expected on the first run of the app. + const int fd = open(path, O_RDONLY); + if (fd < 0) { + return false; + } + close(fd); + + char *data; + int length; + if (!sentrycrashfu_readEntireFile(path, &data, &length, 50000)) { + SentryCrashLOG_ERROR("%s: Could not load file", path); + return false; + } + + SentryCrashJSONDecodeCallbacks callbacks; + callbacks.onBeginArray = onBeginArray; + callbacks.onBeginObject = onBeginObject; + callbacks.onBooleanElement = onBooleanElement; + callbacks.onEndContainer = onEndContainer; + callbacks.onEndData = onEndData; + callbacks.onFloatingPointElement = onFloatingPointElement; + callbacks.onIntegerElement = onIntegerElement; + callbacks.onNullElement = onNullElement; + callbacks.onStringElement = onStringElement; + + int errorOffset = 0; + + char stringBuffer[1000]; + const int result = sentrycrashjson_decode( + data, (int)length, stringBuffer, sizeof(stringBuffer), &callbacks, &g_state, &errorOffset); + free(data); + if (result != SentryCrashJSON_OK) { + SentryCrashLOG_ERROR( + "%s, offset %d: %s", path, errorOffset, sentrycrashjson_stringForError(result)); + return false; + } + return true; +} + +/** Save the persistent state portion of a crash context. + * + * @param path The path to the file to create. + * + * @return true if the operation was successful. + */ +static bool +saveState(const char *const path) +{ + int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644); + if (fd < 0) { + SentryCrashLOG_ERROR("Could not open file %s for writing: %s", path, strerror(errno)); + return false; + } + + SentryCrashJSONEncodeContext JSONContext; + sentrycrashjson_beginEncode(&JSONContext, true, addJSONData, &fd); + + int result; + if ((result = sentrycrashjson_beginObject(&JSONContext, NULL)) != SentryCrashJSON_OK) { + goto done; + } + if ((result + = sentrycrashjson_addIntegerElement(&JSONContext, kKeyFormatVersion, kFormatVersion)) + != SentryCrashJSON_OK) { + goto done; + } + // Record this launch crashed state into "crashed last launch" field. + if ((result = sentrycrashjson_addBooleanElement( + &JSONContext, kKeyCrashedLastLaunch, g_state.crashedThisLaunch)) + != SentryCrashJSON_OK) { + goto done; + } + if ((result = sentrycrashjson_addFloatingPointElement( + &JSONContext, kKeyActiveDurationSinceLastCrash, g_state.activeDurationSinceLastCrash)) + != SentryCrashJSON_OK) { + goto done; + } + if ((result = sentrycrashjson_addFloatingPointElement(&JSONContext, + kKeyBackgroundDurationSinceLastCrash, g_state.backgroundDurationSinceLastCrash)) + != SentryCrashJSON_OK) { + goto done; + } + if ((result = sentrycrashjson_addIntegerElement( + &JSONContext, kKeyLaunchesSinceLastCrash, g_state.launchesSinceLastCrash)) + != SentryCrashJSON_OK) { + goto done; + } + if ((result = sentrycrashjson_addIntegerElement( + &JSONContext, kKeySessionsSinceLastCrash, g_state.sessionsSinceLastCrash)) + != SentryCrashJSON_OK) { + goto done; + } + result = sentrycrashjson_endEncode(&JSONContext); + +done: + close(fd); + if (result != SentryCrashJSON_OK) { + SentryCrashLOG_ERROR("%s: %s", path, sentrycrashjson_stringForError(result)); + return false; + } + return true; +} + +// ============================================================================ +#pragma mark - API - +// ============================================================================ + +void +sentrycrashstate_initialize(const char *const stateFilePath) +{ + g_stateFilePath = strdup(stateFilePath); + memset(&g_state, 0, sizeof(g_state)); + loadState(g_stateFilePath); +} + +bool +sentrycrashstate_reset() +{ + if (g_isEnabled) { + g_state.sessionsSinceLaunch = 1; + g_state.activeDurationSinceLaunch = 0; + g_state.backgroundDurationSinceLaunch = 0; + if (g_state.crashedLastLaunch) { + g_state.activeDurationSinceLastCrash = 0; + g_state.backgroundDurationSinceLastCrash = 0; + g_state.launchesSinceLastCrash = 0; + g_state.sessionsSinceLastCrash = 0; + } + g_state.crashedThisLaunch = false; + + // Simulate first transition to foreground + g_state.launchesSinceLastCrash++; + g_state.sessionsSinceLastCrash++; + g_state.applicationIsInForeground = true; + + return saveState(g_stateFilePath); + } + return false; +} + +void +sentrycrashstate_notifyAppActive(const bool isActive) +{ + if (g_isEnabled) { + g_state.applicationIsActive = isActive; + if (isActive) { + g_state.appStateTransitionTime = getCurentTime(); + } else { + double duration = timeSince(g_state.appStateTransitionTime); + g_state.activeDurationSinceLaunch += duration; + g_state.activeDurationSinceLastCrash += duration; + } + } +} + +void +sentrycrashstate_notifyAppInForeground(const bool isInForeground) +{ + if (g_isEnabled) { + const char *const stateFilePath = g_stateFilePath; + + g_state.applicationIsInForeground = isInForeground; + if (isInForeground) { + double duration = getCurentTime() - g_state.appStateTransitionTime; + g_state.backgroundDurationSinceLaunch += duration; + g_state.backgroundDurationSinceLastCrash += duration; + g_state.sessionsSinceLastCrash++; + g_state.sessionsSinceLaunch++; + } else { + g_state.appStateTransitionTime = getCurentTime(); + saveState(stateFilePath); + } + } +} + +void +sentrycrashstate_notifyAppTerminate(void) +{ + if (g_isEnabled) { + const char *const stateFilePath = g_stateFilePath; + + const double duration = timeSince(g_state.appStateTransitionTime); + g_state.backgroundDurationSinceLastCrash += duration; + saveState(stateFilePath); + } +} + +void +sentrycrashstate_notifyAppCrash(void) +{ + if (g_isEnabled) { + const char *const stateFilePath = g_stateFilePath; + + const double duration = timeSince(g_state.appStateTransitionTime); + if (g_state.applicationIsActive) { + g_state.activeDurationSinceLaunch += duration; + g_state.activeDurationSinceLastCrash += duration; + } else if (!g_state.applicationIsInForeground) { + g_state.backgroundDurationSinceLaunch += duration; + g_state.backgroundDurationSinceLastCrash += duration; + } + g_state.crashedThisLaunch = true; + saveState(stateFilePath); + } +} + +const SentryCrash_AppState *const +sentrycrashstate_currentState(void) +{ + return &g_state; +} + +static void +setEnabled(bool isEnabled) +{ + if (isEnabled != g_isEnabled) { + g_isEnabled = isEnabled; + if (isEnabled) { + sentrycrashstate_reset(); + } + } +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +static void +addContextualInfoToEvent(SentryCrash_MonitorContext *eventContext) +{ + if (g_isEnabled) { + eventContext->AppState.activeDurationSinceLastCrash = g_state.activeDurationSinceLastCrash; + eventContext->AppState.activeDurationSinceLaunch = g_state.activeDurationSinceLaunch; + eventContext->AppState.applicationIsActive = g_state.applicationIsActive; + eventContext->AppState.applicationIsInForeground = g_state.applicationIsInForeground; + eventContext->AppState.appStateTransitionTime = g_state.appStateTransitionTime; + eventContext->AppState.backgroundDurationSinceLastCrash + = g_state.backgroundDurationSinceLastCrash; + eventContext->AppState.backgroundDurationSinceLaunch + = g_state.backgroundDurationSinceLaunch; + eventContext->AppState.crashedLastLaunch = g_state.crashedLastLaunch; + eventContext->AppState.crashedThisLaunch = g_state.crashedThisLaunch; + eventContext->AppState.launchesSinceLastCrash = g_state.launchesSinceLastCrash; + eventContext->AppState.sessionsSinceLastCrash = g_state.sessionsSinceLastCrash; + eventContext->AppState.sessionsSinceLaunch = g_state.sessionsSinceLaunch; + } +} + +SentryCrashMonitorAPI * +sentrycrashcm_appstate_getAPI() +{ + static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; + return &api; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.h new file mode 100644 index 00000000..3802c0ae --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_AppState.h @@ -0,0 +1,129 @@ +// +// SentryCrashMonitor_AppState.h +// +// Created by Karl Stenerud on 2012-02-05. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Manages persistent state information useful for crash reporting such as + * number of sessions, session length, etc. + */ + +#ifndef HDR_SentryCrashMonitor_AppState_h +#define HDR_SentryCrashMonitor_AppState_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" + +#include + +typedef struct { + // Saved data + + /** Total active time elapsed since the last crash. */ + double activeDurationSinceLastCrash; + + /** Total time backgrounded elapsed since the last crash. */ + double backgroundDurationSinceLastCrash; + + /** Number of app launches since the last crash. */ + int launchesSinceLastCrash; + + /** Number of sessions (launch, resume from suspend) since last crash. */ + int sessionsSinceLastCrash; + + /** Total active time elapsed since launch. */ + double activeDurationSinceLaunch; + + /** Total time backgrounded elapsed since launch. */ + double backgroundDurationSinceLaunch; + + /** Number of sessions (launch, resume from suspend) since app launch. */ + int sessionsSinceLaunch; + + /** If true, the application crashed on the previous launch. */ + bool crashedLastLaunch; + + // Live data + + /** If true, the application crashed on this launch. */ + bool crashedThisLaunch; + + /** Timestamp for when the app state was last changed (active<->inactive, + * background<->foreground) */ + double appStateTransitionTime; + + /** If true, the application is currently active. */ + bool applicationIsActive; + + /** If true, the application is currently in the foreground. */ + bool applicationIsInForeground; + +} SentryCrash_AppState; + +/** Initialize the state monitor. + * + * @param stateFilePath Where to store on-disk representation of state. + */ +void sentrycrashstate_initialize(const char *stateFilePath); + +/** Reset the crash state. + */ +bool sentrycrashstate_reset(void); + +/** Notify the crash reporter of the application active state. + * + * @param isActive true if the application is active, otherwise false. + */ +void sentrycrashstate_notifyAppActive(bool isActive); + +/** Notify the crash reporter of the application foreground/background state. + * + * @param isInForeground true if the application is in the foreground, false if + * it is in the background. + */ +void sentrycrashstate_notifyAppInForeground(bool isInForeground); + +/** Notify the crash reporter that the application is terminating. + */ +void sentrycrashstate_notifyAppTerminate(void); + +/** Notify the crash reporter that the application has crashed. + */ +void sentrycrashstate_notifyAppCrash(void); + +/** Read-only access into the current state. + */ +const SentryCrash_AppState *const sentrycrashstate_currentState(void); + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_appstate_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitor_AppState_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.cpp b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.cpp new file mode 100644 index 00000000..f377e756 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.cpp @@ -0,0 +1,213 @@ +// +// SentryCrashMonitor_CPPException.c +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMonitor_CPPException.h" +#include "SentryCrashID.h" +#include "SentryCrashMachineContext.h" +#include "SentryCrashMonitorContext.h" +#include "SentryCrashStackCursor_SelfThread.h" +#include "SentryCrashThread.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include +#include +#include + +#define STACKTRACE_BUFFER_LENGTH 30 +#define DESCRIPTION_BUFFER_LENGTH 1000 + +// Compiler hints for "if" statements +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) + +// ============================================================================ +#pragma mark - Globals - +// ============================================================================ + +/** True if this handler has been installed. */ +static volatile bool g_isEnabled = false; + +/** True if the handler should capture the next stack trace. */ +static bool g_captureNextStackTrace = false; + +static std::terminate_handler g_originalTerminateHandler; + +static char g_eventID[37]; + +static SentryCrash_MonitorContext g_monitorContext; + +// TODO: Thread local storage is not supported < ios 9. +// Find some other way to do thread local. Maybe storage with lookup by tid? +static SentryCrashStackCursor g_stackCursor; + +// ============================================================================ +#pragma mark - Callbacks - +// ============================================================================ + +typedef void (*cxa_throw_type)(void *, std::type_info *, void (*)(void *)); + +extern "C" { +void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void *)) + __attribute__((weak)); + +void +__cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void *)) +{ + if (g_captureNextStackTrace) { + sentrycrashsc_initSelfThread(&g_stackCursor, 1); + } + + static cxa_throw_type orig_cxa_throw = NULL; + unlikely_if(orig_cxa_throw == NULL) + { + orig_cxa_throw = (cxa_throw_type)dlsym(RTLD_NEXT, "__cxa_throw"); + } + orig_cxa_throw(thrown_exception, tinfo, dest); + __builtin_unreachable(); +} +} + +static void +CPPExceptionTerminate(void) +{ + sentrycrashmc_suspendEnvironment(); + SentryCrashLOG_DEBUG("Trapped c++ exception"); + const char *name = NULL; + std::type_info *tinfo = __cxxabiv1::__cxa_current_exception_type(); + if (tinfo != NULL) { + name = tinfo->name(); + } + + if (name == NULL || strcmp(name, "NSException") != 0) { + sentrycrashcm_notifyFatalExceptionCaptured(false); + SentryCrash_MonitorContext *crashContext = &g_monitorContext; + memset(crashContext, 0, sizeof(*crashContext)); + + char descriptionBuff[DESCRIPTION_BUFFER_LENGTH]; + const char *description = descriptionBuff; + descriptionBuff[0] = 0; + + SentryCrashLOG_DEBUG("Discovering what kind of exception was thrown."); + g_captureNextStackTrace = false; + try { + throw; + } catch (std::exception &exc) { + strncpy(descriptionBuff, exc.what(), sizeof(descriptionBuff)); + } +#define CATCH_VALUE(TYPE, PRINTFTYPE) \ + catch (TYPE value) \ + { \ + snprintf(descriptionBuff, sizeof(descriptionBuff), "%" #PRINTFTYPE, value); \ + } + CATCH_VALUE(char, d) + CATCH_VALUE(short, d) + CATCH_VALUE(int, d) + CATCH_VALUE(long, ld) + CATCH_VALUE(long long, lld) + CATCH_VALUE(unsigned char, u) + CATCH_VALUE(unsigned short, u) + CATCH_VALUE(unsigned int, u) + CATCH_VALUE(unsigned long, lu) + CATCH_VALUE(unsigned long long, llu) + CATCH_VALUE(float, f) + CATCH_VALUE(double, f) + CATCH_VALUE(long double, Lf) + CATCH_VALUE(char *, s) + catch (...) { description = NULL; } + g_captureNextStackTrace = g_isEnabled; + + // TODO: Should this be done here? Maybe better in the exception + // handler? + SentryCrashMC_NEW_CONTEXT(machineContext); + sentrycrashmc_getContextForThread(sentrycrashthread_self(), machineContext, true); + + SentryCrashLOG_DEBUG("Filling out context."); + crashContext->crashType = SentryCrashMonitorTypeCPPException; + crashContext->eventID = g_eventID; + crashContext->registersAreValid = false; + crashContext->stackCursor = &g_stackCursor; + crashContext->CPPException.name = name; + crashContext->exceptionName = name; + crashContext->crashReason = description; + crashContext->offendingMachineContext = machineContext; + + sentrycrashcm_handleException(crashContext); + } else { + SentryCrashLOG_DEBUG("Detected NSException. Letting the current " + "NSException handler deal with it."); + } + sentrycrashmc_resumeEnvironment(); + + SentryCrashLOG_DEBUG("Calling original terminate handler."); + g_originalTerminateHandler(); +} + +// ============================================================================ +#pragma mark - Public API - +// ============================================================================ + +static void +initialize() +{ + static bool isInitialized = false; + if (!isInitialized) { + isInitialized = true; + sentrycrashsc_initCursor(&g_stackCursor, NULL, NULL); + } +} + +static void +setEnabled(bool isEnabled) +{ + if (isEnabled != g_isEnabled) { + g_isEnabled = isEnabled; + if (isEnabled) { + initialize(); + + sentrycrashid_generate(g_eventID); + g_originalTerminateHandler = std::set_terminate(CPPExceptionTerminate); + } else { + std::set_terminate(g_originalTerminateHandler); + } + g_captureNextStackTrace = isEnabled; + } +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +extern "C" SentryCrashMonitorAPI * +sentrycrashcm_cppexception_getAPI() +{ + static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, .isEnabled = isEnabled }; + return &api; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.h new file mode 100644 index 00000000..c4206ae9 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.h @@ -0,0 +1,42 @@ +// +// SentryCrashMonitor_CPPException.h +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashMonitor_CPPException_h +#define HDR_SentryCrashMonitor_CPPException_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_cppexception_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitor_CPPException_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.h new file mode 100644 index 00000000..873f9fec --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.h @@ -0,0 +1,56 @@ +// +// SentryCrashMonitor_Deadlock.h +// +// Created by Karl Stenerud on 2012-12-09. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Catches deadlocks in threads and queues. + */ + +#ifndef HDR_SentryCrashMonitor_Deadlock_h +#define HDR_SentryCrashMonitor_Deadlock_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" + +#include + +/** Set the interval between watchdog checks on the main thread. + * Default is 5 seconds. + * + * @param value The number of seconds between checks (0 = disabled). + */ +void sentrycrashcm_setDeadlockHandlerWatchdogInterval(double value); + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_deadlock_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitor_Deadlock_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.m b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.m new file mode 100644 index 00000000..b0ab17a5 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Deadlock.m @@ -0,0 +1,207 @@ +// +// SentryCrashMonitor_Deadlock.m +// +// Created by Karl Stenerud on 2012-12-09. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashMonitor_Deadlock.h" +#import "SentryCrashID.h" +#import "SentryCrashMonitorContext.h" +#import "SentryCrashStackCursor_MachineContext.h" +#import "SentryCrashThread.h" +#import + +//#define SentryCrashLogger_LocalLevel TRACE +#import "SentryCrashLogger.h" + +#define kIdleInterval 5.0f + +@class SentryCrashDeadlockMonitor; + +// ============================================================================ +#pragma mark - Globals - +// ============================================================================ + +static volatile bool g_isEnabled = false; + +static SentryCrash_MonitorContext g_monitorContext; + +/** Thread which monitors other threads. */ +static SentryCrashDeadlockMonitor *g_monitor; + +static SentryCrashThread g_mainQueueThread; + +/** Interval between watchdog pulses. */ +static NSTimeInterval g_watchdogInterval = 0; + +// ============================================================================ +#pragma mark - X - +// ============================================================================ + +@interface SentryCrashDeadlockMonitor : NSObject + +@property (nonatomic, readwrite, retain) NSThread *monitorThread; +@property (atomic, readwrite, assign) BOOL awaitingResponse; + +@end + +@implementation SentryCrashDeadlockMonitor + +@synthesize monitorThread = _monitorThread; +@synthesize awaitingResponse = _awaitingResponse; + +- (id)init +{ + if ((self = [super init])) { + // target (self) is retained until selector (runMonitor) exits. + self.monitorThread = [[NSThread alloc] initWithTarget:self + selector:@selector(runMonitor) + object:nil]; + self.monitorThread.name = @"SentryCrash Deadlock Detection Thread"; + [self.monitorThread start]; + } + return self; +} + +- (void)cancel +{ + [self.monitorThread cancel]; +} + +- (void)watchdogPulse +{ + __block id blockSelf = self; + self.awaitingResponse = YES; + dispatch_async(dispatch_get_main_queue(), ^{ [blockSelf watchdogAnswer]; }); +} + +- (void)watchdogAnswer +{ + self.awaitingResponse = NO; +} + +- (void)handleDeadlock +{ + sentrycrashmc_suspendEnvironment(); + sentrycrashcm_notifyFatalExceptionCaptured(false); + + SentryCrashMC_NEW_CONTEXT(machineContext); + sentrycrashmc_getContextForThread(g_mainQueueThread, machineContext, false); + SentryCrashStackCursor stackCursor; + sentrycrashsc_initWithMachineContext(&stackCursor, 100, machineContext); + char eventID[37]; + sentrycrashid_generate(eventID); + + SentryCrashLOG_DEBUG(@"Filling out context."); + SentryCrash_MonitorContext *crashContext = &g_monitorContext; + memset(crashContext, 0, sizeof(*crashContext)); + crashContext->crashType = SentryCrashMonitorTypeMainThreadDeadlock; + crashContext->eventID = eventID; + crashContext->registersAreValid = false; + crashContext->offendingMachineContext = machineContext; + crashContext->stackCursor = &stackCursor; + + sentrycrashcm_handleException(crashContext); + sentrycrashmc_resumeEnvironment(); + + SentryCrashLOG_DEBUG(@"Calling abort()"); + abort(); +} + +- (void)runMonitor +{ + BOOL cancelled = NO; + do { + // Only do a watchdog check if the watchdog interval is > 0. + // If the interval is <= 0, just idle until the user changes it. + @autoreleasepool { + NSTimeInterval sleepInterval = g_watchdogInterval; + BOOL runWatchdogCheck = sleepInterval > 0; + if (!runWatchdogCheck) { + sleepInterval = kIdleInterval; + } + [NSThread sleepForTimeInterval:sleepInterval]; + cancelled = self.monitorThread.isCancelled; + if (!cancelled && runWatchdogCheck) { + if (self.awaitingResponse) { + [self handleDeadlock]; + } else { + [self watchdogPulse]; + } + } + } + } while (!cancelled); +} + +@end + +// ============================================================================ +#pragma mark - API - +// ============================================================================ + +static void +initialize() +{ + static bool isInitialized = false; + if (!isInitialized) { + isInitialized = true; + dispatch_async( + dispatch_get_main_queue(), ^{ g_mainQueueThread = sentrycrashthread_self(); }); + } +} + +static void +setEnabled(bool isEnabled) +{ + if (isEnabled != g_isEnabled) { + g_isEnabled = isEnabled; + if (isEnabled) { + SentryCrashLOG_DEBUG(@"Creating new deadlock monitor."); + initialize(); + g_monitor = [[SentryCrashDeadlockMonitor alloc] init]; + } else { + SentryCrashLOG_DEBUG(@"Stopping deadlock monitor."); + [g_monitor cancel]; + g_monitor = nil; + } + } +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +SentryCrashMonitorAPI * +sentrycrashcm_deadlock_getAPI() +{ + static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, .isEnabled = isEnabled }; + return &api; +} + +void +sentrycrashcm_setDeadlockHandlerWatchdogInterval(double value) +{ + g_watchdogInterval = value; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.c b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.c new file mode 100644 index 00000000..fb506060 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.c @@ -0,0 +1,527 @@ +// +// SentryCrashMonitor_MachException.c +// +// Created by Karl Stenerud on 2012-02-04. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMonitor_MachException.h" +#include "SentryCrashCPU.h" +#include "SentryCrashID.h" +#include "SentryCrashMonitorContext.h" +#include "SentryCrashStackCursor_MachineContext.h" +#include "SentryCrashSystemCapabilities.h" +#include "SentryCrashThread.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#if SentryCrashCRASH_HAS_MACH + +# include +# include +# include + +// ============================================================================ +# pragma mark - Constants - +// ============================================================================ + +# define kThreadPrimary "SentryCrash Exception Handler (Primary)" +# define kThreadSecondary "SentryCrash Exception Handler (Secondary)" + +// ============================================================================ +# pragma mark - Types - +// ============================================================================ + +/** A mach exception message (according to ux_exception.c, xnu-1699.22.81). + */ +typedef struct { + /** Mach header. */ + mach_msg_header_t header; + + // Start of the kernel processed data. + + /** Basic message body data. */ + mach_msg_body_t body; + + /** The thread that raised the exception. */ + mach_msg_port_descriptor_t thread; + + /** The task that raised the exception. */ + mach_msg_port_descriptor_t task; + + // End of the kernel processed data. + + /** Network Data Representation. */ + NDR_record_t NDR; + + /** The exception that was raised. */ + exception_type_t exception; + + /** The number of codes. */ + mach_msg_type_number_t codeCount; + + /** Exception code and subcode. */ + // ux_exception.c defines this as mach_exception_data_t for some reason. + // But it's not actually a pointer; it's an embedded array. + // On 32-bit systems, only the lower 32 bits of the code and subcode + // are valid. + mach_exception_data_type_t code[0]; + + /** Padding to avoid RCV_TOO_LARGE. */ + char padding[512]; +} MachExceptionMessage; + +/** A mach reply message (according to ux_exception.c, xnu-1699.22.81). + */ +typedef struct { + /** Mach header. */ + mach_msg_header_t header; + + /** Network Data Representation. */ + NDR_record_t NDR; + + /** Return code. */ + kern_return_t returnCode; +} MachReplyMessage; + +// ============================================================================ +# pragma mark - Globals - +// ============================================================================ + +static volatile bool g_isEnabled = false; + +static SentryCrash_MonitorContext g_monitorContext; +static SentryCrashStackCursor g_stackCursor; + +static bool g_isHandlingCrash = false; + +/** Holds exception port info regarding the previously installed exception + * handlers. + */ +static struct { + exception_mask_t masks[EXC_TYPES_COUNT]; + exception_handler_t ports[EXC_TYPES_COUNT]; + exception_behavior_t behaviors[EXC_TYPES_COUNT]; + thread_state_flavor_t flavors[EXC_TYPES_COUNT]; + mach_msg_type_number_t count; +} g_previousExceptionPorts; + +/** Our exception port. */ +static mach_port_t g_exceptionPort = MACH_PORT_NULL; + +/** Primary exception handler thread. */ +static pthread_t g_primaryPThread; +static thread_t g_primaryMachThread; + +/** Secondary exception handler thread in case crash handler crashes. */ +static pthread_t g_secondaryPThread; +static thread_t g_secondaryMachThread; + +static char g_primaryEventID[37]; +static char g_secondaryEventID[37]; + +// ============================================================================ +# pragma mark - Utility - +// ============================================================================ + +/** Restore the original mach exception ports. + */ +static void +restoreExceptionPorts(void) +{ + SentryCrashLOG_DEBUG("Restoring original exception ports."); + if (g_previousExceptionPorts.count == 0) { + SentryCrashLOG_DEBUG("Original exception ports were already restored."); + return; + } + + const task_t thisTask = mach_task_self(); + kern_return_t kr; + + // Reinstall old exception ports. + for (mach_msg_type_number_t i = 0; i < g_previousExceptionPorts.count; i++) { + SentryCrashLOG_TRACE("Restoring port index %d", i); + kr = task_set_exception_ports(thisTask, g_previousExceptionPorts.masks[i], + g_previousExceptionPorts.ports[i], g_previousExceptionPorts.behaviors[i], + g_previousExceptionPorts.flavors[i]); + if (kr != KERN_SUCCESS) { + SentryCrashLOG_ERROR("task_set_exception_ports: %s", mach_error_string(kr)); + } + } + SentryCrashLOG_DEBUG("Exception ports restored."); + g_previousExceptionPorts.count = 0; +} + +# define EXC_UNIX_BAD_SYSCALL 0x10000 /* SIGSYS */ +# define EXC_UNIX_BAD_PIPE 0x10001 /* SIGPIPE */ +# define EXC_UNIX_ABORT 0x10002 /* SIGABRT */ + +static int +signalForMachException(exception_type_t exception, mach_exception_code_t code) +{ + switch (exception) { + case EXC_ARITHMETIC: + return SIGFPE; + case EXC_BAD_ACCESS: + return code == KERN_INVALID_ADDRESS ? SIGSEGV : SIGBUS; + case EXC_BAD_INSTRUCTION: + return SIGILL; + case EXC_BREAKPOINT: + return SIGTRAP; + case EXC_EMULATION: + return SIGEMT; + case EXC_SOFTWARE: { + switch (code) { + case EXC_UNIX_BAD_SYSCALL: + return SIGSYS; + case EXC_UNIX_BAD_PIPE: + return SIGPIPE; + case EXC_UNIX_ABORT: + return SIGABRT; + case EXC_SOFT_SIGNAL: + return SIGKILL; + } + break; + } + } + return 0; +} + +static exception_type_t +machExceptionForSignal(int sigNum) +{ + switch (sigNum) { + case SIGFPE: + return EXC_ARITHMETIC; + case SIGSEGV: + return EXC_BAD_ACCESS; + case SIGBUS: + return EXC_BAD_ACCESS; + case SIGILL: + return EXC_BAD_INSTRUCTION; + case SIGTRAP: + return EXC_BREAKPOINT; + case SIGEMT: + return EXC_EMULATION; + case SIGSYS: + return EXC_UNIX_BAD_SYSCALL; + case SIGPIPE: + return EXC_UNIX_BAD_PIPE; + case SIGABRT: + // The Apple reporter uses EXC_CRASH instead of EXC_UNIX_ABORT + return EXC_CRASH; + case SIGKILL: + return EXC_SOFT_SIGNAL; + } + return 0; +} + +// ============================================================================ +# pragma mark - Handler - +// ============================================================================ + +/** Our exception handler thread routine. + * Wait for an exception message, uninstall our exception port, record the + * exception information, and write a report. + */ +static void * +handleExceptions(void *const userData) +{ + MachExceptionMessage exceptionMessage = { { 0 } }; + MachReplyMessage replyMessage = { { 0 } }; + char *eventID = g_primaryEventID; + + const char *threadName = (const char *)userData; + pthread_setname_np(threadName); + if (strcmp(threadName, kThreadSecondary) == 0) { + SentryCrashLOG_DEBUG("This is the secondary thread. Suspending."); + thread_suspend((thread_t)sentrycrashthread_self()); + eventID = g_secondaryEventID; + } + + for (;;) { + SentryCrashLOG_DEBUG("Waiting for mach exception"); + + // Wait for a message. + kern_return_t kr = mach_msg(&exceptionMessage.header, MACH_RCV_MSG, 0, + sizeof(exceptionMessage), g_exceptionPort, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if (kr == KERN_SUCCESS) { + break; + } + + // Loop and try again on failure. + SentryCrashLOG_ERROR("mach_msg: %s", mach_error_string(kr)); + } + + SentryCrashLOG_DEBUG("Trapped mach exception code 0x%x, subcode 0x%x", exceptionMessage.code[0], + exceptionMessage.code[1]); + if (g_isEnabled) { + sentrycrashmc_suspendEnvironment(); + g_isHandlingCrash = true; + sentrycrashcm_notifyFatalExceptionCaptured(true); + + SentryCrashLOG_DEBUG("Exception handler is installed. Continuing exception handling."); + + // Switch to the secondary thread if necessary, or uninstall the handler + // to avoid a death loop. + if (sentrycrashthread_self() == g_primaryMachThread) { + SentryCrashLOG_DEBUG("This is the primary exception thread. " + "Activating secondary thread."); + // TODO: This was put here to avoid a freeze. Does secondary thread + // ever fire? + restoreExceptionPorts(); + if (thread_resume(g_secondaryMachThread) != KERN_SUCCESS) { + SentryCrashLOG_DEBUG("Could not activate secondary thread. " + "Restoring original exception ports."); + } + } else { + SentryCrashLOG_DEBUG("This is the secondary exception thread. " + "Restoring original exception ports."); + // restoreExceptionPorts(); + } + + // Fill out crash information + SentryCrashLOG_DEBUG("Fetching machine state."); + SentryCrashMC_NEW_CONTEXT(machineContext); + SentryCrash_MonitorContext *crashContext = &g_monitorContext; + crashContext->offendingMachineContext = machineContext; + sentrycrashsc_initCursor(&g_stackCursor, NULL, NULL); + if (sentrycrashmc_getContextForThread(exceptionMessage.thread.name, machineContext, true)) { + sentrycrashsc_initWithMachineContext(&g_stackCursor, 100, machineContext); + SentryCrashLOG_TRACE("Fault address 0x%x, instruction address 0x%x", + sentrycrashcpu_faultAddress(machineContext), + sentrycrashcpu_instructionAddress(machineContext)); + if (exceptionMessage.exception == EXC_BAD_ACCESS) { + crashContext->faultAddress = sentrycrashcpu_faultAddress(machineContext); + } else { + crashContext->faultAddress = sentrycrashcpu_instructionAddress(machineContext); + } + } + + SentryCrashLOG_DEBUG("Filling out context."); + crashContext->crashType = SentryCrashMonitorTypeMachException; + crashContext->eventID = eventID; + crashContext->registersAreValid = true; + crashContext->mach.type = exceptionMessage.exception; + crashContext->mach.code = exceptionMessage.code[0]; + crashContext->mach.subcode = exceptionMessage.code[1]; + if (crashContext->mach.code == KERN_PROTECTION_FAILURE && crashContext->isStackOverflow) { + // A stack overflow should return KERN_INVALID_ADDRESS, but + // when a stack blasts through the guard pages at the top of the + // stack, it generates KERN_PROTECTION_FAILURE. Correct for this. + crashContext->mach.code = KERN_INVALID_ADDRESS; + } + crashContext->signal.signum + = signalForMachException(crashContext->mach.type, crashContext->mach.code); + crashContext->stackCursor = &g_stackCursor; + + sentrycrashcm_handleException(crashContext); + + SentryCrashLOG_DEBUG("Crash handling complete. Restoring original handlers."); + g_isHandlingCrash = false; + sentrycrashmc_resumeEnvironment(); + } + + SentryCrashLOG_DEBUG("Replying to mach exception message."); + // Send a reply saying "I didn't handle this exception". + replyMessage.header = exceptionMessage.header; + replyMessage.NDR = exceptionMessage.NDR; + replyMessage.returnCode = KERN_FAILURE; + + mach_msg(&replyMessage.header, MACH_SEND_MSG, sizeof(replyMessage), 0, MACH_PORT_NULL, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + + return NULL; +} + +// ============================================================================ +# pragma mark - API - +// ============================================================================ + +static void +uninstallExceptionHandler() +{ + SentryCrashLOG_DEBUG("Uninstalling mach exception handler."); + + // NOTE: Do not deallocate the exception port. If a secondary crash occurs + // it will hang the process. + + restoreExceptionPorts(); + + thread_t thread_self = (thread_t)sentrycrashthread_self(); + + if (g_primaryPThread != 0 && g_primaryMachThread != thread_self) { + SentryCrashLOG_DEBUG("Canceling primary exception thread."); + if (g_isHandlingCrash) { + thread_terminate(g_primaryMachThread); + } else { + pthread_cancel(g_primaryPThread); + } + g_primaryMachThread = 0; + g_primaryPThread = 0; + } + if (g_secondaryPThread != 0 && g_secondaryMachThread != thread_self) { + SentryCrashLOG_DEBUG("Canceling secondary exception thread."); + if (g_isHandlingCrash) { + thread_terminate(g_secondaryMachThread); + } else { + pthread_cancel(g_secondaryPThread); + } + g_secondaryMachThread = 0; + g_secondaryPThread = 0; + } + + g_exceptionPort = MACH_PORT_NULL; + SentryCrashLOG_DEBUG("Mach exception handlers uninstalled."); +} + +static bool +installExceptionHandler() +{ + SentryCrashLOG_DEBUG("Installing mach exception handler."); + + bool attributes_created = false; + pthread_attr_t attr; + + kern_return_t kr; + int error; + + const task_t thisTask = mach_task_self(); + exception_mask_t mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC + | EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT; + + SentryCrashLOG_DEBUG("Backing up original exception ports."); + kr = task_get_exception_ports(thisTask, mask, g_previousExceptionPorts.masks, + &g_previousExceptionPorts.count, g_previousExceptionPorts.ports, + g_previousExceptionPorts.behaviors, g_previousExceptionPorts.flavors); + if (kr != KERN_SUCCESS) { + SentryCrashLOG_ERROR("task_get_exception_ports: %s", mach_error_string(kr)); + goto failed; + } + + if (g_exceptionPort == MACH_PORT_NULL) { + SentryCrashLOG_DEBUG("Allocating new port with receive rights."); + kr = mach_port_allocate(thisTask, MACH_PORT_RIGHT_RECEIVE, &g_exceptionPort); + if (kr != KERN_SUCCESS) { + SentryCrashLOG_ERROR("mach_port_allocate: %s", mach_error_string(kr)); + goto failed; + } + + SentryCrashLOG_DEBUG("Adding send rights to port."); + kr = mach_port_insert_right( + thisTask, g_exceptionPort, g_exceptionPort, MACH_MSG_TYPE_MAKE_SEND); + if (kr != KERN_SUCCESS) { + SentryCrashLOG_ERROR("mach_port_insert_right: %s", mach_error_string(kr)); + goto failed; + } + } + + SentryCrashLOG_DEBUG("Installing port as exception handler."); + kr = task_set_exception_ports( + thisTask, mask, g_exceptionPort, EXCEPTION_DEFAULT, THREAD_STATE_NONE); + if (kr != KERN_SUCCESS) { + SentryCrashLOG_ERROR("task_set_exception_ports: %s", mach_error_string(kr)); + goto failed; + } + + SentryCrashLOG_DEBUG("Creating secondary exception thread (suspended)."); + pthread_attr_init(&attr); + attributes_created = true; + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + error = pthread_create(&g_secondaryPThread, &attr, &handleExceptions, kThreadSecondary); + if (error != 0) { + SentryCrashLOG_ERROR("pthread_create_suspended_np: %s", strerror(error)); + goto failed; + } + g_secondaryMachThread = pthread_mach_thread_np(g_secondaryPThread); + sentrycrashmc_addReservedThread(g_secondaryMachThread); + + SentryCrashLOG_DEBUG("Creating primary exception thread."); + error = pthread_create(&g_primaryPThread, &attr, &handleExceptions, kThreadPrimary); + if (error != 0) { + SentryCrashLOG_ERROR("pthread_create: %s", strerror(error)); + goto failed; + } + pthread_attr_destroy(&attr); + g_primaryMachThread = pthread_mach_thread_np(g_primaryPThread); + sentrycrashmc_addReservedThread(g_primaryMachThread); + + SentryCrashLOG_DEBUG("Mach exception handler installed."); + return true; + +failed: + SentryCrashLOG_DEBUG("Failed to install mach exception handler."); + if (attributes_created) { + pthread_attr_destroy(&attr); + } + uninstallExceptionHandler(); + return false; +} + +static void +setEnabled(bool isEnabled) +{ + if (isEnabled != g_isEnabled) { + g_isEnabled = isEnabled; + if (isEnabled) { + sentrycrashid_generate(g_primaryEventID); + sentrycrashid_generate(g_secondaryEventID); + if (!installExceptionHandler()) { + return; + } + } else { + uninstallExceptionHandler(); + } + } +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +static void +addContextualInfoToEvent(struct SentryCrash_MonitorContext *eventContext) +{ + if (eventContext->crashType == SentryCrashMonitorTypeSignal) { + eventContext->mach.type = machExceptionForSignal(eventContext->signal.signum); + } else if (eventContext->crashType != SentryCrashMonitorTypeMachException) { + eventContext->mach.type = EXC_CRASH; + } +} + +#endif + +SentryCrashMonitorAPI * +sentrycrashcm_machexception_getAPI() +{ + static SentryCrashMonitorAPI api = { +#if SentryCrashCRASH_HAS_MACH + .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent +#endif + }; + return &api; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.h new file mode 100644 index 00000000..7ae26e67 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_MachException.h @@ -0,0 +1,48 @@ +// +// SentryCrashMonitor_MachException.h +// +// Created by Karl Stenerud on 2012-02-04. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Catches mach exceptions. + */ + +#ifndef HDR_SentryCrashMonitor_MachException_h +#define HDR_SentryCrashMonitor_MachException_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" +#include + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_machexception_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitor_MachException_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.h new file mode 100644 index 00000000..c6a3f297 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.h @@ -0,0 +1,47 @@ +// +// SentryCrashMonitor_NSException.h +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Catches Objective-C exceptions. + */ + +#ifndef HDR_SentryCrashMonitor_NSException_h +#define HDR_SentryCrashMonitor_NSException_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_nsexception_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitor_NSException_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.m b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.m new file mode 100644 index 00000000..6999abce --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_NSException.m @@ -0,0 +1,160 @@ +// +// SentryCrashMonitor_NSException.m +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashMonitor_NSException.h" +#import "SentryCrash.h" +#include "SentryCrashID.h" +#include "SentryCrashMonitorContext.h" +#import "SentryCrashStackCursor_Backtrace.h" +#include "SentryCrashThread.h" +#import + +//#define SentryCrashLogger_LocalLevel TRACE +#import "SentryCrashLogger.h" + +// ============================================================================ +#pragma mark - Globals - +// ============================================================================ + +static volatile bool g_isEnabled = 0; + +static SentryCrash_MonitorContext g_monitorContext; + +/** The exception handler that was in place before we installed ours. */ +static NSUncaughtExceptionHandler *g_previousUncaughtExceptionHandler; + +// ============================================================================ +#pragma mark - Callbacks - +// ============================================================================ + +/** Our custom excepetion handler. + * Fetch the stack trace from the exception and write a report. + * + * @param exception The exception that was raised. + */ + +static void +handleException(NSException *exception, BOOL currentSnapshotUserReported) +{ + SentryCrashLOG_DEBUG(@"Trapped exception %@", exception); + if (g_isEnabled) { + sentrycrashmc_suspendEnvironment(); + sentrycrashcm_notifyFatalExceptionCaptured(false); + + SentryCrashLOG_DEBUG(@"Filling out context."); + NSArray *addresses = [exception callStackReturnAddresses]; + NSUInteger numFrames = addresses.count; + uintptr_t *callstack = malloc(numFrames * sizeof(*callstack)); + assert(callstack != NULL); + + for (NSUInteger i = 0; i < numFrames; i++) { + callstack[i] = (uintptr_t)[addresses[i] unsignedLongLongValue]; + } + + char eventID[37]; + sentrycrashid_generate(eventID); + SentryCrashMC_NEW_CONTEXT(machineContext); + sentrycrashmc_getContextForThread(sentrycrashthread_self(), machineContext, true); + SentryCrashStackCursor cursor; + sentrycrashsc_initWithBacktrace(&cursor, callstack, (int)numFrames, 0); + + SentryCrash_MonitorContext *crashContext = &g_monitorContext; + memset(crashContext, 0, sizeof(*crashContext)); + crashContext->crashType = SentryCrashMonitorTypeNSException; + crashContext->eventID = eventID; + crashContext->offendingMachineContext = machineContext; + crashContext->registersAreValid = false; + crashContext->NSException.name = [[exception name] UTF8String]; + crashContext->NSException.userInfo = + [[NSString stringWithFormat:@"%@", exception.userInfo] UTF8String]; + crashContext->exceptionName = crashContext->NSException.name; + crashContext->crashReason = [[exception reason] UTF8String]; + crashContext->stackCursor = &cursor; + crashContext->currentSnapshotUserReported = currentSnapshotUserReported; + + SentryCrashLOG_DEBUG(@"Calling main crash handler."); + sentrycrashcm_handleException(crashContext); + + free(callstack); + if (currentSnapshotUserReported) { + sentrycrashmc_resumeEnvironment(); + } + if (g_previousUncaughtExceptionHandler != NULL) { + SentryCrashLOG_DEBUG(@"Calling original exception handler."); + g_previousUncaughtExceptionHandler(exception); + } + } +} + +static void +handleCurrentSnapshotUserReportedException(NSException *exception) +{ + handleException(exception, true); +} + +static void +handleUncaughtException(NSException *exception) +{ + handleException(exception, false); +} + +// ============================================================================ +#pragma mark - API - +// ============================================================================ + +static void +setEnabled(bool isEnabled) +{ + if (isEnabled != g_isEnabled) { + g_isEnabled = isEnabled; + if (isEnabled) { + SentryCrashLOG_DEBUG(@"Backing up original handler."); + g_previousUncaughtExceptionHandler = NSGetUncaughtExceptionHandler(); + + SentryCrashLOG_DEBUG(@"Setting new handler."); + NSSetUncaughtExceptionHandler(&handleUncaughtException); + SentryCrash.sharedInstance.uncaughtExceptionHandler = &handleUncaughtException; + SentryCrash.sharedInstance.currentSnapshotUserReportedExceptionHandler + = &handleCurrentSnapshotUserReportedException; + } else { + SentryCrashLOG_DEBUG(@"Restoring original handler."); + NSSetUncaughtExceptionHandler(g_previousUncaughtExceptionHandler); + } + } +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +SentryCrashMonitorAPI * +sentrycrashcm_nsexception_getAPI() +{ + static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, .isEnabled = isEnabled }; + return &api; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.c b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.c new file mode 100644 index 00000000..2257171c --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.c @@ -0,0 +1,250 @@ +// +// SentryCrashMonitor_Signal.c +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMonitor_Signal.h" +#include "SentryCrashID.h" +#include "SentryCrashMachineContext.h" +#include "SentryCrashMonitorContext.h" +#include "SentryCrashSignalInfo.h" +#include "SentryCrashStackCursor_MachineContext.h" +#include "SentryCrashSystemCapabilities.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#if SentryCrashCRASH_HAS_SIGNAL + +# include +# include +# include +# include +# include + +// ============================================================================ +# pragma mark - Globals - +// ============================================================================ + +static volatile bool g_isEnabled = false; + +static SentryCrash_MonitorContext g_monitorContext; +static SentryCrashStackCursor g_stackCursor; + +# if SentryCrashCRASH_HAS_SIGNAL_STACK +/** Our custom signal stack. The signal handler will use this as its stack. */ +static stack_t g_signalStack = { 0 }; +# endif + +/** Signal handlers that were installed before we installed ours. */ +static struct sigaction *g_previousSignalHandlers = NULL; + +static char g_eventID[37]; + +// ============================================================================ +# pragma mark - Callbacks - +// ============================================================================ + +/** Our custom signal handler. + * Restore the default signal handlers, record the signal information, and + * write a crash report. + * Once we're done, re-raise the signal and let the default handlers deal with + * it. + * + * @param sigNum The signal that was raised. + * + * @param signalInfo Information about the signal. + * + * @param userContext Other contextual information. + */ +static void +handleSignal(int sigNum, siginfo_t *signalInfo, void *userContext) +{ + SentryCrashLOG_DEBUG("Trapped signal %d", sigNum); + if (g_isEnabled) { + sentrycrashmc_suspendEnvironment(); + sentrycrashcm_notifyFatalExceptionCaptured(false); + + SentryCrashLOG_DEBUG("Filling out context."); + SentryCrashMC_NEW_CONTEXT(machineContext); + sentrycrashmc_getContextForSignal(userContext, machineContext); + sentrycrashsc_initWithMachineContext(&g_stackCursor, 100, machineContext); + + SentryCrash_MonitorContext *crashContext = &g_monitorContext; + memset(crashContext, 0, sizeof(*crashContext)); + crashContext->crashType = SentryCrashMonitorTypeSignal; + crashContext->eventID = g_eventID; + crashContext->offendingMachineContext = machineContext; + crashContext->registersAreValid = true; + crashContext->faultAddress = (uintptr_t)signalInfo->si_addr; + crashContext->signal.userContext = userContext; + crashContext->signal.signum = signalInfo->si_signo; + crashContext->signal.sigcode = signalInfo->si_code; + crashContext->stackCursor = &g_stackCursor; + + sentrycrashcm_handleException(crashContext); + sentrycrashmc_resumeEnvironment(); + } + + SentryCrashLOG_DEBUG("Re-raising signal for regular handlers to catch."); + // This is technically not allowed, but it works in OSX and iOS. + raise(sigNum); +} + +// ============================================================================ +# pragma mark - API - +// ============================================================================ + +static bool +installSignalHandler() +{ + SentryCrashLOG_DEBUG("Installing signal handler."); + +# if SentryCrashCRASH_HAS_SIGNAL_STACK + + if (g_signalStack.ss_size == 0) { + SentryCrashLOG_DEBUG("Allocating signal stack area."); + g_signalStack.ss_size = SIGSTKSZ; + g_signalStack.ss_sp = malloc(g_signalStack.ss_size); + + if (g_signalStack.ss_sp == NULL) { + SentryCrashLOG_ERROR( + "Failed to allocate signal stack area of size %ul", g_signalStack.ss_size); + goto failed; + } + } + + SentryCrashLOG_DEBUG("Setting signal stack area."); + if (sigaltstack(&g_signalStack, NULL) != 0) { + SentryCrashLOG_ERROR("signalstack: %s", strerror(errno)); + goto failed; + } +# endif + + const int *fatalSignals = sentrycrashsignal_fatalSignals(); + int fatalSignalsCount = sentrycrashsignal_numFatalSignals(); + + if (g_previousSignalHandlers == NULL) { + SentryCrashLOG_DEBUG("Allocating memory to store previous signal handlers."); + g_previousSignalHandlers + = malloc(sizeof(*g_previousSignalHandlers) * (unsigned)fatalSignalsCount); + } + + struct sigaction action = { { 0 } }; + action.sa_flags = SA_SIGINFO | SA_ONSTACK; +# if SentryCrashCRASH_HOST_APPLE && defined(__LP64__) + action.sa_flags |= SA_64REGSET; +# endif + sigemptyset(&action.sa_mask); + action.sa_sigaction = &handleSignal; + + for (int i = 0; i < fatalSignalsCount; i++) { + SentryCrashLOG_DEBUG("Assigning handler for signal %d", fatalSignals[i]); + if (sigaction(fatalSignals[i], &action, &g_previousSignalHandlers[i]) != 0) { + char sigNameBuff[30]; + const char *sigName = sentrycrashsignal_signalName(fatalSignals[i]); + if (sigName == NULL) { + snprintf(sigNameBuff, sizeof(sigNameBuff), "%d", fatalSignals[i]); + sigName = sigNameBuff; + } + SentryCrashLOG_ERROR("sigaction (%s): %s", sigName, strerror(errno)); + // Try to reverse the damage + for (i--; i >= 0; i--) { + sigaction(fatalSignals[i], &g_previousSignalHandlers[i], NULL); + } + goto failed; + } + } + SentryCrashLOG_DEBUG("Signal handlers installed."); + return true; + +failed: + SentryCrashLOG_DEBUG("Failed to install signal handlers."); + return false; +} + +static void +uninstallSignalHandler(void) +{ + SentryCrashLOG_DEBUG("Uninstalling signal handlers."); + + const int *fatalSignals = sentrycrashsignal_fatalSignals(); + int fatalSignalsCount = sentrycrashsignal_numFatalSignals(); + + for (int i = 0; i < fatalSignalsCount; i++) { + SentryCrashLOG_DEBUG("Restoring original handler for signal %d", fatalSignals[i]); + sigaction(fatalSignals[i], &g_previousSignalHandlers[i], NULL); + } + +# if SentryCrashCRASH_HAS_SIGNAL_STACK + g_signalStack = (stack_t) { 0 }; +# endif + SentryCrashLOG_DEBUG("Signal handlers uninstalled."); +} + +static void +setEnabled(bool isEnabled) +{ + if (isEnabled != g_isEnabled) { + g_isEnabled = isEnabled; + if (isEnabled) { + sentrycrashid_generate(g_eventID); + if (!installSignalHandler()) { + return; + } + } else { + uninstallSignalHandler(); + } + } +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +static void +addContextualInfoToEvent(struct SentryCrash_MonitorContext *eventContext) +{ + if (!(eventContext->crashType + & (SentryCrashMonitorTypeSignal | SentryCrashMonitorTypeMachException))) { + eventContext->signal.signum = SIGABRT; + } +} + +#endif + +SentryCrashMonitorAPI * +sentrycrashcm_signal_getAPI() +{ + static SentryCrashMonitorAPI api = { +#if SentryCrashCRASH_HAS_SIGNAL + .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent +#endif + }; + return &api; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.h new file mode 100644 index 00000000..5c3802f3 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Signal.h @@ -0,0 +1,47 @@ +// +// SentryCrashMonitor_Signal.h +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Catches fatal unix signals. + */ + +#ifndef HDR_SentryCrashMonitor_Signal_h +#define HDR_SentryCrashMonitor_Signal_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_signal_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitor_Signal_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h new file mode 100644 index 00000000..e90bcf77 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.h @@ -0,0 +1,44 @@ +// +// SentryCrashMonitor_System.h +// +// Created by Karl Stenerud on 2012-02-05. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef SentryCrashMonitor_System_h +#define SentryCrashMonitor_System_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_system_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m new file mode 100644 index 00000000..b3c73883 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m @@ -0,0 +1,627 @@ +// +// SentryCrashMonitor_System.m +// +// Created by Karl Stenerud on 2012-02-05. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashMonitor_System.h" + +#import "SentryCrashCPU.h" +#import "SentryCrashDate.h" +#import "SentryCrashDynamicLinker.h" +#import "SentryCrashMonitorContext.h" +#import "SentryCrashSysCtl.h" +#import "SentryCrashSystemCapabilities.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#import "SentryCrashLogger.h" + +#import +#import +#if SentryCrashCRASH_HAS_UIKIT +# import +#endif +#include +#include + +typedef struct { + const char *systemName; + const char *systemVersion; + const char *machine; + const char *model; + const char *kernelVersion; + const char *osVersion; + bool isJailbroken; + const char *bootTime; + const char *appStartTime; + const char *executablePath; + const char *executableName; + const char *bundleID; + const char *bundleName; + const char *bundleVersion; + const char *bundleShortVersion; + const char *appID; + const char *cpuArchitecture; + int cpuType; + int cpuSubType; + int binaryCPUType; + int binaryCPUSubType; + const char *timezone; + const char *processName; + int processID; + int parentProcessID; + const char *deviceAppHash; + const char *buildType; + uint64_t storageSize; + uint64_t memorySize; +} SystemData; + +static SystemData g_systemData; + +static volatile bool g_isEnabled = false; + +// ============================================================================ +#pragma mark - Utility - +// ============================================================================ + +static const char * +cString(NSString *str) +{ + return str == NULL ? NULL : strdup(str.UTF8String); +} + +static NSString * +nsstringSysctl(NSString *name) +{ + NSString *str = nil; + int size = (int)sentrycrashsysctl_stringForName(name.UTF8String, NULL, 0); + + if (size <= 0) { + return @""; + } + + NSMutableData *value = [NSMutableData dataWithLength:(unsigned)size]; + + if (sentrycrashsysctl_stringForName(name.UTF8String, value.mutableBytes, size) != 0) { + str = [NSString stringWithCString:value.mutableBytes encoding:NSUTF8StringEncoding]; + } + + return str; +} + +/** Get a sysctl value as a null terminated string. + * + * @param name The sysctl name. + * + * @return The result of the sysctl call. + */ +static const char * +stringSysctl(const char *name) +{ + int size = (int)sentrycrashsysctl_stringForName(name, NULL, 0); + if (size <= 0) { + return NULL; + } + + char *value = malloc((size_t)size); + if (value == NULL) { + return NULL; + } + + if (sentrycrashsysctl_stringForName(name, value, size) <= 0) { + free(value); + return NULL; + } + + return value; +} + +static const char * +dateString(time_t date) +{ + char *buffer = malloc(21); + if (buffer != NULL) { + sentrycrashdate_utcStringFromTimestamp(date, buffer); + } + return buffer; +} + +/** Get a sysctl value as an NSDate. + * + * @param name The sysctl name. + * + * @return The result of the sysctl call. + */ +static const char * +dateSysctl(const char *name) +{ + struct timeval value = sentrycrashsysctl_timevalForName(name); + return dateString(value.tv_sec); +} + +/** Get the current VM stats. + * + * @param vmStats Gets filled with the VM stats. + * + * @param pageSize gets filled with the page size. + * + * @return true if the operation was successful. + */ +static bool +VMStats(vm_statistics_data_t *const vmStats, vm_size_t *const pageSize) +{ + kern_return_t kr; + const mach_port_t hostPort = mach_host_self(); + + if ((kr = host_page_size(hostPort, pageSize)) != KERN_SUCCESS) { + SentryCrashLOG_ERROR(@"host_page_size: %s", mach_error_string(kr)); + return false; + } + + mach_msg_type_number_t hostSize = sizeof(*vmStats) / sizeof(natural_t); + kr = host_statistics(hostPort, HOST_VM_INFO, (host_info_t)vmStats, &hostSize); + if (kr != KERN_SUCCESS) { + SentryCrashLOG_ERROR(@"host_statistics: %s", mach_error_string(kr)); + return false; + } + + return true; +} + +static uint64_t +freeMemory(void) +{ + vm_statistics_data_t vmStats; + vm_size_t pageSize; + if (VMStats(&vmStats, &pageSize)) { + return ((uint64_t)pageSize) * vmStats.free_count; + } + return 0; +} + +static uint64_t +usableMemory(void) +{ + vm_statistics_data_t vmStats; + vm_size_t pageSize; + if (VMStats(&vmStats, &pageSize)) { + return ((uint64_t)pageSize) + * (vmStats.active_count + vmStats.inactive_count + vmStats.wire_count + + vmStats.free_count); + } + return 0; +} + +/** Convert raw UUID bytes to a human-readable string. + * + * @param uuidBytes The UUID bytes (must be 16 bytes long). + * + * @return The human readable form of the UUID. + */ +static const char * +uuidBytesToString(const uint8_t *uuidBytes) +{ + CFUUIDRef uuidRef = CFUUIDCreateFromUUIDBytes(NULL, *((CFUUIDBytes *)uuidBytes)); + NSString *str = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, uuidRef); + CFRelease(uuidRef); + + return cString(str); +} + +/** Get this application's executable path. + * + * @return Executable path. + */ +static NSString * +getExecutablePath() +{ + NSBundle *mainBundle = [NSBundle mainBundle]; + NSDictionary *infoDict = [mainBundle infoDictionary]; + NSString *bundlePath = [mainBundle bundlePath]; + NSString *executableName = infoDict[@"CFBundleExecutable"]; + return [bundlePath stringByAppendingPathComponent:executableName]; +} + +/** Get this application's UUID. + * + * @return The UUID. + */ +static const char * +getAppUUID() +{ + const char *result = nil; + + NSString *exePath = getExecutablePath(); + + if (exePath != nil) { + const uint8_t *uuidBytes = sentrycrashdl_imageUUID(exePath.UTF8String, true); + if (uuidBytes == NULL) { + // OSX app image path is a lie. + uuidBytes = sentrycrashdl_imageUUID(exePath.lastPathComponent.UTF8String, false); + } + if (uuidBytes != NULL) { + result = uuidBytesToString(uuidBytes); + } + } + + return result; +} + +/** Get the current CPU's architecture. + * + * @return The current CPU archutecture. + */ +static const char * +getCPUArchForCPUType(cpu_type_t cpuType, cpu_subtype_t subType) +{ + switch (cpuType) { + case CPU_TYPE_ARM: { + switch (subType) { + case CPU_SUBTYPE_ARM_V6: + return "armv6"; + case CPU_SUBTYPE_ARM_V7: + return "armv7"; + case CPU_SUBTYPE_ARM_V7F: + return "armv7f"; + case CPU_SUBTYPE_ARM_V7K: + return "armv7k"; +#ifdef CPU_SUBTYPE_ARM_V7S + case CPU_SUBTYPE_ARM_V7S: + return "armv7s"; +#endif + } + break; + } + case CPU_TYPE_X86: + return "x86"; + case CPU_TYPE_X86_64: + return "x86_64"; + } + + return NULL; +} + +static const char * +getCurrentCPUArch() +{ + const char *result = getCPUArchForCPUType(sentrycrashsysctl_int32ForName("hw.cputype"), + sentrycrashsysctl_int32ForName("hw.cpusubtype")); + + if (result == NULL) { + result = sentrycrashcpu_currentArch(); + } + return result; +} + +/** Check if the current device is jailbroken. + * + * @return YES if the device is jailbroken. + */ +static bool +isJailbroken() +{ + return sentrycrashdl_imageNamed("MobileSubstrate", false) != UINT32_MAX; +} + +/** Check if the current build is a debug build. + * + * @return YES if the app was built in debug mode. + */ +static bool +isDebugBuild() +{ +#ifdef DEBUG + return YES; +#else + return NO; +#endif +} + +/** Check if this code is built for the simulator. + * + * @return YES if this is a simulator build. + */ +static bool +isSimulatorBuild() +{ +#if TARGET_OS_SIMULATOR + return YES; +#else + return NO; +#endif +} + +/** The file path for the bundle’s App Store receipt. + * + * @return App Store receipt for iOS 7+, nil otherwise. + */ +static NSString * +getReceiptUrlPath() +{ + NSString *path = nil; +#if SentryCrashCRASH_HOST_IOS + // For iOS 6 compatibility +# ifdef __IPHONE_11_0 + if (@available(iOS 7, *)) { +# else + if ([[UIDevice currentDevice].systemVersion compare:@"7" options:NSNumericSearch] + != NSOrderedAscending) { +# endif +#endif + path = [NSBundle mainBundle].appStoreReceiptURL.path; +#if SentryCrashCRASH_HOST_IOS + } +#endif + return path; +} + +/** Generate a 20 byte SHA1 hash that remains unique across a single device and + * application. This is slightly different from the Apple crash report key, + * which is unique to the device, regardless of the application. + * + * @return The stringified hex representation of the hash for this device + app. + */ +static const char * +getDeviceAndAppHash() +{ + NSMutableData *data = nil; + +#if SentryCrashCRASH_HAS_UIDEVICE + if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) { + data = [NSMutableData dataWithLength:16]; + [[UIDevice currentDevice].identifierForVendor getUUIDBytes:data.mutableBytes]; + } else +#endif + { + data = [NSMutableData dataWithLength:6]; + sentrycrashsysctl_getMacAddress("en0", [data mutableBytes]); + } + + // Append some device-specific data. + [data appendData:(NSData *_Nonnull)[nsstringSysctl(@"hw.machine") + dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:(NSData *_Nonnull)[nsstringSysctl(@"hw.model") + dataUsingEncoding:NSUTF8StringEncoding]]; + // const char *cpuArch = getCurrentCPUArch(); + // [data appendBytes:cpuArch length:strlen(cpuArch)]; + + // Append the bundle ID. + NSData *bundleID = + [[[NSBundle mainBundle] bundleIdentifier] dataUsingEncoding:NSUTF8StringEncoding]; + if (bundleID != nil) { + [data appendData:bundleID]; + } + + // SHA the whole thing. + uint8_t sha[CC_SHA1_DIGEST_LENGTH]; + CC_SHA1([data bytes], (CC_LONG)[data length], sha); + + NSMutableString *hash = [NSMutableString string]; + for (unsigned i = 0; i < sizeof(sha); i++) { + [hash appendFormat:@"%02x", sha[i]]; + } + + return cString(hash); +} + +/** Check if the current build is a "testing" build. + * This is useful for checking if the app was released through Testflight. + * + * @return YES if this is a testing build. + */ +static bool +isTestBuild() +{ + return [getReceiptUrlPath().lastPathComponent isEqualToString:@"sandboxReceipt"]; +} + +/** Check if the app has an app store receipt. + * Only apps released through the app store will have a receipt. + * + * @return YES if there is an app store receipt. + */ +static bool +hasAppStoreReceipt() +{ + NSString *receiptPath = getReceiptUrlPath(); + if (receiptPath == nil) { + return NO; + } + bool isAppStoreReceipt = [receiptPath.lastPathComponent isEqualToString:@"receipt"]; + bool receiptExists = [[NSFileManager defaultManager] fileExistsAtPath:receiptPath]; + + return isAppStoreReceipt && receiptExists; +} + +static const char * +getBuildType() +{ + if (isSimulatorBuild()) { + return "simulator"; + } + if (isDebugBuild()) { + return "debug"; + } + if (isTestBuild()) { + return "test"; + } + if (hasAppStoreReceipt()) { + return "app store"; + } + return "unknown"; +} + +static uint64_t +getStorageSize() +{ + NSNumber *storageSize = [[[NSFileManager defaultManager] + attributesOfFileSystemForPath:NSHomeDirectory() + error:nil] objectForKey:NSFileSystemSize]; + return storageSize.unsignedLongLongValue; +} + +// ============================================================================ +#pragma mark - API - +// ============================================================================ + +static void +initialize() +{ + static bool isInitialized = false; + if (!isInitialized) { + isInitialized = true; + + NSBundle *mainBundle = [NSBundle mainBundle]; + NSDictionary *infoDict = [mainBundle infoDictionary]; + const struct mach_header *header = _dyld_get_image_header(0); + +#if SentryCrashCRASH_HAS_UIDEVICE + g_systemData.systemName = cString([UIDevice currentDevice].systemName); + g_systemData.systemVersion = cString([UIDevice currentDevice].systemVersion); +#else +# if SentryCrashCRASH_HOST_MAC + g_systemData.systemName = "macOS"; +# endif +# if SentryCrashCRASH_HOST_WATCH + g_systemData.systemName = "watchOS"; +# endif + NSOperatingSystemVersion version = { 0, 0, 0 }; + if (@available(macOS 10.10, *)) { + version = [NSProcessInfo processInfo].operatingSystemVersion; + } + NSString *systemVersion; + if (version.patchVersion == 0) { + systemVersion = [NSString + stringWithFormat:@"%d.%d", (int)version.majorVersion, (int)version.minorVersion]; + } else { + systemVersion = [NSString stringWithFormat:@"%d.%d.%d", (int)version.majorVersion, + (int)version.minorVersion, (int)version.patchVersion]; + } + g_systemData.systemVersion = cString(systemVersion); +#endif + if (isSimulatorBuild()) { + g_systemData.machine + = cString([NSProcessInfo processInfo].environment[@"SIMULATOR_MODEL_IDENTIFIER"]); + g_systemData.model = "simulator"; + } else { +#if SentryCrashCRASH_HOST_MAC + // MacOS has the machine in the model field, and no model + g_systemData.machine = stringSysctl("hw.model"); +#else + g_systemData.machine = stringSysctl("hw.machine"); + g_systemData.model = stringSysctl("hw.model"); +#endif + } + + g_systemData.kernelVersion = stringSysctl("kern.version"); + g_systemData.osVersion = stringSysctl("kern.osversion"); + g_systemData.isJailbroken = isJailbroken(); + g_systemData.bootTime = dateSysctl("kern.boottime"); + g_systemData.appStartTime = dateString(time(NULL)); + g_systemData.executablePath = cString(getExecutablePath()); + g_systemData.executableName = cString(infoDict[@"CFBundleExecutable"]); + g_systemData.bundleID = cString(infoDict[@"CFBundleIdentifier"]); + g_systemData.bundleName = cString(infoDict[@"CFBundleName"]); + g_systemData.bundleVersion = cString(infoDict[@"CFBundleVersion"]); + g_systemData.bundleShortVersion = cString(infoDict[@"CFBundleShortVersionString"]); + g_systemData.appID = getAppUUID(); + g_systemData.cpuArchitecture = getCurrentCPUArch(); + g_systemData.cpuType = sentrycrashsysctl_int32ForName("hw.cputype"); + g_systemData.cpuSubType = sentrycrashsysctl_int32ForName("hw.cpusubtype"); + g_systemData.binaryCPUType = header->cputype; + g_systemData.binaryCPUSubType = header->cpusubtype; + g_systemData.timezone = cString([NSTimeZone localTimeZone].abbreviation); + g_systemData.processName = cString([NSProcessInfo processInfo].processName); + g_systemData.processID = [NSProcessInfo processInfo].processIdentifier; + g_systemData.parentProcessID = getppid(); + g_systemData.deviceAppHash = getDeviceAndAppHash(); + g_systemData.buildType = getBuildType(); + g_systemData.storageSize = getStorageSize(); + g_systemData.memorySize = sentrycrashsysctl_uint64ForName("hw.memsize"); + } +} + +static void +setEnabled(bool isEnabled) +{ + if (isEnabled != g_isEnabled) { + g_isEnabled = isEnabled; + if (isEnabled) { + initialize(); + } + } +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +static void +addContextualInfoToEvent(SentryCrash_MonitorContext *eventContext) +{ + if (g_isEnabled) { +#define COPY_REFERENCE(NAME) eventContext->System.NAME = g_systemData.NAME + COPY_REFERENCE(systemName); + COPY_REFERENCE(systemVersion); + COPY_REFERENCE(machine); + COPY_REFERENCE(model); + COPY_REFERENCE(kernelVersion); + COPY_REFERENCE(osVersion); + COPY_REFERENCE(isJailbroken); + COPY_REFERENCE(bootTime); + COPY_REFERENCE(appStartTime); + COPY_REFERENCE(executablePath); + COPY_REFERENCE(executableName); + COPY_REFERENCE(bundleID); + COPY_REFERENCE(bundleName); + COPY_REFERENCE(bundleVersion); + COPY_REFERENCE(bundleShortVersion); + COPY_REFERENCE(appID); + COPY_REFERENCE(cpuArchitecture); + COPY_REFERENCE(cpuType); + COPY_REFERENCE(cpuSubType); + COPY_REFERENCE(binaryCPUType); + COPY_REFERENCE(binaryCPUSubType); + COPY_REFERENCE(timezone); + COPY_REFERENCE(processName); + COPY_REFERENCE(processID); + COPY_REFERENCE(parentProcessID); + COPY_REFERENCE(deviceAppHash); + COPY_REFERENCE(buildType); + COPY_REFERENCE(storageSize); + COPY_REFERENCE(memorySize); + eventContext->System.freeMemory = freeMemory(); + eventContext->System.usableMemory = usableMemory(); + } +} + +SentryCrashMonitorAPI * +sentrycrashcm_system_getAPI() +{ + static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; + return &api; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.c b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.c new file mode 100644 index 00000000..f4ac5d06 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.c @@ -0,0 +1,105 @@ +// +// SentryCrashMonitor_User.c +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMonitor_User.h" +#include "SentryCrashID.h" +#include "SentryCrashMonitorContext.h" +#include "SentryCrashStackCursor_SelfThread.h" +#include "SentryCrashThread.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include + +/** Context to fill with crash information. */ + +static volatile bool g_isEnabled = false; + +void +sentrycrashcm_reportUserException(const char *name, const char *reason, const char *language, + const char *lineOfCode, const char *stackTrace, bool logAllThreads, bool terminateProgram) +{ + if (!g_isEnabled) { + SentryCrashLOG_WARN("User-reported exception monitor is not installed. " + "Exception has not been recorded."); + } else { + if (logAllThreads) { + sentrycrashmc_suspendEnvironment(); + } + if (terminateProgram) { + sentrycrashcm_notifyFatalExceptionCaptured(false); + } + + char eventID[37]; + sentrycrashid_generate(eventID); + SentryCrashMC_NEW_CONTEXT(machineContext); + sentrycrashmc_getContextForThread(sentrycrashthread_self(), machineContext, true); + SentryCrashStackCursor stackCursor; + sentrycrashsc_initSelfThread(&stackCursor, 0); + + SentryCrashLOG_DEBUG("Filling out context."); + SentryCrash_MonitorContext context; + memset(&context, 0, sizeof(context)); + context.crashType = SentryCrashMonitorTypeUserReported; + context.eventID = eventID; + context.offendingMachineContext = machineContext; + context.registersAreValid = false; + context.crashReason = reason; + context.userException.name = name; + context.userException.language = language; + context.userException.lineOfCode = lineOfCode; + context.userException.customStackTrace = stackTrace; + context.stackCursor = &stackCursor; + + sentrycrashcm_handleException(&context); + + if (logAllThreads) { + sentrycrashmc_resumeEnvironment(); + } + if (terminateProgram) { + abort(); + } + } +} + +static void +setEnabled(bool isEnabled) +{ + g_isEnabled = isEnabled; +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +SentryCrashMonitorAPI * +sentrycrashcm_user_getAPI() +{ + static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, .isEnabled = isEnabled }; + return &api; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.h new file mode 100644 index 00000000..f707d187 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_User.h @@ -0,0 +1,70 @@ +// +// SentryCrashMonitor_User.h +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashMonitor_User_h +#define HDR_SentryCrashMonitor_User_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" + +#include + +/** Report a custom, user defined exception. + * If terminateProgram is true, all sentries will be uninstalled and the + * application will terminate with an abort(). + * + * @param name The exception name (for namespacing exception types). + * + * @param reason A description of why the exception occurred. + * + * @param language A unique language identifier. + * + * @param lineOfCode A copy of the offending line of code (NULL = ignore). + * + * @param stackTrace JSON encoded array containing stack trace information (one + * frame per array entry). The frame structure can be anything you want, + * including bare strings. + * + * @param logAllThreads If true, suspend all threads and log their state. Note + * that this incurs a performance penalty, so it's best to use only on fatal + * errors. + * + * @param terminateProgram If true, do not return from this function call. + * Terminate the program instead. + */ +void sentrycrashcm_reportUserException(const char *name, const char *reason, const char *language, + const char *lineOfCode, const char *stackTrace, bool logAllThreads, bool terminateProgram); + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_user_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMonitor_User_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c new file mode 100644 index 00000000..00f80285 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c @@ -0,0 +1,238 @@ +// +// SentryCrashZombie.m +// +// Created by Karl Stenerud on 2012-09-15. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMonitor_Zombie.h" +#include "SentryCrashLogger.h" +#include "SentryCrashMonitorContext.h" +#include "SentryCrashObjC.h" + +#include +#include + +#define CACHE_SIZE 0x8000 + +// Compiler hints for "if" statements +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) + +typedef struct { + const void *object; + const char *className; +} Zombie; + +static volatile Zombie *g_zombieCache; +static unsigned g_zombieHashMask; + +static volatile bool g_isEnabled = false; + +static struct { + Class class; + const void *address; + char name[100]; + char reason[900]; +} g_lastDeallocedException; + +static inline unsigned +hashIndex(const void *object) +{ + uintptr_t objPtr = (uintptr_t)object; + objPtr >>= (sizeof(object) - 1); + return objPtr & g_zombieHashMask; +} + +static bool +copyStringIvar(const void *self, const char *ivarName, char *buffer, int bufferLength) +{ + Class class = object_getClass((id)self); + SentryCrashObjCIvar ivar = { 0 }; + likely_if(sentrycrashobjc_ivarNamed(class, ivarName, &ivar)) + { + void *pointer; + likely_if(sentrycrashobjc_ivarValue(self, ivar.index, &pointer)) + { + likely_if(sentrycrashobjc_isValidObject(pointer)) + { + likely_if(sentrycrashobjc_copyStringContents(pointer, buffer, bufferLength) > 0) + { + return true; + } + else + { + SentryCrashLOG_DEBUG("sentrycrashobjc_copyStringContents %s failed", ivarName); + } + } + else { SentryCrashLOG_DEBUG("sentrycrashobjc_isValidObject %s failed", ivarName); } + } + else { SentryCrashLOG_DEBUG("sentrycrashobjc_ivarValue %s failed", ivarName); } + } + else { SentryCrashLOG_DEBUG("sentrycrashobjc_ivarNamed %s failed", ivarName); } + return false; +} + +static void +storeException(const void *exception) +{ + g_lastDeallocedException.address = exception; + copyStringIvar( + exception, "name", g_lastDeallocedException.name, sizeof(g_lastDeallocedException.name)); + copyStringIvar(exception, "reason", g_lastDeallocedException.reason, + sizeof(g_lastDeallocedException.reason)); +} + +static inline void +handleDealloc(const void *self) +{ + volatile Zombie *cache = g_zombieCache; + likely_if(cache != NULL) + { + Zombie *zombie = (Zombie *)cache + hashIndex(self); + zombie->object = self; + Class class = object_getClass((id)self); + zombie->className = class_getName(class); + for (; class != nil; class = class_getSuperclass(class)) { + unlikely_if(class == g_lastDeallocedException.class) { storeException(self); } + } + } +} + +#define CREATE_ZOMBIE_HANDLER_INSTALLER(CLASS) \ + static IMP g_originalDealloc_##CLASS; \ + static void handleDealloc_##CLASS(id self, SEL _cmd) \ + { \ + handleDealloc(self); \ + typedef void (*fn)(id, SEL); \ + fn f = (fn)g_originalDealloc_##CLASS; \ + f(self, _cmd); \ + } \ + static void installDealloc_##CLASS() \ + { \ + Method method \ + = class_getInstanceMethod(objc_getClass(#CLASS), sel_registerName("dealloc")); \ + g_originalDealloc_##CLASS = method_getImplementation(method); \ + method_setImplementation(method, (IMP)handleDealloc_##CLASS); \ + } +// TODO: Uninstall doesn't work. +// static void uninstallDealloc_ ## CLASS() \ +//{ \ +// method_setImplementation(class_getInstanceMethod(objc_getClass(#CLASS), +// sel_registerName("dealloc")), g_originalDealloc_ ## CLASS); \ +//} + +CREATE_ZOMBIE_HANDLER_INSTALLER(NSObject) +CREATE_ZOMBIE_HANDLER_INSTALLER(NSProxy) + +static void +install() +{ + unsigned cacheSize = CACHE_SIZE; + g_zombieHashMask = cacheSize - 1; + g_zombieCache = calloc(cacheSize, sizeof(*g_zombieCache)); + if (g_zombieCache == NULL) { + SentryCrashLOG_ERROR("Error: Could not allocate %u bytes of memory. " + "SentryCrashZombie NOT installed!", + cacheSize * sizeof(*g_zombieCache)); + return; + } + + g_lastDeallocedException.class = objc_getClass("NSException"); + g_lastDeallocedException.address = NULL; + g_lastDeallocedException.name[0] = 0; + g_lastDeallocedException.reason[0] = 0; + + installDealloc_NSObject(); + installDealloc_NSProxy(); +} + +// TODO: Uninstall doesn't work. +// static void uninstall(void) +//{ +// uninstallDealloc_NSObject(); +// uninstallDealloc_NSProxy(); +// +// void* ptr = (void*)g_zombieCache; +// g_zombieCache = NULL; +// dispatch_time_t tenSeconds = dispatch_time(DISPATCH_TIME_NOW, +// (int64_t)(10.0 * NSEC_PER_SEC)); dispatch_after(tenSeconds, +// dispatch_get_main_queue(), ^ +// { +// free(ptr); +// }); +//} + +const char * +sentrycrashzombie_className(const void *object) +{ + volatile Zombie *cache = g_zombieCache; + if (cache == NULL || object == NULL) { + return NULL; + } + + Zombie *zombie = (Zombie *)cache + hashIndex(object); + if (zombie->object == object) { + return zombie->className; + } + return NULL; +} + +static void +setEnabled(bool isEnabled) +{ + if (isEnabled != g_isEnabled) { + g_isEnabled = isEnabled; + if (isEnabled) { + install(); + } else { + // TODO: Uninstall doesn't work. + g_isEnabled = true; + // uninstall(); + } + } +} + +static bool +isEnabled() +{ + return g_isEnabled; +} + +static void +addContextualInfoToEvent(SentryCrash_MonitorContext *eventContext) +{ + if (g_isEnabled) { + eventContext->ZombieException.address = (uintptr_t)g_lastDeallocedException.address; + eventContext->ZombieException.name = g_lastDeallocedException.name; + eventContext->ZombieException.reason = g_lastDeallocedException.reason; + } +} + +SentryCrashMonitorAPI * +sentrycrashcm_zombie_getAPI() +{ + static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; + return &api; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h new file mode 100644 index 00000000..dc3ec7c9 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h @@ -0,0 +1,67 @@ +// +// SentryCrashMonitor_Zombie.h +// +// Created by Karl Stenerud on 2012-09-15. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Poor man's zombie tracking. + * + * Benefits: + * - Very low CPU overhead. + * - Low memory overhead. + * + * Limitations: + * - Not guaranteed to catch all zombies. + * - Can generate false positives or incorrect class names. + * - SentryCrashZombie itself must be compiled with ARC disabled. You can enable + * ARC in your app, but SentryCrashZombie must be compiled in a separate library + * if you do. + */ + +#ifndef HDR_SentryCrashZombie_h +#define HDR_SentryCrashZombie_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitor.h" +#include + +/** Get the class of a deallocated object pointer, if it was tracked. + * + * @param object A pointer to a deallocated object. + * + * @return The object's class name, or NULL if it wasn't found. + */ +const char *sentrycrashzombie_className(const void *object); + +/** Access the Monitor API. + */ +SentryCrashMonitorAPI *sentrycrashcm_zombie_getAPI(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashZombie_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrash.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrash.h new file mode 100644 index 00000000..6acffe36 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrash.h @@ -0,0 +1,302 @@ +// +// SentryCrash.h +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +#import "SentryCrashMonitorType.h" +#import "SentryCrashReportFilter.h" +#import "SentryCrashReportWriter.h" + +typedef enum { + SentryCrashDemangleLanguageNone = 0, + SentryCrashDemangleLanguageCPlusPlus = 1, + SentryCrashDemangleLanguageSwift = 2, + SentryCrashDemangleLanguageAll = ~1 +} SentryCrashDemangleLanguage; + +typedef enum { + SentryCrashCDeleteNever, + SentryCrashCDeleteOnSucess, + SentryCrashCDeleteAlways +} SentryCrashCDeleteBehavior; + +/** + * Reports any crashes that occur in the application. + * + * The crash reports will be located in + * $APP_HOME/Library/Caches/SentryCrashReports + */ +@interface SentryCrash : NSObject + +#pragma mark - Configuration - + +/** Init SentryCrash instance with custom base path. */ +- (id)initWithBasePath:(NSString *)basePath; + +/** A dictionary containing any info you'd like to appear in crash reports. Must + * contain only JSON-safe data: NSString for keys, and NSDictionary, NSArray, + * NSString, NSDate, and NSNumber for values. + * + * Default: nil + */ +@property (atomic, readwrite, retain) NSDictionary *userInfo; + +/** What to do after sending reports via sendAllReportsWithCompletion: + * + * - Use SentryCrashCDeleteNever if you will manually manage the reports. + * - Use SentryCrashCDeleteAlways if you will be using an alert confirmation + * (otherwise it will nag the user incessantly until he selects "yes"). + * - Use SentryCrashCDeleteOnSuccess for all other situations. + * + * Default: SentryCrashCDeleteAlways + */ +@property (nonatomic, readwrite, assign) SentryCrashCDeleteBehavior deleteBehaviorAfterSendAll; + +/** The monitors that will or have been installed. + * Note: This value may change once SentryCrash is installed if some monitors + * fail to install. + * + * Default: SentryCrashMonitorTypeProductionSafeMinimal + */ +@property (nonatomic, readwrite, assign) SentryCrashMonitorType monitoring; + +/** Maximum time to allow the main thread to run without returning. + * If a task occupies the main thread for longer than this interval, the + * watchdog will consider the queue deadlocked and shut down the app and write a + * crash report. + * + * Note: You must have added SentryCrashMonitorTypeMainThreadDeadlock to the + * monitoring property in order for this to have any effect. + * + * Warning: Make SURE that nothing in your app that runs on the main thread + * takes longer to complete than this value or it WILL get shut down! This + * includes your app startup process, so you may need to push app initialization + * to another thread, or perhaps set this to a higher value until your + * application has been fully initialized. + * + * WARNING: This is still causing false positives in some cases. Use at own + * risk! + * + * 0 = Disabled. + * + * Default: 0 + */ +@property (nonatomic, readwrite, assign) double deadlockWatchdogInterval; + +/** If YES, introspect memory contents during a crash. + * Any Objective-C objects or C strings near the stack pointer or referenced by + * cpu registers or exceptions will be recorded in the crash report, along with + * their contents. + * + * Default: YES + */ +@property (nonatomic, readwrite, assign) BOOL introspectMemory; + +/** If YES, monitor all Objective-C/Swift deallocations and keep track of any + * accesses after deallocation. + * + * Default: NO + */ +@property (nonatomic, readwrite, assign) BOOL catchZombies; + +/** List of Objective-C classes that should never be introspected. + * Whenever a class in this list is encountered, only the class name will be + * recorded. This can be useful for information security concerns. + * + * Default: nil + */ +@property (nonatomic, readwrite, retain) NSArray *doNotIntrospectClasses; + +/** The maximum number of reports allowed on disk before old ones get deleted. + * + * Default: 5 + */ +@property (nonatomic, readwrite, assign) int maxReportCount; + +/** The report sink where reports get sent. + * This MUST be set or else the reporter will not send reports (although it will + * still record them). + * + * Note: If you use an installation, it will automatically set this property. + * Do not modify it in such a case. + */ +@property (nonatomic, readwrite, retain) id sink; + +/** C Function to call during a crash report to give the callee an opportunity + * to add to the report. NULL = ignore. + * + * WARNING: Only call async-safe functions from this function! DO NOT call + * Objective-C methods!!! + * + * Note: If you use an installation, it will automatically set this property. + * Do not modify it in such a case. + */ +@property (nonatomic, readwrite, assign) SentryCrashReportWriteCallback onCrash; + +/** Add a copy of SentryCrash's console log messages to the crash report. + */ +@property (nonatomic, readwrite, assign) BOOL addConsoleLogToReport; + +/** Print the previous app run log to the console when installing SentryCrash. + * This is primarily for debugging purposes. + */ +@property (nonatomic, readwrite, assign) BOOL printPreviousLog; + +/** Which languages to demangle when getting stack traces (default + * SentryCrashDemangleLanguageAll) */ +@property (nonatomic, readwrite, assign) SentryCrashDemangleLanguage demangleLanguages; + +/** Exposes the uncaughtExceptionHandler if set from SentryCrash. Is nil if + * debugger is running. **/ +@property (nonatomic, assign) NSUncaughtExceptionHandler *uncaughtExceptionHandler; + +/** Exposes the currentSnapshotUserReportedExceptionHandler if set from + * SentryCrash. Is nil if debugger is running. **/ +@property (nonatomic, assign) + NSUncaughtExceptionHandler *currentSnapshotUserReportedExceptionHandler; + +#pragma mark - Information - + +/** Total active time elapsed since the last crash. */ +@property (nonatomic, readonly, assign) NSTimeInterval activeDurationSinceLastCrash; + +/** Total time backgrounded elapsed since the last crash. */ +@property (nonatomic, readonly, assign) NSTimeInterval backgroundDurationSinceLastCrash; + +/** Number of app launches since the last crash. */ +@property (nonatomic, readonly, assign) int launchesSinceLastCrash; + +/** Number of sessions (launch, resume from suspend) since last crash. */ +@property (nonatomic, readonly, assign) int sessionsSinceLastCrash; + +/** Total active time elapsed since launch. */ +@property (nonatomic, readonly, assign) NSTimeInterval activeDurationSinceLaunch; + +/** Total time backgrounded elapsed since launch. */ +@property (nonatomic, readonly, assign) NSTimeInterval backgroundDurationSinceLaunch; + +/** Number of sessions (launch, resume from suspend) since app launch. */ +@property (nonatomic, readonly, assign) int sessionsSinceLaunch; + +/** If true, the application crashed on the previous launch. */ +@property (nonatomic, readonly, assign) BOOL crashedLastLaunch; + +/** The total number of unsent reports. Note: This is an expensive operation. */ +@property (nonatomic, readonly, assign) int reportCount; + +/** Information about the operating system and environment */ +@property (nonatomic, readonly, strong) NSDictionary *systemInfo; + +#pragma mark - API - + +/** Get the singleton instance of the crash reporter. + */ ++ (SentryCrash *)sharedInstance; + +/** Install the crash reporter. + * The reporter will record crashes, but will not send any crash reports unless + * sink is set. + * + * @return YES if the reporter successfully installed. + */ +- (BOOL)install; + +/** Send all outstanding crash reports to the current sink. + * It will only attempt to send the most recent 5 reports. All others will be + * deleted. Once the reports are successfully sent to the server, they may be + * deleted locally, depending on the property "deleteAfterSendAll". + * + * Note: property "sink" MUST be set or else this method will call onCompletion + * with an error. + * + * @param onCompletion Called when sending is complete (nil = ignore). + */ +- (void)sendAllReportsWithCompletion:(SentryCrashReportFilterCompletion)onCompletion; + +/** Get all unsent report IDs. + * + * @return An array with report IDs. + */ +- (NSArray *)reportIDs; + +/** Get report. + * + * @param reportID An ID of report. + * + * @return A dictionary with report fields. See SentryCrashReportFields.h for + * available fields. + */ +- (NSDictionary *)reportWithID:(NSNumber *)reportID; + +/** Delete all unsent reports. + */ +- (void)deleteAllReports; + +/** Delete report. + * + * @param reportID An ID of report to delete. + */ +- (void)deleteReportWithID:(NSNumber *)reportID; + +/** Report a custom, user defined exception. + * This can be useful when dealing with scripting languages. + * + * If terminateProgram is true, all sentries will be uninstalled and the + * application will terminate with an abort(). + * + * @param name The exception name (for namespacing exception types). + * + * @param reason A description of why the exception occurred. + * + * @param language A unique language identifier. + * + * @param lineOfCode A copy of the offending line of code (nil = ignore). + * + * @param stackTrace An array of frames (dictionaries or strings) representing + * the call stack leading to the exception (nil = ignore). + * + * @param logAllThreads If true, suspend all threads and log their state. Note + * that this incurs a performance penalty, so it's best to use only on fatal + * errors. + * + * @param terminateProgram If true, do not return from this function call. + * Terminate the program instead. + */ +- (void)reportUserException:(NSString *)name + reason:(NSString *)reason + language:(NSString *)language + lineOfCode:(NSString *)lineOfCode + stackTrace:(NSArray *)stackTrace + logAllThreads:(BOOL)logAllThreads + terminateProgram:(BOOL)terminateProgram; + +@end + +//! Project version number for SentryCrashFramework. +FOUNDATION_EXPORT const double SentryCrashFrameworkVersionNumber; + +//! Project version string for SentryCrashFramework. +FOUNDATION_EXPORT const unsigned char SentryCrashFrameworkVersionString[]; diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrash.m b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrash.m new file mode 100644 index 00000000..ef5a3c52 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrash.m @@ -0,0 +1,571 @@ +// +// SentryCrash.m +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrash.h" + +#import "NSError+SentrySimpleConstructor.h" +#import "SentryCrashC.h" +#import "SentryCrashDoctor.h" +#import "SentryCrashJSONCodecObjC.h" +#import "SentryCrashMonitorContext.h" +#import "SentryCrashMonitor_AppState.h" +#import "SentryCrashMonitor_System.h" +#import "SentryCrashReportFields.h" +#import "SentryCrashSystemCapabilities.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#import "SentryCrashLogger.h" + +#include +#if SentryCrashCRASH_HAS_UIKIT +# import +#endif + +// ============================================================================ +#pragma mark - Globals - +// ============================================================================ + +@interface +SentryCrash () + +@property (nonatomic, readwrite, retain) NSString *bundleName; +@property (nonatomic, readwrite, retain) NSString *basePath; + +@end + +static NSString * +getBundleName() +{ + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + if (bundleName == nil) { + bundleName = @"Unknown"; + } + return bundleName; +} + +static NSString * +getBasePath() +{ + NSArray *directories + = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + if ([directories count] == 0) { + SentryCrashLOG_ERROR(@"Could not locate cache directory path."); + return nil; + } + NSString *cachePath = [directories objectAtIndex:0]; + if ([cachePath length] == 0) { + SentryCrashLOG_ERROR(@"Could not locate cache directory path."); + return nil; + } + NSString *pathEnd = [@"SentryCrash" stringByAppendingPathComponent:getBundleName()]; + return [cachePath stringByAppendingPathComponent:pathEnd]; +} + +@implementation SentryCrash + +// ============================================================================ +#pragma mark - Properties - +// ============================================================================ + +@synthesize sink = _sink; +@synthesize userInfo = _userInfo; +@synthesize deleteBehaviorAfterSendAll = _deleteBehaviorAfterSendAll; +@synthesize monitoring = _monitoring; +@synthesize deadlockWatchdogInterval = _deadlockWatchdogInterval; +@synthesize onCrash = _onCrash; +@synthesize bundleName = _bundleName; +@synthesize basePath = _basePath; +@synthesize introspectMemory = _introspectMemory; +@synthesize catchZombies = _catchZombies; +@synthesize doNotIntrospectClasses = _doNotIntrospectClasses; +@synthesize demangleLanguages = _demangleLanguages; +@synthesize addConsoleLogToReport = _addConsoleLogToReport; +@synthesize printPreviousLog = _printPreviousLog; +@synthesize maxReportCount = _maxReportCount; +@synthesize uncaughtExceptionHandler = _uncaughtExceptionHandler; +@synthesize currentSnapshotUserReportedExceptionHandler + = _currentSnapshotUserReportedExceptionHandler; + +// ============================================================================ +#pragma mark - Lifecycle - +// ============================================================================ + ++ (instancetype)sharedInstance +{ + static SentryCrash *sharedInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ sharedInstance = [[SentryCrash alloc] init]; }); + return sharedInstance; +} + +- (id)init +{ + return [self initWithBasePath:getBasePath()]; +} + +- (id)initWithBasePath:(NSString *)basePath +{ + if ((self = [super init])) { + self.bundleName = getBundleName(); + self.basePath = basePath; + if (self.basePath == nil) { + SentryCrashLOG_ERROR(@"Failed to initialize crash handler. Crash " + @"reporting disabled."); + return nil; + } + self.deleteBehaviorAfterSendAll = SentryCrashCDeleteAlways; + self.introspectMemory = YES; + self.catchZombies = NO; + self.maxReportCount = 5; + self.monitoring = SentryCrashMonitorTypeProductionSafeMinimal; + } + return self; +} + +// ============================================================================ +#pragma mark - API - +// ============================================================================ + +- (NSDictionary *)userInfo +{ + return _userInfo; +} + +- (void)setUserInfo:(NSDictionary *)userInfo +{ + @synchronized(self) { + NSError *error = nil; + NSData *userInfoJSON = nil; + if (userInfo != nil) { + userInfoJSON = + [self nullTerminated:[SentryCrashJSONCodec encode:userInfo + options:SentryCrashJSONEncodeOptionSorted + error:&error]]; + if (error != NULL) { + SentryCrashLOG_ERROR(@"Could not serialize user info: %@", error); + return; + } + } + + _userInfo = userInfo; + sentrycrash_setUserInfoJSON([userInfoJSON bytes]); + } +} + +- (void)setMonitoring:(SentryCrashMonitorType)monitoring +{ + _monitoring = sentrycrash_setMonitoring(monitoring); +} + +- (void)setDeadlockWatchdogInterval:(double)deadlockWatchdogInterval +{ + _deadlockWatchdogInterval = deadlockWatchdogInterval; + sentrycrash_setDeadlockWatchdogInterval(deadlockWatchdogInterval); +} + +- (void)setOnCrash:(SentryCrashReportWriteCallback)onCrash +{ + _onCrash = onCrash; + sentrycrash_setCrashNotifyCallback(onCrash); +} + +- (void)setIntrospectMemory:(BOOL)introspectMemory +{ + _introspectMemory = introspectMemory; + sentrycrash_setIntrospectMemory(introspectMemory); +} + +- (void)setCatchZombies:(BOOL)catchZombies +{ + _catchZombies = catchZombies; + self.monitoring |= SentryCrashMonitorTypeZombie; +} + +- (void)setDoNotIntrospectClasses:(NSArray *)doNotIntrospectClasses +{ + _doNotIntrospectClasses = doNotIntrospectClasses; + NSUInteger count = [doNotIntrospectClasses count]; + if (count == 0) { + sentrycrash_setDoNotIntrospectClasses(nil, 0); + } else { + NSMutableData *data = [NSMutableData dataWithLength:count * sizeof(const char *)]; + const char **classes = data.mutableBytes; + for (unsigned i = 0; i < count; i++) { + classes[i] = [[doNotIntrospectClasses objectAtIndex:i] + cStringUsingEncoding:NSUTF8StringEncoding]; + } + sentrycrash_setDoNotIntrospectClasses(classes, (int)count); + } +} + +- (void)setMaxReportCount:(int)maxReportCount +{ + _maxReportCount = maxReportCount; + sentrycrash_setMaxReportCount(maxReportCount); +} + +- (NSDictionary *)systemInfo +{ + SentryCrash_MonitorContext fakeEvent = { 0 }; + sentrycrashcm_system_getAPI()->addContextualInfoToEvent(&fakeEvent); + NSMutableDictionary *dict = [NSMutableDictionary new]; + +#define COPY_STRING(A) \ + if (fakeEvent.System.A) \ + dict[@ #A] = [NSString stringWithUTF8String:fakeEvent.System.A] +#define COPY_PRIMITIVE(A) dict[@ #A] = @(fakeEvent.System.A) + COPY_STRING(systemName); + COPY_STRING(systemVersion); + COPY_STRING(machine); + COPY_STRING(model); + COPY_STRING(kernelVersion); + COPY_STRING(osVersion); + COPY_PRIMITIVE(isJailbroken); + COPY_STRING(bootTime); + COPY_STRING(appStartTime); + COPY_STRING(executablePath); + COPY_STRING(executableName); + COPY_STRING(bundleID); + COPY_STRING(bundleName); + COPY_STRING(bundleVersion); + COPY_STRING(bundleShortVersion); + COPY_STRING(appID); + COPY_STRING(cpuArchitecture); + COPY_PRIMITIVE(cpuType); + COPY_PRIMITIVE(cpuSubType); + COPY_PRIMITIVE(binaryCPUType); + COPY_PRIMITIVE(binaryCPUSubType); + COPY_STRING(timezone); + COPY_STRING(processName); + COPY_PRIMITIVE(processID); + COPY_PRIMITIVE(parentProcessID); + COPY_STRING(deviceAppHash); + COPY_STRING(buildType); + COPY_PRIMITIVE(storageSize); + COPY_PRIMITIVE(memorySize); + COPY_PRIMITIVE(freeMemory); + COPY_PRIMITIVE(usableMemory); + + return dict; +} + +- (BOOL)install +{ + _monitoring = sentrycrash_install(self.bundleName.UTF8String, self.basePath.UTF8String); + if (self.monitoring == 0) { + return false; + } + +#if SentryCrashCRASH_HAS_UIAPPLICATION + NSNotificationCenter *nCenter = [NSNotificationCenter defaultCenter]; + [nCenter addObserver:self + selector:@selector(applicationDidBecomeActive) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + [nCenter addObserver:self + selector:@selector(applicationWillResignActive) + name:UIApplicationWillResignActiveNotification + object:nil]; + [nCenter addObserver:self + selector:@selector(applicationDidEnterBackground) + name:UIApplicationDidEnterBackgroundNotification + object:nil]; + [nCenter addObserver:self + selector:@selector(applicationWillEnterForeground) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + [nCenter addObserver:self + selector:@selector(applicationWillTerminate) + name:UIApplicationWillTerminateNotification + object:nil]; +#endif +#if SentryCrashCRASH_HAS_NSEXTENSION + NSNotificationCenter *nCenter = [NSNotificationCenter defaultCenter]; + [nCenter addObserver:self + selector:@selector(applicationDidBecomeActive) + name:NSExtensionHostDidBecomeActiveNotification + object:nil]; + [nCenter addObserver:self + selector:@selector(applicationWillResignActive) + name:NSExtensionHostWillResignActiveNotification + object:nil]; + [nCenter addObserver:self + selector:@selector(applicationDidEnterBackground) + name:NSExtensionHostDidEnterBackgroundNotification + object:nil]; + [nCenter addObserver:self + selector:@selector(applicationWillEnterForeground) + name:NSExtensionHostWillEnterForegroundNotification + object:nil]; +#endif + + return true; +} + +- (void)sendAllReportsWithCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSArray *reports = [self allReports]; + + SentryCrashLOG_INFO(@"Sending %d crash reports", [reports count]); + + [self sendReports:reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + SentryCrashLOG_DEBUG(@"Process finished with completion: %d", completed); + if (error != nil) { + SentryCrashLOG_ERROR(@"Failed to send reports: %@", error); + } + if ((self.deleteBehaviorAfterSendAll == SentryCrashCDeleteOnSucess && completed) + || self.deleteBehaviorAfterSendAll == SentryCrashCDeleteAlways) { + sentrycrash_deleteAllReports(); + } + sentrycrash_callCompletion(onCompletion, filteredReports, completed, error); + }]; +} + +- (void)deleteAllReports +{ + sentrycrash_deleteAllReports(); +} + +- (void)deleteReportWithID:(NSNumber *)reportID +{ + sentrycrash_deleteReportWithID([reportID longValue]); +} + +- (void)reportUserException:(NSString *)name + reason:(NSString *)reason + language:(NSString *)language + lineOfCode:(NSString *)lineOfCode + stackTrace:(NSArray *)stackTrace + logAllThreads:(BOOL)logAllThreads + terminateProgram:(BOOL)terminateProgram +{ + const char *cName = [name cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cReason = [reason cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cLanguage = [language cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cLineOfCode = [lineOfCode cStringUsingEncoding:NSUTF8StringEncoding]; + NSError *error = nil; + NSData *jsonData = [SentryCrashJSONCodec encode:stackTrace options:0 error:&error]; + if (jsonData == nil || error != nil) { + SentryCrashLOG_ERROR(@"Error encoding stack trace to JSON: %@", error); + // Don't return, since we can still record other useful information. + } + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + const char *cStackTrace = [jsonString cStringUsingEncoding:NSUTF8StringEncoding]; + + sentrycrash_reportUserException( + cName, cReason, cLanguage, cLineOfCode, cStackTrace, logAllThreads, terminateProgram); +} + +// ============================================================================ +#pragma mark - Advanced API - +// ============================================================================ + +#define SYNTHESIZE_CRASH_STATE_PROPERTY(TYPE, NAME) \ + -(TYPE)NAME { return sentrycrashstate_currentState()->NAME; } + +SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, activeDurationSinceLastCrash) +SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, backgroundDurationSinceLastCrash) +SYNTHESIZE_CRASH_STATE_PROPERTY(int, launchesSinceLastCrash) +SYNTHESIZE_CRASH_STATE_PROPERTY(int, sessionsSinceLastCrash) +SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, activeDurationSinceLaunch) +SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, backgroundDurationSinceLaunch) +SYNTHESIZE_CRASH_STATE_PROPERTY(int, sessionsSinceLaunch) +SYNTHESIZE_CRASH_STATE_PROPERTY(BOOL, crashedLastLaunch) + +- (int)reportCount +{ + return sentrycrash_getReportCount(); +} + +- (void)sendReports:(NSArray *)reports onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + if ([reports count] == 0) { + sentrycrash_callCompletion(onCompletion, reports, YES, nil); + return; + } + + if (self.sink == nil) { + sentrycrash_callCompletion(onCompletion, reports, NO, + [NSError sentryErrorWithDomain:[[self class] description] + code:0 + description:@"No sink set. Crash reports not sent."]); + return; + } + + [self.sink filterReports:reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + sentrycrash_callCompletion(onCompletion, filteredReports, completed, error); + }]; +} + +- (NSData *)loadCrashReportJSONWithID:(int64_t)reportID +{ + char *report = sentrycrash_readReport(reportID); + if (report != NULL) { + return [NSData dataWithBytesNoCopy:report length:strlen(report) freeWhenDone:YES]; + } + return nil; +} + +- (void)doctorReport:(NSMutableDictionary *)report +{ + NSMutableDictionary *crashReport = report[@SentryCrashField_Crash]; + if (crashReport != nil) { + crashReport[@SentryCrashField_Diagnosis] = + [[SentryCrashDoctor doctor] diagnoseCrash:report]; + } + crashReport = report[@SentryCrashField_RecrashReport][@SentryCrashField_Crash]; + if (crashReport != nil) { + crashReport[@SentryCrashField_Diagnosis] = + [[SentryCrashDoctor doctor] diagnoseCrash:report]; + } +} + +- (NSArray *)reportIDs +{ + int reportCount = sentrycrash_getReportCount(); + int64_t reportIDsC[reportCount]; + reportCount = sentrycrash_getReportIDs(reportIDsC, reportCount); + NSMutableArray *reportIDs = [NSMutableArray arrayWithCapacity:(NSUInteger)reportCount]; + for (int i = 0; i < reportCount; i++) { + [reportIDs addObject:@(reportIDsC[i])]; + } + return reportIDs; +} + +- (NSDictionary *)reportWithID:(NSNumber *)reportID +{ + return [self reportWithIntID:[reportID longValue]]; +} + +- (NSDictionary *)reportWithIntID:(int64_t)reportID +{ + NSData *jsonData = [self loadCrashReportJSONWithID:reportID]; + if (jsonData == nil) { + return nil; + } + + NSError *error = nil; + NSMutableDictionary *crashReport = + [SentryCrashJSONCodec decode:jsonData + options:SentryCrashJSONDecodeOptionIgnoreNullInArray + | SentryCrashJSONDecodeOptionIgnoreNullInObject + | SentryCrashJSONDecodeOptionKeepPartialObject + error:&error]; + if (error != nil) { + SentryCrashLOG_ERROR( + @"Encountered error loading crash report %" PRIx64 ": %@", reportID, error); + } + if (crashReport == nil) { + SentryCrashLOG_ERROR(@"Could not load crash report"); + return nil; + } + [self doctorReport:crashReport]; + + return crashReport; +} + +- (NSArray *)allReports +{ + NSMutableArray *reports = [NSMutableArray array]; + int reportCount = sentrycrash_getReportCount(); + if (reportCount > 0) { + int64_t reportIDs[reportCount]; + reportCount = sentrycrash_getReportIDs(reportIDs, reportCount); + for (int i = 0; i < reportCount; i++) { + NSDictionary *report = [self reportWithIntID:reportIDs[i]]; + if (report != nil) { + [reports addObject:report]; + } + } + } + return reports; +} + +- (void)setAddConsoleLogToReport:(BOOL)shouldAddConsoleLogToReport +{ + _addConsoleLogToReport = shouldAddConsoleLogToReport; + sentrycrash_setAddConsoleLogToReport(shouldAddConsoleLogToReport); +} + +- (void)setPrintPreviousLog:(BOOL)shouldPrintPreviousLog +{ + _printPreviousLog = shouldPrintPreviousLog; + sentrycrash_setPrintPreviousLog(shouldPrintPreviousLog); +} + +// ============================================================================ +#pragma mark - Utility - +// ============================================================================ + +- (NSMutableData *)nullTerminated:(NSData *)data +{ + if (data == nil) { + return NULL; + } + NSMutableData *mutable = [NSMutableData dataWithData:data]; + [mutable appendBytes:"\0" length:1]; + return mutable; +} + +// ============================================================================ +#pragma mark - Notifications - +// ============================================================================ + +- (void)applicationDidBecomeActive +{ + sentrycrash_notifyAppActive(true); +} + +- (void)applicationWillResignActive +{ + sentrycrash_notifyAppActive(false); +} + +- (void)applicationDidEnterBackground +{ + sentrycrash_notifyAppInForeground(false); +} + +- (void)applicationWillEnterForeground +{ + sentrycrash_notifyAppInForeground(true); +} + +- (void)applicationWillTerminate +{ + sentrycrash_notifyAppTerminate(); +} + +@end + +//! Project version number for SentryCrashFramework. +const double SentryCrashFrameworkVersionNumber = 1.1518; + +//! Project version string for SentryCrashFramework. +const unsigned char SentryCrashFrameworkVersionString[] = "1.15.18"; diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashC.c b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashC.c new file mode 100644 index 00000000..a618d2b8 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashC.c @@ -0,0 +1,300 @@ +// +// SentryCrashC.c +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashC.h" + +#include "SentryCrashCachedData.h" +#include "SentryCrashFileUtils.h" +#include "SentryCrashMonitorContext.h" +#include "SentryCrashMonitor_AppState.h" +#include "SentryCrashMonitor_Deadlock.h" +#include "SentryCrashMonitor_System.h" +#include "SentryCrashMonitor_User.h" +#include "SentryCrashMonitor_Zombie.h" +#include "SentryCrashObjC.h" +#include "SentryCrashReport.h" +#include "SentryCrashReportFixer.h" +#include "SentryCrashReportStore.h" +#include "SentryCrashString.h" +#include "SentryCrashSystemCapabilities.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include + +// ============================================================================ +#pragma mark - Globals - +// ============================================================================ + +/** True if SentryCrash has been installed. */ +static volatile bool g_installed = 0; + +static bool g_shouldAddConsoleLogToReport = false; +static bool g_shouldPrintPreviousLog = false; +static char g_consoleLogPath[SentryCrashFU_MAX_PATH_LENGTH]; +static SentryCrashMonitorType g_monitoring = SentryCrashMonitorTypeProductionSafeMinimal; +static char g_lastCrashReportFilePath[SentryCrashFU_MAX_PATH_LENGTH]; + +// ============================================================================ +#pragma mark - Utility - +// ============================================================================ + +static void +printPreviousLog(const char *filePath) +{ + char *data; + int length; + if (sentrycrashfu_readEntireFile(filePath, &data, &length, 0)) { + printf("\nvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Previous Log " + "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\n"); + printf("%s\n", data); + printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" + "^^^^^^^^^^^^^^^^^^^^^\n\n"); + fflush(stdout); + } +} + +// ============================================================================ +#pragma mark - Callbacks - +// ============================================================================ + +/** Called when a crash occurs. + * + * This function gets passed as a callback to a crash handler. + */ +static void +onCrash(struct SentryCrash_MonitorContext *monitorContext) +{ + if (monitorContext->currentSnapshotUserReported == false) { + SentryCrashLOG_DEBUG("Updating application state to note crash."); + sentrycrashstate_notifyAppCrash(); + } + monitorContext->consoleLogPath = g_shouldAddConsoleLogToReport ? g_consoleLogPath : NULL; + + if (monitorContext->crashedDuringCrashHandling) { + sentrycrashreport_writeRecrashReport(monitorContext, g_lastCrashReportFilePath); + } else { + char crashReportFilePath[SentryCrashFU_MAX_PATH_LENGTH]; + sentrycrashcrs_getNextCrashReportPath(crashReportFilePath); + strncpy(g_lastCrashReportFilePath, crashReportFilePath, sizeof(g_lastCrashReportFilePath)); + sentrycrashreport_writeStandardReport(monitorContext, crashReportFilePath); + } +} + +// ============================================================================ +#pragma mark - API - +// ============================================================================ + +SentryCrashMonitorType +sentrycrash_install(const char *appName, const char *const installPath) +{ + SentryCrashLOG_DEBUG("Installing crash reporter."); + + if (g_installed) { + SentryCrashLOG_DEBUG("Crash reporter already installed."); + return g_monitoring; + } + g_installed = 1; + + char path[SentryCrashFU_MAX_PATH_LENGTH]; + snprintf(path, sizeof(path), "%s/Reports", installPath); + sentrycrashfu_makePath(path); + sentrycrashcrs_initialize(appName, path); + + snprintf(path, sizeof(path), "%s/Data", installPath); + sentrycrashfu_makePath(path); + snprintf(path, sizeof(path), "%s/Data/CrashState.json", installPath); + sentrycrashstate_initialize(path); + + snprintf(g_consoleLogPath, sizeof(g_consoleLogPath), "%s/Data/ConsoleLog.txt", installPath); + if (g_shouldPrintPreviousLog) { + printPreviousLog(g_consoleLogPath); + } + sentrycrashlog_setLogFilename(g_consoleLogPath, true); + + sentrycrashccd_init(60); + + sentrycrashcm_setEventCallback(onCrash); + SentryCrashMonitorType monitors = sentrycrash_setMonitoring(g_monitoring); + + SentryCrashLOG_DEBUG("Installation complete."); + return monitors; +} + +SentryCrashMonitorType +sentrycrash_setMonitoring(SentryCrashMonitorType monitors) +{ + g_monitoring = monitors; + + if (g_installed) { + sentrycrashcm_setActiveMonitors(monitors); + return sentrycrashcm_getActiveMonitors(); + } + // Return what we will be monitoring in future. + return g_monitoring; +} + +void +sentrycrash_setUserInfoJSON(const char *const userInfoJSON) +{ + sentrycrashreport_setUserInfoJSON(userInfoJSON); +} + +void +sentrycrash_setDeadlockWatchdogInterval(double deadlockWatchdogInterval) +{ +#if SentryCrashCRASH_HAS_OBJC + sentrycrashcm_setDeadlockHandlerWatchdogInterval(deadlockWatchdogInterval); +#endif +} + +void +sentrycrash_setIntrospectMemory(bool introspectMemory) +{ + sentrycrashreport_setIntrospectMemory(introspectMemory); +} + +void +sentrycrash_setDoNotIntrospectClasses(const char **doNotIntrospectClasses, int length) +{ + sentrycrashreport_setDoNotIntrospectClasses(doNotIntrospectClasses, length); +} + +void +sentrycrash_setCrashNotifyCallback(const SentryCrashReportWriteCallback onCrashNotify) +{ + sentrycrashreport_setUserSectionWriteCallback(onCrashNotify); +} + +void +sentrycrash_setAddConsoleLogToReport(bool shouldAddConsoleLogToReport) +{ + g_shouldAddConsoleLogToReport = shouldAddConsoleLogToReport; +} + +void +sentrycrash_setPrintPreviousLog(bool shouldPrintPreviousLog) +{ + g_shouldPrintPreviousLog = shouldPrintPreviousLog; +} + +void +sentrycrash_setMaxReportCount(int maxReportCount) +{ + sentrycrashcrs_setMaxReportCount(maxReportCount); +} + +void +sentrycrash_reportUserException(const char *name, const char *reason, const char *language, + const char *lineOfCode, const char *stackTrace, bool logAllThreads, bool terminateProgram) +{ + sentrycrashcm_reportUserException( + name, reason, language, lineOfCode, stackTrace, logAllThreads, terminateProgram); + if (g_shouldAddConsoleLogToReport) { + sentrycrashlog_clearLogFile(); + } +} + +void +sentrycrash_notifyAppActive(bool isActive) +{ + sentrycrashstate_notifyAppActive(isActive); +} + +void +sentrycrash_notifyAppInForeground(bool isInForeground) +{ + sentrycrashstate_notifyAppInForeground(isInForeground); +} + +void +sentrycrash_notifyAppTerminate(void) +{ + sentrycrashstate_notifyAppTerminate(); +} + +void +sentrycrash_notifyAppCrash(void) +{ + sentrycrashstate_notifyAppCrash(); +} + +int +sentrycrash_getReportCount() +{ + return sentrycrashcrs_getReportCount(); +} + +int +sentrycrash_getReportIDs(int64_t *reportIDs, int count) +{ + return sentrycrashcrs_getReportIDs(reportIDs, count); +} + +char * +sentrycrash_readReport(int64_t reportID) +{ + if (reportID <= 0) { + SentryCrashLOG_ERROR("Report ID was %" PRIx64, reportID); + return NULL; + } + + char *rawReport = sentrycrashcrs_readReport(reportID); + if (rawReport == NULL) { + SentryCrashLOG_ERROR("Failed to load report ID %" PRIx64, reportID); + return NULL; + } + + char *fixedReport = sentrycrashcrf_fixupCrashReport(rawReport); + if (fixedReport == NULL) { + SentryCrashLOG_ERROR("Failed to fixup report ID %" PRIx64, reportID); + } + + free(rawReport); + return fixedReport; +} + +int64_t +sentrycrash_addUserReport(const char *report, int reportLength) +{ + return sentrycrashcrs_addUserReport(report, reportLength); +} + +void +sentrycrash_deleteAllReports() +{ + sentrycrashcrs_deleteAllReports(); +} + +void +sentrycrash_deleteReportWithID(int64_t reportID) +{ + sentrycrashcrs_deleteReportWithID(reportID); +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashC.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashC.h new file mode 100644 index 00000000..f22e210f --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashC.h @@ -0,0 +1,235 @@ +// +// SentryCrashC.h +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Primary C entry point into the crash reporting system. + */ + +#ifndef HDR_SentryCrashC_h +#define HDR_SentryCrashC_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMonitorType.h" +#include "SentryCrashReportWriter.h" + +#include + +/** Install the crash reporter. The reporter will record the next crash and then + * terminate the program. + * + * @param installPath Directory to install to. + * + * @return The crash types that are being handled. + */ +SentryCrashMonitorType sentrycrash_install(const char *appName, const char *const installPath); + +/** Set the crash types that will be handled. + * Some crash types may not be enabled depending on circumstances (e.g. running + * in a debugger). + * + * @param monitors The monitors to install. + * + * @return The monitors that were installed. If SentryCrash has been + * installed, the return value represents the monitors that were + * successfully installed. Otherwise it represents which monitors it + * will attempt to activate when SentryCrash installs. + */ +SentryCrashMonitorType sentrycrash_setMonitoring(SentryCrashMonitorType monitors); + +/** Set the user-supplied data in JSON format. + * + * @param userInfoJSON Pre-baked JSON containing user-supplied information. + * NULL = delete. + */ +void sentrycrash_setUserInfoJSON(const char *const userInfoJSON); + +/** Set the maximum time to allow the main thread to run without returning. + * If a task occupies the main thread for longer than this interval, the + * watchdog will consider the queue deadlocked and shut down the app and write a + * crash report. + * + * Warning: Make SURE that nothing in your app that runs on the main thread + * takes longer to complete than this value or it WILL get shut down! This + * includes your app startup process, so you may need to push app initialization + * to another thread, or perhaps set this to a higher value until your + * application has been fully initialized. + * + * 0 = Disabled. + * + * Default: 0 + */ +void sentrycrash_setDeadlockWatchdogInterval(double deadlockWatchdogInterval); + +/** If true, introspect memory contents during a crash. + * Any Objective-C objects or C strings near the stack pointer or referenced by + * cpu registers or exceptions will be recorded in the crash report, along with + * their contents. + * + * Default: false + */ +void sentrycrash_setIntrospectMemory(bool introspectMemory); + +/** List of Objective-C classes that should never be introspected. + * Whenever a class in this list is encountered, only the class name will be + * recorded. This can be useful for information security concerns. + * + * Default: NULL + */ +void sentrycrash_setDoNotIntrospectClasses(const char **doNotIntrospectClasses, int length); + +/** Set the callback to invoke upon a crash. + * + * WARNING: Only call async-safe functions from this function! DO NOT call + * Objective-C methods!!! + * + * @param onCrashNotify Function to call during a crash report to give the + * callee an opportunity to add to the report. + * NULL = ignore. + * + * Default: NULL + */ +void sentrycrash_setCrashNotifyCallback(const SentryCrashReportWriteCallback onCrashNotify); + +/** Set if SentryCrashLOG console messages should be appended to the report. + * + * @param shouldAddConsoleLogToReport If true, add the log to the report. + */ +void sentrycrash_setAddConsoleLogToReport(bool shouldAddConsoleLogToReport); + +/** Set if SentryCrash should print the previous log to the console on startup. + * This is for debugging purposes. + */ +void sentrycrash_setPrintPreviousLog(bool shouldPrintPreviousLog); + +/** Set the maximum number of reports allowed on disk before old ones get + * deleted. + * + * @param maxReportCount The maximum number of reports. + */ +void sentrycrash_setMaxReportCount(int maxReportCount); + +/** Report a custom, user defined exception. + * This can be useful when dealing with scripting languages. + * + * If terminateProgram is true, all sentries will be uninstalled and the + * application will terminate with an abort(). + * + * @param name The exception name (for namespacing exception types). + * + * @param reason A description of why the exception occurred. + * + * @param language A unique language identifier. + * + * @param lineOfCode A copy of the offending line of code (NULL = ignore). + * + * @param stackTrace JSON encoded array containing stack trace information (one + * frame per array entry). The frame structure can be anything you want, + * including bare strings. + * + * @param logAllThreads If true, suspend all threads and log their state. Note + * that this incurs a performance penalty, so it's best to use only on fatal + * errors. + * + * @param terminateProgram If true, do not return from this function call. + * Terminate the program instead. + */ +void sentrycrash_reportUserException(const char *name, const char *reason, const char *language, + const char *lineOfCode, const char *stackTrace, bool logAllThreads, bool terminateProgram); + +#pragma mark-- Notifications -- + +/** Notify the crash reporter of the application active state. + * + * @param isActive true if the application is active, otherwise false. + */ +void sentrycrash_notifyAppActive(bool isActive); + +/** Notify the crash reporter of the application foreground/background state. + * + * @param isInForeground true if the application is in the foreground, false if + * it is in the background. + */ +void sentrycrash_notifyAppInForeground(bool isInForeground); + +/** Notify the crash reporter that the application is terminating. + */ +void sentrycrash_notifyAppTerminate(void); + +/** Notify the crash reporter that the application has crashed. + */ +void sentrycrash_notifyAppCrash(void); + +#pragma mark-- Reporting -- + +/** Get the number of reports on disk. + */ +int sentrycrash_getReportCount(void); + +/** Get a list of IDs for all reports on disk. + * + * @param reportIDs An array big enough to hold all report IDs. + * @param count How many reports the array can hold. + * + * @return The number of report IDs that were placed in the array. + */ +int sentrycrash_getReportIDs(int64_t *reportIDs, int count); + +/** Read a report. + * + * @param reportID The report's ID. + * + * @return The NULL terminated report, or NULL if not found. + * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on + * the returned value. + */ +char *sentrycrash_readReport(int64_t reportID); + +/** Add a custom report to the store. + * + * @param report The report's contents (must be JSON encoded). + * @param reportLength The length of the report in bytes. + * + * @return the new report's ID. + */ +int64_t sentrycrash_addUserReport(const char *report, int reportLength); + +/** Delete all reports on disk. + */ +void sentrycrash_deleteAllReports(void); + +/** Delete report. + * + * @param reportID An ID of report to delete. + */ +void sentrycrash_deleteReportWithID(int64_t reportID); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashC_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashCachedData.c b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashCachedData.c new file mode 100644 index 00000000..ebb6216e --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashCachedData.c @@ -0,0 +1,211 @@ +// +// SentryCrashCachedData.c +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashCachedData.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include +#include +#include +#include + +#define SWAP_POINTERS(A, B) \ + { \ + void *temp = A; \ + A = B; \ + B = temp; \ + } + +static int g_pollingIntervalInSeconds; +static pthread_t g_cacheThread; +static SentryCrashThread *g_allMachThreads; +static SentryCrashThread *g_allPThreads; +static const char **g_allThreadNames; +static const char **g_allQueueNames; +static int g_allThreadsCount; +static _Atomic(int) g_semaphoreCount; + +static void +updateThreadList() +{ + const task_t thisTask = mach_task_self(); + int oldThreadsCount = g_allThreadsCount; + SentryCrashThread *allMachThreads = NULL; + SentryCrashThread *allPThreads = NULL; + static const char **allThreadNames; + static const char **allQueueNames; + + mach_msg_type_number_t allThreadsCount; + thread_act_array_t threads; + task_threads(thisTask, &threads, &allThreadsCount); + + allMachThreads = calloc(allThreadsCount, sizeof(*allMachThreads)); + allPThreads = calloc(allThreadsCount, sizeof(*allPThreads)); + allThreadNames = calloc(allThreadsCount, sizeof(*allThreadNames)); + allQueueNames = calloc(allThreadsCount, sizeof(*allQueueNames)); + + for (mach_msg_type_number_t i = 0; i < allThreadsCount; i++) { + char buffer[1000]; + thread_t thread = threads[i]; + pthread_t pthread = pthread_from_mach_thread_np(thread); + allMachThreads[i] = (SentryCrashThread)thread; + allPThreads[i] = (SentryCrashThread)pthread; + if (pthread != 0 && pthread_getname_np(pthread, buffer, sizeof(buffer)) == 0 + && buffer[0] != 0) { + allThreadNames[i] = strdup(buffer); + } + } + + g_allThreadsCount + = g_allThreadsCount < (int)allThreadsCount ? g_allThreadsCount : (int)allThreadsCount; + SWAP_POINTERS(g_allMachThreads, allMachThreads); + SWAP_POINTERS(g_allPThreads, allPThreads); + SWAP_POINTERS(g_allThreadNames, allThreadNames); + SWAP_POINTERS(g_allQueueNames, allQueueNames); + g_allThreadsCount = (int)allThreadsCount; + + if (allMachThreads != NULL) { + free(allMachThreads); + } + if (allPThreads != NULL) { + free(allPThreads); + } + if (allThreadNames != NULL) { + for (int i = 0; i < oldThreadsCount; i++) { + const char *name = allThreadNames[i]; + if (name != NULL) { + free((void *)name); + } + } + free(allThreadNames); + } + if (allQueueNames != NULL) { + for (int i = 0; i < oldThreadsCount; i++) { + const char *name = allQueueNames[i]; + if (name != NULL) { + free((void *)name); + } + } + free(allQueueNames); + } + + for (mach_msg_type_number_t i = 0; i < allThreadsCount; i++) { + mach_port_deallocate(thisTask, threads[i]); + } + vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * allThreadsCount); +} + +static void * +monitorCachedData(__unused void *const userData) +{ + static int quickPollCount = 4; + usleep(1); + for (;;) { + if (g_semaphoreCount <= 0) { + updateThreadList(); + } + unsigned pollintInterval = (unsigned)g_pollingIntervalInSeconds; + if (quickPollCount > 0) { + // Lots can happen in the first few seconds of operation. + quickPollCount--; + pollintInterval = 1; + } + sleep(pollintInterval); + } + return NULL; +} + +void +sentrycrashccd_init(int pollingIntervalInSeconds) +{ + g_pollingIntervalInSeconds = pollingIntervalInSeconds; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + int error = pthread_create( + &g_cacheThread, &attr, &monitorCachedData, "SentryCrash Cached Data Monitor"); + if (error != 0) { + SentryCrashLOG_ERROR("pthread_create_suspended_np: %s", strerror(error)); + } + pthread_attr_destroy(&attr); +} + +void +sentrycrashccd_freeze() +{ + if (g_semaphoreCount++ <= 0) { + // Sleep just in case the cached data thread is in the middle of an + // update. + usleep(1); + } +} + +void +sentrycrashccd_unfreeze() +{ + if (--g_semaphoreCount < 0) { + // Handle extra calls to unfreeze somewhat gracefully. + g_semaphoreCount++; + } +} + +SentryCrashThread * +sentrycrashccd_getAllThreads(int *threadCount) +{ + if (threadCount != NULL) { + *threadCount = g_allThreadsCount; + } + return g_allMachThreads; +} + +const char * +sentrycrashccd_getThreadName(SentryCrashThread thread) +{ + if (g_allThreadNames != NULL) { + for (int i = 0; i < g_allThreadsCount; i++) { + if (g_allMachThreads[i] == thread) { + return g_allThreadNames[i]; + } + } + } + return NULL; +} + +const char * +sentrycrashccd_getQueueName(SentryCrashThread thread) +{ + if (g_allQueueNames != NULL) { + for (int i = 0; i < g_allThreadsCount; i++) { + if (g_allMachThreads[i] == thread) { + return g_allQueueNames[i]; + } + } + } + return NULL; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashCachedData.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashCachedData.h new file mode 100644 index 00000000..2b01ffa5 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashCachedData.h @@ -0,0 +1,39 @@ +// +// SentryCrashCachedData.h +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Maintains a cache of difficult-to-retrieve data. + */ + +#include "SentryCrashThread.h" + +void sentrycrashccd_init(int pollingIntervalInSeconds); + +void sentrycrashccd_freeze(void); +void sentrycrashccd_unfreeze(void); + +SentryCrashThread *sentrycrashccd_getAllThreads(int *threadCount); + +const char *sentrycrashccd_getThreadName(SentryCrashThread thread); + +const char *sentrycrashccd_getQueueName(SentryCrashThread thread); diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashDoctor.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashDoctor.h new file mode 100644 index 00000000..af7aab96 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashDoctor.h @@ -0,0 +1,17 @@ +// +// SentryCrashDoctor.h +// SentryCrash +// +// Created by Karl Stenerud on 2012-11-10. +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// + +#import + +@interface SentryCrashDoctor : NSObject + ++ (SentryCrashDoctor *)doctor; + +- (NSString *)diagnoseCrash:(NSDictionary *)crashReport; + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashDoctor.m b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashDoctor.m new file mode 100644 index 00000000..592e96c0 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashDoctor.m @@ -0,0 +1,490 @@ +// +// SentryCrashDoctor.m +// SentryCrash +// +// Created by Karl Stenerud on 2012-11-10. +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// + +#import "SentryCrashDoctor.h" +#import "SentryCrashMonitor_System.h" +#import "SentryCrashReportFields.h" + +typedef enum { CPUFamilyUnknown, CPUFamilyArm, CPUFamilyX86, CPUFamilyX86_64 } CPUFamily; + +@interface SentryCrashDoctorParam : NSObject + +@property (nonatomic, readwrite, retain) NSString *className; +@property (nonatomic, readwrite, retain) NSString *previousClassName; +@property (nonatomic, readwrite, retain) NSString *type; +@property (nonatomic, readwrite, assign) BOOL isInstance; +@property (nonatomic, readwrite, assign) uintptr_t address; +@property (nonatomic, readwrite, retain) NSString *value; + +@end + +@implementation SentryCrashDoctorParam + +@synthesize className = _className; +@synthesize previousClassName = _previousClassName; +@synthesize isInstance = _isInstance; +@synthesize address = _address; +@synthesize value = _value; +@synthesize type = _type; + +@end + +@interface SentryCrashDoctorFunctionCall : NSObject + +@property (nonatomic, readwrite, retain) NSString *name; +@property (nonatomic, readwrite, retain) NSArray *params; + +@end + +@implementation SentryCrashDoctorFunctionCall + +@synthesize name = _name; +@synthesize params = _params; + +- (NSString *)descriptionForObjCCall +{ + if (![self.name isEqualToString:@"objc_msgSend"]) { + return nil; + } + SentryCrashDoctorParam *receiverParam = [self.params objectAtIndex:0]; + NSString *receiver = receiverParam.previousClassName; + if (receiver == nil) { + receiver = receiverParam.className; + if (receiver == nil) { + receiver = @"id"; + } + } + + SentryCrashDoctorParam *selectorParam = [self.params objectAtIndex:1]; + if (![selectorParam.type isEqualToString:@SentryCrashMemType_String]) { + return nil; + } + NSArray *splitSelector = [selectorParam.value componentsSeparatedByString:@":"]; + int paramCount = (int)splitSelector.count - 1; + + NSMutableString *string = + [NSMutableString stringWithFormat:@"-[%@ %@", receiver, [splitSelector objectAtIndex:0]]; + for (int paramNum = 0; paramNum < paramCount; paramNum++) { + [string appendString:@":"]; + if (paramNum < 2) { + SentryCrashDoctorParam *param = [self.params objectAtIndex:(NSUInteger)paramNum + 2]; + if (param.value != nil) { + if ([param.type isEqualToString:@SentryCrashMemType_String]) { + [string appendFormat:@"\"%@\"", param.value]; + } else { + [string appendString:param.value]; + } + } else if (param.previousClassName != nil) { + [string appendString:param.previousClassName]; + } else if (param.className != nil) { + [string appendFormat:@"%@ (%@)", param.className, + param.isInstance ? @"instance" : @"class"]; + } else { + [string appendString:@"?"]; + } + } else { + [string appendString:@"?"]; + } + if (paramNum < paramCount - 1) { + [string appendString:@" "]; + } + } + + [string appendString:@"]"]; + return string; +} + +- (NSString *)descriptionWithParamCount:(int)paramCount +{ + NSString *objCCall = [self descriptionForObjCCall]; + if (objCCall != nil) { + return objCCall; + } + + if (paramCount > (int)self.params.count) { + paramCount = (int)self.params.count; + } + NSMutableString *str = [NSMutableString string]; + [str appendFormat:@"Function: %@\n", self.name]; + for (int i = 0; i < paramCount; i++) { + SentryCrashDoctorParam *param = [self.params objectAtIndex:(NSUInteger)i]; + [str appendFormat:@"Param %d: ", i + 1]; + if (param.className != nil) { + [str appendFormat:@"%@ (%@) ", param.className, + param.isInstance ? @"instance" : @"class"]; + } + if (param.value != nil) { + [str appendFormat:@"%@ ", param.value]; + } + if (param.previousClassName != nil) { + [str appendFormat:@"(was %@)", param.previousClassName]; + } + if (i < paramCount - 1) { + [str appendString:@"\n"]; + } + } + return str; +} + +@end + +@implementation SentryCrashDoctor + ++ (SentryCrashDoctor *)doctor +{ + return [[self alloc] init]; +} + +- (NSDictionary *)recrashReport:(NSDictionary *)report +{ + return [report objectForKey:@SentryCrashField_RecrashReport]; +} + +- (NSDictionary *)systemReport:(NSDictionary *)report +{ + return [report objectForKey:@SentryCrashField_System]; +} + +- (NSDictionary *)crashReport:(NSDictionary *)report +{ + return [report objectForKey:@SentryCrashField_Crash]; +} + +- (NSDictionary *)infoReport:(NSDictionary *)report +{ + return [report objectForKey:@SentryCrashField_Report]; +} + +- (NSDictionary *)errorReport:(NSDictionary *)report +{ + return [[self crashReport:report] objectForKey:@SentryCrashField_Error]; +} + +- (CPUFamily)cpuFamily:(NSDictionary *)report +{ + NSDictionary *system = [self systemReport:report]; + NSString *cpuArch = [system objectForKey:@SentryCrashField_CPUArch]; + if ([cpuArch rangeOfString:@"arm"].location == 0) { + return CPUFamilyArm; + } + if ([cpuArch rangeOfString:@"i"].location == 0 && [cpuArch rangeOfString:@"86"].location == 2) { + return CPUFamilyX86; + } + if ([cpuArch rangeOfString:@"x86_64" options:NSCaseInsensitiveSearch].location != NSNotFound) { + return CPUFamilyX86_64; + } + return CPUFamilyUnknown; +} + +- (NSString *)registerNameForFamily:(CPUFamily)family paramIndex:(int)index +{ + switch (family) { + case CPUFamilyArm: { + switch (index) { + case 0: + return @"r0"; + case 1: + return @"r1"; + case 2: + return @"r2"; + case 3: + return @"r3"; + } + } + case CPUFamilyX86: { + switch (index) { + case 0: + return @"edi"; + case 1: + return @"esi"; + case 2: + return @"edx"; + case 3: + return @"ecx"; + } + } + case CPUFamilyX86_64: { + switch (index) { + case 0: + return @"rdi"; + case 1: + return @"rsi"; + case 2: + return @"rdx"; + case 3: + return @"rcx"; + } + } + case CPUFamilyUnknown: + return nil; + } + return nil; +} + +- (NSString *)mainExecutableNameForReport:(NSDictionary *)report +{ + NSDictionary *info = [self infoReport:report]; + return [info objectForKey:@SentryCrashField_ProcessName]; +} + +- (NSDictionary *)crashedThreadReport:(NSDictionary *)report +{ + NSDictionary *crashReport = [self crashReport:report]; + NSDictionary *crashedThread = [crashReport objectForKey:@SentryCrashField_CrashedThread]; + if (crashedThread != nil) { + return crashedThread; + } + + for (NSDictionary *thread in [crashReport objectForKey:@SentryCrashField_Threads]) { + if ([[thread objectForKey:@SentryCrashField_Crashed] boolValue]) { + return thread; + } + } + return nil; +} + +- (NSArray *)backtraceFromThreadReport:(NSDictionary *)threadReport +{ + NSDictionary *backtrace = [threadReport objectForKey:@SentryCrashField_Backtrace]; + return [backtrace objectForKey:@SentryCrashField_Contents]; +} + +- (NSDictionary *)basicRegistersFromThreadReport:(NSDictionary *)threadReport +{ + NSDictionary *registers = [threadReport objectForKey:@SentryCrashField_Registers]; + NSDictionary *basic = [registers objectForKey:@SentryCrashField_Basic]; + return basic; +} + +- (NSDictionary *)lastInAppStackEntry:(NSDictionary *)report +{ + NSString *executableName = [self mainExecutableNameForReport:report]; + NSDictionary *crashedThread = [self crashedThreadReport:report]; + NSArray *backtrace = [self backtraceFromThreadReport:crashedThread]; + for (NSDictionary *entry in backtrace) { + NSString *objectName = [entry objectForKey:@SentryCrashField_ObjectName]; + if ([objectName isEqualToString:executableName]) { + return entry; + } + } + return nil; +} + +- (NSDictionary *)lastStackEntry:(NSDictionary *)report +{ + NSDictionary *crashedThread = [self crashedThreadReport:report]; + NSArray *backtrace = [self backtraceFromThreadReport:crashedThread]; + if ([backtrace count] > 0) { + return [backtrace objectAtIndex:0]; + } + return nil; +} + +- (BOOL)isInvalidAddress:(NSDictionary *)errorReport +{ + NSDictionary *machError = [errorReport objectForKey:@SentryCrashField_Mach]; + if (machError != nil) { + NSString *exceptionName = [machError objectForKey:@SentryCrashField_ExceptionName]; + return [exceptionName isEqualToString:@"EXC_BAD_ACCESS"]; + } + NSDictionary *signal = [errorReport objectForKey:@SentryCrashField_Signal]; + NSString *sigName = [signal objectForKey:@SentryCrashField_Name]; + return [sigName isEqualToString:@"SIGSEGV"]; +} + +- (BOOL)isMathError:(NSDictionary *)errorReport +{ + NSDictionary *machError = [errorReport objectForKey:@SentryCrashField_Mach]; + if (machError != nil) { + NSString *exceptionName = [machError objectForKey:@SentryCrashField_ExceptionName]; + return [exceptionName isEqualToString:@"EXC_ARITHMETIC"]; + } + NSDictionary *signal = [errorReport objectForKey:@SentryCrashField_Signal]; + NSString *sigName = [signal objectForKey:@SentryCrashField_Name]; + return [sigName isEqualToString:@"SIGFPE"]; +} + +- (BOOL)isMemoryCorruption:(NSDictionary *)report +{ + NSDictionary *crashedThread = [self crashedThreadReport:report]; + NSArray *notableAddresses = [crashedThread objectForKey:@SentryCrashField_NotableAddresses]; + for (NSDictionary *address in [notableAddresses objectEnumerator]) { + NSString *type = [address objectForKey:@SentryCrashField_Type]; + if ([type isEqualToString:@"string"]) { + NSString *value = [address objectForKey:@SentryCrashField_Value]; + if ([value rangeOfString:@"autorelease pool page"].location != NSNotFound && + [value rangeOfString:@"corrupted"].location != NSNotFound) { + return YES; + } + if ([value rangeOfString:@"incorrect checksum for freed object"].location + != NSNotFound) { + return YES; + } + } + } + + NSArray *backtrace = [self backtraceFromThreadReport:crashedThread]; + for (NSDictionary *entry in backtrace) { + NSString *objectName = [entry objectForKey:@SentryCrashField_ObjectName]; + NSString *symbolName = [entry objectForKey:@SentryCrashField_SymbolName]; + if ([symbolName isEqualToString:@"objc_autoreleasePoolPush"]) { + return YES; + } + if ([symbolName isEqualToString:@"free_list_checksum_botch"]) { + return YES; + } + if ([symbolName isEqualToString:@"szone_malloc_should_clear"]) { + return YES; + } + if ([symbolName isEqualToString:@"lookUpMethod"] && + [objectName isEqualToString:@"libobjc.A.dylib"]) { + return YES; + } + } + + return NO; +} + +- (SentryCrashDoctorFunctionCall *)lastFunctionCall:(NSDictionary *)report +{ + SentryCrashDoctorFunctionCall *function = [[SentryCrashDoctorFunctionCall alloc] init]; + NSDictionary *lastStackEntry = [self lastStackEntry:report]; + function.name = [lastStackEntry objectForKey:@SentryCrashField_SymbolName]; + + NSDictionary *crashedThread = [self crashedThreadReport:report]; + NSDictionary *notableAddresses = + [crashedThread objectForKey:@SentryCrashField_NotableAddresses]; + CPUFamily family = [self cpuFamily:report]; + NSDictionary *registers = [self basicRegistersFromThreadReport:crashedThread]; + NSArray *regNames = [NSArray arrayWithObjects:[self registerNameForFamily:family paramIndex:0], + [self registerNameForFamily:family paramIndex:1], + [self registerNameForFamily:family paramIndex:2], + [self registerNameForFamily:family paramIndex:3], nil]; + NSMutableArray *params = [NSMutableArray arrayWithCapacity:4]; + for (NSString *regName in regNames) { + SentryCrashDoctorParam *param = [[SentryCrashDoctorParam alloc] init]; + param.address = (uintptr_t)[[registers objectForKey:regName] unsignedLongLongValue]; + NSDictionary *notableAddress = [notableAddresses objectForKey:regName]; + if (notableAddress == nil) { + param.value = [NSString stringWithFormat:@"%p", (void *)param.address]; + } else { + param.type = [notableAddress objectForKey:@SentryCrashField_Type]; + NSString *className = [notableAddress objectForKey:@SentryCrashField_Class]; + NSString *previousClass = + [notableAddress objectForKey:@SentryCrashField_LastDeallocObject]; + NSString *value = [notableAddress objectForKey:@SentryCrashField_Value]; + + if ([param.type isEqualToString:@SentryCrashMemType_String]) { + param.value = value; + } else if ([param.type isEqualToString:@SentryCrashMemType_Object]) { + param.className = className; + param.isInstance = YES; + } else if ([param.type isEqualToString:@SentryCrashMemType_Class]) { + param.className = className; + param.isInstance = NO; + } + param.previousClassName = previousClass; + } + + [params addObject:param]; + } + + function.params = params; + return function; +} + +- (NSString *)zombieCall:(SentryCrashDoctorFunctionCall *)functionCall +{ + if ([functionCall.name isEqualToString:@"objc_msgSend"] && functionCall.params.count > 0 && + [[functionCall.params objectAtIndex:0] previousClassName] != nil) { + return [functionCall descriptionWithParamCount:4]; + } else if ([functionCall.name isEqualToString:@"objc_retain"] && functionCall.params.count > 0 + && [[functionCall.params objectAtIndex:0] previousClassName] != nil) { + return [functionCall descriptionWithParamCount:1]; + } + return nil; +} + +- (BOOL)isStackOverflow:(NSDictionary *)crashedThreadReport +{ + NSDictionary *stack = [crashedThreadReport objectForKey:@SentryCrashField_Stack]; + return [[stack objectForKey:@SentryCrashField_Overflow] boolValue]; +} + +- (BOOL)isDeadlock:(NSDictionary *)report +{ + NSDictionary *errorReport = [self errorReport:report]; + NSString *crashType = [errorReport objectForKey:@SentryCrashField_Type]; + return [@SentryCrashExcType_Deadlock isEqualToString:crashType]; +} + +- (NSString *)diagnoseCrash:(NSDictionary *)report +{ + @try { + NSString *lastFunctionName = + [[self lastInAppStackEntry:report] objectForKey:@SentryCrashField_SymbolName]; + NSDictionary *crashedThreadReport = [self crashedThreadReport:report]; + NSDictionary *errorReport = [self errorReport:report]; + + if ([self isDeadlock:report]) { + return [NSString stringWithFormat:@"Main thread deadlocked in %@", lastFunctionName]; + } + + if ([self isStackOverflow:crashedThreadReport]) { + return [NSString stringWithFormat:@"Stack overflow in %@", lastFunctionName]; + } + + NSString *crashType = [errorReport objectForKey:@SentryCrashField_Type]; + if ([crashType isEqualToString:@SentryCrashExcType_NSException]) { + NSDictionary *exception = [errorReport objectForKey:@SentryCrashField_NSException]; + NSString *name = [exception objectForKey:@SentryCrashField_Name]; + NSString *reason = [exception objectForKey:@SentryCrashField_Reason] + ? [exception objectForKey:@SentryCrashField_Reason] + : [errorReport objectForKey:@SentryCrashField_Reason]; + return [NSString stringWithFormat:@"Application threw exception %@: %@", name, reason]; + } + + if ([self isMemoryCorruption:report]) { + return @"Rogue memory write has corrupted memory."; + } + + if ([self isMathError:errorReport]) { + return @"Math error (usually caused from division by 0)."; + } + + SentryCrashDoctorFunctionCall *functionCall = [self lastFunctionCall:report]; + NSString *zombieCall = [self zombieCall:functionCall]; + if (zombieCall != nil) { + return [NSString stringWithFormat:@"Possible zombie in call: %@", zombieCall]; + } + + if ([self isInvalidAddress:errorReport]) { + uintptr_t address = (uintptr_t)[ + [errorReport objectForKey:@SentryCrashField_Address] unsignedLongLongValue]; + if (address == 0) { + return @"Attempted to dereference null pointer."; + } + return [NSString + stringWithFormat:@"Attempted to dereference garbage pointer %p.", (void *)address]; + } + + return nil; + } @catch (NSException *e) { + NSArray *symbols = [e callStackSymbols]; + if (symbols) { + return [NSString stringWithFormat:@"No diagnosis due to exception %@:\n%@\nPlease " + @"file a bug report to the SentryCrash project.", + e, symbols]; + } + return [NSString stringWithFormat:@"No diagnosis due to exception %@\nPlease file a " + @"bug report to the SentryCrash project.", + e]; + } +} + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReport.c b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReport.c new file mode 100644 index 00000000..bb87492a --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReport.c @@ -0,0 +1,1782 @@ +// +// SentryCrashReport.m +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashReport.h" + +#include "SentryCrashCPU.h" +#include "SentryCrashCachedData.h" +#include "SentryCrashDynamicLinker.h" +#include "SentryCrashFileUtils.h" +#include "SentryCrashJSONCodec.h" +#include "SentryCrashMach.h" +#include "SentryCrashMemory.h" +#include "SentryCrashMonitor_Zombie.h" +#include "SentryCrashObjC.h" +#include "SentryCrashReportFields.h" +#include "SentryCrashReportVersion.h" +#include "SentryCrashReportWriter.h" +#include "SentryCrashSignalInfo.h" +#include "SentryCrashStackCursor_Backtrace.h" +#include "SentryCrashStackCursor_MachineContext.h" +#include "SentryCrashString.h" +#include "SentryCrashSystemCapabilities.h" +#include "SentryCrashThread.h" +#include "SentryCrashUUIDConversion.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include +#include +#include +#include + +// ============================================================================ +#pragma mark - Constants - +// ============================================================================ + +/** Default number of objects, subobjects, and ivars to record from a memory loc + */ +#define kDefaultMemorySearchDepth 15 + +/** How far to search the stack (in pointer sized jumps) for notable data. */ +#define kStackNotableSearchBackDistance 20 +#define kStackNotableSearchForwardDistance 10 + +/** How much of the stack to dump (in pointer sized jumps). */ +#define kStackContentsPushedDistance 20 +#define kStackContentsPoppedDistance 10 +#define kStackContentsTotalDistance (kStackContentsPushedDistance + kStackContentsPoppedDistance) + +/** The minimum length for a valid string. */ +#define kMinStringLength 4 + +// ============================================================================ +#pragma mark - JSON Encoding - +// ============================================================================ + +#define getJsonContext(REPORT_WRITER) ((SentryCrashJSONEncodeContext *)((REPORT_WRITER)->context)) + +// ============================================================================ +#pragma mark - Runtime Config - +// ============================================================================ + +typedef struct { + /** If YES, introspect memory contents during a crash. + * Any Objective-C objects or C strings near the stack pointer or referenced + * by cpu registers or exceptions will be recorded in the crash report, + * along with their contents. + */ + bool enabled; + + /** List of classes that should never be introspected. + * Whenever a class in this list is encountered, only the class name will be + * recorded. + */ + const char **restrictedClasses; + int restrictedClassesCount; +} SentryCrash_IntrospectionRules; + +static const char *g_userInfoJSON; +static SentryCrash_IntrospectionRules g_introspectionRules; +static SentryCrashReportWriteCallback g_userSectionWriteCallback; + +#pragma mark Callbacks + +static void +addBooleanElement( + const SentryCrashReportWriter *const writer, const char *const key, const bool value) +{ + sentrycrashjson_addBooleanElement(getJsonContext(writer), key, value); +} + +static void +addFloatingPointElement( + const SentryCrashReportWriter *const writer, const char *const key, const double value) +{ + sentrycrashjson_addFloatingPointElement(getJsonContext(writer), key, value); +} + +static void +addIntegerElement( + const SentryCrashReportWriter *const writer, const char *const key, const int64_t value) +{ + sentrycrashjson_addIntegerElement(getJsonContext(writer), key, value); +} + +static void +addUIntegerElement( + const SentryCrashReportWriter *const writer, const char *const key, const uint64_t value) +{ + sentrycrashjson_addIntegerElement(getJsonContext(writer), key, (int64_t)value); +} + +static void +addStringElement( + const SentryCrashReportWriter *const writer, const char *const key, const char *const value) +{ + sentrycrashjson_addStringElement( + getJsonContext(writer), key, value, SentryCrashJSON_SIZE_AUTOMATIC); +} + +static void +addTextFileElement( + const SentryCrashReportWriter *const writer, const char *const key, const char *const filePath) +{ + const int fd = open(filePath, O_RDONLY); + if (fd < 0) { + SentryCrashLOG_ERROR("Could not open file %s: %s", filePath, strerror(errno)); + return; + } + + if (sentrycrashjson_beginStringElement(getJsonContext(writer), key) != SentryCrashJSON_OK) { + SentryCrashLOG_ERROR("Could not start string element"); + goto done; + } + + char buffer[512]; + int bytesRead; + for (bytesRead = (int)read(fd, buffer, sizeof(buffer)); bytesRead > 0; + bytesRead = (int)read(fd, buffer, sizeof(buffer))) { + if (sentrycrashjson_appendStringElement(getJsonContext(writer), buffer, bytesRead) + != SentryCrashJSON_OK) { + SentryCrashLOG_ERROR("Could not append string element"); + goto done; + } + } + +done: + sentrycrashjson_endStringElement(getJsonContext(writer)); + close(fd); +} + +static void +addDataElement(const SentryCrashReportWriter *const writer, const char *const key, + const char *const value, const int length) +{ + sentrycrashjson_addDataElement(getJsonContext(writer), key, value, length); +} + +static void +beginDataElement(const SentryCrashReportWriter *const writer, const char *const key) +{ + sentrycrashjson_beginDataElement(getJsonContext(writer), key); +} + +static void +appendDataElement( + const SentryCrashReportWriter *const writer, const char *const value, const int length) +{ + sentrycrashjson_appendDataElement(getJsonContext(writer), value, length); +} + +static void +endDataElement(const SentryCrashReportWriter *const writer) +{ + sentrycrashjson_endDataElement(getJsonContext(writer)); +} + +static void +addUUIDElement(const SentryCrashReportWriter *const writer, const char *const key, + const unsigned char *const value) +{ + if (value == NULL) { + sentrycrashjson_addNullElement(getJsonContext(writer), key); + } else { + int uuidLength = 36; + char uuidBuffer[uuidLength + 1]; // one for the null terminator + const unsigned char *src = value; + char *dst = uuidBuffer; + + sentrycrashdl_convertBinaryImageUUID(src, dst); + + sentrycrashjson_addStringElement(getJsonContext(writer), key, uuidBuffer, uuidLength); + } +} + +static void +addJSONElement(const SentryCrashReportWriter *const writer, const char *const key, + const char *const jsonElement, bool closeLastContainer) +{ + int jsonResult = sentrycrashjson_addJSONElement( + getJsonContext(writer), key, jsonElement, (int)strlen(jsonElement), closeLastContainer); + if (jsonResult != SentryCrashJSON_OK) { + char errorBuff[100]; + snprintf(errorBuff, sizeof(errorBuff), "Invalid JSON data: %s", + sentrycrashjson_stringForError(jsonResult)); + sentrycrashjson_beginObject(getJsonContext(writer), key); + sentrycrashjson_addStringElement(getJsonContext(writer), SentryCrashField_Error, errorBuff, + SentryCrashJSON_SIZE_AUTOMATIC); + sentrycrashjson_addStringElement(getJsonContext(writer), SentryCrashField_JSONData, + jsonElement, SentryCrashJSON_SIZE_AUTOMATIC); + sentrycrashjson_endContainer(getJsonContext(writer)); + } +} + +static void +addJSONElementFromFile(const SentryCrashReportWriter *const writer, const char *const key, + const char *const filePath, bool closeLastContainer) +{ + sentrycrashjson_addJSONFromFile(getJsonContext(writer), key, filePath, closeLastContainer); +} + +static void +beginObject(const SentryCrashReportWriter *const writer, const char *const key) +{ + sentrycrashjson_beginObject(getJsonContext(writer), key); +} + +static void +beginArray(const SentryCrashReportWriter *const writer, const char *const key) +{ + sentrycrashjson_beginArray(getJsonContext(writer), key); +} + +static void +endContainer(const SentryCrashReportWriter *const writer) +{ + sentrycrashjson_endContainer(getJsonContext(writer)); +} + +static void +addTextLinesFromFile( + const SentryCrashReportWriter *const writer, const char *const key, const char *const filePath) +{ + char readBuffer[1024]; + SentryCrashBufferedReader reader; + if (!sentrycrashfu_openBufferedReader(&reader, filePath, readBuffer, sizeof(readBuffer))) { + return; + } + char buffer[1024]; + beginArray(writer, key); + { + for (;;) { + int length = sizeof(buffer); + sentrycrashfu_readBufferedReaderUntilChar(&reader, '\n', buffer, &length); + if (length <= 0) { + break; + } + buffer[length - 1] = '\0'; + sentrycrashjson_addStringElement( + getJsonContext(writer), NULL, buffer, SentryCrashJSON_SIZE_AUTOMATIC); + } + } + endContainer(writer); + sentrycrashfu_closeBufferedReader(&reader); +} + +static int +addJSONData(const char *restrict const data, const int length, void *restrict userData) +{ + SentryCrashBufferedWriter *writer = (SentryCrashBufferedWriter *)userData; + const bool success = sentrycrashfu_writeBufferedWriter(writer, data, length); + return success ? SentryCrashJSON_OK : SentryCrashJSON_ERROR_CANNOT_ADD_DATA; +} + +// ============================================================================ +#pragma mark - Utility - +// ============================================================================ + +/** Check if a memory address points to a valid null terminated UTF-8 string. + * + * @param address The address to check. + * + * @return true if the address points to a string. + */ +static bool +isValidString(const void *const address) +{ + if ((void *)address == NULL) { + return false; + } + + char buffer[500]; + if ((uintptr_t)address + sizeof(buffer) < (uintptr_t)address) { + // Wrapped around the address range. + return false; + } + if (!sentrycrashmem_copySafely(address, buffer, sizeof(buffer))) { + return false; + } + return sentrycrashstring_isNullTerminatedUTF8String(buffer, kMinStringLength, sizeof(buffer)); +} + +/** Get the backtrace for the specified machine context. + * + * This function will choose how to fetch the backtrace based on the crash and + * machine context. It may store the backtrace in backtraceBuffer unless it can + * be fetched directly from memory. Do not count on backtraceBuffer containing + * anything. Always use the return value. + * + * @param crash The crash handler context. + * + * @param machineContext The machine context. + * + * @param cursor The stack cursor to fill. + * + * @return True if the cursor was filled. + */ +static bool +getStackCursor(const SentryCrash_MonitorContext *const crash, + const struct SentryCrashMachineContext *const machineContext, SentryCrashStackCursor *cursor) +{ + if (sentrycrashmc_getThreadFromContext(machineContext) + == sentrycrashmc_getThreadFromContext(crash->offendingMachineContext)) { + *cursor = *((SentryCrashStackCursor *)crash->stackCursor); + return true; + } + + sentrycrashsc_initWithMachineContext( + cursor, SentryCrashSC_STACK_OVERFLOW_THRESHOLD, machineContext); + return true; +} + +// ============================================================================ +#pragma mark - Report Writing - +// ============================================================================ + +/** Write the contents of a memory location. + * Also writes meta information about the data. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param address The memory address. + * + * @param limit How many more subreferenced objects to write, if any. + */ +static void writeMemoryContents(const SentryCrashReportWriter *const writer, const char *const key, + const uintptr_t address, int *limit); + +/** Write a string to the report. + * This will only print the first child of the array. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param objectAddress The object's address. + * + * @param limit How many more subreferenced objects to write, if any. + */ +static void +writeNSStringContents(const SentryCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, __unused int *limit) +{ + const void *object = (const void *)objectAddress; + char buffer[200]; + if (sentrycrashobjc_copyStringContents(object, buffer, sizeof(buffer))) { + writer->addStringElement(writer, key, buffer); + } +} + +/** Write a URL to the report. + * This will only print the first child of the array. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param objectAddress The object's address. + * + * @param limit How many more subreferenced objects to write, if any. + */ +static void +writeURLContents(const SentryCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, __unused int *limit) +{ + const void *object = (const void *)objectAddress; + char buffer[200]; + if (sentrycrashobjc_copyStringContents(object, buffer, sizeof(buffer))) { + writer->addStringElement(writer, key, buffer); + } +} + +/** Write a date to the report. + * This will only print the first child of the array. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param objectAddress The object's address. + * + * @param limit How many more subreferenced objects to write, if any. + */ +static void +writeDateContents(const SentryCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, __unused int *limit) +{ + const void *object = (const void *)objectAddress; + writer->addFloatingPointElement(writer, key, sentrycrashobjc_dateContents(object)); +} + +/** Write a number to the report. + * This will only print the first child of the array. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param objectAddress The object's address. + * + * @param limit How many more subreferenced objects to write, if any. + */ +static void +writeNumberContents(const SentryCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, __unused int *limit) +{ + const void *object = (const void *)objectAddress; + writer->addFloatingPointElement(writer, key, sentrycrashobjc_numberAsFloat(object)); +} + +/** Write an array to the report. + * This will only print the first child of the array. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param objectAddress The object's address. + * + * @param limit How many more subreferenced objects to write, if any. + */ +static void +writeArrayContents(const SentryCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, int *limit) +{ + const void *object = (const void *)objectAddress; + uintptr_t firstObject; + if (sentrycrashobjc_arrayContents(object, &firstObject, 1) == 1) { + writeMemoryContents(writer, key, firstObject, limit); + } +} + +/** Write out ivar information about an unknown object. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param objectAddress The object's address. + * + * @param limit How many more subreferenced objects to write, if any. + */ +static void +writeUnknownObjectContents(const SentryCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, int *limit) +{ + (*limit)--; + const void *object = (const void *)objectAddress; + SentryCrashObjCIvar ivars[10]; + int8_t s8; + int16_t s16; + int sInt; + int32_t s32; + int64_t s64; + uint8_t u8; + uint16_t u16; + unsigned int uInt; + uint32_t u32; + uint64_t u64; + float f32; + double f64; + bool b; + void *pointer; + + writer->beginObject(writer, key); + { + if (sentrycrashobjc_isTaggedPointer(object)) { + writer->addIntegerElement( + writer, "tagged_payload", (int64_t)sentrycrashobjc_taggedPointerPayload(object)); + } else { + const void *class = sentrycrashobjc_isaPointer(object); + int ivarCount = sentrycrashobjc_ivarList(class, ivars, sizeof(ivars) / sizeof(*ivars)); + *limit -= ivarCount; + for (int i = 0; i < ivarCount; i++) { + SentryCrashObjCIvar *ivar = &ivars[i]; + switch (ivar->type[0]) { + case 'c': + sentrycrashobjc_ivarValue(object, ivar->index, &s8); + writer->addIntegerElement(writer, ivar->name, s8); + break; + case 'i': + sentrycrashobjc_ivarValue(object, ivar->index, &sInt); + writer->addIntegerElement(writer, ivar->name, sInt); + break; + case 's': + sentrycrashobjc_ivarValue(object, ivar->index, &s16); + writer->addIntegerElement(writer, ivar->name, s16); + break; + case 'l': + sentrycrashobjc_ivarValue(object, ivar->index, &s32); + writer->addIntegerElement(writer, ivar->name, s32); + break; + case 'q': + sentrycrashobjc_ivarValue(object, ivar->index, &s64); + writer->addIntegerElement(writer, ivar->name, s64); + break; + case 'C': + sentrycrashobjc_ivarValue(object, ivar->index, &u8); + writer->addUIntegerElement(writer, ivar->name, u8); + break; + case 'I': + sentrycrashobjc_ivarValue(object, ivar->index, &uInt); + writer->addUIntegerElement(writer, ivar->name, uInt); + break; + case 'S': + sentrycrashobjc_ivarValue(object, ivar->index, &u16); + writer->addUIntegerElement(writer, ivar->name, u16); + break; + case 'L': + sentrycrashobjc_ivarValue(object, ivar->index, &u32); + writer->addUIntegerElement(writer, ivar->name, u32); + break; + case 'Q': + sentrycrashobjc_ivarValue(object, ivar->index, &u64); + writer->addUIntegerElement(writer, ivar->name, u64); + break; + case 'f': + sentrycrashobjc_ivarValue(object, ivar->index, &f32); + writer->addFloatingPointElement(writer, ivar->name, f32); + break; + case 'd': + sentrycrashobjc_ivarValue(object, ivar->index, &f64); + writer->addFloatingPointElement(writer, ivar->name, f64); + break; + case 'B': + sentrycrashobjc_ivarValue(object, ivar->index, &b); + writer->addBooleanElement(writer, ivar->name, b); + break; + case '*': + case '@': + case '#': + case ':': + sentrycrashobjc_ivarValue(object, ivar->index, &pointer); + writeMemoryContents(writer, ivar->name, (uintptr_t)pointer, limit); + break; + default: + SentryCrashLOG_DEBUG("%s: Unknown ivar type [%s]", ivar->name, ivar->type); + } + } + } + } + writer->endContainer(writer); +} + +static bool +isRestrictedClass(const char *name) +{ + if (g_introspectionRules.restrictedClasses != NULL) { + for (int i = 0; i < g_introspectionRules.restrictedClassesCount; i++) { + const char *className = g_introspectionRules.restrictedClasses[i]; + if (className != NULL && strcmp(name, className) == 0) { + return true; + } + } + } + return false; +} + +static void +writeZombieIfPresent( + const SentryCrashReportWriter *const writer, const char *const key, const uintptr_t address) +{ +#if SentryCrashCRASH_HAS_OBJC + const void *object = (const void *)address; + const char *zombieClassName = sentrycrashzombie_className(object); + if (zombieClassName != NULL) { + writer->addStringElement(writer, key, zombieClassName); + } +#endif +} + +static bool +writeObjCObject(const SentryCrashReportWriter *const writer, const uintptr_t address, int *limit) +{ +#if SentryCrashCRASH_HAS_OBJC + const void *object = (const void *)address; + switch (sentrycrashobjc_objectType(object)) { + case SentryCrashObjCTypeClass: + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashMemType_Class); + writer->addStringElement(writer, SentryCrashField_Class, sentrycrashobjc_className(object)); + return true; + case SentryCrashObjCTypeObject: { + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashMemType_Object); + const char *className = sentrycrashobjc_objectClassName(object); + writer->addStringElement(writer, SentryCrashField_Class, className); + if (!isRestrictedClass(className)) { + switch (sentrycrashobjc_objectClassType(object)) { + case SentryCrashObjCClassTypeString: + writeNSStringContents(writer, SentryCrashField_Value, address, limit); + return true; + case SentryCrashObjCClassTypeURL: + writeURLContents(writer, SentryCrashField_Value, address, limit); + return true; + case SentryCrashObjCClassTypeDate: + writeDateContents(writer, SentryCrashField_Value, address, limit); + return true; + case SentryCrashObjCClassTypeArray: + if (*limit > 0) { + writeArrayContents(writer, SentryCrashField_FirstObject, address, limit); + } + return true; + case SentryCrashObjCClassTypeNumber: + writeNumberContents(writer, SentryCrashField_Value, address, limit); + return true; + case SentryCrashObjCClassTypeDictionary: + case SentryCrashObjCClassTypeException: + // TODO: Implement these. + if (*limit > 0) { + writeUnknownObjectContents(writer, SentryCrashField_Ivars, address, limit); + } + return true; + case SentryCrashObjCClassTypeUnknown: + if (*limit > 0) { + writeUnknownObjectContents(writer, SentryCrashField_Ivars, address, limit); + } + return true; + } + } + break; + } + case SentryCrashObjCTypeBlock: + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashMemType_Block); + const char *className = sentrycrashobjc_objectClassName(object); + writer->addStringElement(writer, SentryCrashField_Class, className); + return true; + case SentryCrashObjCTypeUnknown: + break; + } +#endif + + return false; +} + +/** Write the contents of a memory location. + * Also writes meta information about the data. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param address The memory address. + * + * @param limit How many more subreferenced objects to write, if any. + */ +static void +writeMemoryContents(const SentryCrashReportWriter *const writer, const char *const key, + const uintptr_t address, int *limit) +{ + (*limit)--; + const void *object = (const void *)address; + writer->beginObject(writer, key); + { + writer->addUIntegerElement(writer, SentryCrashField_Address, address); + writeZombieIfPresent(writer, SentryCrashField_LastDeallocObject, address); + if (!writeObjCObject(writer, address, limit)) { + if (object == NULL) { + writer->addStringElement( + writer, SentryCrashField_Type, SentryCrashMemType_NullPointer); + } else if (isValidString(object)) { + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashMemType_String); + writer->addStringElement(writer, SentryCrashField_Value, (const char *)object); + } else { + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashMemType_Unknown); + } + } + } + writer->endContainer(writer); +} + +static bool +isValidPointer(const uintptr_t address) +{ + if (address == (uintptr_t)NULL) { + return false; + } + +#if SentryCrashCRASH_HAS_OBJC + if (sentrycrashobjc_isTaggedPointer((const void *)address)) { + if (!sentrycrashobjc_isValidTaggedPointer((const void *)address)) { + return false; + } + } +#endif + + return true; +} + +static bool +isNotableAddress(const uintptr_t address) +{ + if (!isValidPointer(address)) { + return false; + } + + const void *object = (const void *)address; + +#if SentryCrashCRASH_HAS_OBJC + if (sentrycrashzombie_className(object) != NULL) { + return true; + } + + if (sentrycrashobjc_objectType(object) != SentryCrashObjCTypeUnknown) { + return true; + } +#endif + + if (isValidString(object)) { + return true; + } + + return false; +} + +/** Write the contents of a memory location only if it contains notable data. + * Also writes meta information about the data. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param address The memory address. + */ +static void +writeMemoryContentsIfNotable( + const SentryCrashReportWriter *const writer, const char *const key, const uintptr_t address) +{ + if (isNotableAddress(address)) { + int limit = kDefaultMemorySearchDepth; + writeMemoryContents(writer, key, address, &limit); + } +} + +/** Look for a hex value in a string and try to write whatever it references. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param string The string to search. + */ +static void +writeAddressReferencedByString( + const SentryCrashReportWriter *const writer, const char *const key, const char *string) +{ + uint64_t address = 0; + if (string == NULL + || !sentrycrashstring_extractHexValue(string, (int)strlen(string), &address)) { + return; + } + + int limit = kDefaultMemorySearchDepth; + writeMemoryContents(writer, key, (uintptr_t)address, &limit); +} + +#pragma mark Backtrace + +/** Write a backtrace to the report. + * + * @param writer The writer to write the backtrace to. + * + * @param key The object key, if needed. + * + * @param stackCursor The stack cursor to read from. + */ +static void +writeBacktrace(const SentryCrashReportWriter *const writer, const char *const key, + SentryCrashStackCursor *stackCursor) +{ + writer->beginObject(writer, key); + { + writer->beginArray(writer, SentryCrashField_Contents); + { + while (stackCursor->advanceCursor(stackCursor)) { + writer->beginObject(writer, NULL); + { + if (stackCursor->symbolicate(stackCursor)) { + if (stackCursor->stackEntry.imageName != NULL) { + writer->addStringElement(writer, SentryCrashField_ObjectName, + sentrycrashfu_lastPathEntry(stackCursor->stackEntry.imageName)); + } + writer->addUIntegerElement(writer, SentryCrashField_ObjectAddr, + stackCursor->stackEntry.imageAddress); + if (stackCursor->stackEntry.symbolName != NULL) { + writer->addStringElement(writer, SentryCrashField_SymbolName, + stackCursor->stackEntry.symbolName); + } + writer->addUIntegerElement(writer, SentryCrashField_SymbolAddr, + stackCursor->stackEntry.symbolAddress); + } + writer->addUIntegerElement( + writer, SentryCrashField_InstructionAddr, stackCursor->stackEntry.address); + } + writer->endContainer(writer); + } + } + writer->endContainer(writer); + writer->addIntegerElement(writer, SentryCrashField_Skipped, 0); + } + writer->endContainer(writer); +} + +#pragma mark Stack + +/** Write a dump of the stack contents to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param machineContext The context to retrieve the stack from. + * + * @param isStackOverflow If true, the stack has overflowed. + */ +static void +writeStackContents(const SentryCrashReportWriter *const writer, const char *const key, + const struct SentryCrashMachineContext *const machineContext, const bool isStackOverflow) +{ + uintptr_t sp = sentrycrashcpu_stackPointer(machineContext); + if ((void *)sp == NULL) { + return; + } + + uintptr_t lowAddress = sp + + (uintptr_t)(kStackContentsPushedDistance * (int)sizeof(sp) + * sentrycrashcpu_stackGrowDirection() * -1); + uintptr_t highAddress = sp + + (uintptr_t)(kStackContentsPoppedDistance * (int)sizeof(sp) + * sentrycrashcpu_stackGrowDirection()); + if (highAddress < lowAddress) { + uintptr_t tmp = lowAddress; + lowAddress = highAddress; + highAddress = tmp; + } + writer->beginObject(writer, key); + { + writer->addStringElement(writer, SentryCrashField_GrowDirection, + sentrycrashcpu_stackGrowDirection() > 0 ? "+" : "-"); + writer->addUIntegerElement(writer, SentryCrashField_DumpStart, lowAddress); + writer->addUIntegerElement(writer, SentryCrashField_DumpEnd, highAddress); + writer->addUIntegerElement(writer, SentryCrashField_StackPtr, sp); + writer->addBooleanElement(writer, SentryCrashField_Overflow, isStackOverflow); + uint8_t stackBuffer[kStackContentsTotalDistance * sizeof(sp)]; + int copyLength = (int)(highAddress - lowAddress); + if (sentrycrashmem_copySafely((void *)lowAddress, stackBuffer, copyLength)) { + writer->addDataElement( + writer, SentryCrashField_Contents, (void *)stackBuffer, copyLength); + } else { + writer->addStringElement( + writer, SentryCrashField_Error, "Stack contents not accessible"); + } + } + writer->endContainer(writer); +} + +/** Write any notable addresses near the stack pointer (above and below). + * + * @param writer The writer. + * + * @param machineContext The context to retrieve the stack from. + * + * @param backDistance The distance towards the beginning of the stack to check. + * + * @param forwardDistance The distance past the end of the stack to check. + */ +static void +writeNotableStackContents(const SentryCrashReportWriter *const writer, + const struct SentryCrashMachineContext *const machineContext, const int backDistance, + const int forwardDistance) +{ + uintptr_t sp = sentrycrashcpu_stackPointer(machineContext); + if ((void *)sp == NULL) { + return; + } + + uintptr_t lowAddress = sp + + (uintptr_t)(backDistance * (int)sizeof(sp) * sentrycrashcpu_stackGrowDirection() * -1); + uintptr_t highAddress + = sp + (uintptr_t)(forwardDistance * (int)sizeof(sp) * sentrycrashcpu_stackGrowDirection()); + if (highAddress < lowAddress) { + uintptr_t tmp = lowAddress; + lowAddress = highAddress; + highAddress = tmp; + } + uintptr_t contentsAsPointer; + char nameBuffer[40]; + for (uintptr_t address = lowAddress; address < highAddress; address += sizeof(address)) { + if (sentrycrashmem_copySafely( + (void *)address, &contentsAsPointer, sizeof(contentsAsPointer))) { + sprintf(nameBuffer, "stack@%p", (void *)address); + writeMemoryContentsIfNotable(writer, nameBuffer, contentsAsPointer); + } + } +} + +#pragma mark Registers + +/** Write the contents of all regular registers to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param machineContext The context to retrieve the registers from. + */ +static void +writeBasicRegisters(const SentryCrashReportWriter *const writer, const char *const key, + const struct SentryCrashMachineContext *const machineContext) +{ + char registerNameBuff[30]; + const char *registerName; + writer->beginObject(writer, key); + { + const int numRegisters = sentrycrashcpu_numRegisters(); + for (int reg = 0; reg < numRegisters; reg++) { + registerName = sentrycrashcpu_registerName(reg); + if (registerName == NULL) { + snprintf(registerNameBuff, sizeof(registerNameBuff), "r%d", reg); + registerName = registerNameBuff; + } + writer->addUIntegerElement( + writer, registerName, sentrycrashcpu_registerValue(machineContext, reg)); + } + } + writer->endContainer(writer); +} + +/** Write the contents of all exception registers to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param machineContext The context to retrieve the registers from. + */ +static void +writeExceptionRegisters(const SentryCrashReportWriter *const writer, const char *const key, + const struct SentryCrashMachineContext *const machineContext) +{ + char registerNameBuff[30]; + const char *registerName; + writer->beginObject(writer, key); + { + const int numRegisters = sentrycrashcpu_numExceptionRegisters(); + for (int reg = 0; reg < numRegisters; reg++) { + registerName = sentrycrashcpu_exceptionRegisterName(reg); + if (registerName == NULL) { + snprintf(registerNameBuff, sizeof(registerNameBuff), "r%d", reg); + registerName = registerNameBuff; + } + writer->addUIntegerElement( + writer, registerName, sentrycrashcpu_exceptionRegisterValue(machineContext, reg)); + } + } + writer->endContainer(writer); +} + +/** Write all applicable registers. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param machineContext The context to retrieve the registers from. + */ +static void +writeRegisters(const SentryCrashReportWriter *const writer, const char *const key, + const struct SentryCrashMachineContext *const machineContext) +{ + writer->beginObject(writer, key); + { + writeBasicRegisters(writer, SentryCrashField_Basic, machineContext); + if (sentrycrashmc_hasValidExceptionRegisters(machineContext)) { + writeExceptionRegisters(writer, SentryCrashField_Exception, machineContext); + } + } + writer->endContainer(writer); +} + +/** Write any notable addresses contained in the CPU registers. + * + * @param writer The writer. + * + * @param machineContext The context to retrieve the registers from. + */ +static void +writeNotableRegisters(const SentryCrashReportWriter *const writer, + const struct SentryCrashMachineContext *const machineContext) +{ + char registerNameBuff[30]; + const char *registerName; + const int numRegisters = sentrycrashcpu_numRegisters(); + for (int reg = 0; reg < numRegisters; reg++) { + registerName = sentrycrashcpu_registerName(reg); + if (registerName == NULL) { + snprintf(registerNameBuff, sizeof(registerNameBuff), "r%d", reg); + registerName = registerNameBuff; + } + writeMemoryContentsIfNotable( + writer, registerName, (uintptr_t)sentrycrashcpu_registerValue(machineContext, reg)); + } +} + +#pragma mark Thread-specific + +/** Write any notable addresses in the stack or registers to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param machineContext The context to retrieve the registers from. + */ +static void +writeNotableAddresses(const SentryCrashReportWriter *const writer, const char *const key, + const struct SentryCrashMachineContext *const machineContext) +{ + writer->beginObject(writer, key); + { + writeNotableRegisters(writer, machineContext); + writeNotableStackContents(writer, machineContext, kStackNotableSearchBackDistance, + kStackNotableSearchForwardDistance); + } + writer->endContainer(writer); +} + +/** Write information about a thread to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param crash The crash handler context. + * + * @param machineContext The context whose thread to write about. + * + * @param shouldWriteNotableAddresses If true, write any notable addresses + * found. + */ +static void +writeThread(const SentryCrashReportWriter *const writer, const char *const key, + const SentryCrash_MonitorContext *const crash, + const struct SentryCrashMachineContext *const machineContext, const int threadIndex, + const bool shouldWriteNotableAddresses) +{ + bool isCrashedThread = sentrycrashmc_isCrashedContext(machineContext); + SentryCrashThread thread = sentrycrashmc_getThreadFromContext(machineContext); + SentryCrashLOG_DEBUG( + "Writing thread %x (index %d). is crashed: %d", thread, threadIndex, isCrashedThread); + + SentryCrashStackCursor stackCursor; + bool hasBacktrace = getStackCursor(crash, machineContext, &stackCursor); + + writer->beginObject(writer, key); + { + if (hasBacktrace) { + writeBacktrace(writer, SentryCrashField_Backtrace, &stackCursor); + } + if (sentrycrashmc_canHaveCPUState(machineContext)) { + writeRegisters(writer, SentryCrashField_Registers, machineContext); + } + writer->addIntegerElement(writer, SentryCrashField_Index, threadIndex); + const char *name = sentrycrashccd_getThreadName(thread); + if (name != NULL) { + writer->addStringElement(writer, SentryCrashField_Name, name); + } + name = sentrycrashccd_getQueueName(thread); + if (name != NULL) { + writer->addStringElement(writer, SentryCrashField_DispatchQueue, name); + } + writer->addBooleanElement(writer, SentryCrashField_Crashed, isCrashedThread); + writer->addBooleanElement( + writer, SentryCrashField_CurrentThread, thread == sentrycrashthread_self()); + if (isCrashedThread) { + writeStackContents( + writer, SentryCrashField_Stack, machineContext, stackCursor.state.hasGivenUp); + if (shouldWriteNotableAddresses) { + writeNotableAddresses(writer, SentryCrashField_NotableAddresses, machineContext); + } + } + } + writer->endContainer(writer); +} + +/** Write information about all threads to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param crash The crash handler context. + */ +static void +writeAllThreads(const SentryCrashReportWriter *const writer, const char *const key, + const SentryCrash_MonitorContext *const crash, bool writeNotableAddresses) +{ + const struct SentryCrashMachineContext *const context = crash->offendingMachineContext; + SentryCrashThread offendingThread = sentrycrashmc_getThreadFromContext(context); + int threadCount = sentrycrashmc_getThreadCount(context); + SentryCrashMC_NEW_CONTEXT(machineContext); + + // Fetch info for all threads. + writer->beginArray(writer, key); + { + SentryCrashLOG_DEBUG("Writing %d threads.", threadCount); + for (int i = 0; i < threadCount; i++) { + SentryCrashThread thread = sentrycrashmc_getThreadAtIndex(context, i); + if (thread == offendingThread) { + writeThread(writer, NULL, crash, context, i, writeNotableAddresses); + } else { + sentrycrashmc_getContextForThread(thread, machineContext, false); + writeThread(writer, NULL, crash, machineContext, i, writeNotableAddresses); + } + } + } + writer->endContainer(writer); +} + +#pragma mark Global Report Data + +/** Write information about a binary image to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param index Which image to write about. + */ +static void +writeBinaryImage( + const SentryCrashReportWriter *const writer, const char *const key, const int index) +{ + SentryCrashBinaryImage image = { 0 }; + if (!sentrycrashdl_getBinaryImage(index, &image)) { + return; + } + + writer->beginObject(writer, key); + { + writer->addUIntegerElement(writer, SentryCrashField_ImageAddress, image.address); + writer->addUIntegerElement(writer, SentryCrashField_ImageVmAddress, image.vmAddress); + writer->addUIntegerElement(writer, SentryCrashField_ImageSize, image.size); + writer->addStringElement(writer, SentryCrashField_Name, image.name); + writer->addUUIDElement(writer, SentryCrashField_UUID, image.uuid); + writer->addIntegerElement(writer, SentryCrashField_CPUType, image.cpuType); + writer->addIntegerElement(writer, SentryCrashField_CPUSubType, image.cpuSubType); + writer->addUIntegerElement(writer, SentryCrashField_ImageMajorVersion, image.majorVersion); + writer->addUIntegerElement(writer, SentryCrashField_ImageMinorVersion, image.minorVersion); + writer->addUIntegerElement( + writer, SentryCrashField_ImageRevisionVersion, image.revisionVersion); + } + writer->endContainer(writer); +} + +/** Write information about all images to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + */ +static void +writeBinaryImages(const SentryCrashReportWriter *const writer, const char *const key) +{ + const int imageCount = sentrycrashdl_imageCount(); + + writer->beginArray(writer, key); + { + for (int iImg = 0; iImg < imageCount; iImg++) { + writeBinaryImage(writer, NULL, iImg); + } + } + writer->endContainer(writer); +} + +/** Write information about system memory to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + */ +static void +writeMemoryInfo(const SentryCrashReportWriter *const writer, const char *const key, + const SentryCrash_MonitorContext *const monitorContext) +{ + writer->beginObject(writer, key); + { + writer->addUIntegerElement( + writer, SentryCrashField_Size, monitorContext->System.memorySize); + writer->addUIntegerElement( + writer, SentryCrashField_Usable, monitorContext->System.usableMemory); + writer->addUIntegerElement( + writer, SentryCrashField_Free, monitorContext->System.freeMemory); + } + writer->endContainer(writer); +} + +/** Write information about the error leading to the crash to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param crash The crash handler context. + */ +static void +writeError(const SentryCrashReportWriter *const writer, const char *const key, + const SentryCrash_MonitorContext *const crash) +{ + writer->beginObject(writer, key); + { +#if SentryCrashCRASH_HOST_APPLE + writer->beginObject(writer, SentryCrashField_Mach); + { + const char *machExceptionName = sentrycrashmach_exceptionName(crash->mach.type); + const char *machCodeName = crash->mach.code == 0 + ? NULL + : sentrycrashmach_kernelReturnCodeName(crash->mach.code); + writer->addUIntegerElement( + writer, SentryCrashField_Exception, (unsigned)crash->mach.type); + if (machExceptionName != NULL) { + writer->addStringElement(writer, SentryCrashField_ExceptionName, machExceptionName); + } + writer->addUIntegerElement(writer, SentryCrashField_Code, (unsigned)crash->mach.code); + if (machCodeName != NULL) { + writer->addStringElement(writer, SentryCrashField_CodeName, machCodeName); + } + writer->addUIntegerElement( + writer, SentryCrashField_Subcode, (unsigned)crash->mach.subcode); + } + writer->endContainer(writer); +#endif + writer->beginObject(writer, SentryCrashField_Signal); + { + const char *sigName = sentrycrashsignal_signalName(crash->signal.signum); + const char *sigCodeName + = sentrycrashsignal_signalCodeName(crash->signal.signum, crash->signal.sigcode); + writer->addUIntegerElement( + writer, SentryCrashField_Signal, (unsigned)crash->signal.signum); + if (sigName != NULL) { + writer->addStringElement(writer, SentryCrashField_Name, sigName); + } + writer->addUIntegerElement( + writer, SentryCrashField_Code, (unsigned)crash->signal.sigcode); + if (sigCodeName != NULL) { + writer->addStringElement(writer, SentryCrashField_CodeName, sigCodeName); + } + } + writer->endContainer(writer); + + writer->addUIntegerElement(writer, SentryCrashField_Address, crash->faultAddress); + if (crash->crashReason != NULL) { + writer->addStringElement(writer, SentryCrashField_Reason, crash->crashReason); + } + + // Gather specific info. + switch (crash->crashType) { + case SentryCrashMonitorTypeMainThreadDeadlock: + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashExcType_Deadlock); + break; + + case SentryCrashMonitorTypeMachException: + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashExcType_Mach); + break; + + case SentryCrashMonitorTypeCPPException: { + writer->addStringElement( + writer, SentryCrashField_Type, SentryCrashExcType_CPPException); + writer->beginObject(writer, SentryCrashField_CPPException); + { + writer->addStringElement(writer, SentryCrashField_Name, crash->CPPException.name); + } + writer->endContainer(writer); + break; + } + case SentryCrashMonitorTypeNSException: { + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashExcType_NSException); + writer->beginObject(writer, SentryCrashField_NSException); + { + writer->addStringElement(writer, SentryCrashField_Name, crash->NSException.name); + writer->addStringElement( + writer, SentryCrashField_UserInfo, crash->NSException.userInfo); + writeAddressReferencedByString( + writer, SentryCrashField_ReferencedObject, crash->crashReason); + } + writer->endContainer(writer); + break; + } + case SentryCrashMonitorTypeSignal: + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashExcType_Signal); + break; + + case SentryCrashMonitorTypeUserReported: { + writer->addStringElement(writer, SentryCrashField_Type, SentryCrashExcType_User); + writer->beginObject(writer, SentryCrashField_UserReported); + { + writer->addStringElement(writer, SentryCrashField_Name, crash->userException.name); + if (crash->userException.language != NULL) { + writer->addStringElement( + writer, SentryCrashField_Language, crash->userException.language); + } + if (crash->userException.lineOfCode != NULL) { + writer->addStringElement( + writer, SentryCrashField_LineOfCode, crash->userException.lineOfCode); + } + if (crash->userException.customStackTrace != NULL) { + writer->addJSONElement(writer, SentryCrashField_Backtrace, + crash->userException.customStackTrace, true); + } + } + writer->endContainer(writer); + break; + } + case SentryCrashMonitorTypeSystem: + case SentryCrashMonitorTypeApplicationState: + case SentryCrashMonitorTypeZombie: + SentryCrashLOG_ERROR( + "Crash monitor type 0x%x shouldn't be able to cause events!", crash->crashType); + break; + } + } + writer->endContainer(writer); +} + +/** Write information about app runtime, etc to the report. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param monitorContext The event monitor context. + */ +static void +writeAppStats(const SentryCrashReportWriter *const writer, const char *const key, + const SentryCrash_MonitorContext *const monitorContext) +{ + writer->beginObject(writer, key); + { + writer->addBooleanElement( + writer, SentryCrashField_AppActive, monitorContext->AppState.applicationIsActive); + writer->addBooleanElement( + writer, SentryCrashField_AppInFG, monitorContext->AppState.applicationIsInForeground); + + writer->addIntegerElement(writer, SentryCrashField_LaunchesSinceCrash, + monitorContext->AppState.launchesSinceLastCrash); + writer->addIntegerElement(writer, SentryCrashField_SessionsSinceCrash, + monitorContext->AppState.sessionsSinceLastCrash); + writer->addFloatingPointElement(writer, SentryCrashField_ActiveTimeSinceCrash, + monitorContext->AppState.activeDurationSinceLastCrash); + writer->addFloatingPointElement(writer, SentryCrashField_BGTimeSinceCrash, + monitorContext->AppState.backgroundDurationSinceLastCrash); + + writer->addIntegerElement(writer, SentryCrashField_SessionsSinceLaunch, + monitorContext->AppState.sessionsSinceLaunch); + writer->addFloatingPointElement(writer, SentryCrashField_ActiveTimeSinceLaunch, + monitorContext->AppState.activeDurationSinceLaunch); + writer->addFloatingPointElement(writer, SentryCrashField_BGTimeSinceLaunch, + monitorContext->AppState.backgroundDurationSinceLaunch); + } + writer->endContainer(writer); +} + +/** Write information about this process. + * + * @param writer The writer. + * + * @param key The object key, if needed. + */ +static void +writeProcessState(const SentryCrashReportWriter *const writer, const char *const key, + const SentryCrash_MonitorContext *const monitorContext) +{ + writer->beginObject(writer, key); + { + if (monitorContext->ZombieException.address != 0) { + writer->beginObject(writer, SentryCrashField_LastDeallocedNSException); + { + writer->addUIntegerElement( + writer, SentryCrashField_Address, monitorContext->ZombieException.address); + writer->addStringElement( + writer, SentryCrashField_Name, monitorContext->ZombieException.name); + writer->addStringElement( + writer, SentryCrashField_Reason, monitorContext->ZombieException.reason); + writeAddressReferencedByString(writer, SentryCrashField_ReferencedObject, + monitorContext->ZombieException.reason); + } + writer->endContainer(writer); + } + } + writer->endContainer(writer); +} + +/** Write basic report information. + * + * @param writer The writer. + * + * @param key The object key, if needed. + * + * @param type The report type. + * + * @param reportID The report ID. + */ +static void +writeReportInfo(const SentryCrashReportWriter *const writer, const char *const key, + const char *const type, const char *const reportID, const char *const processName) +{ + writer->beginObject(writer, key); + { + writer->addStringElement(writer, SentryCrashField_Version, SentryCrashCRASH_REPORT_VERSION); + writer->addStringElement(writer, SentryCrashField_ID, reportID); + writer->addStringElement(writer, SentryCrashField_ProcessName, processName); + writer->addIntegerElement(writer, SentryCrashField_Timestamp, time(NULL)); + writer->addStringElement(writer, SentryCrashField_Type, type); + } + writer->endContainer(writer); +} + +static void +writeRecrash( + const SentryCrashReportWriter *const writer, const char *const key, const char *crashReportPath) +{ + writer->addJSONFileElement(writer, key, crashReportPath, true); +} + +#pragma mark Setup + +/** Prepare a report writer for use. + * + * @oaram writer The writer to prepare. + * + * @param context JSON writer contextual information. + */ +static void +prepareReportWriter( + SentryCrashReportWriter *const writer, SentryCrashJSONEncodeContext *const context) +{ + writer->addBooleanElement = addBooleanElement; + writer->addFloatingPointElement = addFloatingPointElement; + writer->addIntegerElement = addIntegerElement; + writer->addUIntegerElement = addUIntegerElement; + writer->addStringElement = addStringElement; + writer->addTextFileElement = addTextFileElement; + writer->addTextFileLinesElement = addTextLinesFromFile; + writer->addJSONFileElement = addJSONElementFromFile; + writer->addDataElement = addDataElement; + writer->beginDataElement = beginDataElement; + writer->appendDataElement = appendDataElement; + writer->endDataElement = endDataElement; + writer->addUUIDElement = addUUIDElement; + writer->addJSONElement = addJSONElement; + writer->beginObject = beginObject; + writer->beginArray = beginArray; + writer->endContainer = endContainer; + writer->context = context; +} + +// ============================================================================ +#pragma mark - Main API - +// ============================================================================ + +void +sentrycrashreport_writeRecrashReport( + const SentryCrash_MonitorContext *const monitorContext, const char *const path) +{ + char writeBuffer[1024]; + SentryCrashBufferedWriter bufferedWriter; + static char tempPath[SentryCrashFU_MAX_PATH_LENGTH]; + strncpy(tempPath, path, sizeof(tempPath) - 10); + strncpy(tempPath + strlen(tempPath) - 5, ".old", 5); + SentryCrashLOG_INFO("Writing recrash report to %s", path); + + if (rename(path, tempPath) < 0) { + SentryCrashLOG_ERROR("Could not rename %s to %s: %s", path, tempPath, strerror(errno)); + } + if (!sentrycrashfu_openBufferedWriter( + &bufferedWriter, path, writeBuffer, sizeof(writeBuffer))) { + return; + } + + sentrycrashccd_freeze(); + + SentryCrashJSONEncodeContext jsonContext; + jsonContext.userData = &bufferedWriter; + SentryCrashReportWriter concreteWriter; + SentryCrashReportWriter *writer = &concreteWriter; + prepareReportWriter(writer, &jsonContext); + + sentrycrashjson_beginEncode(getJsonContext(writer), true, addJSONData, &bufferedWriter); + + writer->beginObject(writer, SentryCrashField_Report); + { + writeRecrash(writer, SentryCrashField_RecrashReport, tempPath); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + if (remove(tempPath) < 0) { + SentryCrashLOG_ERROR("Could not remove %s: %s", tempPath, strerror(errno)); + } + writeReportInfo(writer, SentryCrashField_Report, SentryCrashReportType_Minimal, + monitorContext->eventID, monitorContext->System.processName); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + + writer->beginObject(writer, SentryCrashField_Crash); + { + writeError(writer, SentryCrashField_Error, monitorContext); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + int threadIndex = sentrycrashmc_indexOfThread(monitorContext->offendingMachineContext, + sentrycrashmc_getThreadFromContext(monitorContext->offendingMachineContext)); + writeThread(writer, SentryCrashField_CrashedThread, monitorContext, + monitorContext->offendingMachineContext, threadIndex, false); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + } + writer->endContainer(writer); + } + writer->endContainer(writer); + + sentrycrashjson_endEncode(getJsonContext(writer)); + sentrycrashfu_closeBufferedWriter(&bufferedWriter); + sentrycrashccd_unfreeze(); +} + +static void +writeSystemInfo(const SentryCrashReportWriter *const writer, const char *const key, + const SentryCrash_MonitorContext *const monitorContext) +{ + writer->beginObject(writer, key); + { + writer->addStringElement( + writer, SentryCrashField_SystemName, monitorContext->System.systemName); + writer->addStringElement( + writer, SentryCrashField_SystemVersion, monitorContext->System.systemVersion); + writer->addStringElement(writer, SentryCrashField_Machine, monitorContext->System.machine); + writer->addStringElement(writer, SentryCrashField_Model, monitorContext->System.model); + writer->addStringElement( + writer, SentryCrashField_KernelVersion, monitorContext->System.kernelVersion); + writer->addStringElement( + writer, SentryCrashField_OSVersion, monitorContext->System.osVersion); + writer->addBooleanElement( + writer, SentryCrashField_Jailbroken, monitorContext->System.isJailbroken); + writer->addStringElement( + writer, SentryCrashField_BootTime, monitorContext->System.bootTime); + writer->addStringElement( + writer, SentryCrashField_AppStartTime, monitorContext->System.appStartTime); + writer->addStringElement( + writer, SentryCrashField_ExecutablePath, monitorContext->System.executablePath); + writer->addStringElement( + writer, SentryCrashField_Executable, monitorContext->System.executableName); + writer->addStringElement( + writer, SentryCrashField_BundleID, monitorContext->System.bundleID); + writer->addStringElement( + writer, SentryCrashField_BundleName, monitorContext->System.bundleName); + writer->addStringElement( + writer, SentryCrashField_BundleVersion, monitorContext->System.bundleVersion); + writer->addStringElement( + writer, SentryCrashField_BundleShortVersion, monitorContext->System.bundleShortVersion); + writer->addStringElement(writer, SentryCrashField_AppUUID, monitorContext->System.appID); + writer->addStringElement( + writer, SentryCrashField_CPUArch, monitorContext->System.cpuArchitecture); + writer->addIntegerElement(writer, SentryCrashField_CPUType, monitorContext->System.cpuType); + writer->addIntegerElement( + writer, SentryCrashField_CPUSubType, monitorContext->System.cpuSubType); + writer->addIntegerElement( + writer, SentryCrashField_BinaryCPUType, monitorContext->System.binaryCPUType); + writer->addIntegerElement( + writer, SentryCrashField_BinaryCPUSubType, monitorContext->System.binaryCPUSubType); + writer->addStringElement( + writer, SentryCrashField_TimeZone, monitorContext->System.timezone); + writer->addStringElement( + writer, SentryCrashField_ProcessName, monitorContext->System.processName); + writer->addIntegerElement( + writer, SentryCrashField_ProcessID, monitorContext->System.processID); + writer->addIntegerElement( + writer, SentryCrashField_ParentProcessID, monitorContext->System.parentProcessID); + writer->addStringElement( + writer, SentryCrashField_DeviceAppHash, monitorContext->System.deviceAppHash); + writer->addStringElement( + writer, SentryCrashField_BuildType, monitorContext->System.buildType); + writer->addIntegerElement( + writer, SentryCrashField_Storage, (int64_t)monitorContext->System.storageSize); + + writeMemoryInfo(writer, SentryCrashField_Memory, monitorContext); + writeAppStats(writer, SentryCrashField_AppStats, monitorContext); + } + writer->endContainer(writer); +} + +static void +writeDebugInfo(const SentryCrashReportWriter *const writer, const char *const key, + const SentryCrash_MonitorContext *const monitorContext) +{ + writer->beginObject(writer, key); + { + if (monitorContext->consoleLogPath != NULL) { + addTextLinesFromFile( + writer, SentryCrashField_ConsoleLog, monitorContext->consoleLogPath); + } + } + writer->endContainer(writer); +} + +void +sentrycrashreport_writeStandardReport( + const SentryCrash_MonitorContext *const monitorContext, const char *const path) +{ + SentryCrashLOG_INFO("Writing crash report to %s", path); + char writeBuffer[1024]; + SentryCrashBufferedWriter bufferedWriter; + + if (!sentrycrashfu_openBufferedWriter( + &bufferedWriter, path, writeBuffer, sizeof(writeBuffer))) { + return; + } + + sentrycrashccd_freeze(); + + SentryCrashJSONEncodeContext jsonContext; + jsonContext.userData = &bufferedWriter; + SentryCrashReportWriter concreteWriter; + SentryCrashReportWriter *writer = &concreteWriter; + prepareReportWriter(writer, &jsonContext); + + sentrycrashjson_beginEncode(getJsonContext(writer), true, addJSONData, &bufferedWriter); + + writer->beginObject(writer, SentryCrashField_Report); + { + writeReportInfo(writer, SentryCrashField_Report, SentryCrashReportType_Standard, + monitorContext->eventID, monitorContext->System.processName); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + + writeBinaryImages(writer, SentryCrashField_BinaryImages); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + + writeProcessState(writer, SentryCrashField_ProcessState, monitorContext); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + + writeSystemInfo(writer, SentryCrashField_System, monitorContext); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + + writer->beginObject(writer, SentryCrashField_Crash); + { + writeError(writer, SentryCrashField_Error, monitorContext); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + writeAllThreads( + writer, SentryCrashField_Threads, monitorContext, g_introspectionRules.enabled); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + } + writer->endContainer(writer); + + if (g_userInfoJSON != NULL) { + addJSONElement(writer, SentryCrashField_User, g_userInfoJSON, false); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + } else { + writer->beginObject(writer, SentryCrashField_User); + } + if (g_userSectionWriteCallback != NULL) { + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + if (monitorContext->currentSnapshotUserReported == false) { + g_userSectionWriteCallback(writer); + } + } + writer->endContainer(writer); + sentrycrashfu_flushBufferedWriter(&bufferedWriter); + + writeDebugInfo(writer, SentryCrashField_Debug, monitorContext); + } + writer->endContainer(writer); + + sentrycrashjson_endEncode(getJsonContext(writer)); + sentrycrashfu_closeBufferedWriter(&bufferedWriter); + sentrycrashccd_unfreeze(); +} + +void +sentrycrashreport_setUserInfoJSON(const char *const userInfoJSON) +{ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + SentryCrashLOG_TRACE("set userInfoJSON to %p", userInfoJSON); + + pthread_mutex_lock(&mutex); + if (g_userInfoJSON != NULL) { + free((void *)g_userInfoJSON); + } + if (userInfoJSON == NULL) { + g_userInfoJSON = NULL; + } else { + g_userInfoJSON = strdup(userInfoJSON); + } + pthread_mutex_unlock(&mutex); +} + +void +sentrycrashreport_setIntrospectMemory(bool shouldIntrospectMemory) +{ + g_introspectionRules.enabled = shouldIntrospectMemory; +} + +void +sentrycrashreport_setDoNotIntrospectClasses(const char **doNotIntrospectClasses, int length) +{ + const char **oldClasses = g_introspectionRules.restrictedClasses; + int oldClassesLength = g_introspectionRules.restrictedClassesCount; + const char **newClasses = NULL; + int newClassesLength = 0; + + if (doNotIntrospectClasses != NULL && length > 0) { + newClassesLength = length; + newClasses = malloc(sizeof(*newClasses) * (unsigned)newClassesLength); + if (newClasses == NULL) { + SentryCrashLOG_ERROR("Could not allocate memory"); + return; + } + + for (int i = 0; i < newClassesLength; i++) { + newClasses[i] = strdup(doNotIntrospectClasses[i]); + } + } + + g_introspectionRules.restrictedClasses = newClasses; + g_introspectionRules.restrictedClassesCount = newClassesLength; + + if (oldClasses != NULL) { + for (int i = 0; i < oldClassesLength; i++) { + if (oldClasses[i] != NULL) { + free((void *)oldClasses[i]); + } + } + free(oldClasses); + } +} + +void +sentrycrashreport_setUserSectionWriteCallback( + const SentryCrashReportWriteCallback userSectionWriteCallback) +{ + SentryCrashLOG_TRACE("Set userSectionWriteCallback to %p", userSectionWriteCallback); + g_userSectionWriteCallback = userSectionWriteCallback; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReport.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReport.h new file mode 100644 index 00000000..0a620bd6 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReport.h @@ -0,0 +1,103 @@ +// +// SentryCrashReport.h +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Writes a crash report to disk. + */ + +#ifndef HDR_SentryCrashReport_h +#define HDR_SentryCrashReport_h + +#ifdef __cplusplus +extern "C" { +#endif + +#import "SentryCrashMonitorContext.h" +#import "SentryCrashReportWriter.h" + +#include + +// ============================================================================ +#pragma mark - Configuration - +// ============================================================================ + +/** Set custom user information to be stored in the report. + * + * @param userInfoJSON The user information, in JSON format. + */ +void sentrycrashreport_setUserInfoJSON(const char *const userInfoJSON); + +/** Configure whether to introspect any interesting memory locations. + * This can find things like strings or Objective-C classes. + * + * @param shouldIntrospectMemory If true, introspect memory. + */ +void sentrycrashreport_setIntrospectMemory(bool shouldIntrospectMemory); + +/** Specify which objective-c classes should not be introspected. + * + * @param doNotIntrospectClasses Array of class names. + * @param length Length of the array. + */ +void sentrycrashreport_setDoNotIntrospectClasses(const char **doNotIntrospectClasses, int length); + +/** Set the function to call when writing the user section of the report. + * This allows the user to add more fields to the user section at the time of + * the crash. Note: Only async-safe functions are allowed in the callback. + * + * @param userSectionWriteCallback The user section write callback. + */ +void sentrycrashreport_setUserSectionWriteCallback( + const SentryCrashReportWriteCallback userSectionWriteCallback); + +// ============================================================================ +#pragma mark - Main API - +// ============================================================================ + +/** Write a standard crash report to a file. + * + * @param monitorContext Contextual information about the crash and environment. + * The caller must fill this out before passing it in. + * + * @param path The file to write to. + */ +void sentrycrashreport_writeStandardReport( + const struct SentryCrash_MonitorContext *const monitorContext, const char *path); + +/** Write a minimal crash report to a file. + * + * @param monitorContext Contextual information about the crash and environment. + * The caller must fill this out before passing it in. + * + * @param path The file to write to. + */ +void sentrycrashreport_writeRecrashReport( + const struct SentryCrash_MonitorContext *const monitorContext, const char *path); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashReport_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFields.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFields.h new file mode 100644 index 00000000..54cff7e8 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFields.h @@ -0,0 +1,212 @@ +// +// SentryCrashReportFields.h +// +// Created by Karl Stenerud on 2012-10-07. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashReportFields_h +#define HDR_SentryCrashReportFields_h + +#pragma mark - Report Types - + +#define SentryCrashReportType_Minimal "minimal" +#define SentryCrashReportType_Standard "standard" +#define SentryCrashReportType_Custom "custom" + +#pragma mark - Memory Types - + +#define SentryCrashMemType_Block "objc_block" +#define SentryCrashMemType_Class "objc_class" +#define SentryCrashMemType_NullPointer "null_pointer" +#define SentryCrashMemType_Object "objc_object" +#define SentryCrashMemType_String "string" +#define SentryCrashMemType_Unknown "unknown" + +#pragma mark - Exception Types - + +#define SentryCrashExcType_CPPException "cpp_exception" +#define SentryCrashExcType_Deadlock "deadlock" +#define SentryCrashExcType_Mach "mach" +#define SentryCrashExcType_NSException "nsexception" +#define SentryCrashExcType_Signal "signal" +#define SentryCrashExcType_User "user" + +#pragma mark - Common - + +#define SentryCrashField_Address "address" +#define SentryCrashField_Contents "contents" +#define SentryCrashField_Exception "exception" +#define SentryCrashField_FirstObject "first_object" +#define SentryCrashField_Index "index" +#define SentryCrashField_Ivars "ivars" +#define SentryCrashField_Language "language" +#define SentryCrashField_Name "name" +#define SentryCrashField_UserInfo "userInfo" +#define SentryCrashField_ReferencedObject "referenced_object" +#define SentryCrashField_Type "type" +#define SentryCrashField_UUID "uuid" +#define SentryCrashField_Value "value" + +#define SentryCrashField_Error "error" +#define SentryCrashField_JSONData "json_data" + +#pragma mark - Notable Address - + +#define SentryCrashField_Class "class" +#define SentryCrashField_LastDeallocObject "last_deallocated_obj" + +#pragma mark - Backtrace - + +#define SentryCrashField_InstructionAddr "instruction_addr" +#define SentryCrashField_LineOfCode "line_of_code" +#define SentryCrashField_ObjectAddr "object_addr" +#define SentryCrashField_ObjectName "object_name" +#define SentryCrashField_SymbolAddr "symbol_addr" +#define SentryCrashField_SymbolName "symbol_name" + +#pragma mark - Stack Dump - + +#define SentryCrashField_DumpEnd "dump_end" +#define SentryCrashField_DumpStart "dump_start" +#define SentryCrashField_GrowDirection "grow_direction" +#define SentryCrashField_Overflow "overflow" +#define SentryCrashField_StackPtr "stack_pointer" + +#pragma mark - Thread Dump - + +#define SentryCrashField_Backtrace "backtrace" +#define SentryCrashField_Basic "basic" +#define SentryCrashField_Crashed "crashed" +#define SentryCrashField_CurrentThread "current_thread" +#define SentryCrashField_DispatchQueue "dispatch_queue" +#define SentryCrashField_NotableAddresses "notable_addresses" +#define SentryCrashField_Registers "registers" +#define SentryCrashField_Skipped "skipped" +#define SentryCrashField_Stack "stack" + +#pragma mark - Binary Image - + +#define SentryCrashField_CPUSubType "cpu_subtype" +#define SentryCrashField_CPUType "cpu_type" +#define SentryCrashField_ImageAddress "image_addr" +#define SentryCrashField_ImageVmAddress "image_vmaddr" +#define SentryCrashField_ImageSize "image_size" +#define SentryCrashField_ImageMajorVersion "major_version" +#define SentryCrashField_ImageMinorVersion "minor_version" +#define SentryCrashField_ImageRevisionVersion "revision_version" + +#pragma mark - Memory - + +#define SentryCrashField_Free "free" +#define SentryCrashField_Usable "usable" + +#pragma mark - Error - + +#define SentryCrashField_Backtrace "backtrace" +#define SentryCrashField_Code "code" +#define SentryCrashField_CodeName "code_name" +#define SentryCrashField_CPPException "cpp_exception" +#define SentryCrashField_ExceptionName "exception_name" +#define SentryCrashField_Mach "mach" +#define SentryCrashField_NSException "nsexception" +#define SentryCrashField_Reason "reason" +#define SentryCrashField_Signal "signal" +#define SentryCrashField_Subcode "subcode" +#define SentryCrashField_UserReported "user_reported" + +#pragma mark - Process State - + +#define SentryCrashField_LastDeallocedNSException "last_dealloced_nsexception" +#define SentryCrashField_ProcessState "process" + +#pragma mark - App Stats - + +#define SentryCrashField_ActiveTimeSinceCrash "active_time_since_last_crash" +#define SentryCrashField_ActiveTimeSinceLaunch "active_time_since_launch" +#define SentryCrashField_AppActive "application_active" +#define SentryCrashField_AppInFG "application_in_foreground" +#define SentryCrashField_BGTimeSinceCrash "background_time_since_last_crash" +#define SentryCrashField_BGTimeSinceLaunch "background_time_since_launch" +#define SentryCrashField_LaunchesSinceCrash "launches_since_last_crash" +#define SentryCrashField_SessionsSinceCrash "sessions_since_last_crash" +#define SentryCrashField_SessionsSinceLaunch "sessions_since_launch" + +#pragma mark - Report - + +#define SentryCrashField_Crash "crash" +#define SentryCrashField_Debug "debug" +#define SentryCrashField_Diagnosis "diagnosis" +#define SentryCrashField_ID "id" +#define SentryCrashField_ProcessName "process_name" +#define SentryCrashField_Report "report" +#define SentryCrashField_Timestamp "timestamp" +#define SentryCrashField_Version "version" + +#pragma mark Minimal +#define SentryCrashField_CrashedThread "crashed_thread" + +#pragma mark Standard +#define SentryCrashField_AppStats "application_stats" +#define SentryCrashField_BinaryImages "binary_images" +#define SentryCrashField_System "system" +#define SentryCrashField_Memory "memory" +#define SentryCrashField_Threads "threads" +#define SentryCrashField_User "user" +#define SentryCrashField_ConsoleLog "console_log" + +#pragma mark Incomplete +#define SentryCrashField_Incomplete "incomplete" +#define SentryCrashField_RecrashReport "recrash_report" + +#pragma mark System +#define SentryCrashField_AppStartTime "app_start_time" +#define SentryCrashField_AppUUID "app_uuid" +#define SentryCrashField_BootTime "boot_time" +#define SentryCrashField_BundleID "CFBundleIdentifier" +#define SentryCrashField_BundleName "CFBundleName" +#define SentryCrashField_BundleShortVersion "CFBundleShortVersionString" +#define SentryCrashField_BundleVersion "CFBundleVersion" +#define SentryCrashField_CPUArch "cpu_arch" +#define SentryCrashField_CPUType "cpu_type" +#define SentryCrashField_CPUSubType "cpu_subtype" +#define SentryCrashField_BinaryCPUType "binary_cpu_type" +#define SentryCrashField_BinaryCPUSubType "binary_cpu_subtype" +#define SentryCrashField_DeviceAppHash "device_app_hash" +#define SentryCrashField_Executable "CFBundleExecutable" +#define SentryCrashField_ExecutablePath "CFBundleExecutablePath" +#define SentryCrashField_Jailbroken "jailbroken" +#define SentryCrashField_KernelVersion "kernel_version" +#define SentryCrashField_Machine "machine" +#define SentryCrashField_Model "model" +#define SentryCrashField_OSVersion "os_version" +#define SentryCrashField_ParentProcessID "parent_process_id" +#define SentryCrashField_ProcessID "process_id" +#define SentryCrashField_ProcessName "process_name" +#define SentryCrashField_Size "size" +#define SentryCrashField_Storage "storage" +#define SentryCrashField_SystemName "system_name" +#define SentryCrashField_SystemVersion "system_version" +#define SentryCrashField_TimeZone "time_zone" +#define SentryCrashField_BuildType "build_type" + +#endif diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFixer.c b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFixer.c new file mode 100644 index 00000000..f7151d7d --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFixer.c @@ -0,0 +1,272 @@ +// +// SentryCrashReportFixer.c +// +// Created by Karl Stenerud on 2016-11-07. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashDate.h" +#include "SentryCrashJSONCodec.h" +#include "SentryCrashLogger.h" +#include "SentryCrashReportFields.h" +#include "SentryCrashSystemCapabilities.h" + +#include +#include + +#define MAX_DEPTH 100 +#define MAX_NAME_LENGTH 100 + +static char *datePaths[][MAX_DEPTH] = { + { "", SentryCrashField_Report, SentryCrashField_Timestamp }, + { "", SentryCrashField_RecrashReport, SentryCrashField_Report, SentryCrashField_Timestamp }, +}; +static int datePathsCount = sizeof(datePaths) / sizeof(*datePaths); + +typedef struct { + SentryCrashJSONEncodeContext *encodeContext; + char objectPath[MAX_DEPTH][MAX_NAME_LENGTH]; + int currentDepth; + char *outputPtr; + int outputBytesLeft; +} FixupContext; + +static bool +increaseDepth(FixupContext *context, const char *name) +{ + if (context->currentDepth >= MAX_DEPTH) { + return false; + } + if (name == NULL) { + *context->objectPath[context->currentDepth] = '\0'; + } else { + strncpy(context->objectPath[context->currentDepth], name, + sizeof(context->objectPath[context->currentDepth])); + } + context->currentDepth++; + return true; +} + +static bool +decreaseDepth(FixupContext *context) +{ + if (context->currentDepth <= 0) { + return false; + } + context->currentDepth--; + return true; +} + +static bool +matchesPath(FixupContext *context, char **path, const char *finalName) +{ + if (finalName == NULL) { + finalName = ""; + } + + for (int i = 0; i < context->currentDepth; i++) { + if (strncmp(context->objectPath[i], path[i], MAX_NAME_LENGTH) != 0) { + return false; + } + } + if (strncmp(finalName, path[context->currentDepth], MAX_NAME_LENGTH) != 0) { + return false; + } + return true; +} + +static bool +matchesAPath(FixupContext *context, const char *name, char *paths[][MAX_DEPTH], int pathsCount) +{ + for (int i = 0; i < pathsCount; i++) { + if (matchesPath(context, paths[i], name)) { + return true; + } + } + return false; +} + +static bool +shouldFixDate(FixupContext *context, const char *name) +{ + return matchesAPath(context, name, datePaths, datePathsCount); +} + +static int +onBooleanElement(const char *const name, const bool value, void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + return sentrycrashjson_addBooleanElement(context->encodeContext, name, value); +} + +static int +onFloatingPointElement(const char *const name, const double value, void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + return sentrycrashjson_addFloatingPointElement(context->encodeContext, name, value); +} + +static int +onIntegerElement(const char *const name, const int64_t value, void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + int result = SentryCrashJSON_OK; + if (shouldFixDate(context, name)) { + char buffer[21]; + sentrycrashdate_utcStringFromTimestamp((time_t)value, buffer); + + result = sentrycrashjson_addStringElement( + context->encodeContext, name, buffer, (int)strlen(buffer)); + } else { + result = sentrycrashjson_addIntegerElement(context->encodeContext, name, value); + } + return result; +} + +static int +onNullElement(const char *const name, void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + return sentrycrashjson_addNullElement(context->encodeContext, name); +} + +static int +onStringElement(const char *const name, const char *const value, void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + const char *stringValue = value; + + int result = sentrycrashjson_addStringElement( + context->encodeContext, name, stringValue, (int)strlen(stringValue)); + + return result; +} + +static int +onBeginObject(const char *const name, void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + int result = sentrycrashjson_beginObject(context->encodeContext, name); + if (!increaseDepth(context, name)) { + return SentryCrashJSON_ERROR_DATA_TOO_LONG; + } + return result; +} + +static int +onBeginArray(const char *const name, void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + int result = sentrycrashjson_beginArray(context->encodeContext, name); + if (!increaseDepth(context, name)) { + return SentryCrashJSON_ERROR_DATA_TOO_LONG; + } + return result; +} + +static int +onEndContainer(void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + int result = sentrycrashjson_endContainer(context->encodeContext); + if (!decreaseDepth(context)) { + // Do something; + } + return result; +} + +static int +onEndData(__unused void *const userData) +{ + FixupContext *context = (FixupContext *)userData; + return sentrycrashjson_endEncode(context->encodeContext); +} + +static int +addJSONData(const char *data, int length, void *userData) +{ + FixupContext *context = (FixupContext *)userData; + if (length > context->outputBytesLeft) { + return SentryCrashJSON_ERROR_DATA_TOO_LONG; + } + memcpy(context->outputPtr, data, length); + context->outputPtr += length; + context->outputBytesLeft -= length; + + return SentryCrashJSON_OK; +} + +char * +sentrycrashcrf_fixupCrashReport(const char *crashReport) +{ + if (crashReport == NULL) { + return NULL; + } + + SentryCrashJSONDecodeCallbacks callbacks = { + .onBeginArray = onBeginArray, + .onBeginObject = onBeginObject, + .onBooleanElement = onBooleanElement, + .onEndContainer = onEndContainer, + .onEndData = onEndData, + .onFloatingPointElement = onFloatingPointElement, + .onIntegerElement = onIntegerElement, + .onNullElement = onNullElement, + .onStringElement = onStringElement, + }; + int stringBufferLength = SentryCrashMAX_STRINGBUFFERSIZE; + char *stringBuffer = malloc((unsigned)stringBufferLength); + if (stringBuffer == NULL) { + SentryCrashLOG_ERROR("Failed to allocate string buffer of size %ul", stringBufferLength); + return NULL; + } + int crashReportLength = (int)strlen(crashReport); + int fixedReportLength = (int)(crashReportLength * 1.5); + char *fixedReport = malloc((unsigned)fixedReportLength); + if (fixedReport == NULL) { + free(stringBuffer); + SentryCrashLOG_ERROR( + "Failed to allocate fixed report buffer of size %ld", fixedReportLength); + return NULL; + } + SentryCrashJSONEncodeContext encodeContext; + FixupContext fixupContext = { + .encodeContext = &encodeContext, + .currentDepth = 0, + .outputPtr = fixedReport, + .outputBytesLeft = fixedReportLength, + }; + + sentrycrashjson_beginEncode(&encodeContext, true, addJSONData, &fixupContext); + + int errorOffset = 0; + int result = sentrycrashjson_decode(crashReport, (int)strlen(crashReport), stringBuffer, + stringBufferLength, &callbacks, &fixupContext, &errorOffset); + *fixupContext.outputPtr = '\0'; + free(stringBuffer); + if (result != SentryCrashJSON_OK) { + SentryCrashLOG_ERROR("Could not decode report: %s", sentrycrashjson_stringForError(result)); + free(fixedReport); + return NULL; + } + return fixedReport; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFixer.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFixer.h new file mode 100644 index 00000000..bc259043 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportFixer.h @@ -0,0 +1,50 @@ +// +// SentryCrashReportFixer.c +// +// Created by Karl Stenerud on 2016-11-07. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashReportFixer_h +#define HDR_SentryCrashReportFixer_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** Fixes up fields in a crash report that could not be fixed up at crash time. + * Some fields, such a mangled fields and dates, cannot be fixed up at crash + * time because the function calls needed to do it are not async-safe. + * + * @param crashReport A raw report loaded from disk. + * + * @return A fixed up crash report. + * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on + * the returned value. + */ +char *sentrycrashcrf_fixupCrashReport(const char *crashReport); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashReportFixer_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportStore.c b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportStore.c new file mode 100644 index 00000000..c6cb4e7b --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportStore.c @@ -0,0 +1,267 @@ +// +// SentryCrashReportStore.c +// +// Created by Karl Stenerud on 2012-02-05. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashReportStore.h" +#include "SentryCrashFileUtils.h" +#include "SentryCrashLogger.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int g_maxReportCount = 5; +// Have to use max 32-bit atomics because of MIPS. +static _Atomic(uint32_t) g_nextUniqueIDLow; +static int64_t g_nextUniqueIDHigh; +static const char *g_appName; +static const char *g_reportsPath; +static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int +compareInt64(const void *a, const void *b) +{ + int64_t diff = *(int64_t *)a - *(int64_t *)b; + if (diff < 0) { + return -1; + } else if (diff > 0) { + return 1; + } + return 0; +} + +static inline int64_t +getNextUniqueID() +{ + return g_nextUniqueIDHigh + g_nextUniqueIDLow++; +} + +static void +getCrashReportPathByID(int64_t id, char *pathBuffer) +{ + snprintf(pathBuffer, SentryCrashCRS_MAX_PATH_LENGTH, "%s/%s-report-%016llx.json", g_reportsPath, + g_appName, id); +} + +static int64_t +getReportIDFromFilename(const char *filename) +{ + char scanFormat[100]; + snprintf(scanFormat, sizeof(scanFormat), "%s-report-%%" PRIx64 ".json", g_appName); + + int64_t reportID = 0; + sscanf(filename, scanFormat, &reportID); + return reportID; +} + +static int +getReportCount() +{ + int count = 0; + DIR *dir = opendir(g_reportsPath); + if (dir == NULL) { + SentryCrashLOG_ERROR("Could not open directory %s", g_reportsPath); + goto done; + } + struct dirent *ent; + while ((ent = readdir(dir)) != NULL) { + if (getReportIDFromFilename(ent->d_name) > 0) { + count++; + } + } + +done: + if (dir != NULL) { + closedir(dir); + } + return count; +} + +static int +getReportIDs(int64_t *reportIDs, int count) +{ + int index = 0; + DIR *dir = opendir(g_reportsPath); + if (dir == NULL) { + SentryCrashLOG_ERROR("Could not open directory %s", g_reportsPath); + goto done; + } + + struct dirent *ent; + while ((ent = readdir(dir)) != NULL && index < count) { + int64_t reportID = getReportIDFromFilename(ent->d_name); + if (reportID > 0) { + reportIDs[index++] = reportID; + } + } + + qsort(reportIDs, (unsigned)count, sizeof(reportIDs[0]), compareInt64); + +done: + if (dir != NULL) { + closedir(dir); + } + return index; +} + +static void +pruneReports() +{ + int reportCount = getReportCount(); + if (reportCount > g_maxReportCount) { + int64_t reportIDs[reportCount]; + reportCount = getReportIDs(reportIDs, reportCount); + + for (int i = 0; i < reportCount - g_maxReportCount; i++) { + sentrycrashcrs_deleteReportWithID(reportIDs[i]); + } + } +} + +static void +initializeIDs() +{ + time_t rawTime; + time(&rawTime); + struct tm time; + gmtime_r(&rawTime, &time); + int64_t baseID = (int64_t)time.tm_sec + (int64_t)time.tm_min * 61 + + (int64_t)time.tm_hour * 61 * 60 + (int64_t)time.tm_yday * 61 * 60 * 24 + + (int64_t)time.tm_year * 61 * 60 * 24 * 366; + baseID <<= 23; + + g_nextUniqueIDHigh = baseID & ~0xffffffff; + g_nextUniqueIDLow = (uint32_t)(baseID & 0xffffffff); +} + +// Public API + +void +sentrycrashcrs_initialize(const char *appName, const char *reportsPath) +{ + pthread_mutex_lock(&g_mutex); + g_appName = strdup(appName); + g_reportsPath = strdup(reportsPath); + sentrycrashfu_makePath(reportsPath); + pruneReports(); + initializeIDs(); + pthread_mutex_unlock(&g_mutex); +} + +void +sentrycrashcrs_getNextCrashReportPath(char *crashReportPathBuffer) +{ + getCrashReportPathByID(getNextUniqueID(), crashReportPathBuffer); +} + +int +sentrycrashcrs_getReportCount() +{ + pthread_mutex_lock(&g_mutex); + int count = getReportCount(); + pthread_mutex_unlock(&g_mutex); + return count; +} + +int +sentrycrashcrs_getReportIDs(int64_t *reportIDs, int count) +{ + pthread_mutex_lock(&g_mutex); + count = getReportIDs(reportIDs, count); + pthread_mutex_unlock(&g_mutex); + return count; +} + +char * +sentrycrashcrs_readReport(int64_t reportID) +{ + pthread_mutex_lock(&g_mutex); + char path[SentryCrashCRS_MAX_PATH_LENGTH]; + getCrashReportPathByID(reportID, path); + char *result; + sentrycrashfu_readEntireFile(path, &result, NULL, 2000000); + pthread_mutex_unlock(&g_mutex); + return result; +} + +int64_t +sentrycrashcrs_addUserReport(const char *report, int reportLength) +{ + pthread_mutex_lock(&g_mutex); + int64_t currentID = getNextUniqueID(); + char crashReportPath[SentryCrashCRS_MAX_PATH_LENGTH]; + getCrashReportPathByID(currentID, crashReportPath); + + int fd = open(crashReportPath, O_WRONLY | O_CREAT, 0644); + if (fd < 0) { + SentryCrashLOG_ERROR("Could not open file %s: %s", crashReportPath, strerror(errno)); + goto done; + } + + int bytesWritten = (int)write(fd, report, (unsigned)reportLength); + if (bytesWritten < 0) { + SentryCrashLOG_ERROR("Could not write to file %s: %s", crashReportPath, strerror(errno)); + goto done; + } else if (bytesWritten < reportLength) { + SentryCrashLOG_ERROR("Expected to write %d bytes to file %s, but only wrote %d", + crashReportPath, reportLength, bytesWritten); + } + +done: + if (fd >= 0) { + close(fd); + } + pthread_mutex_unlock(&g_mutex); + + return currentID; +} + +void +sentrycrashcrs_deleteAllReports() +{ + pthread_mutex_lock(&g_mutex); + sentrycrashfu_deleteContentsOfPath(g_reportsPath); + pthread_mutex_unlock(&g_mutex); +} + +void +sentrycrashcrs_deleteReportWithID(int64_t reportID) +{ + char path[SentryCrashCRS_MAX_PATH_LENGTH]; + getCrashReportPathByID(reportID, path); + sentrycrashfu_removeFile(path, true); +} + +void +sentrycrashcrs_setMaxReportCount(int maxReportCount) +{ + g_maxReportCount = maxReportCount; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportStore.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportStore.h new file mode 100644 index 00000000..e6c77fb9 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportStore.h @@ -0,0 +1,106 @@ +// +// SentryCrashReportStore.h +// +// Created by Karl Stenerud on 2012-02-05. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashReportStore_h +#define HDR_SentryCrashReportStore_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define SentryCrashCRS_MAX_PATH_LENGTH 500 + +/** Initialize the report store. + * + * @param appName The application's name. + * @param reportsPath Full path to directory where the reports are to be stored + * (path will be created if needed). + */ +void sentrycrashcrs_initialize(const char *appName, const char *reportsPath); + +/** Get the path to the next crash report to be generated. + * Max length for paths is SentryCrashCRS_MAX_PATH_LENGTH + * + * @param crashReportPathBuffer Buffer to store the crash report path. + */ +void sentrycrashcrs_getNextCrashReportPath(char *crashReportPathBuffer); + +/** Get the number of reports on disk. + */ +int sentrycrashcrs_getReportCount(void); + +/** Get a list of IDs for all reports on disk. + * + * @param reportIDs An array big enough to hold all report IDs. + * @param count How many reports the array can hold. + * + * @return The number of report IDs that were placed in the array. + */ +int sentrycrashcrs_getReportIDs(int64_t *reportIDs, int count); + +/** Read a report. + * + * @param reportID The report's ID. + * + * @return The NULL terminated report, or NULL if not found. + * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on + * the returned value. + */ +char *sentrycrashcrs_readReport(int64_t reportID); + +/** Add a custom report to the store. + * + * @param report The report's contents (must be JSON encoded). + * @param reportLength The length of the report in bytes. + * + * @return the new report's ID. + */ +int64_t sentrycrashcrs_addUserReport(const char *report, int reportLength); + +/** Delete all reports on disk. + */ +void sentrycrashcrs_deleteAllReports(void); + +/** Delete report. + * + * @param reportID An ID of report to delete. + */ +void sentrycrashcrs_deleteReportWithID(int64_t reportID); + +/** Set the maximum number of reports allowed on disk before old ones get + * deleted. + * + * @param maxReportCount The maximum number of reports. + */ +void sentrycrashcrs_setMaxReportCount(int maxReportCount); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashReportStore_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportVersion.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportVersion.h new file mode 100644 index 00000000..651bfd86 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportVersion.h @@ -0,0 +1,32 @@ +// +// SentryCrashReportVersion.h +// +// Created by Karl Stenerud on 2016-03-10. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashReportVersion_h +#define HDR_SentryCrashReportVersion_h + +#define SentryCrashCRASH_REPORT_VERSION "3.2.0" + +#endif /* HDR_SentryCrashReportVersion_h */ diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportWriter.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportWriter.h new file mode 100644 index 00000000..4febb0bf --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashReportWriter.h @@ -0,0 +1,230 @@ +// +// SentryCrashReportWriter.h +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Pointers to functions for writing to a crash report. All JSON types are + * supported. + */ + +#ifndef HDR_SentryCrashReportWriter_h +#define HDR_SentryCrashReportWriter_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * Encapsulates report writing functionality. + */ +typedef struct SentryCrashReportWriter { + /** Add a boolean element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param value The value to add. + */ + void (*addBooleanElement)( + const struct SentryCrashReportWriter *writer, const char *name, bool value); + + /** Add a floating point element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param value The value to add. + */ + void (*addFloatingPointElement)( + const struct SentryCrashReportWriter *writer, const char *name, double value); + + /** Add an integer element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param value The value to add. + */ + void (*addIntegerElement)( + const struct SentryCrashReportWriter *writer, const char *name, int64_t value); + + /** Add an unsigned integer element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param value The value to add. + */ + void (*addUIntegerElement)( + const struct SentryCrashReportWriter *writer, const char *name, uint64_t value); + + /** Add a string element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param value The value to add. + */ + void (*addStringElement)( + const struct SentryCrashReportWriter *writer, const char *name, const char *value); + + /** Add a string element from a text file to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param filePath The path to the file containing the value to add. + */ + void (*addTextFileElement)( + const struct SentryCrashReportWriter *writer, const char *name, const char *filePath); + + /** Add an array of string elements representing lines from a text file to + * the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param filePath The path to the file containing the value to add. + */ + void (*addTextFileLinesElement)( + const struct SentryCrashReportWriter *writer, const char *name, const char *filePath); + + /** Add a JSON element from a text file to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param filePath The path to the file containing the value to add. + * + * @param closeLastContainer If false, do not close the last container. + */ + void (*addJSONFileElement)(const struct SentryCrashReportWriter *writer, const char *name, + const char *filePath, const bool closeLastContainer); + + /** Add a hex encoded data element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param value A pointer to the binary data. + * + * @paramn length The length of the data. + */ + void (*addDataElement)(const struct SentryCrashReportWriter *writer, const char *name, + const char *value, const int length); + + /** Begin writing a hex encoded data element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + */ + void (*beginDataElement)(const struct SentryCrashReportWriter *writer, const char *name); + + /** Append hex encoded data to the current data element in the report. + * + * @param writer This writer. + * + * @param value A pointer to the binary data. + * + * @paramn length The length of the data. + */ + void (*appendDataElement)( + const struct SentryCrashReportWriter *writer, const char *value, const int length); + + /** Complete writing a hex encoded data element to the report. + * + * @param writer This writer. + */ + void (*endDataElement)(const struct SentryCrashReportWriter *writer); + + /** Add a UUID element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param value A pointer to the binary UUID data. + */ + void (*addUUIDElement)( + const struct SentryCrashReportWriter *writer, const char *name, const unsigned char *value); + + /** Add a preformatted JSON element to the report. + * + * @param writer This writer. + * + * @param name The name to give this element. + * + * @param value A pointer to the JSON data. + */ + void (*addJSONElement)(const struct SentryCrashReportWriter *writer, const char *name, + const char *jsonElement, bool closeLastContainer); + + /** Begin a new object container. + * + * @param writer This writer. + * + * @param name The name to give this element. + */ + void (*beginObject)(const struct SentryCrashReportWriter *writer, const char *name); + + /** Begin a new array container. + * + * @param writer This writer. + * + * @param name The name to give this element. + */ + void (*beginArray)(const struct SentryCrashReportWriter *writer, const char *name); + + /** Leave the current container, returning to the next higher level + * container. + * + * @param writer This writer. + */ + void (*endContainer)(const struct SentryCrashReportWriter *writer); + + /** Internal contextual data for the writer */ + void *context; + +} SentryCrashReportWriter; + +typedef void (*SentryCrashReportWriteCallback)(const SentryCrashReportWriter *writer); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashReportWriter_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashSystemCapabilities.h b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashSystemCapabilities.h new file mode 100644 index 00000000..16bf1d83 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/SentryCrashSystemCapabilities.h @@ -0,0 +1,156 @@ +// +// SentryCrashSystemCapabilities.h +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashSystemCapabilities_h +#define HDR_SentryCrashSystemCapabilities_h + +#ifdef __APPLE__ +# include +# define SentryCrashCRASH_HOST_APPLE 1 +#endif + +#ifdef __ANDROID__ +# define SentryCrashCRASH_HOST_ANDROID 1 +#endif + +#define SentryCrashCRASH_HOST_IOS (SentryCrashCRASH_HOST_APPLE && TARGET_OS_IOS) +#define SentryCrashCRASH_HOST_TV (SentryCrashCRASH_HOST_APPLE && TARGET_OS_TV) +#define SentryCrashCRASH_HOST_WATCH (SentryCrashCRASH_HOST_APPLE && TARGET_OS_WATCH) +#define SentryCrashCRASH_HOST_MAC \ + (SentryCrashCRASH_HOST_APPLE && TARGET_OS_MAC \ + && !(TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH)) + +#if SentryCrashCRASH_HOST_APPLE +# define SentryCrashCRASH_CAN_GET_MAC_ADDRESS 1 +#else +# define SentryCrashCRASH_CAN_GET_MAC_ADDRESS 0 +#endif + +#if SentryCrashCRASH_HOST_APPLE +# define SentryCrashCRASH_HAS_OBJC 1 +# define SentryCrashCRASH_HAS_SWIFT 1 +#else +# define SentryCrashCRASH_HAS_OBJC 0 +# define SentryCrashCRASH_HAS_SWIFT 0 +#endif + +#if SentryCrashCRASH_HOST_APPLE +# define SentryCrashCRASH_HAS_KINFO_PROC 1 +#else +# define SentryCrashCRASH_HAS_KINFO_PROC 0 +#endif + +#if SentryCrashCRASH_HOST_APPLE +# define SentryCrashCRASH_HAS_STRNSTR 1 +#else +# define SentryCrashCRASH_HAS_STRNSTR 0 +#endif + +#if SentryCrashCRASH_HOST_IOS || SentryCrashCRASH_HOST_TV || SentryCrashCRASH_HOST_WATCH +# define SentryCrashCRASH_HAS_UIKIT 1 +#else +# define SentryCrashCRASH_HAS_UIKIT 0 +#endif + +#if SentryCrashCRASH_HOST_IOS || SentryCrashCRASH_HOST_TV +# define SentryCrashCRASH_HAS_UIAPPLICATION 1 +#else +# define SentryCrashCRASH_HAS_UIAPPLICATION 0 +#endif + +#if SentryCrashCRASH_HOST_WATCH +# define SentryCrashCRASH_HAS_NSEXTENSION 1 +#else +# define SentryCrashCRASH_HAS_NSEXTENSION 0 +#endif + +#if SentryCrashCRASH_HOST_IOS +# define SentryCrashCRASH_HAS_MESSAGEUI 1 +#else +# define SentryCrashCRASH_HAS_MESSAGEUI 0 +#endif + +#if SentryCrashCRASH_HOST_IOS || SentryCrashCRASH_HOST_TV +# define SentryCrashCRASH_HAS_UIDEVICE 1 +#else +# define SentryCrashCRASH_HAS_UIDEVICE 0 +#endif + +#if SentryCrashCRASH_HOST_IOS || SentryCrashCRASH_HOST_MAC || SentryCrashCRASH_HOST_TV +# define SentryCrashCRASH_HAS_ALERTVIEW 1 +#else +# define SentryCrashCRASH_HAS_ALERTVIEW 0 +#endif + +#if SentryCrashCRASH_HOST_IOS +# define SentryCrashCRASH_HAS_UIALERTVIEW 1 +#else +# define SentryCrashCRASH_HAS_UIALERTVIEW 0 +#endif + +#if SentryCrashCRASH_HOST_TV +# define SentryCrashCRASH_HAS_UIALERTCONTROLLER 1 +#else +# define SentryCrashCRASH_HAS_UIALERTCONTROLLER 0 +#endif + +#if SentryCrashCRASH_HOST_MAC +# define SentryCrashCRASH_HAS_NSALERT 1 +#else +# define SentryCrashCRASH_HAS_NSALERT 0 +#endif + +#if SentryCrashCRASH_HOST_IOS || SentryCrashCRASH_HOST_MAC +# define SentryCrashCRASH_HAS_MACH 1 +#else +# define SentryCrashCRASH_HAS_MACH 0 +#endif + +// WatchOS signal is broken as of 3.1 +#if SentryCrashCRASH_HOST_ANDROID || SentryCrashCRASH_HOST_IOS || SentryCrashCRASH_HOST_MAC \ + || SentryCrashCRASH_HOST_TV +# define SentryCrashCRASH_HAS_SIGNAL 1 +#else +# define SentryCrashCRASH_HAS_SIGNAL 0 +#endif + +#if SentryCrashCRASH_HOST_ANDROID || SentryCrashCRASH_HOST_MAC || SentryCrashCRASH_HOST_IOS +# define SentryCrashCRASH_HAS_SIGNAL_STACK 1 +#else +# define SentryCrashCRASH_HAS_SIGNAL_STACK 0 +#endif + +#if SentryCrashCRASH_HOST_MAC || SentryCrashCRASH_HOST_IOS || SentryCrashCRASH_HOST_TV +# define SentryCrashCRASH_HAS_THREADS_API 1 +#else +# define SentryCrashCRASH_HAS_THREADS_API 0 +#endif + +#if SentryCrashCRASH_HOST_MAC || SentryCrashCRASH_HOST_IOS || SentryCrashCRASH_HOST_TV +# define SentryCrashCRASH_HAS_REACHABILITY 1 +#else +# define SentryCrashCRASH_HAS_REACHABILITY 0 +#endif + +#endif // HDR_SentryCrashSystemCapabilities_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.h new file mode 100644 index 00000000..9b042193 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.h @@ -0,0 +1,67 @@ +// +// NSError+SimpleConstructor.h +// +// Created by Karl Stenerud on 2013-02-09. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +/** + * Simpler interface for constructing NSError objects. + */ +@interface NSError (SentrySimpleConstructor) + +/** Convenience constructor to make an error with the specified localized + * description. + * + * @param domain The domain + * @param code The code + * @param fmt Description of the error (gets placed into the user data with the + * key NSLocalizedDescriptionKey). + */ ++ (NSError *)sentryErrorWithDomain:(NSString *)domain + code:(NSInteger)code + description:(NSString *)fmt, ...; + +/** Fill an error pointer with an NSError object if it's not nil. + * + * @param error Error pointer to fill (ignored if nil). + * @param domain The domain + * @param code The code + * @param fmt Description of the error (gets placed into the user data with the + * key NSLocalizedDescriptionKey). + * @return NO (to keep the analyzer happy). + */ ++ (BOOL)sentryFillError:(NSError **)error + withDomain:(NSString *)domain + code:(NSInteger)code + description:(NSString *)fmt, ...; + +/** Clear a pointer-to-error to nil of its pointer is not nil. + * + * @param error Error pointer to fill (ignored if nil). + * @return NO (to keep the analyzer happy). + */ ++ (BOOL)sentryClearError:(NSError **)error; + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.m b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.m new file mode 100644 index 00000000..8ba06ad2 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/NSError+SentrySimpleConstructor.m @@ -0,0 +1,81 @@ +// +// NSError+SimpleConstructor.m +// +// Created by Karl Stenerud on 2013-02-09. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "NSError+SentrySimpleConstructor.h" + +@implementation NSError (SentrySimpleConstructor) + ++ (NSError *)sentryErrorWithDomain:(NSString *)domain + code:(NSInteger)code + description:(NSString *)fmt, ... +{ + va_list args; + va_start(args, fmt); + + NSString *desc = [[NSString alloc] initWithFormat:fmt arguments:args]; + va_end(args); + + return [NSError errorWithDomain:domain + code:code + userInfo:[NSDictionary dictionaryWithObject:desc + forKey:NSLocalizedDescriptionKey]]; +} + ++ (BOOL)sentryFillError:(NSError *__autoreleasing *)error + withDomain:(NSString *)domain + code:(NSInteger)code + description:(NSString *)fmt, ... +{ + if (error != nil) { + va_list args; + va_start(args, fmt); + + NSString *desc = [[NSString alloc] initWithFormat:fmt arguments:args]; + va_end(args); + + *error = + [NSError errorWithDomain:domain + code:code + userInfo:[NSDictionary dictionaryWithObject:desc + forKey:NSLocalizedDescriptionKey]]; + } + return NO; +} + ++ (BOOL)sentryClearError:(NSError *__autoreleasing *)error +{ + if (error != nil) { + *error = nil; + } + return NO; +} + +@end + +@interface sentrycrashobjc_NSError_SimpleConstructor_AOG8G : NSObject +@end +@implementation sentrycrashobjc_NSError_SimpleConstructor_AOG8G +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU.c new file mode 100644 index 00000000..106b624a --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU.c @@ -0,0 +1,71 @@ +// +// SentryCrashCPU.h +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashCPU.h" + +#include "SentryCrashSystemCapabilities.h" + +#include +#include + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +const char * +sentrycrashcpu_currentArch(void) +{ + // This is blocking App Store submissions and must be worked around + // TODO: Figure out a replacement + // const NXArchInfo *archInfo = NXGetLocalArchInfo(); + // return archInfo == NULL ? NULL : archInfo->name; + return NULL; +} + +#if SentryCrashCRASH_HAS_THREADS_API +bool +sentrycrashcpu_i_fillState(const thread_t thread, const thread_state_t state, + const thread_state_flavor_t flavor, const mach_msg_type_number_t stateCount) +{ + SentryCrashLOG_TRACE("Filling thread state with flavor %x.", flavor); + mach_msg_type_number_t stateCountBuff = stateCount; + kern_return_t kr; + + kr = thread_get_state(thread, flavor, state, &stateCountBuff); + if (kr != KERN_SUCCESS) { + SentryCrashLOG_ERROR("thread_get_state: %s", mach_error_string(kr)); + return false; + } + return true; +} +#else +bool +sentrycrashcpu_i_fillState(__unused const thread_t thread, __unused const thread_state_t state, + __unused const thread_state_flavor_t flavor, __unused const mach_msg_type_number_t stateCount) +{ + return false; +} + +#endif diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU.h new file mode 100644 index 00000000..982006f3 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU.h @@ -0,0 +1,159 @@ +// +// SentryCrashCPU.h +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashCPU_h +#define HDR_SentryCrashCPU_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMachineContext.h" + +#include +#include + +/** Get the current CPU architecture. + * + * @return The current architecture. + */ +const char *sentrycrashcpu_currentArch(void); + +/** Get the frame pointer for a machine context. + * The frame pointer marks the top of the call stack. + * + * @param context The machine context. + * + * @return The context's frame pointer. + */ +uintptr_t sentrycrashcpu_framePointer(const struct SentryCrashMachineContext *const context); + +/** Get the current stack pointer for a machine context. + * + * @param context The machine context. + * + * @return The context's stack pointer. + */ +uintptr_t sentrycrashcpu_stackPointer(const struct SentryCrashMachineContext *const context); + +/** Get the address of the instruction about to be, or being executed by a + * machine context. + * + * @param context The machine context. + * + * @return The context's next instruction address. + */ +uintptr_t sentrycrashcpu_instructionAddress(const struct SentryCrashMachineContext *const context); + +/** Get the address stored in the link register (arm only). This may + * contain the first return address of the stack. + * + * @param context The machine context. + * + * @return The link register value. + */ +uintptr_t sentrycrashcpu_linkRegister(const struct SentryCrashMachineContext *const context); + +/** Get the address whose access caused the last fault. + * + * @param context The machine context. + * + * @return The faulting address. + */ +uintptr_t sentrycrashcpu_faultAddress(const struct SentryCrashMachineContext *const context); + +/** Get the number of normal (not floating point or exception) registers the + * currently running CPU has. + * + * @return The number of registers. + */ +int sentrycrashcpu_numRegisters(void); + +/** Get the name of a normal register. + * + * @param regNumber The register index. + * + * @return The register's name or NULL if not found. + */ +const char *sentrycrashcpu_registerName(int regNumber); + +/** Get the value stored in a normal register. + * + * @param regNumber The register index. + * + * @return The register's current value. + */ +uint64_t sentrycrashcpu_registerValue( + const struct SentryCrashMachineContext *const context, int regNumber); + +/** Get the number of exception registers the currently running CPU has. + * + * @return The number of registers. + */ +int sentrycrashcpu_numExceptionRegisters(void); + +/** Get the name of an exception register. + * + * @param regNumber The register index. + * + * @return The register's name or NULL if not found. + */ +const char *sentrycrashcpu_exceptionRegisterName(int regNumber); + +/** Get the value stored in an exception register. + * + * @param regNumber The register index. + * + * @return The register's current value. + */ +uint64_t sentrycrashcpu_exceptionRegisterValue( + const struct SentryCrashMachineContext *const context, int regNumber); + +/** Get the direction in which the stack grows on the current architecture. + * + * @return 1 or -1, depending on which direction the stack grows in. + */ +int sentrycrashcpu_stackGrowDirection(void); + +/** Fetch the CPU state for this context and store it in the context. + * + * @param destinationContext The context to fill. + */ +void sentrycrashcpu_getState(struct SentryCrashMachineContext *destinationContext); + +/** Strip PAC from an instruction pointer. + * + * @param ip PAC encoded instruction pointer. + * + * @return Instruction pointer without PAC. + */ +uintptr_t sentrycrashcpu_normaliseInstructionPointer(uintptr_t ip); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashCPU_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_Apple.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_Apple.h new file mode 100644 index 00000000..42cd748a --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_Apple.h @@ -0,0 +1,55 @@ +// +// SentryCrashCPU_Apple.h +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashCPU_Apple_h +#define HDR_SentryCrashCPU_Apple_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** Fill in state information about a thread. + * + * @param thread The thread to get information about. + * + * @param state Pointer to buffer for state information. + * + * @param flavor The kind of information to get (arch specific). + * + * @param stateCount Number of entries in the state information buffer. + * + * @return true if state fetching was successful. + */ +bool sentrycrashcpu_i_fillState(thread_t thread, thread_state_t state, thread_state_flavor_t flavor, + mach_msg_type_number_t stateCount); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashCPU_Apple_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_arm.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_arm.c new file mode 100644 index 00000000..0159c08d --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_arm.c @@ -0,0 +1,170 @@ +// +// SentryCrashCPU_arm.c +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#if defined(__arm__) + +# include "SentryCrashCPU.h" +# include "SentryCrashCPU_Apple.h" +# include "SentryCrashMachineContext.h" +# include "SentryCrashMachineContext_Apple.h" +# include + +//#define SentryCrashLogger_LocalLevel TRACE +# include "SentryCrashLogger.h" + +static const char *g_registerNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "ip", "sp", "lr", "pc", "cpsr" }; +static const int g_registerNamesCount = sizeof(g_registerNames) / sizeof(*g_registerNames); + +static const char *g_exceptionRegisterNames[] = { "exception", "fsr", "far" }; +static const int g_exceptionRegisterNamesCount + = sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); + +uintptr_t +sentrycrashcpu_framePointer(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__r[7]; +} + +uintptr_t +sentrycrashcpu_stackPointer(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__sp; +} + +uintptr_t +sentrycrashcpu_instructionAddress(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__pc; +} + +uintptr_t +sentrycrashcpu_linkRegister(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__lr; +} + +void +sentrycrashcpu_getState(SentryCrashMachineContext *context) +{ + thread_t thread = context->thisThread; + STRUCT_MCONTEXT_L *const machineContext = &context->machineContext; + + sentrycrashcpu_i_fillState( + thread, (thread_state_t)&machineContext->__ss, ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT); + sentrycrashcpu_i_fillState(thread, (thread_state_t)&machineContext->__es, ARM_EXCEPTION_STATE, + ARM_EXCEPTION_STATE_COUNT); +} + +int +sentrycrashcpu_numRegisters(void) +{ + return g_registerNamesCount; +} + +const char * +sentrycrashcpu_registerName(const int regNumber) +{ + if (regNumber < sentrycrashcpu_numRegisters()) { + return g_registerNames[regNumber]; + } + return NULL; +} + +uint64_t +sentrycrashcpu_registerValue(const SentryCrashMachineContext *const context, const int regNumber) +{ + if (regNumber <= 12) { + return context->machineContext.__ss.__r[regNumber]; + } + + switch (regNumber) { + case 13: + return context->machineContext.__ss.__sp; + case 14: + return context->machineContext.__ss.__lr; + case 15: + return context->machineContext.__ss.__pc; + case 16: + return context->machineContext.__ss.__cpsr; + } + + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return 0; +} + +int +sentrycrashcpu_numExceptionRegisters(void) +{ + return g_exceptionRegisterNamesCount; +} + +const char * +sentrycrashcpu_exceptionRegisterName(const int regNumber) +{ + if (regNumber < sentrycrashcpu_numExceptionRegisters()) { + return g_exceptionRegisterNames[regNumber]; + } + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return NULL; +} + +uint64_t +sentrycrashcpu_exceptionRegisterValue( + const SentryCrashMachineContext *const context, const int regNumber) +{ + switch (regNumber) { + case 0: + return context->machineContext.__es.__exception; + case 1: + return context->machineContext.__es.__fsr; + case 2: + return context->machineContext.__es.__far; + } + + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return 0; +} + +uintptr_t +sentrycrashcpu_faultAddress(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__es.__far; +} + +int +sentrycrashcpu_stackGrowDirection(void) +{ + return -1; +} + +uintptr_t +sentrycrashcpu_normaliseInstructionPointer(uintptr_t ip) +{ + return ip; +} + +#endif diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_arm64.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_arm64.c new file mode 100644 index 00000000..877b474d --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_arm64.c @@ -0,0 +1,195 @@ +// +// SentryCrashCPU_arm64_Apple.c +// +// Created by Karl Stenerud on 2013-09-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#if defined(__arm64__) + +# include "SentryCrashCPU.h" +# include "SentryCrashCPU_Apple.h" +# include "SentryCrashMachineContext.h" +# include "SentryCrashMachineContext_Apple.h" +# include + +//#define SentryCrashLogger_LocalLevel TRACE +# include "SentryCrashLogger.h" + +# define KSPACStrippingMask_ARM64e 0x0000000fffffffff + +static const char *g_registerNames[] = { "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", + "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", + "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", "pc", "cpsr" }; +static const int g_registerNamesCount = sizeof(g_registerNames) / sizeof(*g_registerNames); + +static const char *g_exceptionRegisterNames[] = { "exception", "esr", "far" }; +static const int g_exceptionRegisterNamesCount + = sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); + +uintptr_t +sentrycrashcpu_framePointer(const SentryCrashMachineContext *const context) +{ + // We don't want this from stopping us to enable warnings as errors. This needs to be fixed. +# pragma clang diagnostic push +# pragma GCC diagnostic ignored "-Wshorten-64-to-32" + return context->machineContext.__ss.__fp; +# pragma clang diagnostic pop +} + +uintptr_t +sentrycrashcpu_stackPointer(const SentryCrashMachineContext *const context) +{ + // We don't want this from stopping us to enable warnings as errors. This needs to be fixed. +# pragma clang diagnostic push +# pragma GCC diagnostic ignored "-Wshorten-64-to-32" + return context->machineContext.__ss.__sp; +# pragma clang diagnostic pop +} + +uintptr_t +sentrycrashcpu_instructionAddress(const SentryCrashMachineContext *const context) +{ + // We don't want this from stopping us to enable warnings as errors. This needs to be fixed. +# pragma clang diagnostic push +# pragma GCC diagnostic ignored "-Wshorten-64-to-32" + return context->machineContext.__ss.__pc; +# pragma clang diagnostic pop +} + +uintptr_t +sentrycrashcpu_linkRegister(const SentryCrashMachineContext *const context) +{ + // We don't want this from stopping us to enable warnings as errors. This needs to be fixed. +# pragma clang diagnostic push +# pragma GCC diagnostic ignored "-Wshorten-64-to-32" + return context->machineContext.__ss.__lr; +# pragma clang diagnostic pop +} + +void +sentrycrashcpu_getState(SentryCrashMachineContext *context) +{ + thread_t thread = context->thisThread; + STRUCT_MCONTEXT_L *const machineContext = &context->machineContext; + + sentrycrashcpu_i_fillState(thread, (thread_state_t)&machineContext->__ss, ARM_THREAD_STATE64, + ARM_THREAD_STATE64_COUNT); + sentrycrashcpu_i_fillState(thread, (thread_state_t)&machineContext->__es, ARM_EXCEPTION_STATE64, + ARM_EXCEPTION_STATE64_COUNT); +} + +int +sentrycrashcpu_numRegisters(void) +{ + return g_registerNamesCount; +} + +const char * +sentrycrashcpu_registerName(const int regNumber) +{ + if (regNumber < sentrycrashcpu_numRegisters()) { + return g_registerNames[regNumber]; + } + return NULL; +} + +uint64_t +sentrycrashcpu_registerValue(const SentryCrashMachineContext *const context, const int regNumber) +{ + if (regNumber < 29) { + return context->machineContext.__ss.__x[regNumber]; + } + + switch (regNumber) { + case 29: + return context->machineContext.__ss.__fp; + case 30: + return context->machineContext.__ss.__lr; + case 31: + return context->machineContext.__ss.__sp; + case 32: + return context->machineContext.__ss.__pc; + case 33: + return context->machineContext.__ss.__cpsr; + } + + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return 0; +} + +int +sentrycrashcpu_numExceptionRegisters(void) +{ + return g_exceptionRegisterNamesCount; +} + +const char * +sentrycrashcpu_exceptionRegisterName(const int regNumber) +{ + if (regNumber < sentrycrashcpu_numExceptionRegisters()) { + return g_exceptionRegisterNames[regNumber]; + } + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return NULL; +} + +uint64_t +sentrycrashcpu_exceptionRegisterValue( + const SentryCrashMachineContext *const context, const int regNumber) +{ + switch (regNumber) { + case 0: + return context->machineContext.__es.__exception; + case 1: + return context->machineContext.__es.__esr; + case 2: + return context->machineContext.__es.__far; + } + + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return 0; +} + +uintptr_t +sentrycrashcpu_faultAddress(const SentryCrashMachineContext *const context) +{ + // We don't want this from stopping us to enable warnings as errors. This needs to be fixed. +# pragma clang diagnostic push +# pragma GCC diagnostic ignored "-Wshorten-64-to-32" + return context->machineContext.__es.__far; +# pragma clang diagnostic pop +} + +int +sentrycrashcpu_stackGrowDirection(void) +{ + return -1; +} + +uintptr_t +sentrycrashcpu_normaliseInstructionPointer(uintptr_t ip) +{ + return ip & KSPACStrippingMask_ARM64e; +} + +#endif diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_x86_32.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_x86_32.c new file mode 100644 index 00000000..3addbb41 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_x86_32.c @@ -0,0 +1,206 @@ +// +// SentryCrashCPU_x86_32.c +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#if defined(__i386__) + +# include "SentryCrashCPU.h" +# include "SentryCrashCPU_Apple.h" +# include "SentryCrashMachineContext.h" +# include "SentryCrashMachineContext_Apple.h" +# include + +//#define SentryCrashLogger_LocalLevel TRACE +# include "SentryCrashLogger.h" + +static const char *g_registerNames[] = { + "eax", + "ebx", + "ecx", + "edx", + "edi", + "esi", + "ebp", + "esp", + "ss", + "eflags", + "eip", + "cs", + "ds", + "es", + "fs", + "gs", +}; +static const int g_registerNamesCount = sizeof(g_registerNames) / sizeof(*g_registerNames); + +static const char *g_exceptionRegisterNames[] = { "trapno", "err", "faultvaddr" }; +static const int g_exceptionRegisterNamesCount + = sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); + +uintptr_t +sentrycrashcpu_framePointer(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__ebp; +} + +uintptr_t +sentrycrashcpu_stackPointer(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__esp; +} + +uintptr_t +sentrycrashcpu_instructionAddress(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__eip; +} + +uintptr_t +sentrycrashcpu_linkRegister(__unused const SentryCrashMachineContext *const context) +{ + return 0; +} + +void +sentrycrashcpu_getState(SentryCrashMachineContext *context) +{ + thread_t thread = context->thisThread; + STRUCT_MCONTEXT_L *const machineContext = &context->machineContext; + + sentrycrashcpu_i_fillState(thread, (thread_state_t)&machineContext->__ss, x86_THREAD_STATE32, + x86_THREAD_STATE32_COUNT); + sentrycrashcpu_i_fillState(thread, (thread_state_t)&machineContext->__es, x86_EXCEPTION_STATE32, + x86_EXCEPTION_STATE32_COUNT); +} + +int +sentrycrashcpu_numRegisters(void) +{ + return g_registerNamesCount; +} + +const char * +sentrycrashcpu_registerName(const int regNumber) +{ + if (regNumber < sentrycrashcpu_numRegisters()) { + return g_registerNames[regNumber]; + } + return NULL; +} + +uint64_t +sentrycrashcpu_registerValue(const SentryCrashMachineContext *const context, const int regNumber) +{ + switch (regNumber) { + case 0: + return context->machineContext.__ss.__eax; + case 1: + return context->machineContext.__ss.__ebx; + case 2: + return context->machineContext.__ss.__ecx; + case 3: + return context->machineContext.__ss.__edx; + case 4: + return context->machineContext.__ss.__edi; + case 5: + return context->machineContext.__ss.__esi; + case 6: + return context->machineContext.__ss.__ebp; + case 7: + return context->machineContext.__ss.__esp; + case 8: + return context->machineContext.__ss.__ss; + case 9: + return context->machineContext.__ss.__eflags; + case 10: + return context->machineContext.__ss.__eip; + case 11: + return context->machineContext.__ss.__cs; + case 12: + return context->machineContext.__ss.__ds; + case 13: + return context->machineContext.__ss.__es; + case 14: + return context->machineContext.__ss.__fs; + case 15: + return context->machineContext.__ss.__gs; + } + + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return 0; +} + +int +sentrycrashcpu_numExceptionRegisters(void) +{ + return g_exceptionRegisterNamesCount; +} + +const char * +sentrycrashcpu_exceptionRegisterName(const int regNumber) +{ + if (regNumber < sentrycrashcpu_numExceptionRegisters()) { + return g_exceptionRegisterNames[regNumber]; + } + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return NULL; +} + +uint64_t +sentrycrashcpu_exceptionRegisterValue( + const SentryCrashMachineContext *const context, const int regNumber) +{ + switch (regNumber) { + case 0: + return context->machineContext.__es.__trapno; + case 1: + return context->machineContext.__es.__err; + case 2: + return context->machineContext.__es.__faultvaddr; + } + + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return 0; +} + +uintptr_t +sentrycrashcpu_faultAddress(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__es.__faultvaddr; +} + +int +sentrycrashcpu_stackGrowDirection(void) +{ + return -1; +} + +uintptr_t +sentrycrashcpu_normaliseInstructionPointer(uintptr_t ip) +{ + return ip; +} + +#endif diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_x86_64.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_x86_64.c new file mode 100644 index 00000000..d4bc29b5 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashCPU_x86_64.c @@ -0,0 +1,201 @@ +// +// SentryCrashCPU_x86_64.c +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#if defined(__x86_64__) + +# include "SentryCrashCPU.h" +# include "SentryCrashCPU_Apple.h" +# include "SentryCrashMachineContext.h" +# include "SentryCrashMachineContext_Apple.h" + +# include + +//#define SentryCrashLogger_LocalLevel TRACE +# include "SentryCrashLogger.h" + +static const char *g_registerNames[] = { "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rip", "rflags", "cs", "fs", "gs" }; +static const int g_registerNamesCount = sizeof(g_registerNames) / sizeof(*g_registerNames); + +static const char *g_exceptionRegisterNames[] = { "trapno", "err", "faultvaddr" }; +static const int g_exceptionRegisterNamesCount + = sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); + +uintptr_t +sentrycrashcpu_framePointer(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__rbp; +} + +uintptr_t +sentrycrashcpu_stackPointer(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__rsp; +} + +uintptr_t +sentrycrashcpu_instructionAddress(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__ss.__rip; +} + +uintptr_t +sentrycrashcpu_linkRegister(__unused const SentryCrashMachineContext *const context) +{ + return 0; +} + +void +sentrycrashcpu_getState(SentryCrashMachineContext *context) +{ + thread_t thread = context->thisThread; + STRUCT_MCONTEXT_L *const machineContext = &context->machineContext; + + sentrycrashcpu_i_fillState(thread, (thread_state_t)&machineContext->__ss, x86_THREAD_STATE64, + x86_THREAD_STATE64_COUNT); + sentrycrashcpu_i_fillState(thread, (thread_state_t)&machineContext->__es, x86_EXCEPTION_STATE64, + x86_EXCEPTION_STATE64_COUNT); +} + +int +sentrycrashcpu_numRegisters(void) +{ + return g_registerNamesCount; +} + +const char * +sentrycrashcpu_registerName(const int regNumber) +{ + if (regNumber < sentrycrashcpu_numRegisters()) { + return g_registerNames[regNumber]; + } + return NULL; +} + +uint64_t +sentrycrashcpu_registerValue(const SentryCrashMachineContext *const context, const int regNumber) +{ + switch (regNumber) { + case 0: + return context->machineContext.__ss.__rax; + case 1: + return context->machineContext.__ss.__rbx; + case 2: + return context->machineContext.__ss.__rcx; + case 3: + return context->machineContext.__ss.__rdx; + case 4: + return context->machineContext.__ss.__rdi; + case 5: + return context->machineContext.__ss.__rsi; + case 6: + return context->machineContext.__ss.__rbp; + case 7: + return context->machineContext.__ss.__rsp; + case 8: + return context->machineContext.__ss.__r8; + case 9: + return context->machineContext.__ss.__r9; + case 10: + return context->machineContext.__ss.__r10; + case 11: + return context->machineContext.__ss.__r11; + case 12: + return context->machineContext.__ss.__r12; + case 13: + return context->machineContext.__ss.__r13; + case 14: + return context->machineContext.__ss.__r14; + case 15: + return context->machineContext.__ss.__r15; + case 16: + return context->machineContext.__ss.__rip; + case 17: + return context->machineContext.__ss.__rflags; + case 18: + return context->machineContext.__ss.__cs; + case 19: + return context->machineContext.__ss.__fs; + case 20: + return context->machineContext.__ss.__gs; + } + + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return 0; +} + +int +sentrycrashcpu_numExceptionRegisters(void) +{ + return g_exceptionRegisterNamesCount; +} + +const char * +sentrycrashcpu_exceptionRegisterName(const int regNumber) +{ + if (regNumber < sentrycrashcpu_numExceptionRegisters()) { + return g_exceptionRegisterNames[regNumber]; + } + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return NULL; +} + +uint64_t +sentrycrashcpu_exceptionRegisterValue( + const SentryCrashMachineContext *const context, const int regNumber) +{ + switch (regNumber) { + case 0: + return context->machineContext.__es.__trapno; + case 1: + return context->machineContext.__es.__err; + case 2: + return context->machineContext.__es.__faultvaddr; + } + + SentryCrashLOG_ERROR("Invalid register number: %d", regNumber); + return 0; +} + +uintptr_t +sentrycrashcpu_faultAddress(const SentryCrashMachineContext *const context) +{ + return context->machineContext.__es.__faultvaddr; +} + +int +sentrycrashcpu_stackGrowDirection(void) +{ + return -1; +} + +uintptr_t +sentrycrashcpu_normaliseInstructionPointer(uintptr_t ip) +{ + return ip; +} + +#endif diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDate.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDate.c new file mode 100644 index 00000000..c00a10b0 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDate.c @@ -0,0 +1,36 @@ +// +// SentryCrashDate.c +// +// Copyright 2016 Karl Stenerud. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashDate.h" +#include +#include + +void +sentrycrashdate_utcStringFromTimestamp(time_t timestamp, char *buffer21Chars) +{ + struct tm result = { 0 }; + gmtime_r(×tamp, &result); + snprintf(buffer21Chars, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ", result.tm_year + 1900, + result.tm_mon + 1, result.tm_mday, result.tm_hour, result.tm_min, result.tm_sec); +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDate.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDate.h new file mode 100644 index 00000000..281035bb --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDate.h @@ -0,0 +1,47 @@ +// +// SentryCrashDate.h +// +// Copyright 2016 Karl Stenerud. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef SentryCrashDate_h +#define SentryCrashDate_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** Convert a UNIX timestamp to an RFC3339 string representation. + * + * @param timestamp The date to convert. + * + * @param buffer21Chars A buffer of at least 21 chars to hold the RFC3339 date + * string. + */ +void sentrycrashdate_utcStringFromTimestamp(time_t timestamp, char *buffer21Chars); + +#ifdef __cplusplus +} +#endif + +#endif /* SentryCrashDate_h */ diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDebug.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDebug.c new file mode 100644 index 00000000..e060264d --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDebug.c @@ -0,0 +1,54 @@ +// +// SentryCrashDebug.c +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashDebug.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include + +/** Check if the current process is being traced or not. + * + * @return true if we're being traced. + */ +bool +sentrycrashdebug_isBeingTraced(void) +{ + struct kinfo_proc procInfo; + size_t structSize = sizeof(procInfo); + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; + + if (sysctl(mib, sizeof(mib) / sizeof(*mib), &procInfo, &structSize, NULL, 0) != 0) { + SentryCrashLOG_ERROR("sysctl: %s", strerror(errno)); + return false; + } + + return (procInfo.kp_proc.p_flag & P_TRACED) != 0; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDebug.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDebug.h new file mode 100644 index 00000000..c4aeaa26 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDebug.h @@ -0,0 +1,49 @@ +// +// SentryCrashDebug.h +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Utility functions for querying the mach kernel. + */ + +#ifndef HDR_SentryCrashDebug_h +#define HDR_SentryCrashDebug_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** Check if the current process is being traced or not. + * + * @return true if we're being traced. + */ +bool sentrycrashdebug_isBeingTraced(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashDebug_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.c new file mode 100644 index 00000000..69e1c76e --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.c @@ -0,0 +1,333 @@ +// +// SentryCrashDynamicLinker.c +// +// Created by Karl Stenerud on 2013-10-02. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashDynamicLinker.h" + +#include +#include +#include +#include + +#include "SentryCrashLogger.h" + +#ifdef __LP64__ +# define STRUCT_NLIST struct nlist_64 +#else +# define STRUCT_NLIST struct nlist +#endif + +/** Get the address of the first command following a header (which will be of + * type struct load_command). + * + * @param header The header to get commands for. + * + * @return The address of the first command, or NULL if none was found (which + * should not happen unless the header or image is corrupt). + */ +static uintptr_t +firstCmdAfterHeader(const struct mach_header *const header) +{ + switch (header->magic) { + case MH_MAGIC: + case MH_CIGAM: + return (uintptr_t)(header + 1); + case MH_MAGIC_64: + case MH_CIGAM_64: + return (uintptr_t)(((struct mach_header_64 *)header) + 1); + default: + // Header is corrupt + return 0; + } +} + +/** Get the image index that the specified address is part of. + * + * @param address The address to examine. + * @return The index of the image it is part of, or UINT_MAX if none was found. + */ +static uint32_t +imageIndexContainingAddress(const uintptr_t address) +{ + const uint32_t imageCount = _dyld_image_count(); + const struct mach_header *header = 0; + + for (uint32_t iImg = 0; iImg < imageCount; iImg++) { + header = _dyld_get_image_header(iImg); + if (header != NULL) { + // Look for a segment command with this address within its range. + uintptr_t addressWSlide = address - (uintptr_t)_dyld_get_image_vmaddr_slide(iImg); + uintptr_t cmdPtr = firstCmdAfterHeader(header); + if (cmdPtr == 0) { + continue; + } + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SEGMENT) { + const struct segment_command *segCmd = (struct segment_command *)cmdPtr; + if (addressWSlide >= segCmd->vmaddr + && addressWSlide < segCmd->vmaddr + segCmd->vmsize) { + return iImg; + } + } else if (loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segCmd = (struct segment_command_64 *)cmdPtr; + if (addressWSlide >= segCmd->vmaddr + && addressWSlide < segCmd->vmaddr + segCmd->vmsize) { + return iImg; + } + } + cmdPtr += loadCmd->cmdsize; + } + } + } + return UINT_MAX; +} + +/** Get the segment base address of the specified image. + * + * This is required for any symtab command offsets. + * + * @param idx The image index. + * @return The image's base address, or 0 if none was found. + */ +static uintptr_t +segmentBaseOfImageIndex(const uint32_t idx) +{ + const struct mach_header *header = _dyld_get_image_header(idx); + + // Look for a segment command and return the file image address. + uintptr_t cmdPtr = firstCmdAfterHeader(header); + if (cmdPtr == 0) { + return 0; + } + for (uint32_t i = 0; i < header->ncmds; i++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SEGMENT) { + const struct segment_command *segmentCmd = (struct segment_command *)cmdPtr; + if (strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) { + return segmentCmd->vmaddr - segmentCmd->fileoff; + } + } else if (loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segmentCmd = (struct segment_command_64 *)cmdPtr; + if (strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) { + return (uintptr_t)(segmentCmd->vmaddr - segmentCmd->fileoff); + } + } + cmdPtr += loadCmd->cmdsize; + } + + return 0; +} + +uint32_t +sentrycrashdl_imageNamed(const char *const imageName, bool exactMatch) +{ + if (imageName != NULL) { + const uint32_t imageCount = _dyld_image_count(); + + for (uint32_t iImg = 0; iImg < imageCount; iImg++) { + const char *name = _dyld_get_image_name(iImg); + if (exactMatch) { + if (strcmp(name, imageName) == 0) { + return iImg; + } + } else { + if (strstr(name, imageName) != NULL) { + return iImg; + } + } + } + } + return UINT32_MAX; +} + +const uint8_t * +sentrycrashdl_imageUUID(const char *const imageName, bool exactMatch) +{ + if (imageName != NULL) { + const uint32_t iImg = sentrycrashdl_imageNamed(imageName, exactMatch); + if (iImg != UINT32_MAX) { + const struct mach_header *header = _dyld_get_image_header(iImg); + if (header != NULL) { + uintptr_t cmdPtr = firstCmdAfterHeader(header); + if (cmdPtr != 0) { + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_UUID) { + struct uuid_command *uuidCmd = (struct uuid_command *)cmdPtr; + return uuidCmd->uuid; + } + cmdPtr += loadCmd->cmdsize; + } + } + } + } + } + return NULL; +} + +bool +sentrycrashdl_dladdr(const uintptr_t address, Dl_info *const info) +{ + info->dli_fname = NULL; + info->dli_fbase = NULL; + info->dli_sname = NULL; + info->dli_saddr = NULL; + + const uint32_t idx = imageIndexContainingAddress(address); + if (idx == UINT_MAX) { + return false; + } + const struct mach_header *header = _dyld_get_image_header(idx); + const uintptr_t imageVMAddrSlide = (uintptr_t)_dyld_get_image_vmaddr_slide(idx); + const uintptr_t addressWithSlide = address - imageVMAddrSlide; + const uintptr_t segmentBase = segmentBaseOfImageIndex(idx) + imageVMAddrSlide; + if (segmentBase == 0) { + return false; + } + + info->dli_fname = _dyld_get_image_name(idx); + info->dli_fbase = (void *)header; + + // Find symbol tables and get whichever symbol is closest to the address. + const STRUCT_NLIST *bestMatch = NULL; + uintptr_t bestDistance = ULONG_MAX; + uintptr_t cmdPtr = firstCmdAfterHeader(header); + if (cmdPtr == 0) { + return false; + } + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SYMTAB) { + const struct symtab_command *symtabCmd = (struct symtab_command *)cmdPtr; + const STRUCT_NLIST *symbolTable = (STRUCT_NLIST *)(segmentBase + symtabCmd->symoff); + const uintptr_t stringTable = segmentBase + symtabCmd->stroff; + + for (uint32_t iSym = 0; iSym < symtabCmd->nsyms; iSym++) { + // If n_value is 0, the symbol refers to an external object. + if (symbolTable[iSym].n_value != 0) { + uintptr_t symbolBase = symbolTable[iSym].n_value; + uintptr_t currentDistance = addressWithSlide - symbolBase; + if ((addressWithSlide >= symbolBase) && (currentDistance <= bestDistance)) { + bestMatch = symbolTable + iSym; + bestDistance = currentDistance; + } + } + } + if (bestMatch != NULL) { + info->dli_saddr = (void *)(bestMatch->n_value + imageVMAddrSlide); + if (bestMatch->n_desc == 16) { + // This image has been stripped. The name is meaningless, + // and almost certainly resolves to "_mh_execute_header" + info->dli_sname = NULL; + } else { + info->dli_sname + = (char *)((intptr_t)stringTable + (intptr_t)bestMatch->n_un.n_strx); + if (*info->dli_sname == '_') { + info->dli_sname++; + } + } + break; + } + } + cmdPtr += loadCmd->cmdsize; + } + + return true; +} + +int +sentrycrashdl_imageCount() +{ + return (int)_dyld_image_count(); +} + +bool +sentrycrashdl_getBinaryImage(int index, SentryCrashBinaryImage *buffer) +{ + const struct mach_header *header = _dyld_get_image_header((unsigned)index); + if (header == NULL) { + return false; + } + + uintptr_t cmdPtr = firstCmdAfterHeader(header); + if (cmdPtr == 0) { + return false; + } + + // Look for the TEXT segment to get the image size. + // Also look for a UUID command. + uint64_t imageSize = 0; + uint64_t imageVmAddr = 0; + uint64_t version = 0; + uint8_t *uuid = NULL; + + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + struct load_command *loadCmd = (struct load_command *)cmdPtr; + switch (loadCmd->cmd) { + case LC_SEGMENT: { + struct segment_command *segCmd = (struct segment_command *)cmdPtr; + if (strcmp(segCmd->segname, SEG_TEXT) == 0) { + imageSize = segCmd->vmsize; + imageVmAddr = segCmd->vmaddr; + } + break; + } + case LC_SEGMENT_64: { + struct segment_command_64 *segCmd = (struct segment_command_64 *)cmdPtr; + if (strcmp(segCmd->segname, SEG_TEXT) == 0) { + imageSize = segCmd->vmsize; + imageVmAddr = segCmd->vmaddr; + } + break; + } + case LC_UUID: { + struct uuid_command *uuidCmd = (struct uuid_command *)cmdPtr; + uuid = uuidCmd->uuid; + break; + } + case LC_ID_DYLIB: { + + struct dylib_command *dc = (struct dylib_command *)cmdPtr; + version = dc->dylib.current_version; + break; + } + } + cmdPtr += loadCmd->cmdsize; + } + + buffer->address = (uintptr_t)header; + buffer->vmAddress = imageVmAddr; + buffer->size = imageSize; + buffer->name = _dyld_get_image_name((unsigned)index); + buffer->uuid = uuid; + buffer->cpuType = header->cputype; + buffer->cpuSubType = header->cpusubtype; + buffer->majorVersion = version >> 16; + buffer->minorVersion = (version >> 8) & 0xff; + buffer->revisionVersion = version & 0xff; + + return true; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.h new file mode 100644 index 00000000..893e7b61 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashDynamicLinker.h @@ -0,0 +1,106 @@ +// +// SentryCrashDynamicLinker.h +// +// Created by Karl Stenerud on 2013-10-02. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashDynamicLinker_h +#define HDR_SentryCrashDynamicLinker_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +typedef struct { + uint64_t address; + uint64_t vmAddress; + uint64_t size; + const char *name; + const uint8_t *uuid; + int cpuType; + int cpuSubType; + uint64_t majorVersion; + uint64_t minorVersion; + uint64_t revisionVersion; +} SentryCrashBinaryImage; + +/** Get the number of loaded binary images. + */ +int sentrycrashdl_imageCount(void); + +/** Get information about a binary image. + * + * @param index The binary index. + * + * @param buffer A structure to hold the information. + * + * @return True if the image was successfully queried. + */ +bool sentrycrashdl_getBinaryImage(int index, SentryCrashBinaryImage *buffer); + +/** Find a loaded binary image with the specified name. + * + * @param imageName The image name to look for. + * + * @param exactMatch If true, look for an exact match instead of a partial one. + * + * @return the index of the matched image, or UINT32_MAX if not found. + */ +uint32_t sentrycrashdl_imageNamed(const char *const imageName, bool exactMatch); + +/** Get the UUID of a loaded binary image with the specified name. + * + * @param imageName The image name to look for. + * + * @param exactMatch If true, look for an exact match instead of a partial one. + * + * @return A pointer to the binary (16 byte) UUID of the image, or NULL if it + * wasn't found. + */ +const uint8_t *sentrycrashdl_imageUUID(const char *const imageName, bool exactMatch); + +/** async-safe version of dladdr. + * + * This method searches the dynamic loader for information about any image + * containing the specified address. It may not be entirely successful in + * finding information, in which case any fields it could not find will be set + * to NULL. + * + * Unlike dladdr(), this method does not make use of locks, and does not call + * async-unsafe functions. + * + * @param address The address to search for. + * @param info Gets filled out by this function. + * @return true if at least some information was found. + */ +bool sentrycrashdl_dladdr(const uintptr_t address, Dl_info *const info); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashDynamicLinker_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.c new file mode 100644 index 00000000..fa020bfc --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.c @@ -0,0 +1,582 @@ +// +// SentryCrashFileUtils.c +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashFileUtils.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/** Buffer size to use in the "writeFmt" functions. + * If the formatted output length would exceed this value, it is truncated. + */ +#ifndef SentryCrashFU_WriteFmtBufferSize +# define SentryCrashFU_WriteFmtBufferSize 1024 +#endif + +// ============================================================================ +#pragma mark - Utility - +// ============================================================================ + +static bool +canDeletePath(const char *path) +{ + const char *lastComponent = strrchr(path, '/'); + if (lastComponent == NULL) { + lastComponent = path; + } else { + lastComponent++; + } + if (strcmp(lastComponent, ".") == 0) { + return false; + } + if (strcmp(lastComponent, "..") == 0) { + return false; + } + return true; +} + +static int +dirContentsCount(const char *path) +{ + int count = 0; + DIR *dir = opendir(path); + if (dir == NULL) { + SentryCrashLOG_ERROR("Error reading directory %s: %s", strerror(errno)); + return 0; + } + + struct dirent *ent; + while ((ent = readdir(dir))) { + count++; + } + + closedir(dir); + return count; +} + +static void +dirContents(const char *path, char ***entries, int *count) +{ + DIR *dir = NULL; + char **entryList = NULL; + int entryCount = dirContentsCount(path); + if (entryCount <= 0) { + goto done; + } + dir = opendir(path); + if (dir == NULL) { + SentryCrashLOG_ERROR("Error reading directory %s: %s", strerror(errno)); + goto done; + } + + entryList = calloc((unsigned)entryCount, sizeof(char *)); + if (entryList != NULL) { + struct dirent *ent; + int index = 0; + while ((ent = readdir(dir))) { + if (index >= entryCount) { + SentryCrashLOG_ERROR("Contents of %s have been mutated", path); + goto done; + } + entryList[index] = strdup(ent->d_name); + index++; + } + } + +done: + if (dir != NULL) { + closedir(dir); + } + if (entryList == NULL) { + entryCount = 0; + } + *entries = entryList; + *count = entryCount; +} + +static void +freeDirListing(char **entries, int count) +{ + if (entries != NULL) { + for (int i = 0; i < count; i++) { + char *ptr = entries[i]; + if (ptr != NULL) { + free(ptr); + } + } + free(entries); + } +} + +static bool +deletePathContents(const char *path, bool deleteTopLevelPathAlso) +{ + struct stat statStruct = { 0 }; + if (stat(path, &statStruct) != 0) { + SentryCrashLOG_ERROR("Could not stat %s: %s", strerror(errno)); + return false; + } + if (S_ISDIR(statStruct.st_mode)) { + char **entries = NULL; + int entryCount = 0; + dirContents(path, &entries, &entryCount); + + int bufferLength = SentryCrashFU_MAX_PATH_LENGTH; + char *pathBuffer = malloc((unsigned)bufferLength); + snprintf(pathBuffer, bufferLength, "%s/", path); + char *pathPtr = pathBuffer + strlen(pathBuffer); + int pathRemainingLength = bufferLength - (int)(pathPtr - pathBuffer); + + for (int i = 0; i < entryCount; i++) { + char *entry = entries[i]; + if (entry != NULL && canDeletePath(entry)) { + strncpy(pathPtr, entry, pathRemainingLength); + deletePathContents(pathBuffer, true); + } + } + + free(pathBuffer); + freeDirListing(entries, entryCount); + if (deleteTopLevelPathAlso) { + sentrycrashfu_removeFile(path, false); + } + } else if (S_ISREG(statStruct.st_mode)) { + sentrycrashfu_removeFile(path, false); + } else { + SentryCrashLOG_ERROR("Could not delete %s: Not a regular file.", path); + return false; + } + return true; +} + +// ============================================================================ +#pragma mark - API - +// ============================================================================ + +const char * +sentrycrashfu_lastPathEntry(const char *const path) +{ + if (path == NULL) { + return NULL; + } + + char *lastFile = strrchr(path, '/'); + return lastFile == NULL ? path : lastFile + 1; +} + +bool +sentrycrashfu_writeBytesToFD(const int fd, const char *const bytes, int length) +{ + const char *pos = bytes; + while (length > 0) { + int bytesWritten = (int)write(fd, pos, (unsigned)length); + if (bytesWritten == -1) { + SentryCrashLOG_ERROR("Could not write to fd %d: %s", fd, strerror(errno)); + return false; + } + length -= bytesWritten; + pos += bytesWritten; + } + return true; +} + +bool +sentrycrashfu_readBytesFromFD(const int fd, char *const bytes, int length) +{ + char *pos = bytes; + while (length > 0) { + int bytesRead = (int)read(fd, pos, (unsigned)length); + if (bytesRead == -1) { + SentryCrashLOG_ERROR("Could not write to fd %d: %s", fd, strerror(errno)); + return false; + } + length -= bytesRead; + pos += bytesRead; + } + return true; +} + +bool +sentrycrashfu_readEntireFile(const char *const path, char **data, int *length, int maxLength) +{ + bool isSuccessful = false; + int bytesRead = 0; + char *mem = NULL; + int fd = -1; + int bytesToRead = maxLength; + + struct stat st; + if (stat(path, &st) < 0) { + SentryCrashLOG_ERROR("Could not stat %s: %s", path, strerror(errno)); + goto done; + } + + fd = open(path, O_RDONLY); + if (fd < 0) { + SentryCrashLOG_ERROR("Could not open %s: %s", path, strerror(errno)); + goto done; + } + + if (bytesToRead == 0 || bytesToRead >= (int)st.st_size) { + bytesToRead = (int)st.st_size; + } else if (bytesToRead > 0) { + if (lseek(fd, -bytesToRead, SEEK_END) < 0) { + SentryCrashLOG_ERROR( + "Could not seek to %d from end of %s: %s", -bytesToRead, path, strerror(errno)); + goto done; + } + } + + mem = malloc((unsigned)bytesToRead + 1); + if (mem == NULL) { + SentryCrashLOG_ERROR("Out of memory"); + goto done; + } + + if (!sentrycrashfu_readBytesFromFD(fd, mem, bytesToRead)) { + goto done; + } + + bytesRead = bytesToRead; + mem[bytesRead] = '\0'; + isSuccessful = true; + +done: + if (fd >= 0) { + close(fd); + } + if (!isSuccessful && mem != NULL) { + free(mem); + mem = NULL; + } + + *data = mem; + if (length != NULL) { + *length = bytesRead; + } + + return isSuccessful; +} + +bool +sentrycrashfu_writeStringToFD(const int fd, const char *const string) +{ + if (*string != 0) { + int bytesToWrite = (int)strlen(string); + const char *pos = string; + while (bytesToWrite > 0) { + int bytesWritten = (int)write(fd, pos, (unsigned)bytesToWrite); + if (bytesWritten == -1) { + SentryCrashLOG_ERROR("Could not write to fd %d: %s", fd, strerror(errno)); + return false; + } + bytesToWrite -= bytesWritten; + pos += bytesWritten; + } + return true; + } + return false; +} + +bool +sentrycrashfu_writeFmtToFD(const int fd, const char *const fmt, ...) +{ + if (*fmt != 0) { + va_list args; + va_start(args, fmt); + bool result = sentrycrashfu_writeFmtArgsToFD(fd, fmt, args); + va_end(args); + return result; + } + return false; +} + +bool +sentrycrashfu_writeFmtArgsToFD(const int fd, const char *const fmt, va_list args) +{ + if (*fmt != 0) { + char buffer[SentryCrashFU_WriteFmtBufferSize]; + vsnprintf(buffer, sizeof(buffer), fmt, args); + return sentrycrashfu_writeStringToFD(fd, buffer); + } + return false; +} + +int +sentrycrashfu_readLineFromFD(const int fd, char *const buffer, const int maxLength) +{ + char *end = buffer + maxLength - 1; + *end = 0; + char *ch; + for (ch = buffer; ch < end; ch++) { + int bytesRead = (int)read(fd, ch, 1); + if (bytesRead < 0) { + SentryCrashLOG_ERROR("Could not read from fd %d: %s", fd, strerror(errno)); + return -1; + } else if (bytesRead == 0 || *ch == '\n') { + break; + } + } + *ch = 0; + return (int)(ch - buffer); +} + +bool +sentrycrashfu_makePath(const char *absolutePath) +{ + bool isSuccessful = false; + char *pathCopy = strdup(absolutePath); + for (char *ptr = pathCopy + 1; *ptr != '\0'; ptr++) { + if (*ptr == '/') { + *ptr = '\0'; + if (mkdir(pathCopy, S_IRWXU) < 0 && errno != EEXIST) { + SentryCrashLOG_ERROR( + "Could not create directory %s: %s", pathCopy, strerror(errno)); + goto done; + } + *ptr = '/'; + } + } + if (mkdir(pathCopy, S_IRWXU) < 0 && errno != EEXIST) { + SentryCrashLOG_ERROR("Could not create directory %s: %s", pathCopy, strerror(errno)); + goto done; + } + isSuccessful = true; + +done: + free(pathCopy); + return isSuccessful; +} + +bool +sentrycrashfu_removeFile(const char *path, bool mustExist) +{ + if (remove(path) < 0) { + if (mustExist || errno != ENOENT) { + SentryCrashLOG_ERROR("Could not delete %s: %s", path, strerror(errno)); + } + return false; + } + return true; +} + +bool +sentrycrashfu_deleteContentsOfPath(const char *path) +{ + if (!canDeletePath(path)) { + return false; + } + + return deletePathContents(path, false); +} + +bool +sentrycrashfu_openBufferedWriter(SentryCrashBufferedWriter *writer, const char *const path, + char *writeBuffer, int writeBufferLength) +{ + writer->buffer = writeBuffer; + writer->bufferLength = writeBufferLength; + writer->position = 0; + writer->fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0644); + if (writer->fd < 0) { + SentryCrashLOG_ERROR("Could not open crash report file %s: %s", path, strerror(errno)); + return false; + } + return true; +} + +void +sentrycrashfu_closeBufferedWriter(SentryCrashBufferedWriter *writer) +{ + if (writer->fd > 0) { + sentrycrashfu_flushBufferedWriter(writer); + close(writer->fd); + writer->fd = -1; + } +} + +bool +sentrycrashfu_writeBufferedWriter( + SentryCrashBufferedWriter *writer, const char *restrict const data, const int length) +{ + if (length > writer->bufferLength - writer->position) { + sentrycrashfu_flushBufferedWriter(writer); + } + if (length > writer->bufferLength) { + return sentrycrashfu_writeBytesToFD(writer->fd, data, length); + } + memcpy(writer->buffer + writer->position, data, length); + writer->position += length; + return true; +} + +bool +sentrycrashfu_flushBufferedWriter(SentryCrashBufferedWriter *writer) +{ + if (writer->fd > 0 && writer->position > 0) { + if (!sentrycrashfu_writeBytesToFD(writer->fd, writer->buffer, writer->position)) { + return false; + } + writer->position = 0; + } + return true; +} + +static inline bool +isReadBufferEmpty(SentryCrashBufferedReader *reader) +{ + return reader->dataEndPos == reader->dataStartPos; +} + +static bool +fillReadBuffer(SentryCrashBufferedReader *reader) +{ + if (reader->dataStartPos > 0) { + memmove(reader->buffer, reader->buffer + reader->dataStartPos, reader->dataStartPos); + reader->dataEndPos -= reader->dataStartPos; + reader->dataStartPos = 0; + reader->buffer[reader->dataEndPos] = '\0'; + } + int bytesToRead = reader->bufferLength - reader->dataEndPos; + if (bytesToRead <= 0) { + return true; + } + int bytesRead = (int)read(reader->fd, reader->buffer + reader->dataEndPos, (size_t)bytesToRead); + if (bytesRead < 0) { + SentryCrashLOG_ERROR("Could not read: %s", strerror(errno)); + return false; + } else { + reader->dataEndPos += bytesRead; + reader->buffer[reader->dataEndPos] = '\0'; + } + return true; +} + +int +sentrycrashfu_readBufferedReader(SentryCrashBufferedReader *reader, char *dstBuffer, int byteCount) +{ + int bytesRemaining = byteCount; + int bytesConsumed = 0; + char *pDst = dstBuffer; + while (bytesRemaining > 0) { + int bytesInReader = reader->dataEndPos - reader->dataStartPos; + if (bytesInReader <= 0) { + if (!fillReadBuffer(reader)) { + break; + } + bytesInReader = reader->dataEndPos - reader->dataStartPos; + if (bytesInReader <= 0) { + break; + } + } + int bytesToCopy = bytesInReader <= bytesRemaining ? bytesInReader : bytesRemaining; + char *pSrc = reader->buffer + reader->dataStartPos; + memcpy(pDst, pSrc, bytesToCopy); + pDst += bytesToCopy; + reader->dataStartPos += bytesToCopy; + bytesConsumed += bytesToCopy; + bytesRemaining -= bytesToCopy; + } + + return bytesConsumed; +} + +bool +sentrycrashfu_readBufferedReaderUntilChar( + SentryCrashBufferedReader *reader, int ch, char *dstBuffer, int *length) +{ + int bytesRemaining = *length; + int bytesConsumed = 0; + char *pDst = dstBuffer; + while (bytesRemaining > 0) { + int bytesInReader = reader->dataEndPos - reader->dataStartPos; + int bytesToCopy = bytesInReader <= bytesRemaining ? bytesInReader : bytesRemaining; + char *pSrc = reader->buffer + reader->dataStartPos; + char *pChar = strchr(pSrc, ch); + bool isFound = pChar != NULL; + if (isFound) { + int bytesToChar = (int)(pChar - pSrc) + 1; + if (bytesToChar < bytesToCopy) { + bytesToCopy = bytesToChar; + } + } + memcpy(pDst, pSrc, bytesToCopy); + pDst += bytesToCopy; + reader->dataStartPos += bytesToCopy; + bytesConsumed += bytesToCopy; + bytesRemaining -= bytesToCopy; + if (isFound) { + *length = bytesConsumed; + return true; + } + if (bytesRemaining > 0) { + fillReadBuffer(reader); + if (isReadBufferEmpty(reader)) { + break; + } + } + } + + *length = bytesConsumed; + return false; +} + +bool +sentrycrashfu_openBufferedReader(SentryCrashBufferedReader *reader, const char *const path, + char *readBuffer, int readBufferLength) +{ + readBuffer[0] = '\0'; + readBuffer[readBufferLength - 1] = '\0'; + reader->buffer = readBuffer; + reader->bufferLength = readBufferLength - 1; + reader->dataStartPos = 0; + reader->dataEndPos = 0; + reader->fd = open(path, O_RDONLY); + if (reader->fd < 0) { + SentryCrashLOG_ERROR("Could not open file %s: %s", path, strerror(errno)); + return false; + } + fillReadBuffer(reader); + return true; +} + +void +sentrycrashfu_closeBufferedReader(SentryCrashBufferedReader *reader) +{ + if (reader->fd > 0) { + close(reader->fd); + reader->fd = -1; + } +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.h new file mode 100644 index 00000000..1218e645 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashFileUtils.h @@ -0,0 +1,276 @@ +// +// SentryCrashFileUtils.h +// +// Created by Karl Stenerud on 2012-01-28. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Basic file reading/writing functions. + */ + +#ifndef HDR_SentryCrashFileUtils_h +#define HDR_SentryCrashFileUtils_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define SentryCrashFU_MAX_PATH_LENGTH 500 + +/** Get the last entry in a file path. Assumes UNIX style separators. + * + * @param path The file path. + * + * @return the last entry in the path. + */ +const char *sentrycrashfu_lastPathEntry(const char *path); + +/** Write bytes to a file descriptor. + * + * @param fd The file descriptor. + * + * @param bytes Buffer containing the bytes. + * + * @param length The number of bytes to write. + * + * @return true if the operation was successful. + */ +bool sentrycrashfu_writeBytesToFD(const int fd, const char *bytes, int length); + +/** Read bytes from a file descriptor. + * + * @param fd The file descriptor. + * + * @param bytes Buffer to store the bytes in. + * + * @param length The number of bytes to read. + * + * @return true if the operation was successful. + */ +bool sentrycrashfu_readBytesFromFD(const int fd, char *bytes, int length); + +/** Read an entire file. Returns a buffer of file size + 1, null terminated. + * + * @param path The path to the file. + * + * @param data Place to store a pointer to the loaded data (must be freed). + * + * @param length Place to store the length of the loaded data (can be NULL). + * + * @param maxLength the maximum amount of bytes to read. It will skip beginning + * bytes if necessary, and always get the latter part of the + * file. 0 = no maximum. + * + * @return true if the operation was successful. + */ +bool sentrycrashfu_readEntireFile(const char *path, char **data, int *length, int maxLength); + +/** Write a string to a file. + * + * @param fd The file descriptor. + * + * @param string The string to write. + * + * @return true if successful. + */ +bool sentrycrashfu_writeStringToFD(const int fd, const char *string); + +/** Write a formatted string to a file. + * + * @param fd The file descriptor. + * + * @param fmt The format specifier, followed by its arguments. + * + * @return true if successful. + */ +bool sentrycrashfu_writeFmtToFD(const int fd, const char *fmt, ...); + +/** Write a formatted string to a file. + * + * @param fd The file descriptor. + * + * @param fmt The format specifier. + * + * @param args The arguments list. + * + * @return true if successful. + */ +bool sentrycrashfu_writeFmtArgsToFD(const int fd, const char *fmt, va_list args); + +/** Read a single line from a file. + * + * @param fd The file descriptor. + * + * @param buffer The buffer to read into. + * + * @param maxLength The maximum length to read. + * + * @return The number of bytes read. + */ +int sentrycrashfu_readLineFromFD(const int fd, char *buffer, int maxLength); + +/** Make all directories in a path. + * + * @param absolutePath The full, absolute path to create. + * + * @return true if successful. + */ +bool sentrycrashfu_makePath(const char *absolutePath); + +/** Remove a file or directory. + * + * @param path Path to the file to remove. + * + * @param mustExist If true, and the path doesn't exist, log an error. + * + * @return true if successful. + */ +bool sentrycrashfu_removeFile(const char *path, bool mustExist); + +/** Delete the contents of a directory. + * + * @param path The path of the directory whose contents to delete. + * + * @return true if successful. + */ +bool sentrycrashfu_deleteContentsOfPath(const char *path); + +/** Buffered writer structure. Everything inside should be considered internal + * use only. */ +typedef struct { + char *buffer; + int bufferLength; + int position; + int fd; +} SentryCrashBufferedWriter; + +/** Open a file for buffered writing. + * + * @param writer The writer to initialize. + * + * @param path The path of the file to open. + * + * @param writeBuffer Memory to use as the write buffer. + * + * @param writeBufferLength Length of the memory to use as the write buffer. + * + * @return True if the file was successfully opened. + */ +bool sentrycrashfu_openBufferedWriter(SentryCrashBufferedWriter *writer, const char *const path, + char *writeBuffer, int writeBufferLength); + +/** Close a buffered writer. + * + * @param writer The writer to close. + */ +void sentrycrashfu_closeBufferedWriter(SentryCrashBufferedWriter *writer); + +/** Write to a buffered writer. + * + * @param writer The writer to write to. + * + * @param data The data to write. + * + * @param length The length of the data to write. + * + * @return True if the data was successfully written. + */ +bool sentrycrashfu_writeBufferedWriter( + SentryCrashBufferedWriter *writer, const char *restrict const data, const int length); + +/** Flush a buffered writer, writing all uncommitted data to disk. + * + * @param writer The writer to flush. + * + * @return True if the buffer was successfully flushed. + */ +bool sentrycrashfu_flushBufferedWriter(SentryCrashBufferedWriter *writer); + +/** Buffered reader structure. Everything inside should be considered internal + * use only. */ +typedef struct { + char *buffer; + int bufferLength; + int dataStartPos; + int dataEndPos; + int fd; +} SentryCrashBufferedReader; + +/** Open a file for buffered reading. + * + * @param reader The reader to initialize. + * + * @param path The path to the file to open. + * + * @param readBuffer The memory to use for buffered reading. + * + * @param readBufferLength The length of the memory to use for buffered reading. + * + * @return True if the file was successfully opened. + */ +bool sentrycrashfu_openBufferedReader(SentryCrashBufferedReader *reader, const char *const path, + char *readBuffer, int readBufferLength); + +/** Close a buffered reader. + * + * @param reader The reader to close. + */ +void sentrycrashfu_closeBufferedReader(SentryCrashBufferedReader *reader); + +/** Read from a buffered reader. + * + * @param reader The reader to read from. + * + * @param dstBuffer The buffer to read into. + * + * @param byteCount The number of bytes to read. + * + * @return The number of bytes actually read. + */ +int sentrycrashfu_readBufferedReader( + SentryCrashBufferedReader *reader, char *dstBuffer, int byteCount); + +/** Read from a buffered reader until the specified character is encountered. + * All bytes up to and including the character will be read. + * + * @param reader The reader to read from. + * + * @param ch The character to look for. + * + * @param dstBuffer The buffer to read into. + * + * @param length in: The maximum number of bytes to read before giving up the + * search. out: The actual number of bytes read. + * + * @return True if the character was found before giving up. + */ +bool sentrycrashfu_readBufferedReaderUntilChar( + SentryCrashBufferedReader *reader, int ch, char *dstBuffer, int *length); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashFileUtils_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashID.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashID.c new file mode 100644 index 00000000..be519cb5 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashID.c @@ -0,0 +1,39 @@ +// +// SentryCrashID.c +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include +#include + +void +sentrycrashid_generate(char *destinationBuffer37Bytes) +{ + uuid_t uuid; + uuid_generate(uuid); + snprintf(destinationBuffer37Bytes, 37, + "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", (unsigned)uuid[0], + (unsigned)uuid[1], (unsigned)uuid[2], (unsigned)uuid[3], (unsigned)uuid[4], + (unsigned)uuid[5], (unsigned)uuid[6], (unsigned)uuid[7], (unsigned)uuid[8], + (unsigned)uuid[9], (unsigned)uuid[10], (unsigned)uuid[11], (unsigned)uuid[12], + (unsigned)uuid[13], (unsigned)uuid[14], (unsigned)uuid[15]); +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashID.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashID.h new file mode 100644 index 00000000..bce2d5cd --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashID.h @@ -0,0 +1,42 @@ +// +// SentryCrashID.h +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashID_h +#define HDR_SentryCrashID_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** Generate a new human readabale, null terminated, globally unique ID string. + * + * @param destinationBuffer37Bytes Buffer of at least 37 bytes to hold the ID. + */ +void sentrycrashid_generate(char *destinationBuffer37Bytes); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashID_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.c new file mode 100644 index 00000000..ab5e488c --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.c @@ -0,0 +1,1510 @@ +// +// SentryCrashJSONCodec.c +// +// Created by Karl Stenerud on 2012-01-07. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashJSONCodec.h" + +#include +#include +#include +#include +#include +#include +#include + +// ============================================================================ +#pragma mark - Configuration - +// ============================================================================ + +/** Set to 1 if you're also compiling SentryCrashLogger and want to use it here + */ +#ifndef SentryCrashJSONCODEC_UseKSLogger +# define SentryCrashJSONCODEC_UseKSLogger 1 +#endif + +#if SentryCrashJSONCODEC_UseKSLogger +# include "SentryCrashLogger.h" +#else +# define SentryCrashLOG_DEBUG(FMT, ...) +#endif + +/** The work buffer size to use when escaping string values. + * There's little reason to change this since nothing ever gets truncated. + */ +#ifndef SentryCrashJSONCODEC_WorkBufferSize +# define SentryCrashJSONCODEC_WorkBufferSize 512 +#endif + +// ============================================================================ +#pragma mark - Helpers - +// ============================================================================ + +// Compiler hints for "if" statements +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) + +/** Used for writing hex string values. */ +static char g_hexNybbles[] + = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +const char * +sentrycrashjson_stringForError(const int error) +{ + switch (error) { + case SentryCrashJSON_ERROR_INVALID_CHARACTER: + return "Invalid character"; + case SentryCrashJSON_ERROR_DATA_TOO_LONG: + return "Data too long"; + case SentryCrashJSON_ERROR_CANNOT_ADD_DATA: + return "Cannot add data"; + case SentryCrashJSON_ERROR_INCOMPLETE: + return "Incomplete data"; + case SentryCrashJSON_ERROR_INVALID_DATA: + return "Invalid data"; + default: + return "(unknown error)"; + } +} + +// ============================================================================ +#pragma mark - Encode - +// ============================================================================ + +/** Add JSON encoded data to an external handler. + * The external handler will decide how to handle the data (store/transmit/etc). + * + * @param context The encoding context. + * + * @param data The encoded data. + * + * @param length The length of the data. + * + * @return SentryCrashJSON_OK if the data was handled successfully. + */ +#define addJSONData(CONTEXT, DATA, LENGTH) (CONTEXT)->addJSONData(DATA, LENGTH, (CONTEXT)->userData) + +/** Escape a string portion for use with JSON and send to data handler. + * + * @param context The JSON context. + * + * @param string The string to escape and write. + * + * @param length The length of the string. + * + * @return SentryCrashJSON_OK if the data was handled successfully. + */ +static int +appendEscapedString( + SentryCrashJSONEncodeContext *const context, const char *restrict const string, int length) +{ + char workBuffer[SentryCrashJSONCODEC_WorkBufferSize]; + const char *const srcEnd = string + length; + + const char *restrict src = string; + char *restrict dst = workBuffer; + + // Simple case (no escape or special characters) + for (; src < srcEnd && *src != '\\' && *src != '\"' && (unsigned char)*src >= ' '; src++) { + *dst++ = *src; + } + + // Deal with complicated case (if any) + for (; src < srcEnd; src++) { + switch (*src) { + case '\\': + case '\"': + *dst++ = '\\'; + *dst++ = *src; + break; + case '\b': + *dst++ = '\\'; + *dst++ = 'b'; + break; + case '\f': + *dst++ = '\\'; + *dst++ = 'f'; + break; + case '\n': + *dst++ = '\\'; + *dst++ = 'n'; + break; + case '\r': + *dst++ = '\\'; + *dst++ = 'r'; + break; + case '\t': + *dst++ = '\\'; + *dst++ = 't'; + break; + default: + unlikely_if((unsigned char)*src < ' ') + { + SentryCrashLOG_DEBUG("Invalid character 0x%02x in string: %s", *src, string); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + *dst++ = *src; + } + } + int encLength = (int)(dst - workBuffer); + dst -= encLength; + return addJSONData(context, dst, encLength); +} + +/** Escape a string for use with JSON and send to data handler. + * + * @param context The JSON context. + * + * @param string The string to escape and write. + * + * @param length The length of the string. + * + * @return SentryCrashJSON_OK if the data was handled successfully. + */ +static int +addEscapedString( + SentryCrashJSONEncodeContext *const context, const char *restrict const string, int length) +{ + int result = SentryCrashJSON_OK; + + // Keep adding portions until the whole string has been processed. + int offset = 0; + while (offset < length) { + int toAdd = length - offset; + unlikely_if(toAdd > SentryCrashJSONCODEC_WorkBufferSize / 2) + { + toAdd = SentryCrashJSONCODEC_WorkBufferSize / 2; + } + result = appendEscapedString(context, string + offset, toAdd); + unlikely_if(result != SentryCrashJSON_OK) { break; } + offset += toAdd; + } + return result; +} + +/** Escape and quote a string for use with JSON and send to data handler. + * + * @param context The JSON context. + * + * @param string The string to escape and write. + * + * @param length The length of the string. + * + * @return SentryCrashJSON_OK if the data was handled successfully. + */ +static int +addQuotedEscapedString( + SentryCrashJSONEncodeContext *const context, const char *restrict const string, int length) +{ + int result; + unlikely_if((result = addJSONData(context, "\"", 1)) != SentryCrashJSON_OK) { return result; } + result = addEscapedString(context, string, length); + + // Always close string, even if we failed to write its content + int closeResult = addJSONData(context, "\"", 1); + + return result || closeResult; +} + +int +sentrycrashjson_beginElement(SentryCrashJSONEncodeContext *const context, const char *const name) +{ + int result = SentryCrashJSON_OK; + + // Decide if a comma is warranted. + unlikely_if(context->containerFirstEntry) { context->containerFirstEntry = false; } + else + { + unlikely_if((result = addJSONData(context, ",", 1)) != SentryCrashJSON_OK) + { + return result; + } + } + + // Pretty printing + unlikely_if(context->prettyPrint && context->containerLevel > 0) + { + unlikely_if((result = addJSONData(context, "\n", 1)) != SentryCrashJSON_OK) + { + return result; + } + for (int i = 0; i < context->containerLevel; i++) { + unlikely_if((result = addJSONData(context, " ", 4)) != SentryCrashJSON_OK) + { + return result; + } + } + } + + // Add a name field if we're in an object. + if (context->isObject[context->containerLevel]) { + unlikely_if(name == NULL) + { + SentryCrashLOG_DEBUG("Name was null inside an object"); + return SentryCrashJSON_ERROR_INVALID_DATA; + } + unlikely_if((result = addQuotedEscapedString(context, name, (int)strlen(name))) + != SentryCrashJSON_OK) + { + return result; + } + unlikely_if(context->prettyPrint) + { + unlikely_if((result = addJSONData(context, ": ", 2)) != SentryCrashJSON_OK) + { + return result; + } + } + else + { + unlikely_if((result = addJSONData(context, ":", 1)) != SentryCrashJSON_OK) + { + return result; + } + } + } + return result; +} + +int +sentrycrashjson_addRawJSONData( + SentryCrashJSONEncodeContext *const context, const char *const data, const int length) +{ + return addJSONData(context, data, length); +} + +int +sentrycrashjson_addBooleanElement( + SentryCrashJSONEncodeContext *const context, const char *const name, const bool value) +{ + int result = sentrycrashjson_beginElement(context, name); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + if (value) { + return addJSONData(context, "true", 4); + } else { + return addJSONData(context, "false", 5); + } +} + +int +sentrycrashjson_addFloatingPointElement( + SentryCrashJSONEncodeContext *const context, const char *const name, double value) +{ + int result = sentrycrashjson_beginElement(context, name); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + char buff[50]; + snprintf(buff, sizeof(buff), "%lg", value); + return addJSONData(context, buff, (int)strlen(buff)); +} + +int +sentrycrashjson_addIntegerElement( + SentryCrashJSONEncodeContext *const context, const char *const name, int64_t value) +{ + int result = sentrycrashjson_beginElement(context, name); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + char buff[30]; + snprintf(buff, sizeof(buff), "%" PRId64, value); + return addJSONData(context, buff, (int)strlen(buff)); +} + +int +sentrycrashjson_addNullElement(SentryCrashJSONEncodeContext *const context, const char *const name) +{ + int result = sentrycrashjson_beginElement(context, name); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + return addJSONData(context, "null", 4); +} + +int +sentrycrashjson_addStringElement(SentryCrashJSONEncodeContext *const context, + const char *const name, const char *const value, int length) +{ + unlikely_if(value == NULL) { return sentrycrashjson_addNullElement(context, name); } + int result = sentrycrashjson_beginElement(context, name); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + if (length == SentryCrashJSON_SIZE_AUTOMATIC) { + length = (int)strlen(value); + } + return addQuotedEscapedString(context, value, length); +} + +int +sentrycrashjson_beginStringElement( + SentryCrashJSONEncodeContext *const context, const char *const name) +{ + int result = sentrycrashjson_beginElement(context, name); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + return addJSONData(context, "\"", 1); +} + +int +sentrycrashjson_appendStringElement( + SentryCrashJSONEncodeContext *const context, const char *const value, int length) +{ + return addEscapedString(context, value, length); +} + +int +sentrycrashjson_endStringElement(SentryCrashJSONEncodeContext *const context) +{ + return addJSONData(context, "\"", 1); +} + +int +sentrycrashjson_addDataElement( + SentryCrashJSONEncodeContext *const context, const char *name, const char *value, int length) +{ + int result = SentryCrashJSON_OK; + result = sentrycrashjson_beginDataElement(context, name); + if (result == SentryCrashJSON_OK) { + result = sentrycrashjson_appendDataElement(context, value, length); + } + if (result == SentryCrashJSON_OK) { + result = sentrycrashjson_endDataElement(context); + } + return result; +} + +int +sentrycrashjson_beginDataElement( + SentryCrashJSONEncodeContext *const context, const char *const name) +{ + return sentrycrashjson_beginStringElement(context, name); +} + +int +sentrycrashjson_appendDataElement( + SentryCrashJSONEncodeContext *const context, const char *const value, int length) +{ + unsigned char *currentByte = (unsigned char *)value; + unsigned char *end = currentByte + length; + char chars[2]; + int result = SentryCrashJSON_OK; + while (currentByte < end) { + chars[0] = g_hexNybbles[(*currentByte >> 4) & 15]; + chars[1] = g_hexNybbles[*currentByte & 15]; + result = addJSONData(context, chars, sizeof(chars)); + if (result != SentryCrashJSON_OK) { + break; + } + currentByte++; + } + return result; +} + +int +sentrycrashjson_endDataElement(SentryCrashJSONEncodeContext *const context) +{ + return sentrycrashjson_endStringElement(context); +} + +int +sentrycrashjson_beginArray(SentryCrashJSONEncodeContext *const context, const char *const name) +{ + likely_if(context->containerLevel >= 0) + { + int result = sentrycrashjson_beginElement(context, name); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + } + + context->containerLevel++; + context->isObject[context->containerLevel] = false; + context->containerFirstEntry = true; + + return addJSONData(context, "[", 1); +} + +int +sentrycrashjson_beginObject(SentryCrashJSONEncodeContext *const context, const char *const name) +{ + likely_if(context->containerLevel >= 0) + { + int result = sentrycrashjson_beginElement(context, name); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + } + + context->containerLevel++; + context->isObject[context->containerLevel] = true; + context->containerFirstEntry = true; + + return addJSONData(context, "{", 1); +} + +int +sentrycrashjson_endContainer(SentryCrashJSONEncodeContext *const context) +{ + unlikely_if(context->containerLevel <= 0) { return SentryCrashJSON_OK; } + + bool isObject = context->isObject[context->containerLevel]; + context->containerLevel--; + + // Pretty printing + unlikely_if(context->prettyPrint && !context->containerFirstEntry) + { + int result; + unlikely_if((result = addJSONData(context, "\n", 1)) != SentryCrashJSON_OK) + { + return result; + } + for (int i = 0; i < context->containerLevel; i++) { + unlikely_if((result = addJSONData(context, " ", 4)) != SentryCrashJSON_OK) + { + return result; + } + } + } + context->containerFirstEntry = false; + return addJSONData(context, isObject ? "}" : "]", 1); +} + +void +sentrycrashjson_beginEncode(SentryCrashJSONEncodeContext *const context, bool prettyPrint, + SentryCrashJSONAddDataFunc addJSONDataFunc, void *const userData) +{ + memset(context, 0, sizeof(*context)); + context->addJSONData = addJSONDataFunc; + context->userData = userData; + context->prettyPrint = prettyPrint; + context->containerFirstEntry = true; +} + +int +sentrycrashjson_endEncode(SentryCrashJSONEncodeContext *const context) +{ + int result = SentryCrashJSON_OK; + while (context->containerLevel > 0) { + unlikely_if((result = sentrycrashjson_endContainer(context)) != SentryCrashJSON_OK) + { + return result; + } + } + return result; +} + +// ============================================================================ +#pragma mark - Decode - +// ============================================================================ + +#define INV 0x11111 + +typedef struct { + /** Pointer to current work area in the buffer. */ + const char *bufferPtr; + /** Pointer to the end of the buffer. */ + const char *bufferEnd; + /** Pointer to a buffer for storing a decoded name. */ + char *nameBuffer; + /** Length of the name buffer. */ + int nameBufferLength; + /** Pointer to a buffer for storing a decoded string. */ + char *stringBuffer; + /** Length of the string buffer. */ + int stringBufferLength; + /** The callbacks to call while decoding. */ + SentryCrashJSONDecodeCallbacks *const callbacks; + /** Data that was specified when calling sentrycrashjson_decode(). */ + void *userData; +} SentryCrashJSONDecodeContext; + +/** Lookup table for converting hex values to integers. + * INV (0x11111) is used to mark invalid characters so that any attempted + * invalid nybble conversion is always > 0xffff. + */ +static const unsigned int g_hexConversion[] = { + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + 0x0, + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + 0x9, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + 0xa, + 0xb, + 0xc, + 0xd, + 0xe, + 0xf, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + 0xa, + 0xb, + 0xc, + 0xd, + 0xe, + 0xf, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, +}; + +/** Encode a UTF-16 character to UTF-8. The dest pointer gets incremented + * by however many bytes were needed for the conversion (1-4). + * + * @param character The UTF-16 character. + * + * @param dst Where to write the UTF-8 character. + * + * @return SentryCrashJSON_OK if the encoding was successful. + */ +static int writeUTF8(unsigned int character, char **dst); + +/** Decode a string value. + * + * @param context The decoding context. + * + * @param dstBuffer Buffer to hold the decoded string. + * + * @param dstBufferLength Length of the destination buffer. + * + * @return SentryCrashJSON_OK if successful. + */ +static int decodeString( + SentryCrashJSONDecodeContext *context, char *dstBuffer, int dstBufferLength); + +/** Decode a JSON element. + * + * @param name This element's name (or NULL if it has none). + * + * @param context The decoding context. + * + * @return SentryCrashJSON_OK if successful. + */ +static int decodeElement(const char *const name, SentryCrashJSONDecodeContext *context); + +/** Skip past any whitespace. + * + * @param CONTEXT The decoding context. + */ +#define SKIP_WHITESPACE(CONTEXT) \ + while (CONTEXT->bufferPtr < CONTEXT->bufferEnd && isspace(*CONTEXT->bufferPtr)) { \ + CONTEXT->bufferPtr++; \ + } + +/** Check if a character is valid for representing part of a floating point + * number. + * + * @param ch The character to test. + * + * @return true if the character is valid for floating point. + */ +static inline bool +isFPChar(char ch) +{ + switch (ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + case 'e': + case 'E': + case '+': + case '-': + return true; + default: + return false; + } +} + +static int +writeUTF8(unsigned int character, char **dst) +{ + likely_if(character <= 0x7f) + { + **dst = (char)character; + (*dst)++; + return SentryCrashJSON_OK; + } + if (character <= 0x7ff) { + (*dst)[0] = (char)(0xc0 | (character >> 6)); + (*dst)[1] = (char)(0x80 | (character & 0x3f)); + *dst += 2; + return SentryCrashJSON_OK; + } + if (character <= 0xffff) { + (*dst)[0] = (char)(0xe0 | (character >> 12)); + (*dst)[1] = (char)(0x80 | ((character >> 6) & 0x3f)); + (*dst)[2] = (char)(0x80 | (character & 0x3f)); + *dst += 3; + return SentryCrashJSON_OK; + } + // RFC3629 restricts UTF-8 to end at 0x10ffff. + if (character <= 0x10ffff) { + (*dst)[0] = (char)(0xf0 | (character >> 18)); + (*dst)[1] = (char)(0x80 | ((character >> 12) & 0x3f)); + (*dst)[2] = (char)(0x80 | ((character >> 6) & 0x3f)); + (*dst)[3] = (char)(0x80 | (character & 0x3f)); + *dst += 4; + return SentryCrashJSON_OK; + } + + // If we get here, the character cannot be converted to valid UTF-8. + SentryCrashLOG_DEBUG("Invalid unicode: 0x%04x", character); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; +} + +static int +decodeString(SentryCrashJSONDecodeContext *context, char *dstBuffer, int dstBufferLength) +{ + *dstBuffer = '\0'; + unlikely_if(*context->bufferPtr != '\"') + { + SentryCrashLOG_DEBUG("Expected '\"' but got '%c'", *context->bufferPtr); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + + const char *src = context->bufferPtr + 1; + bool fastCopy = true; + + for (; src < context->bufferEnd && *src != '\"'; src++) { + unlikely_if(*src == '\\') + { + fastCopy = false; + src++; + } + } + unlikely_if(src >= context->bufferEnd) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + const char *srcEnd = src; + src = context->bufferPtr + 1; + int length = (int)(srcEnd - src); + if (length >= dstBufferLength) { + SentryCrashLOG_DEBUG("String is too long"); + return SentryCrashJSON_ERROR_DATA_TOO_LONG; + } + + context->bufferPtr = srcEnd + 1; + + // If no escape characters were encountered, we can fast copy. + likely_if(fastCopy) + { + memcpy(dstBuffer, src, length); + dstBuffer[length] = 0; + return SentryCrashJSON_OK; + } + + char *dst = dstBuffer; + + for (; src < srcEnd; src++) { + likely_if(*src != '\\') { *dst++ = *src; } + else + { + src++; + switch (*src) { + case '"': + *dst++ = '\"'; + continue; + case '\\': + *dst++ = '\\'; + continue; + case 'n': + *dst++ = '\n'; + continue; + case 'r': + *dst++ = '\r'; + continue; + case '/': + *dst++ = '/'; + continue; + case 't': + *dst++ = '\t'; + continue; + case 'b': + *dst++ = '\b'; + continue; + case 'f': + *dst++ = '\f'; + continue; + case 'u': { + unlikely_if(src + 5 > srcEnd) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + unsigned int accum = g_hexConversion[src[1]] << 12 | g_hexConversion[src[2]] << 8 + | g_hexConversion[src[3]] << 4 | g_hexConversion[src[4]]; + unlikely_if(accum > 0xffff) + { + SentryCrashLOG_DEBUG( + "Invalid unicode sequence: %c%c%c%c", src[1], src[2], src[3], src[4]); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + + // UTF-16 Trail surrogate on its own. + unlikely_if(accum >= 0xdc00 && accum <= 0xdfff) + { + SentryCrashLOG_DEBUG("Unexpected trail surrogate: 0x%04x", accum); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + + // UTF-16 Lead surrogate. + unlikely_if(accum >= 0xd800 && accum <= 0xdbff) + { + // Fetch trail surrogate. + unlikely_if(src + 11 > srcEnd) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + unlikely_if(src[5] != '\\' || src[6] != 'u') + { + SentryCrashLOG_DEBUG("Expected \"\\u\" but got: \"%c%c\"", src[5], src[6]); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + src += 6; + unsigned int accum2 = g_hexConversion[src[1]] << 12 + | g_hexConversion[src[2]] << 8 | g_hexConversion[src[3]] << 4 + | g_hexConversion[src[4]]; + unlikely_if(accum2 < 0xdc00 || accum2 > 0xdfff) + { + SentryCrashLOG_DEBUG("Invalid trail surrogate: 0x%04x", accum2); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + // And combine 20 bit result. + accum = ((accum - 0xd800) << 10) | (accum2 - 0xdc00); + } + + int result = writeUTF8(accum, &dst); + unlikely_if(result != SentryCrashJSON_OK) { return result; } + src += 4; + continue; + } + default: + SentryCrashLOG_DEBUG("Invalid control character '%c'", *src); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + } + } + + *dst = 0; + return SentryCrashJSON_OK; +} + +static int +decodeElement(const char *const name, SentryCrashJSONDecodeContext *context) +{ + SKIP_WHITESPACE(context); + unlikely_if(context->bufferPtr >= context->bufferEnd) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + + int sign = 1; + int result; + + switch (*context->bufferPtr) { + case '[': { + context->bufferPtr++; + result = context->callbacks->onBeginArray(name, context->userData); + unlikely_if(result != SentryCrashJSON_OK) return result; + while (context->bufferPtr < context->bufferEnd) { + SKIP_WHITESPACE(context); + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } + unlikely_if(*context->bufferPtr == ']') + { + context->bufferPtr++; + return context->callbacks->onEndContainer(context->userData); + } + result = decodeElement(NULL, context); + unlikely_if(result != SentryCrashJSON_OK) return result; + SKIP_WHITESPACE(context); + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } + likely_if(*context->bufferPtr == ',') { context->bufferPtr++; } + } + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + case '{': { + context->bufferPtr++; + result = context->callbacks->onBeginObject(name, context->userData); + unlikely_if(result != SentryCrashJSON_OK) return result; + while (context->bufferPtr < context->bufferEnd) { + SKIP_WHITESPACE(context); + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } + unlikely_if(*context->bufferPtr == '}') + { + context->bufferPtr++; + return context->callbacks->onEndContainer(context->userData); + } + result = decodeString(context, context->nameBuffer, context->nameBufferLength); + unlikely_if(result != SentryCrashJSON_OK) return result; + SKIP_WHITESPACE(context); + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } + unlikely_if(*context->bufferPtr != ':') + { + SentryCrashLOG_DEBUG("Expected ':' but got '%c'", *context->bufferPtr); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + context->bufferPtr++; + SKIP_WHITESPACE(context); + result = decodeElement(context->nameBuffer, context); + unlikely_if(result != SentryCrashJSON_OK) return result; + SKIP_WHITESPACE(context); + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } + likely_if(*context->bufferPtr == ',') { context->bufferPtr++; } + } + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + case '\"': { + result = decodeString(context, context->stringBuffer, context->stringBufferLength); + unlikely_if(result != SentryCrashJSON_OK) return result; + result + = context->callbacks->onStringElement(name, context->stringBuffer, context->userData); + return result; + } + case 'f': { + unlikely_if(context->bufferEnd - context->bufferPtr < 5) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + unlikely_if(!(context->bufferPtr[1] == 'a' && context->bufferPtr[2] == 'l' + && context->bufferPtr[3] == 's' && context->bufferPtr[4] == 'e')) + { + SentryCrashLOG_DEBUG("Expected \"false\" but got \"f%c%c%c%c\"", context->bufferPtr[1], + context->bufferPtr[2], context->bufferPtr[3], context->bufferPtr[4]); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + context->bufferPtr += 5; + return context->callbacks->onBooleanElement(name, false, context->userData); + } + case 't': { + unlikely_if(context->bufferEnd - context->bufferPtr < 4) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + unlikely_if(!(context->bufferPtr[1] == 'r' && context->bufferPtr[2] == 'u' + && context->bufferPtr[3] == 'e')) + { + SentryCrashLOG_DEBUG("Expected \"true\" but got \"t%c%c%c\"", context->bufferPtr[1], + context->bufferPtr[2], context->bufferPtr[3]); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + context->bufferPtr += 4; + return context->callbacks->onBooleanElement(name, true, context->userData); + } + case 'n': { + unlikely_if(context->bufferEnd - context->bufferPtr < 4) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + unlikely_if(!(context->bufferPtr[1] == 'u' && context->bufferPtr[2] == 'l' + && context->bufferPtr[3] == 'l')) + { + SentryCrashLOG_DEBUG("Expected \"null\" but got \"n%c%c%c\"", context->bufferPtr[1], + context->bufferPtr[2], context->bufferPtr[3]); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + context->bufferPtr += 4; + return context->callbacks->onNullElement(name, context->userData); + } + case '-': + sign = -1; + context->bufferPtr++; + unlikely_if(!isdigit(*context->bufferPtr)) + { + SentryCrashLOG_DEBUG("Not a digit: '%c'", *context->bufferPtr); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; + } + // Fall through + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + // Try integer conversion. + int64_t accum = 0; + const char *const start = context->bufferPtr; + + for (; context->bufferPtr < context->bufferEnd && isdigit(*context->bufferPtr); + context->bufferPtr++) { + accum = accum * 10 + (*context->bufferPtr - '0'); + unlikely_if(accum < 0) + { + // Overflow + break; + } + } + + unlikely_if(context->bufferPtr >= context->bufferEnd) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + + if (!isFPChar(*context->bufferPtr) && accum >= 0) { + accum *= sign; + return context->callbacks->onIntegerElement(name, accum, context->userData); + } + + while (context->bufferPtr < context->bufferEnd && isFPChar(*context->bufferPtr)) { + context->bufferPtr++; + } + + unlikely_if(context->bufferPtr >= context->bufferEnd) + { + SentryCrashLOG_DEBUG("Premature end of data"); + return SentryCrashJSON_ERROR_INCOMPLETE; + } + + // our buffer is not necessarily NULL-terminated, so + // it would be undefined to call sscanf/sttod etc. directly. + // instead we create a temporary string. + double value; + int len = (int)(context->bufferPtr - start); + if (len >= context->stringBufferLength) { + SentryCrashLOG_DEBUG("Number is too long."); + return SentryCrashJSON_ERROR_DATA_TOO_LONG; + } + strncpy(context->stringBuffer, start, len); + context->stringBuffer[len] = '\0'; + + sscanf(context->stringBuffer, "%lg", &value); + + value *= sign; + return context->callbacks->onFloatingPointElement(name, value, context->userData); + } + } + SentryCrashLOG_DEBUG("Invalid character '%c'", *context->bufferPtr); + return SentryCrashJSON_ERROR_INVALID_CHARACTER; +} + +int +sentrycrashjson_decode(const char *const data, int length, char *stringBuffer, + int stringBufferLength, SentryCrashJSONDecodeCallbacks *const callbacks, void *const userData, + int *const errorOffset) +{ + char *nameBuffer = stringBuffer; + int nameBufferLength = stringBufferLength / 4; + stringBuffer = nameBuffer + nameBufferLength; + stringBufferLength -= nameBufferLength; + SentryCrashJSONDecodeContext context = { .bufferPtr = (char *)data, + .bufferEnd = (char *)data + length, + .nameBuffer = nameBuffer, + .nameBufferLength = nameBufferLength, + .stringBuffer = stringBuffer, + .stringBufferLength = (int)stringBufferLength, + .callbacks = callbacks, + .userData = userData }; + + const char *ptr = data; + + int result = decodeElement(NULL, &context); + likely_if(result == SentryCrashJSON_OK) { result = callbacks->onEndData(userData); } + + unlikely_if(result != SentryCrashJSON_OK && errorOffset != NULL) + { + *errorOffset = (int)(ptr - data); + } + return result; +} + +struct JSONFromFileContext; +typedef void (*UpdateDecoderCallback)(struct JSONFromFileContext *context); + +typedef struct JSONFromFileContext { + SentryCrashJSONEncodeContext *encodeContext; + SentryCrashJSONDecodeContext *decodeContext; + char *bufferStart; + const char *sourceFilename; + int fd; + bool isEOF; + bool closeLastContainer; + UpdateDecoderCallback updateDecoderCallback; +} JSONFromFileContext; + +static void +updateDecoder_doNothing(__unused struct JSONFromFileContext *context) +{ +} + +static void +updateDecoder_readFile(struct JSONFromFileContext *context) +{ + likely_if(!context->isEOF) + { + const char *end = context->decodeContext->bufferEnd; + char *start = context->bufferStart; + const char *ptr = context->decodeContext->bufferPtr; + int bufferLength = (int)(end - start); + int remainingLength = (int)(end - ptr); + unlikely_if(remainingLength < bufferLength / 2) + { + int fillLength = bufferLength - remainingLength; + memcpy(start, ptr, remainingLength); + context->decodeContext->bufferPtr = start; + int bytesRead = (int)read(context->fd, start + remainingLength, (unsigned)fillLength); + unlikely_if(bytesRead < fillLength) + { + if (bytesRead < 0) { + SentryCrashLOG_ERROR( + "Error reading file %s: %s", context->sourceFilename, strerror(errno)); + } + context->isEOF = true; + } + } + } +} + +static int +addJSONFromFile_onBooleanElement(const char *const name, const bool value, void *const userData) +{ + JSONFromFileContext *context = (JSONFromFileContext *)userData; + int result = sentrycrashjson_addBooleanElement(context->encodeContext, name, value); + context->updateDecoderCallback(context); + return result; +} + +static int +addJSONFromFile_onFloatingPointElement( + const char *const name, const double value, void *const userData) +{ + JSONFromFileContext *context = (JSONFromFileContext *)userData; + int result = sentrycrashjson_addFloatingPointElement(context->encodeContext, name, value); + context->updateDecoderCallback(context); + return result; +} + +static int +addJSONFromFile_onIntegerElement(const char *const name, const int64_t value, void *const userData) +{ + JSONFromFileContext *context = (JSONFromFileContext *)userData; + int result = sentrycrashjson_addIntegerElement(context->encodeContext, name, value); + context->updateDecoderCallback(context); + return result; +} + +static int +addJSONFromFile_onNullElement(const char *const name, void *const userData) +{ + JSONFromFileContext *context = (JSONFromFileContext *)userData; + int result = sentrycrashjson_addNullElement(context->encodeContext, name); + context->updateDecoderCallback(context); + return result; +} + +static int +addJSONFromFile_onStringElement( + const char *const name, const char *const value, void *const userData) +{ + JSONFromFileContext *context = (JSONFromFileContext *)userData; + int result + = sentrycrashjson_addStringElement(context->encodeContext, name, value, (int)strlen(value)); + context->updateDecoderCallback(context); + return result; +} + +static int +addJSONFromFile_onBeginObject(const char *const name, void *const userData) +{ + JSONFromFileContext *context = (JSONFromFileContext *)userData; + int result = sentrycrashjson_beginObject(context->encodeContext, name); + context->updateDecoderCallback(context); + return result; +} + +static int +addJSONFromFile_onBeginArray(const char *const name, void *const userData) +{ + JSONFromFileContext *context = (JSONFromFileContext *)userData; + int result = sentrycrashjson_beginArray(context->encodeContext, name); + context->updateDecoderCallback(context); + return result; +} + +static int +addJSONFromFile_onEndContainer(void *const userData) +{ + JSONFromFileContext *context = (JSONFromFileContext *)userData; + int result = SentryCrashJSON_OK; + if (context->closeLastContainer || context->encodeContext->containerLevel > 2) { + result = sentrycrashjson_endContainer(context->encodeContext); + } + context->updateDecoderCallback(context); + return result; +} + +static int +addJSONFromFile_onEndData(__unused void *const userData) +{ + return SentryCrashJSON_OK; +} + +int +sentrycrashjson_addJSONFromFile(SentryCrashJSONEncodeContext *const encodeContext, + const char *restrict const name, const char *restrict const filename, + const bool closeLastContainer) +{ + SentryCrashJSONDecodeCallbacks callbacks = { + .onBeginArray = addJSONFromFile_onBeginArray, + .onBeginObject = addJSONFromFile_onBeginObject, + .onBooleanElement = addJSONFromFile_onBooleanElement, + .onEndContainer = addJSONFromFile_onEndContainer, + .onEndData = addJSONFromFile_onEndData, + .onFloatingPointElement = addJSONFromFile_onFloatingPointElement, + .onIntegerElement = addJSONFromFile_onIntegerElement, + .onNullElement = addJSONFromFile_onNullElement, + .onStringElement = addJSONFromFile_onStringElement, + }; + char nameBuffer[100] = { 0 }; + char stringBuffer[500] = { 0 }; + char fileBuffer[1000] = { 0 }; + SentryCrashJSONDecodeContext decodeContext = { + .bufferPtr = fileBuffer, + .bufferEnd = fileBuffer + sizeof(fileBuffer), + .nameBuffer = nameBuffer, + .nameBufferLength = sizeof(nameBuffer), + .stringBuffer = stringBuffer, + .stringBufferLength = sizeof(stringBuffer), + .callbacks = &callbacks, + .userData = NULL, + }; + + int fd = open(filename, O_RDONLY); + JSONFromFileContext jsonContext = { + .encodeContext = encodeContext, + .decodeContext = &decodeContext, + .bufferStart = fileBuffer, + .sourceFilename = filename, + .fd = fd, + .closeLastContainer = closeLastContainer, + .isEOF = false, + .updateDecoderCallback = updateDecoder_readFile, + }; + decodeContext.userData = &jsonContext; + int containerLevel = encodeContext->containerLevel; + + // Manually trigger a data load. + decodeContext.bufferPtr = decodeContext.bufferEnd; + jsonContext.updateDecoderCallback(&jsonContext); + + int result = decodeElement(name, &decodeContext); + close(fd); + while (closeLastContainer && encodeContext->containerLevel > containerLevel) { + sentrycrashjson_endContainer(encodeContext); + } + + return result; +} + +int +sentrycrashjson_addJSONElement(SentryCrashJSONEncodeContext *const encodeContext, + const char *restrict const name, const char *restrict const jsonData, const int jsonDataLength, + const bool closeLastContainer) +{ + SentryCrashJSONDecodeCallbacks callbacks = { + .onBeginArray = addJSONFromFile_onBeginArray, + .onBeginObject = addJSONFromFile_onBeginObject, + .onBooleanElement = addJSONFromFile_onBooleanElement, + .onEndContainer = addJSONFromFile_onEndContainer, + .onEndData = addJSONFromFile_onEndData, + .onFloatingPointElement = addJSONFromFile_onFloatingPointElement, + .onIntegerElement = addJSONFromFile_onIntegerElement, + .onNullElement = addJSONFromFile_onNullElement, + .onStringElement = addJSONFromFile_onStringElement, + }; + char nameBuffer[100] = { 0 }; + char stringBuffer[5000] = { 0 }; + SentryCrashJSONDecodeContext decodeContext = { + .bufferPtr = jsonData, + .bufferEnd = jsonData + jsonDataLength, + .nameBuffer = nameBuffer, + .nameBufferLength = sizeof(nameBuffer), + .stringBuffer = stringBuffer, + .stringBufferLength = sizeof(stringBuffer), + .callbacks = &callbacks, + .userData = NULL, + }; + + JSONFromFileContext jsonContext = { + .encodeContext = encodeContext, + .decodeContext = &decodeContext, + .bufferStart = (char *)jsonData, + .sourceFilename = NULL, + .fd = 0, + .closeLastContainer = closeLastContainer, + .isEOF = false, + .updateDecoderCallback = updateDecoder_doNothing, + }; + decodeContext.userData = &jsonContext; + int containerLevel = encodeContext->containerLevel; + + int result = decodeElement(name, &decodeContext); + while (closeLastContainer && encodeContext->containerLevel > containerLevel) { + sentrycrashjson_endContainer(encodeContext); + } + + return result; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h new file mode 100644 index 00000000..fedb3bf9 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h @@ -0,0 +1,514 @@ +// +// SentryCrashJSONCodec.h +// +// Created by Karl Stenerud on 2012-01-07. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Reads and writes JSON encoded data. + */ + +#ifndef HDR_SentryCrashJSONCodec_h +#define HDR_SentryCrashJSONCodec_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* Tells the encoder to automatically determine the length of a field value. + * Currently, this is done using strlen(). + */ +#define SentryCrashJSON_SIZE_AUTOMATIC -1 + +#define SentryCrashMAX_STRINGBUFFERSIZE 100000 + +enum { + /** Encoding or decoding: Everything completed without error */ + SentryCrashJSON_OK = 0, + + /** Encoding or decoding: Encountered an unexpected or invalid character */ + SentryCrashJSON_ERROR_INVALID_CHARACTER = 1, + + /** Decoding: Source data was too long. */ + SentryCrashJSON_ERROR_DATA_TOO_LONG = 2, + + /** Encoding: addJSONData could not handle the data. + * This code is not used by the decoder, but is meant to be returned by + * the addJSONData callback method if it couldn't handle the data. + */ + SentryCrashJSON_ERROR_CANNOT_ADD_DATA = 3, + + /** Decoding: Source data appears to be truncated. */ + SentryCrashJSON_ERROR_INCOMPLETE = 4, + + /** Decoding: Parsing failed due to bad data structure/type/contents. + * This code is not used by the decoder, but is meant to be returned + * by the user callback methods if the decoded data is incorrect for + * semantic or structural reasons. + */ + SentryCrashJSON_ERROR_INVALID_DATA = 5, +}; + +/** Get a description for an error code. + * + * @param error The error code. + * + * @return A string describing the error. + */ +const char *sentrycrashjson_stringForError(const int error); + +// ============================================================================ +// Encode +// ============================================================================ + +/** Function pointer for adding more UTF-8 encoded JSON data. + * + * @param data The UTF-8 data to add. + * + * @param length The length of the data. + * + * @param userData user-specified contextual data. + * + * @return SentryCrashJSON_OK if the data was handled. + * otherwise SentryCrashJSON_ERROR_CANNOT_ADD_DATA. + */ +typedef int (*SentryCrashJSONAddDataFunc)(const char *data, int length, void *userData); + +typedef struct { + /** Function to call to add more encoded JSON data. */ + SentryCrashJSONAddDataFunc addJSONData; + + /** User-specified data */ + void *userData; + + /** How many containers deep we are. */ + int containerLevel; + + /** Whether or not the current container is an object. */ + bool isObject[200]; + + /** true if this is the first entry at the current container level. */ + bool containerFirstEntry; + + bool prettyPrint; + +} SentryCrashJSONEncodeContext; + +/** Begin a new encoding process. + * + * @param context The encoding context. + * + * @param prettyPrint If true, insert whitespace to make the output pretty. + * + * @param addJSONData Function to handle adding data. + * + * @param userData User-specified data which gets passed to addJSONData. + */ +void sentrycrashjson_beginEncode(SentryCrashJSONEncodeContext *context, bool prettyPrint, + SentryCrashJSONAddDataFunc addJSONData, void *userData); + +/** End the encoding process, ending any remaining open containers. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_endEncode(SentryCrashJSONEncodeContext *context); + +/** Add a boolean element. + * + * @param context The encoding context. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_addBooleanElement( + SentryCrashJSONEncodeContext *context, const char *name, bool value); + +/** Add an integer element. + * + * @param context The encoding context. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_addIntegerElement( + SentryCrashJSONEncodeContext *context, const char *name, int64_t value); + +/** Add a floating point element. + * + * @param context The encoding context. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_addFloatingPointElement( + SentryCrashJSONEncodeContext *context, const char *name, double value); + +/** Add a null element. + * + * @param context The encoding context. + * + * @param name The element's name. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_addNullElement(SentryCrashJSONEncodeContext *context, const char *name); + +/** Add a string element. + * + * @param context The encoding context. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @param length the length of the string, or SentryCrashJSON_SIZE_AUTOMATIC. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_addStringElement( + SentryCrashJSONEncodeContext *context, const char *name, const char *value, int length); + +/** Start an incrementally-built string element. + * + * Use this for constructing very large strings. + * + * @param context The encoding context. + * + * @param name The element's name. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_beginStringElement(SentryCrashJSONEncodeContext *context, const char *name); + +/** Add a string fragment to an incrementally-built string element. + * + * @param context The encoding context. + * + * @param value The string fragment. + * + * @param length the length of the string fragment. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_appendStringElement( + SentryCrashJSONEncodeContext *context, const char *value, int length); + +/** End an incrementally-built string element. + * + * @param context The encoding context. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_endStringElement(SentryCrashJSONEncodeContext *context); + +/** Add a string element. The element will be converted to string-coded hex. + * + * @param context The encoding context. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @param length The length of the data. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_addDataElement( + SentryCrashJSONEncodeContext *const context, const char *name, const char *value, int length); + +/** Start an incrementally-built data element. The element will be converted + * to string-coded hex. + * + * Use this for constructing very large data elements. + * + * @param context The encoding context. + * + * @param name The element's name. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_beginDataElement( + SentryCrashJSONEncodeContext *const context, const char *const name); + +/** Add a data fragment to an incrementally-built data element. + * + * @param context The encoding context. + * + * @param value The data fragment. + * + * @param length the length of the data fragment. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_appendDataElement( + SentryCrashJSONEncodeContext *const context, const char *const value, int length); + +/** End an incrementally-built data element. + * + * @param context The encoding context. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_endDataElement(SentryCrashJSONEncodeContext *const context); + +/** Add a pre-formatted JSON element. + * + * @param encodeContext The encoding context. + * + * @param name The element's name. + * + * @param jsonData The element's value. MUST BE VALID JSON! + * + * @param jsonDataLength The length of the element. + * + * @param closeLastContainer If false, do not close the last container. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_addJSONElement(SentryCrashJSONEncodeContext *const encodeContext, + const char *restrict const name, const char *restrict const jsonData, const int jsonDataLength, + const bool closeLastContainer); + +/** Begin a new object container. + * + * @param context The encoding context. + * + * @param name The object's name. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_beginObject(SentryCrashJSONEncodeContext *context, const char *name); + +/** Begin a new array container. + * + * @param context The encoding context. + * + * @param name The array's name. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_beginArray(SentryCrashJSONEncodeContext *context, const char *name); + +/** Begin a generic JSON element, adding any necessary JSON preamble text, + * including commas and names. + * Note: This does not add any object or array specifiers ('{', '['). + * + * @param context The JSON context. + * + * @param name The name of the next element (only needed if parent is a + * dictionary). + */ +int sentrycrashjson_beginElement( + SentryCrashJSONEncodeContext *const context, const char *const name); + +/** Add JSON data manually. + * This function just passes your data directly through, even if it's malforned. + * + * @param context The encoding context. + * + * @param data The data to write. + * + * @param length The length of the data. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_addRawJSONData( + SentryCrashJSONEncodeContext *const context, const char *const data, const int length); + +/** End the current container and return to the next higher level. + * + * @param context The encoding context. + * + * @return SentryCrashJSON_OK if the process was successful. + */ +int sentrycrashjson_endContainer(SentryCrashJSONEncodeContext *context); + +/** Decode and add JSON data from a file. + * + * @param context The encoding context. + * + * @param name The name to give the top element from the file. + * + * @param filename The file to read from. + * + * @param closeLastContainer If false, do not close the last container. + */ +int sentrycrashjson_addJSONFromFile(SentryCrashJSONEncodeContext *const context, + const char *restrict const name, const char *restrict const filename, + const bool closeLastContainer); + +// ============================================================================ +// Decode +// ============================================================================ + +/** + * Callbacks called during a JSON decode process. + * All function pointers must point to valid functions. + */ +typedef struct SentryCrashJSONDecodeCallbacks { + /** Called when a boolean element is decoded. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onBooleanElement)(const char *name, bool value, void *userData); + + /** Called when a floating point element is decoded. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onFloatingPointElement)(const char *name, double value, void *userData); + + /** Called when an integer element is decoded. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onIntegerElement)(const char *name, int64_t value, void *userData); + + /** Called when a null element is decoded. + * + * @param name The element's name. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onNullElement)(const char *name, void *userData); + + /** Called when a string element is decoded. + * + * @param name The element's name. + * + * @param value The element's value. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onStringElement)(const char *name, const char *value, void *userData); + + /** Called when a new object is encountered. + * + * @param name The object's name. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onBeginObject)(const char *name, void *userData); + + /** Called when a new array is encountered. + * + * @param name The array's name. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onBeginArray)(const char *name, void *userData); + + /** Called when leaving the current container and returning to the next + * higher level container. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onEndContainer)(void *userData); + + /** Called when the end of the input data is reached. + * + * @param userData Data that was specified when calling + * sentrycrashjson_decode(). + * + * @return SentryCrashJSON_OK if decoding should continue. + */ + int (*onEndData)(void *userData); + +} SentryCrashJSONDecodeCallbacks; + +/** Read a JSON encoded file from the specified FD. + * + * @param data UTF-8 encoded JSON data. + * + * @param length Length of the data. + * + * @param stringBuffer A buffer to use for decoding strings. + * Note: 1/4 of this buffer will be used for dictionary name + * decoding. + * + * @param stringBufferLength The length of the string buffer. + * + * @param callbacks The callbacks to call while decoding. + * + * @param userData Any data you would like passed to the callbacks. + * + * @oaram errorOffset If not null, will contain the offset into the data + * where the error (if any) occurred. + * + * @return SentryCrashJSON_OK if succesful. An error code otherwise. + */ +int sentrycrashjson_decode(const char *data, int length, char *stringBuffer, int stringBufferLength, + SentryCrashJSONDecodeCallbacks *callbacks, void *userData, int *errorOffset); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashJSONCodec_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.h new file mode 100644 index 00000000..ebfa2d49 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.h @@ -0,0 +1,98 @@ +// +// SentryCrashJSONCodecObjC.h +// +// Created by Karl Stenerud on 2012-01-08. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +/** Optional behavior when encoding JSON data */ +typedef enum { + SentryCrashJSONEncodeOptionNone = 0, + + /** Indent 4 spaces per object/array level */ + SentryCrashJSONEncodeOptionPretty = 1, + + /** Sort object contents by key name */ + SentryCrashJSONEncodeOptionSorted = 2, +} SentryCrashJSONEncodeOption; + +/** Optional behavior when decoding JSON data */ +typedef enum { + SentryCrashJSONDecodeOptionNone = 0, + + /** Normally, null elements get stored as [NSNull null]. + * If this option is set, do not store anything when a null element is + * encountered inside an array. + */ + SentryCrashJSONDecodeOptionIgnoreNullInArray = 1, + + /** Normally, null elements get stored as [NSNull null]. + * If this option is set, do not store anything when a null element is + * encountered inside an object. + */ + SentryCrashJSONDecodeOptionIgnoreNullInObject = 2, + + /** Convenience enum to ignore nulls in arrays and objects. */ + SentryCrashJSONDecodeOptionIgnoreAllNulls = 3, + + /** If an error is encountered, return the partially decoded object. */ + SentryCrashJSONDecodeOptionKeepPartialObject = 4, +} SentryCrashJSONDecodeOption; + +/** + * Encodes and decodes UTF-8 JSON data. + */ +@interface SentryCrashJSONCodec : NSObject + +/** Encode an object to JSON data. + * + * @param object The array or dictionary to encode. + * + * @param options Options for how to encode the data. + * + * @param error Place to store any error that occurs (nil = ignore). Will be + * set to nil on success. + * + * @return The encoded UTF-8 JSON data or nil if an error occurred. + */ ++ (NSData *)encode:(id)object options:(SentryCrashJSONEncodeOption)options error:(NSError **)error; + +/** Decode JSON data to an object. + * + * @param JSONData The UTF-8 data to decode. + * + * @param options Options for how to decode the data. + * + * @param error Place to store any error that occurs (nil = ignore). Will be + * set to nil on success. + * + * @return The decoded object or, if the + * SentryCrashJSONDecodeOptionKeepPartialFile option is not set, nil when an + * error occurs. + */ ++ (id)decode:(NSData *)JSONData + options:(SentryCrashJSONDecodeOption)options + error:(NSError **)error; + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.m b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.m new file mode 100644 index 00000000..fca9a7a6 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.m @@ -0,0 +1,452 @@ +// +// SentryCrashJSONCodecObjC.m +// +// Created by Karl Stenerud on 2012-01-08. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashJSONCodecObjC.h" + +#import "NSError+SentrySimpleConstructor.h" +#import "SentryCrashDate.h" +#import "SentryCrashJSONCodec.h" + +@interface +SentryCrashJSONCodec () + +#pragma mark Properties + +/** Callbacks from the C library */ +@property (nonatomic, readwrite, assign) SentryCrashJSONDecodeCallbacks *callbacks; + +/** Stack of arrays/objects as the decoded content is built */ +@property (nonatomic, readwrite, retain) NSMutableArray *containerStack; + +/** Current array or object being decoded (weak ref) */ +@property (nonatomic, readwrite, assign) id currentContainer; + +/** Top level array or object in the decoded tree */ +@property (nonatomic, readwrite, retain) id topLevelContainer; + +/** Data that has been serialized into JSON form */ +@property (nonatomic, readwrite, retain) NSMutableData *serializedData; + +/** Any error that has occurred */ +@property (nonatomic, readwrite, retain) NSError *error; + +/** If true, pretty print while encoding */ +@property (nonatomic, readwrite, assign) bool prettyPrint; + +/** If true, sort object keys while encoding */ +@property (nonatomic, readwrite, assign) bool sorted; + +/** If true, don't store nulls in arrays */ +@property (nonatomic, readwrite, assign) bool ignoreNullsInArrays; + +/** If true, don't store nulls in objects */ +@property (nonatomic, readwrite, assign) bool ignoreNullsInObjects; + +#pragma mark Constructors + +/** Convenience constructor. + * + * @param encodeOptions Optional behavior when encoding to JSON. + * + * @param decodeOptions Optional behavior when decoding from JSON. + * + * @return A new codec. + */ ++ (SentryCrashJSONCodec *)codecWithEncodeOptions:(SentryCrashJSONEncodeOption)encodeOptions + decodeOptions:(SentryCrashJSONDecodeOption)decodeOptions; + +/** Initializer. + * + * @param encodeOptions Optional behavior when encoding to JSON. + * + * @param decodeOptions Optional behavior when decoding from JSON. + * + * @return The initialized codec. + */ +- (id)initWithEncodeOptions:(SentryCrashJSONEncodeOption)encodeOptions + decodeOptions:(SentryCrashJSONDecodeOption)decodeOptions; + +@end + +#pragma mark - +#pragma mark - + +@implementation SentryCrashJSONCodec + +#pragma mark Properties + +@synthesize topLevelContainer = _topLevelContainer; +@synthesize currentContainer = _currentContainer; +@synthesize containerStack = _containerStack; +@synthesize callbacks = _callbacks; +@synthesize serializedData = _serializedData; +@synthesize error = _error; +@synthesize prettyPrint = _prettyPrint; +@synthesize sorted = _sorted; +@synthesize ignoreNullsInArrays = _ignoreNullsInArrays; +@synthesize ignoreNullsInObjects = _ignoreNullsInObjects; + +#pragma mark Constructors/Destructor + ++ (SentryCrashJSONCodec *)codecWithEncodeOptions:(SentryCrashJSONEncodeOption)encodeOptions + decodeOptions:(SentryCrashJSONDecodeOption)decodeOptions +{ + return [[self alloc] initWithEncodeOptions:encodeOptions decodeOptions:decodeOptions]; +} + +- (id)initWithEncodeOptions:(SentryCrashJSONEncodeOption)encodeOptions + decodeOptions:(SentryCrashJSONDecodeOption)decodeOptions +{ + if ((self = [super init])) { + self.containerStack = [NSMutableArray array]; + + self.callbacks = malloc(sizeof(*self.callbacks)); + // Unlikely malloc failure. + NSAssert(self.callbacks != NULL, @"Could not allocate callbacks"); + + self.callbacks->onBeginArray = onBeginArray; + self.callbacks->onBeginObject = onBeginObject; + self.callbacks->onBooleanElement = onBooleanElement; + self.callbacks->onEndContainer = onEndContainer; + self.callbacks->onEndData = onEndData; + self.callbacks->onFloatingPointElement = onFloatingPointElement; + self.callbacks->onIntegerElement = onIntegerElement; + self.callbacks->onNullElement = onNullElement; + self.callbacks->onStringElement = onStringElement; + + self.prettyPrint = (encodeOptions & SentryCrashJSONEncodeOptionPretty) != 0; + self.sorted = (encodeOptions & SentryCrashJSONEncodeOptionSorted) != 0; + self.ignoreNullsInArrays + = (decodeOptions & SentryCrashJSONDecodeOptionIgnoreNullInArray) != 0; + self.ignoreNullsInObjects + = (decodeOptions & SentryCrashJSONDecodeOptionIgnoreNullInObject) != 0; + } + return self; +} + +- (void)dealloc +{ + free(self.callbacks); +} + +#pragma mark Utility + +static inline NSString * +stringFromCString(const char *const string) +{ + if (string == NULL) { + return nil; + } + return [NSString stringWithCString:string encoding:NSUTF8StringEncoding]; +} + +#pragma mark Callbacks + +static int +onElement(SentryCrashJSONCodec *codec, NSString *name, id element) +{ + if (codec->_currentContainer == nil) { + codec.error = [NSError + sentryErrorWithDomain:@"SentryCrashJSONCodecObjC" + code:0 + description:@"Type %@ not allowed as top level container", [element class]]; + return SentryCrashJSON_ERROR_INVALID_DATA; + } + + if ([codec->_currentContainer isKindOfClass:[NSMutableDictionary class]]) { + [(NSMutableDictionary *)codec->_currentContainer setValue:element forKey:name]; + } else { + [(NSMutableArray *)codec->_currentContainer addObject:element]; + } + return SentryCrashJSON_OK; +} + +static int +onBeginContainer(SentryCrashJSONCodec *codec, NSString *name, id container) +{ + if (codec->_topLevelContainer == nil) { + codec->_topLevelContainer = container; + } else { + int result = onElement(codec, name, container); + if (result != SentryCrashJSON_OK) { + return result; + } + } + codec->_currentContainer = container; + [codec->_containerStack addObject:container]; + return SentryCrashJSON_OK; +} + +static int +onBooleanElement(const char *const cName, const bool value, void *const userData) +{ + NSString *name = stringFromCString(cName); + id element = [NSNumber numberWithBool:value]; + SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData; + return onElement(codec, name, element); +} + +static int +onFloatingPointElement(const char *const cName, const double value, void *const userData) +{ + NSString *name = stringFromCString(cName); + id element = [NSNumber numberWithDouble:value]; + SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData; + return onElement(codec, name, element); +} + +static int +onIntegerElement(const char *const cName, const int64_t value, void *const userData) +{ + NSString *name = stringFromCString(cName); + id element = [NSNumber numberWithLongLong:value]; + SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData; + return onElement(codec, name, element); +} + +static int +onNullElement(const char *const cName, void *const userData) +{ + NSString *name = stringFromCString(cName); + SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData; + + if ((codec->_ignoreNullsInArrays && [codec->_currentContainer isKindOfClass:[NSArray class]]) + || (codec->_ignoreNullsInObjects && + [codec->_currentContainer isKindOfClass:[NSDictionary class]])) { + return SentryCrashJSON_OK; + } + + return onElement(codec, name, [NSNull null]); +} + +static int +onStringElement(const char *const cName, const char *const value, void *const userData) +{ + NSString *name = stringFromCString(cName); + id element = [NSString stringWithCString:value encoding:NSUTF8StringEncoding]; + SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData; + return onElement(codec, name, element); +} + +static int +onBeginObject(const char *const cName, void *const userData) +{ + NSString *name = stringFromCString(cName); + id container = [NSMutableDictionary dictionary]; + SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData; + return onBeginContainer(codec, name, container); +} + +static int +onBeginArray(const char *const cName, void *const userData) +{ + NSString *name = stringFromCString(cName); + id container = [NSMutableArray array]; + SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData; + return onBeginContainer(codec, name, container); +} + +static int +onEndContainer(void *const userData) +{ + SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData; + + if ([codec->_containerStack count] == 0) { + codec.error = + [NSError sentryErrorWithDomain:@"SentryCrashJSONCodecObjC" + code:0 + description:@"Already at the top level; no container left to end"]; + return SentryCrashJSON_ERROR_INVALID_DATA; + } + [codec->_containerStack removeLastObject]; + NSUInteger count = [codec->_containerStack count]; + if (count > 0) { + codec->_currentContainer = [codec->_containerStack objectAtIndex:count - 1]; + } else { + codec->_currentContainer = nil; + } + return SentryCrashJSON_OK; +} + +static int +onEndData(__unused void *const userData) +{ + return SentryCrashJSON_OK; +} + +static int +addJSONData(const char *const bytes, const int length, void *const userData) +{ + NSMutableData *data = (__bridge NSMutableData *)userData; + [data appendBytes:bytes length:(unsigned)length]; + return SentryCrashJSON_OK; +} + +static int +encodeObject( + SentryCrashJSONCodec *codec, id object, NSString *name, SentryCrashJSONEncodeContext *context) +{ + int result; + const char *cName = [name UTF8String]; + if ([object isKindOfClass:[NSString class]]) { + NSData *data = [object dataUsingEncoding:NSUTF8StringEncoding]; + result = sentrycrashjson_addStringElement(context, cName, data.bytes, (int)data.length); + if (result == SentryCrashJSON_ERROR_INVALID_CHARACTER) { + codec.error = [NSError sentryErrorWithDomain:@"SentryCrashJSONCodecObjC" + code:0 + description:@"Invalid character in %@", object]; + } + return result; + } + + if ([object isKindOfClass:[NSNumber class]]) { + switch (CFNumberGetType((__bridge CFNumberRef)object)) { + case kCFNumberFloat32Type: + case kCFNumberFloat64Type: + case kCFNumberFloatType: + case kCFNumberCGFloatType: + case kCFNumberDoubleType: + return sentrycrashjson_addFloatingPointElement(context, cName, [object doubleValue]); + case kCFNumberCharType: + return sentrycrashjson_addBooleanElement(context, cName, [object boolValue]); + default: + return sentrycrashjson_addIntegerElement(context, cName, [object longLongValue]); + } + } + + if ([object isKindOfClass:[NSArray class]]) { + if ((result = sentrycrashjson_beginArray(context, cName)) != SentryCrashJSON_OK) { + return result; + } + for (id subObject in object) { + if ((result = encodeObject(codec, subObject, NULL, context)) != SentryCrashJSON_OK) { + return result; + } + } + return sentrycrashjson_endContainer(context); + } + + if ([object isKindOfClass:[NSDictionary class]]) { + NSDictionary *dict = (NSDictionary *)object; + if ((result = sentrycrashjson_beginObject(context, cName)) != SentryCrashJSON_OK) { + return result; + } + NSArray *keys = [dict allKeys]; + + BOOL allKeysOfSameType = YES; + for (int i = 1; i < [keys count]; i++) { + if ([keys[i - 1] class] != [keys[i] class]) { + allKeysOfSameType = NO; + } + } + + // We can only sort the keys if all of them are of the same type, which is not guaranteed. + // Sorting an array with different types can cause a crash. + if (codec->_sorted && allKeysOfSameType) { + keys = [keys sortedArrayUsingSelector:@selector(compare:)]; + } + + for (id key in keys) { + // It is not guaranteed that a key is NSString. + if ((result = encodeObject(codec, dict[key], [key description], context)) + != SentryCrashJSON_OK) { + return result; + } + } + return sentrycrashjson_endContainer(context); + } + + if ([object isKindOfClass:[NSNull class]]) { + return sentrycrashjson_addNullElement(context, cName); + } + + if ([object isKindOfClass:[NSDate class]]) { + char string[21]; + time_t timestamp = (time_t)((NSDate *)object).timeIntervalSince1970; + sentrycrashdate_utcStringFromTimestamp(timestamp, string); + NSData *data = [NSData dataWithBytes:string length:strnlen(string, 20)]; + return sentrycrashjson_addStringElement(context, cName, data.bytes, (int)data.length); + } + + if ([object isKindOfClass:[NSData class]]) { + NSData *data = (NSData *)object; + return sentrycrashjson_addDataElement(context, cName, data.bytes, (int)data.length); + } + + codec.error = [NSError sentryErrorWithDomain:@"SentryCrashJSONCodecObjC" + code:0 + description:@"Could not determine type of %@", [object class]]; + return SentryCrashJSON_ERROR_INVALID_DATA; +} + +#pragma mark Public API + ++ (NSData *)encode:(id)object + options:(SentryCrashJSONEncodeOption)encodeOptions + error:(NSError *__autoreleasing *)error +{ + NSMutableData *data = [NSMutableData data]; + SentryCrashJSONEncodeContext JSONContext; + sentrycrashjson_beginEncode(&JSONContext, encodeOptions & SentryCrashJSONEncodeOptionPretty, + addJSONData, (__bridge void *)data); + SentryCrashJSONCodec *codec = [self codecWithEncodeOptions:encodeOptions + decodeOptions:SentryCrashJSONDecodeOptionNone]; + + int result = encodeObject(codec, object, NULL, &JSONContext); + if (error != nil) { + *error = codec.error; + } + return result == SentryCrashJSON_OK ? data : nil; +} + ++ (id)decode:(NSData *)JSONData + options:(SentryCrashJSONDecodeOption)decodeOptions + error:(NSError *__autoreleasing *)error +{ + SentryCrashJSONCodec *codec = [self codecWithEncodeOptions:0 decodeOptions:decodeOptions]; + NSMutableData *stringData = [NSMutableData dataWithLength:SentryCrashMAX_STRINGBUFFERSIZE + 1]; + int errorOffset; + int result + = sentrycrashjson_decode(JSONData.bytes, (int)JSONData.length, stringData.mutableBytes, + (int)stringData.length, codec.callbacks, (__bridge void *)codec, &errorOffset); + if (result != SentryCrashJSON_OK && codec.error == nil) { + codec.error = [NSError sentryErrorWithDomain:@"SentryCrashJSONCodecObjC" + code:0 + description:@"%s (offset %d)", + sentrycrashjson_stringForError(result), errorOffset]; + } + if (error != nil) { + *error = codec.error; + } + + if (result != SentryCrashJSON_OK + && !(decodeOptions & SentryCrashJSONDecodeOptionKeepPartialObject)) { + return nil; + } + return codec.topLevelContainer; +} + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashLogger.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashLogger.c new file mode 100644 index 00000000..b626f098 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashLogger.c @@ -0,0 +1,325 @@ +// +// SentryCrashLogger.c +// +// Created by Karl Stenerud on 11-06-25. +// +// Copyright (c) 2011 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashLogger.h" +#include "SentryCrashSystemCapabilities.h" + +// =========================================================================== +#pragma mark - Common - +// =========================================================================== + +#include +#include +#include +#include +#include +#include + +// Compiler hints for "if" statements +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) + +/** The buffer size to use when writing log entries. + * + * If this value is > 0, any log entries that expand beyond this length will + * be truncated. + * If this value = 0, the logging system will dynamically allocate memory + * and never truncate. However, the log functions won't be async-safe. + * + * Unless you're logging from within signal handlers, it's safe to set it to 0. + */ +#ifndef SentryCrashLOGGER_CBufferSize +# define SentryCrashLOGGER_CBufferSize 1024 +#endif + +/** Where console logs will be written */ +static char g_logFilename[1024]; + +/** Write a formatted string to the log. + * + * @param fmt The format string, followed by its arguments. + */ +static void writeFmtToLog(const char *fmt, ...); + +/** Write a formatted string to the log using a vararg list. + * + * @param fmt The format string. + * + * @param args The variable arguments. + */ +static void writeFmtArgsToLog(const char *fmt, va_list args); + +/** Flush the log stream. + */ +static void flushLog(void); + +static inline const char * +lastPathEntry(const char *const path) +{ + const char *lastFile = strrchr(path, '/'); + return lastFile == 0 ? path : lastFile + 1; +} + +static inline void +writeFmtToLog(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + writeFmtArgsToLog(fmt, args); + va_end(args); +} + +#if SentryCrashLOGGER_CBufferSize > 0 + +/** The file descriptor where log entries get written. */ +static int g_fd = -1; + +static void +writeToLog(const char *const str) +{ + if (g_fd >= 0) { + int bytesToWrite = (int)strlen(str); + const char *pos = str; + while (bytesToWrite > 0) { + int bytesWritten = (int)write(g_fd, pos, (unsigned)bytesToWrite); + unlikely_if(bytesWritten == -1) { break; } + bytesToWrite -= bytesWritten; + pos += bytesWritten; + } + } + write(STDOUT_FILENO, str, strlen(str)); +} + +static inline void +writeFmtArgsToLog(const char *fmt, va_list args) +{ + unlikely_if(fmt == NULL) { writeToLog("(null)"); } + else + { + char buffer[SentryCrashLOGGER_CBufferSize]; + vsnprintf(buffer, sizeof(buffer), fmt, args); + writeToLog(buffer); + } +} + +static inline void +flushLog(void) +{ + // Nothing to do. +} + +static inline void +setLogFD(int fd) +{ + if (g_fd >= 0 && g_fd != STDOUT_FILENO && g_fd != STDERR_FILENO && g_fd != STDIN_FILENO) { + close(g_fd); + } + g_fd = fd; +} + +bool +sentrycrashlog_setLogFilename(const char *filename, bool overwrite) +{ + static int fd = -1; + if (filename != NULL) { + int openMask = O_WRONLY | O_CREAT; + if (overwrite) { + openMask |= O_TRUNC; + } + fd = open(filename, openMask, 0644); + unlikely_if(fd < 0) + { + writeFmtToLog("SentryCrashLogger: Could not open %s: %s", filename, strerror(errno)); + return false; + } + if (filename != g_logFilename) { + strncpy(g_logFilename, filename, sizeof(g_logFilename)); + } + } + + setLogFD(fd); + return true; +} + +#else // if SentryCrashLogger_CBufferSize <= 0 + +static FILE *g_file = NULL; + +static inline void +setLogFD(FILE *file) +{ + if (g_file != NULL && g_file != stdout && g_file != stderr && g_file != stdin) { + fclose(g_file); + } + g_file = file; +} + +void +writeToLog(const char *const str) +{ + if (g_file != NULL) { + fprintf(g_file, "%s", str); + } + fprintf(stdout, "%s", str); +} + +static inline void +writeFmtArgsToLog(const char *fmt, va_list args) +{ + unlikely_if(g_file == NULL) { g_file = stdout; } + + if (fmt == NULL) { + writeToLog("(null)"); + } else { + vfprintf(g_file, fmt, args); + } +} + +static inline void +flushLog(void) +{ + fflush(g_file); +} + +bool +sentrycrashlog_setLogFilename(const char *filename, bool overwrite) +{ + static FILE *file = NULL; + FILE *oldFile = file; + if (filename != NULL) { + file = fopen(filename, overwrite ? "wb" : "ab"); + unlikely_if(file == NULL) + { + writeFmtToLog("SentryCrashLogger: Could not open %s: %s", filename, strerror(errno)); + return false; + } + } + if (filename != g_logFilename) { + strncpy(g_logFilename, filename, sizeof(g_logFilename)); + } + + if (oldFile != NULL) { + fclose(oldFile); + } + + setLogFD(file); + return true; +} + +#endif + +bool +sentrycrashlog_clearLogFile() +{ + return sentrycrashlog_setLogFilename(g_logFilename, true); +} + +// =========================================================================== +#pragma mark - C - +// =========================================================================== + +void +i_sentrycrashlog_logCBasic(const char *const fmt, ...) +{ + va_list args; + va_start(args, fmt); + writeFmtArgsToLog(fmt, args); + va_end(args); + writeToLog("\n"); + flushLog(); +} + +void +i_sentrycrashlog_logC(const char *const level, const char *const file, const int line, + const char *const function, const char *const fmt, ...) +{ + writeFmtToLog("%s: %s (%u): %s: ", level, lastPathEntry(file), line, function); + va_list args; + va_start(args, fmt); + writeFmtArgsToLog(fmt, args); + va_end(args); + writeToLog("\n"); + flushLog(); +} + +// =========================================================================== +#pragma mark - Objective-C - +// =========================================================================== + +#if SentryCrashCRASH_HAS_OBJC +# include + +void +i_sentrycrashlog_logObjCBasic(CFStringRef fmt, ...) +{ + if (fmt == NULL) { + writeToLog("(null)"); + return; + } + + va_list args; + va_start(args, fmt); + CFStringRef entry = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, args); + va_end(args); + + int bufferLength = (int)CFStringGetLength(entry) * 4 + 1; + char *stringBuffer = malloc((unsigned)bufferLength); + if (stringBuffer != NULL + && CFStringGetCString(entry, stringBuffer, (CFIndex)bufferLength, kCFStringEncodingUTF8)) { + writeToLog(stringBuffer); + } else { + writeToLog("Could not convert log string to UTF-8. No logging performed."); + } + writeToLog("\n"); + + if (stringBuffer != NULL) { + free(stringBuffer); + } + CFRelease(entry); +} + +void +i_sentrycrashlog_logObjC(const char *const level, const char *const file, const int line, + const char *const function, CFStringRef fmt, ...) +{ + CFStringRef logFmt = NULL; + if (fmt == NULL) { + logFmt = CFStringCreateWithCString(NULL, "%s: %s (%u): %s: (null)", kCFStringEncodingUTF8); + i_sentrycrashlog_logObjCBasic(logFmt, level, lastPathEntry(file), line, function); + } else { + va_list args; + va_start(args, fmt); + CFStringRef entry = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, args); + va_end(args); + + logFmt = CFStringCreateWithCString(NULL, "%s: %s (%u): %s: %@", kCFStringEncodingUTF8); + i_sentrycrashlog_logObjCBasic(logFmt, level, lastPathEntry(file), line, function, entry); + + CFRelease(entry); + } + CFRelease(logFmt); +} +#endif // SentryCrashCRASH_HAS_OBJC diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashLogger.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashLogger.h new file mode 100644 index 00000000..765dc767 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashLogger.h @@ -0,0 +1,373 @@ +// +// SentryCrashLogger.h +// +// Created by Karl Stenerud on 11-06-25. +// +// Copyright (c) 2011 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/** + * SentryCrashLogger + * ======== + * + * Prints log entries to the console consisting of: + * - Level (Error, Warn, Info, Debug, Trace) + * - File + * - Line + * - Function + * - Message + * + * Allows setting the minimum logging level in the preprocessor. + * + * Works in C or Objective-C contexts, with or without ARC, using CLANG or GCC. + * + * + * ===== + * USAGE + * ===== + * + * Set the log level in your "Preprocessor Macros" build setting. You may choose + * TRACE, DEBUG, INFO, WARN, ERROR. If nothing is set, it defaults to ERROR. + * + * Example: SentryCrashLogger_Level=WARN + * + * Anything below the level specified for SentryCrashLogger_Level will not be + * compiled or printed. + * + * + * Next, include the header file: + * + * #include "SentryCrashLogger.h" + * + * + * Next, call the logger functions from your code (using objective-c strings + * in objective-C files and regular strings in regular C files): + * + * Code: + * SentryCrashLOG_ERROR(@"Some error message"); + * + * Prints: + * 2011-07-16 05:41:01.379 TestApp[4439:f803] ERROR: SomeClass.m (21): + * -[SomeFunction]: Some error message + * + * Code: + * SentryCrashLOG_INFO(@"Info about %@", someObject); + * + * Prints: + * 2011-07-16 05:44:05.239 TestApp[4473:f803] INFO : SomeClass.m (20): + * -[SomeFunction]: Info about + * + * + * The "BASIC" versions of the macros behave exactly like NSLog() or printf(), + * except they respect the SentryCrashLogger_Level setting: + * + * Code: + * SentryCrashLOGBASIC_ERROR(@"A basic log entry"); + * + * Prints: + * 2011-07-16 05:44:05.916 TestApp[4473:f803] A basic log entry + * + * + * NOTE: In C files, use "" instead of @"" in the format field. Logging calls + * in C files do not print the NSLog preamble: + * + * Objective-C version: + * SentryCrashLOG_ERROR(@"Some error message"); + * + * 2011-07-16 05:41:01.379 TestApp[4439:f803] ERROR: SomeClass.m (21): + * -[SomeFunction]: Some error message + * + * C version: + * SentryCrashLOG_ERROR("Some error message"); + * + * ERROR: SomeClass.c (21): SomeFunction(): Some error message + * + * + * ============= + * LOCAL LOGGING + * ============= + * + * You can control logging messages at the local file level using the + * "SentryCrashLogger_LocalLevel" define. Note that it must be defined BEFORE + * including SentryCrashLogger.h + * + * The SentryCrashLOG_XX() and SentryCrashLOGBASIC_XX() macros will print out + * based on the LOWER of SentryCrashLogger_Level and + * SentryCrashLogger_LocalLevel, so if SentryCrashLogger_Level is DEBUG and + * SentryCrashLogger_LocalLevel is TRACE, it will print all the way down to the + * trace level for the local file where SentryCrashLogger_LocalLevel was + * defined, and to the debug level everywhere else. + * + * Example: + * + * // SentryCrashLogger_LocalLevel, if defined, MUST come BEFORE including + * SentryCrashLogger.h #define SentryCrashLogger_LocalLevel TRACE #import + * "SentryCrashLogger.h" + * + * + * =============== + * IMPORTANT NOTES + * =============== + * + * The C logger changes its behavior depending on the value of the preprocessor + * define SentryCrashLogger_CBufferSize. + * + * If SentryCrashLogger_CBufferSize is > 0, the C logger will behave in an + * async-safe manner, calling write() instead of printf(). Any log messages that + * exceed the length specified by SentryCrashLogger_CBufferSize will be + * truncated. + * + * If SentryCrashLogger_CBufferSize == 0, the C logger will use printf(), and + * there will be no limit on the log message length. + * + * SentryCrashLogger_CBufferSize can only be set as a preprocessor define, and + * will default to 1024 if not specified during compilation. + */ + +// ============================================================================ +#pragma mark - (internal) - +// ============================================================================ + +#ifndef HDR_SentryCrashLogger_h +# define HDR_SentryCrashLogger_h + +# ifdef __cplusplus +extern "C" { +# endif + +# include + +# ifdef __OBJC__ + +# import + +void i_sentrycrashlog_logObjC( + const char *level, const char *file, int line, const char *function, CFStringRef fmt, ...); + +void i_sentrycrashlog_logObjCBasic(CFStringRef fmt, ...); + +# define i_SentryCrashLOG_FULL(LEVEL, FILE, LINE, FUNCTION, FMT, ...) \ + i_sentrycrashlog_logObjC( \ + LEVEL, FILE, LINE, FUNCTION, (__bridge CFStringRef)FMT, ##__VA_ARGS__) +# define i_SentryCrashLOG_BASIC(FMT, ...) \ + i_sentrycrashlog_logObjCBasic((__bridge CFStringRef)FMT, ##__VA_ARGS__) + +# else // __OBJC__ + +void i_sentrycrashlog_logC( + const char *level, const char *file, int line, const char *function, const char *fmt, ...); + +void i_sentrycrashlog_logCBasic(const char *fmt, ...); + +# define i_SentryCrashLOG_FULL i_sentrycrashlog_logC +# define i_SentryCrashLOG_BASIC i_sentrycrashlog_logCBasic + +# endif // __OBJC__ + +/* Back up any existing defines by the same name */ +# ifdef SentryCrash_NONE +# define SentryCrashLOG_BAK_NONE SentryCrash_NONE +# undef SentryCrash_NONE +# endif +# ifdef ERROR +# define SentryCrashLOG_BAK_ERROR ERROR +# undef ERROR +# endif +# ifdef WARN +# define SentryCrashLOG_BAK_WARN WARN +# undef WARN +# endif +# ifdef INFO +# define SentryCrashLOG_BAK_INFO INFO +# undef INFO +# endif +# ifdef DEBUG +# define SentryCrashLOG_BAK_DEBUG DEBUG +# undef DEBUG +# endif +# ifdef TRACE +# define SentryCrashLOG_BAK_TRACE TRACE +# undef TRACE +# endif + +# define SentryCrashLogger_Level_None 0 +# define SentryCrashLogger_Level_Error 10 +# define SentryCrashLogger_Level_Warn 20 +# define SentryCrashLogger_Level_Info 30 +# define SentryCrashLogger_Level_Debug 40 +# define SentryCrashLogger_Level_Trace 50 + +# define SentryCrash_NONE SentryCrashLogger_Level_None +# define ERROR SentryCrashLogger_Level_Error +# define WARN SentryCrashLogger_Level_Warn +# define INFO SentryCrashLogger_Level_Info +# define DEBUG SentryCrashLogger_Level_Debug +# define TRACE SentryCrashLogger_Level_Trace + +# ifndef SentryCrashLogger_Level +# define SentryCrashLogger_Level SentryCrashLogger_Level_Error +# endif + +# ifndef SentryCrashLogger_LocalLevel +# define SentryCrashLogger_LocalLevel SentryCrashLogger_Level_None +# endif + +# define a_SentryCrashLOG_FULL(LEVEL, FMT, ...) \ + i_SentryCrashLOG_FULL(LEVEL, __FILE__, __LINE__, __PRETTY_FUNCTION__, FMT, ##__VA_ARGS__) + +// ============================================================================ +# pragma mark - API - +// ============================================================================ + +/** Set the filename to log to. + * + * @param filename The file to write to (NULL = write to stdout). + * + * @param overwrite If true, overwrite the log file. + */ +bool sentrycrashlog_setLogFilename(const char *filename, bool overwrite); + +/** Clear the log file. */ +bool sentrycrashlog_clearLogFile(void); + +/** Tests if the logger would print at the specified level. + * + * @param LEVEL The level to test for. One of: + * SentryCrashLogger_Level_Error, + * SentryCrashLogger_Level_Warn, + * SentryCrashLogger_Level_Info, + * SentryCrashLogger_Level_Debug, + * SentryCrashLogger_Level_Trace, + * + * @return TRUE if the logger would print at the specified level. + */ +# define SentryCrashLOG_PRINTS_AT_LEVEL(LEVEL) \ + (SentryCrashLogger_Level >= LEVEL || SentryCrashLogger_LocalLevel >= LEVEL) + +/** Log a message regardless of the log settings. + * Normal version prints out full context. Basic version prints directly. + * + * @param FMT The format specifier, followed by its arguments. + */ +# define SentryCrashLOG_ALWAYS(FMT, ...) a_SentryCrashLOG_FULL("FORCE", FMT, ##__VA_ARGS__) +# define SentryCrashLOGBASIC_ALWAYS(FMT, ...) i_SentryCrashLOG_BASIC(FMT, ##__VA_ARGS__) + +/** Log an error. + * Normal version prints out full context. Basic version prints directly. + * + * @param FMT The format specifier, followed by its arguments. + */ +# if SentryCrashLOG_PRINTS_AT_LEVEL(SentryCrashLogger_Level_Error) +# define SentryCrashLOG_ERROR(FMT, ...) a_SentryCrashLOG_FULL("ERROR", FMT, ##__VA_ARGS__) +# define SentryCrashLOGBASIC_ERROR(FMT, ...) i_SentryCrashLOG_BASIC(FMT, ##__VA_ARGS__) +# else +# define SentryCrashLOG_ERROR(FMT, ...) +# define SentryCrashLOGBASIC_ERROR(FMT, ...) +# endif + +/** Log a warning. + * Normal version prints out full context. Basic version prints directly. + * + * @param FMT The format specifier, followed by its arguments. + */ +# if SentryCrashLOG_PRINTS_AT_LEVEL(SentryCrashLogger_Level_Warn) +# define SentryCrashLOG_WARN(FMT, ...) a_SentryCrashLOG_FULL("WARN ", FMT, ##__VA_ARGS__) +# define SentryCrashLOGBASIC_WARN(FMT, ...) i_SentryCrashLOG_BASIC(FMT, ##__VA_ARGS__) +# else +# define SentryCrashLOG_WARN(FMT, ...) +# define SentryCrashLOGBASIC_WARN(FMT, ...) +# endif + +/** Log an info message. + * Normal version prints out full context. Basic version prints directly. + * + * @param FMT The format specifier, followed by its arguments. + */ +# if SentryCrashLOG_PRINTS_AT_LEVEL(SentryCrashLogger_Level_Info) +# define SentryCrashLOG_INFO(FMT, ...) a_SentryCrashLOG_FULL("INFO ", FMT, ##__VA_ARGS__) +# define SentryCrashLOGBASIC_INFO(FMT, ...) i_SentryCrashLOG_BASIC(FMT, ##__VA_ARGS__) +# else +# define SentryCrashLOG_INFO(FMT, ...) +# define SentryCrashLOGBASIC_INFO(FMT, ...) +# endif + +/** Log a debug message. + * Normal version prints out full context. Basic version prints directly. + * + * @param FMT The format specifier, followed by its arguments. + */ +# if SentryCrashLOG_PRINTS_AT_LEVEL(SentryCrashLogger_Level_Debug) +# define SentryCrashLOG_DEBUG(FMT, ...) a_SentryCrashLOG_FULL("DEBUG", FMT, ##__VA_ARGS__) +# define SentryCrashLOGBASIC_DEBUG(FMT, ...) i_SentryCrashLOG_BASIC(FMT, ##__VA_ARGS__) +# else +# define SentryCrashLOG_DEBUG(FMT, ...) +# define SentryCrashLOGBASIC_DEBUG(FMT, ...) +# endif + +/** Log a trace message. + * Normal version prints out full context. Basic version prints directly. + * + * @param FMT The format specifier, followed by its arguments. + */ +# if SentryCrashLOG_PRINTS_AT_LEVEL(SentryCrashLogger_Level_Trace) +# define SentryCrashLOG_TRACE(FMT, ...) a_SentryCrashLOG_FULL("TRACE", FMT, ##__VA_ARGS__) +# define SentryCrashLOGBASIC_TRACE(FMT, ...) i_SentryCrashLOG_BASIC(FMT, ##__VA_ARGS__) +# else +# define SentryCrashLOG_TRACE(FMT, ...) +# define SentryCrashLOGBASIC_TRACE(FMT, ...) +# endif + +// ============================================================================ +# pragma mark - (internal) - +// ============================================================================ + +/* Put everything back to the way we found it. */ +# undef ERROR +# ifdef SentryCrashLOG_BAK_ERROR +# define ERROR SentryCrashLOG_BAK_ERROR +# undef SentryCrashLOG_BAK_ERROR +# endif +# undef WARNING +# ifdef SentryCrashLOG_BAK_WARN +# define WARNING SentryCrashLOG_BAK_WARN +# undef SentryCrashLOG_BAK_WARN +# endif +# undef INFO +# ifdef SentryCrashLOG_BAK_INFO +# define INFO SentryCrashLOG_BAK_INFO +# undef SentryCrashLOG_BAK_INFO +# endif +# undef DEBUG +# ifdef SentryCrashLOG_BAK_DEBUG +# define DEBUG SentryCrashLOG_BAK_DEBUG +# undef SentryCrashLOG_BAK_DEBUG +# endif +# undef TRACE +# ifdef SentryCrashLOG_BAK_TRACE +# define TRACE SentryCrashLOG_BAK_TRACE +# undef SentryCrashLOG_BAK_TRACE +# endif + +# ifdef __cplusplus +} +# endif + +#endif // HDR_SentryCrashLogger_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMach.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMach.c new file mode 100644 index 00000000..f46f8568 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMach.c @@ -0,0 +1,173 @@ +// +// SentryCrashMach.c +// +// Copyright 2016 Karl Stenerud. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMach.h" + +#include +#include + +#define RETURN_NAME_FOR_ENUM(A) \ + case A: \ + return #A + +const char * +sentrycrashmach_exceptionName(const int64_t exceptionType) +{ + switch (exceptionType) { + RETURN_NAME_FOR_ENUM(EXC_BAD_ACCESS); + RETURN_NAME_FOR_ENUM(EXC_BAD_INSTRUCTION); + RETURN_NAME_FOR_ENUM(EXC_ARITHMETIC); + RETURN_NAME_FOR_ENUM(EXC_EMULATION); + RETURN_NAME_FOR_ENUM(EXC_SOFTWARE); + RETURN_NAME_FOR_ENUM(EXC_BREAKPOINT); + RETURN_NAME_FOR_ENUM(EXC_SYSCALL); + RETURN_NAME_FOR_ENUM(EXC_MACH_SYSCALL); + RETURN_NAME_FOR_ENUM(EXC_RPC_ALERT); + RETURN_NAME_FOR_ENUM(EXC_CRASH); + } + return NULL; +} + +const char * +sentrycrashmach_kernelReturnCodeName(const int64_t returnCode) +{ + switch (returnCode) { + RETURN_NAME_FOR_ENUM(KERN_SUCCESS); + RETURN_NAME_FOR_ENUM(KERN_INVALID_ADDRESS); + RETURN_NAME_FOR_ENUM(KERN_PROTECTION_FAILURE); + RETURN_NAME_FOR_ENUM(KERN_NO_SPACE); + RETURN_NAME_FOR_ENUM(KERN_INVALID_ARGUMENT); + RETURN_NAME_FOR_ENUM(KERN_FAILURE); + RETURN_NAME_FOR_ENUM(KERN_RESOURCE_SHORTAGE); + RETURN_NAME_FOR_ENUM(KERN_NOT_RECEIVER); + RETURN_NAME_FOR_ENUM(KERN_NO_ACCESS); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_FAILURE); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_ERROR); + RETURN_NAME_FOR_ENUM(KERN_ALREADY_IN_SET); + RETURN_NAME_FOR_ENUM(KERN_NOT_IN_SET); + RETURN_NAME_FOR_ENUM(KERN_NAME_EXISTS); + RETURN_NAME_FOR_ENUM(KERN_ABORTED); + RETURN_NAME_FOR_ENUM(KERN_INVALID_NAME); + RETURN_NAME_FOR_ENUM(KERN_INVALID_TASK); + RETURN_NAME_FOR_ENUM(KERN_INVALID_RIGHT); + RETURN_NAME_FOR_ENUM(KERN_INVALID_VALUE); + RETURN_NAME_FOR_ENUM(KERN_UREFS_OVERFLOW); + RETURN_NAME_FOR_ENUM(KERN_INVALID_CAPABILITY); + RETURN_NAME_FOR_ENUM(KERN_RIGHT_EXISTS); + RETURN_NAME_FOR_ENUM(KERN_INVALID_HOST); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_PRESENT); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_DATA_MOVED); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_RESTART_COPY); + RETURN_NAME_FOR_ENUM(KERN_INVALID_PROCESSOR_SET); + RETURN_NAME_FOR_ENUM(KERN_POLICY_LIMIT); + RETURN_NAME_FOR_ENUM(KERN_INVALID_POLICY); + RETURN_NAME_FOR_ENUM(KERN_INVALID_OBJECT); + RETURN_NAME_FOR_ENUM(KERN_ALREADY_WAITING); + RETURN_NAME_FOR_ENUM(KERN_DEFAULT_SET); + RETURN_NAME_FOR_ENUM(KERN_EXCEPTION_PROTECTED); + RETURN_NAME_FOR_ENUM(KERN_INVALID_LEDGER); + RETURN_NAME_FOR_ENUM(KERN_INVALID_MEMORY_CONTROL); + RETURN_NAME_FOR_ENUM(KERN_INVALID_SECURITY); + RETURN_NAME_FOR_ENUM(KERN_NOT_DEPRESSED); + RETURN_NAME_FOR_ENUM(KERN_TERMINATED); + RETURN_NAME_FOR_ENUM(KERN_LOCK_SET_DESTROYED); + RETURN_NAME_FOR_ENUM(KERN_LOCK_UNSTABLE); + RETURN_NAME_FOR_ENUM(KERN_LOCK_OWNED); + RETURN_NAME_FOR_ENUM(KERN_LOCK_OWNED_SELF); + RETURN_NAME_FOR_ENUM(KERN_SEMAPHORE_DESTROYED); + RETURN_NAME_FOR_ENUM(KERN_RPC_SERVER_TERMINATED); + RETURN_NAME_FOR_ENUM(KERN_RPC_TERMINATE_ORPHAN); + RETURN_NAME_FOR_ENUM(KERN_RPC_CONTINUE_ORPHAN); + RETURN_NAME_FOR_ENUM(KERN_NOT_SUPPORTED); + RETURN_NAME_FOR_ENUM(KERN_NODE_DOWN); + RETURN_NAME_FOR_ENUM(KERN_NOT_WAITING); + RETURN_NAME_FOR_ENUM(KERN_OPERATION_TIMED_OUT); + RETURN_NAME_FOR_ENUM(KERN_CODESIGN_ERROR); + } + return NULL; +} + +#define EXC_UNIX_BAD_SYSCALL 0x10000 /* SIGSYS */ +#define EXC_UNIX_BAD_PIPE 0x10001 /* SIGPIPE */ +#define EXC_UNIX_ABORT 0x10002 /* SIGABRT */ + +int +sentrycrashmach_machExceptionForSignal(const int sigNum) +{ + switch (sigNum) { + case SIGFPE: + return EXC_ARITHMETIC; + case SIGSEGV: + return EXC_BAD_ACCESS; + case SIGBUS: + return EXC_BAD_ACCESS; + case SIGILL: + return EXC_BAD_INSTRUCTION; + case SIGTRAP: + return EXC_BREAKPOINT; + case SIGEMT: + return EXC_EMULATION; + case SIGSYS: + return EXC_UNIX_BAD_SYSCALL; + case SIGPIPE: + return EXC_UNIX_BAD_PIPE; + case SIGABRT: + // The Apple reporter uses EXC_CRASH instead of EXC_UNIX_ABORT + return EXC_CRASH; + case SIGKILL: + return EXC_SOFT_SIGNAL; + } + return 0; +} + +int +sentrycrashmach_signalForMachException(const int exception, const mach_exception_code_t code) +{ + switch (exception) { + case EXC_ARITHMETIC: + return SIGFPE; + case EXC_BAD_ACCESS: + return code == KERN_INVALID_ADDRESS ? SIGSEGV : SIGBUS; + case EXC_BAD_INSTRUCTION: + return SIGILL; + case EXC_BREAKPOINT: + return SIGTRAP; + case EXC_EMULATION: + return SIGEMT; + case EXC_SOFTWARE: { + switch (code) { + case EXC_UNIX_BAD_SYSCALL: + return SIGSYS; + case EXC_UNIX_BAD_PIPE: + return SIGPIPE; + case EXC_UNIX_ABORT: + return SIGABRT; + case EXC_SOFT_SIGNAL: + return SIGKILL; + } + break; + } + } + return 0; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMach.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMach.h new file mode 100644 index 00000000..8979eba5 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMach.h @@ -0,0 +1,72 @@ +// +// SentryCrashMach.h +// +// Copyright 2016 Karl Stenerud. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashMach_h +#define HDR_SentryCrashMach_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** Get the name of a mach exception. + * + * @param exceptionType The exception type. + * + * @return The exception's name or NULL if not found. + */ +const char *sentrycrashmach_exceptionName(int64_t exceptionType); + +/** Get the name of a mach kernel return code. + * + * @param returnCode The return code. + * + * @return The code's name or NULL if not found. + */ +const char *sentrycrashmach_kernelReturnCodeName(int64_t returnCode); + +/** Get the signal equivalent of a mach exception. + * + * @param exception The mach exception. + * + * @param code The mach exception code. + * + * @return The matching signal, or 0 if not found. + */ +int sentrycrashmach_signalForMachException(int exception, int64_t code); + +/** Get the mach exception equivalent of a signal. + * + * @param signal The signal. + * + * @return The matching mach exception, or 0 if not found. + */ +int sentrycrashmach_machExceptionForSignal(int signal); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMach_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c new file mode 100644 index 00000000..7b7f4654 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c @@ -0,0 +1,298 @@ +// +// SentryCrashMachineContext.c +// +// Created by Karl Stenerud on 2016-12-02. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMachineContext.h" +#include "SentryCrashCPU.h" +#include "SentryCrashCPU_Apple.h" +#include "SentryCrashMachineContext_Apple.h" +#include "SentryCrashStackCursor_MachineContext.h" +#include "SentryCrashSystemCapabilities.h" + +#include + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#ifdef __arm64__ +# define UC_MCONTEXT uc_mcontext64 +typedef ucontext64_t SignalUserContext; +#else +# define UC_MCONTEXT uc_mcontext +typedef ucontext_t SignalUserContext; +#endif + +static SentryCrashThread g_reservedThreads[10]; +static int g_reservedThreadsMaxIndex = sizeof(g_reservedThreads) / sizeof(g_reservedThreads[0]) - 1; +static int g_reservedThreadsCount = 0; + +static inline bool +isStackOverflow(const SentryCrashMachineContext *const context) +{ + SentryCrashStackCursor stackCursor; + sentrycrashsc_initWithMachineContext( + &stackCursor, SentryCrashSC_STACK_OVERFLOW_THRESHOLD, context); + while (stackCursor.advanceCursor(&stackCursor)) { } + return stackCursor.state.hasGivenUp; +} + +static inline bool +getThreadList(SentryCrashMachineContext *context) +{ + const task_t thisTask = mach_task_self(); + SentryCrashLOG_DEBUG("Getting thread list"); + kern_return_t kr; + thread_act_array_t threads; + mach_msg_type_number_t actualThreadCount; + + if ((kr = task_threads(thisTask, &threads, &actualThreadCount)) != KERN_SUCCESS) { + SentryCrashLOG_ERROR("task_threads: %s", mach_error_string(kr)); + return false; + } + SentryCrashLOG_TRACE("Got %d threads", context->threadCount); + int threadCount = (int)actualThreadCount; + int maxThreadCount = sizeof(context->allThreads) / sizeof(context->allThreads[0]); + if (threadCount > maxThreadCount) { + SentryCrashLOG_ERROR( + "Thread count %d is higher than maximum of %d", threadCount, maxThreadCount); + threadCount = maxThreadCount; + } + for (int i = 0; i < threadCount; i++) { + context->allThreads[i] = threads[i]; + } + context->threadCount = threadCount; + + for (mach_msg_type_number_t i = 0; i < actualThreadCount; i++) { + mach_port_deallocate(thisTask, context->allThreads[i]); + } + vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * actualThreadCount); + + return true; +} + +int +sentrycrashmc_contextSize() +{ + return sizeof(SentryCrashMachineContext); +} + +SentryCrashThread +sentrycrashmc_getThreadFromContext(const SentryCrashMachineContext *const context) +{ + return context->thisThread; +} + +bool +sentrycrashmc_getContextForThread( + SentryCrashThread thread, SentryCrashMachineContext *destinationContext, bool isCrashedContext) +{ + SentryCrashLOG_DEBUG("Fill thread 0x%x context into %p. is crashed = %d", thread, + destinationContext, isCrashedContext); + memset(destinationContext, 0, sizeof(*destinationContext)); + destinationContext->thisThread = (thread_t)thread; + destinationContext->isCurrentThread = thread == sentrycrashthread_self(); + destinationContext->isCrashedContext = isCrashedContext; + destinationContext->isSignalContext = false; + if (sentrycrashmc_canHaveCPUState(destinationContext)) { + sentrycrashcpu_getState(destinationContext); + } + if (sentrycrashmc_isCrashedContext(destinationContext)) { + destinationContext->isStackOverflow = isStackOverflow(destinationContext); + getThreadList(destinationContext); + } + SentryCrashLOG_TRACE("Context retrieved."); + return true; +} + +bool +sentrycrashmc_getContextForSignal( + void *signalUserContext, SentryCrashMachineContext *destinationContext) +{ + SentryCrashLOG_DEBUG( + "Get context from signal user context and put into %p.", destinationContext); + _STRUCT_MCONTEXT *sourceContext = ((SignalUserContext *)signalUserContext)->UC_MCONTEXT; + memcpy(&destinationContext->machineContext, sourceContext, + sizeof(destinationContext->machineContext)); + destinationContext->thisThread = (thread_t)sentrycrashthread_self(); + destinationContext->isCrashedContext = true; + destinationContext->isSignalContext = true; + destinationContext->isStackOverflow = isStackOverflow(destinationContext); + getThreadList(destinationContext); + SentryCrashLOG_TRACE("Context retrieved."); + return true; +} + +void +sentrycrashmc_addReservedThread(SentryCrashThread thread) +{ + int nextIndex = g_reservedThreadsCount; + if (nextIndex > g_reservedThreadsMaxIndex) { + SentryCrashLOG_ERROR( + "Too many reserved threads (%d). Max is %d", nextIndex, g_reservedThreadsMaxIndex); + return; + } + g_reservedThreads[g_reservedThreadsCount++] = thread; +} + +#if SentryCrashCRASH_HAS_THREADS_API +static inline bool +isThreadInList(thread_t thread, SentryCrashThread *list, int listCount) +{ + for (int i = 0; i < listCount; i++) { + if (list[i] == (SentryCrashThread)thread) { + return true; + } + } + return false; +} +#endif + +void +sentrycrashmc_suspendEnvironment() +{ +#if SentryCrashCRASH_HAS_THREADS_API + SentryCrashLOG_DEBUG("Suspending environment."); + kern_return_t kr; + const task_t thisTask = mach_task_self(); + const thread_t thisThread = (thread_t)sentrycrashthread_self(); + thread_act_array_t threads; + mach_msg_type_number_t numThreads; + + if ((kr = task_threads(thisTask, &threads, &numThreads)) != KERN_SUCCESS) { + SentryCrashLOG_ERROR("task_threads: %s", mach_error_string(kr)); + return; + } + + for (mach_msg_type_number_t i = 0; i < numThreads; i++) { + thread_t thread = threads[i]; + if (thread != thisThread + && !isThreadInList(thread, g_reservedThreads, g_reservedThreadsCount)) { + if ((kr = thread_suspend(thread)) != KERN_SUCCESS) { + // Record the error and keep going. + SentryCrashLOG_ERROR("thread_suspend (%08x): %s", thread, mach_error_string(kr)); + } + } + } + + for (mach_msg_type_number_t i = 0; i < numThreads; i++) { + mach_port_deallocate(thisTask, threads[i]); + } + vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads); + + SentryCrashLOG_DEBUG("Suspend complete."); +#endif +} + +void +sentrycrashmc_resumeEnvironment() +{ +#if SentryCrashCRASH_HAS_THREADS_API + SentryCrashLOG_DEBUG("Resuming environment."); + kern_return_t kr; + const task_t thisTask = mach_task_self(); + const thread_t thisThread = (thread_t)sentrycrashthread_self(); + thread_act_array_t threads; + mach_msg_type_number_t numThreads; + + if ((kr = task_threads(thisTask, &threads, &numThreads)) != KERN_SUCCESS) { + SentryCrashLOG_ERROR("task_threads: %s", mach_error_string(kr)); + return; + } + + for (mach_msg_type_number_t i = 0; i < numThreads; i++) { + thread_t thread = threads[i]; + if (thread != thisThread + && !isThreadInList(thread, g_reservedThreads, g_reservedThreadsCount)) { + if ((kr = thread_resume(thread)) != KERN_SUCCESS) { + // Record the error and keep going. + SentryCrashLOG_ERROR("thread_resume (%08x): %s", thread, mach_error_string(kr)); + } + } + } + + for (mach_msg_type_number_t i = 0; i < numThreads; i++) { + mach_port_deallocate(thisTask, threads[i]); + } + vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads); + + SentryCrashLOG_DEBUG("Resume complete."); +#endif +} + +int +sentrycrashmc_getThreadCount(const SentryCrashMachineContext *const context) +{ + return context->threadCount; +} + +SentryCrashThread +sentrycrashmc_getThreadAtIndex(const SentryCrashMachineContext *const context, int index) +{ + return context->allThreads[index]; +} + +int +sentrycrashmc_indexOfThread( + const SentryCrashMachineContext *const context, SentryCrashThread thread) +{ + SentryCrashLOG_TRACE("check thread vs %d threads", context->threadCount); + for (int i = 0; i < (int)context->threadCount; i++) { + SentryCrashLOG_TRACE("%d: %x vs %x", i, thread, context->allThreads[i]); + if (context->allThreads[i] == thread) { + return i; + } + } + return -1; +} + +bool +sentrycrashmc_isCrashedContext(const SentryCrashMachineContext *const context) +{ + return context->isCrashedContext; +} + +static inline bool +isContextForCurrentThread(const SentryCrashMachineContext *const context) +{ + return context->isCurrentThread; +} + +static inline bool +isSignalContext(const SentryCrashMachineContext *const context) +{ + return context->isSignalContext; +} + +bool +sentrycrashmc_canHaveCPUState(const SentryCrashMachineContext *const context) +{ + return !isContextForCurrentThread(context) || isSignalContext(context); +} + +bool +sentrycrashmc_hasValidExceptionRegisters(const SentryCrashMachineContext *const context) +{ + return sentrycrashmc_canHaveCPUState(context) && sentrycrashmc_isCrashedContext(context); +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h new file mode 100644 index 00000000..2a4a7efa --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h @@ -0,0 +1,150 @@ +// +// SentryCrashMachineContext.h +// +// Created by Karl Stenerud on 2016-12-02. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashMachineContext_h +#define HDR_SentryCrashMachineContext_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashThread.h" +#include + +/** Suspend the runtime environment. + */ +void sentrycrashmc_suspendEnvironment(void); + +/** Resume the runtime environment. + */ +void sentrycrashmc_resumeEnvironment(void); + +/** Create a new machine context on the stack. + * This macro creates a storage object on the stack, as well as a pointer of + * type struct SentryCrashMachineContext* in the current scope, which points to + * the storage object. + * + * Example usage: SentryCrashMC_NEW_CONTEXT(a_context); + * This creates a new pointer at the current scope that behaves as if: + * struct SentryCrashMachineContext* a_context = some_storage_location; + * + * @param NAME The C identifier to give the pointer. + */ +#define SentryCrashMC_NEW_CONTEXT(NAME) \ + char sentrycrashmc_##NAME##_storage[sentrycrashmc_contextSize()]; \ + struct SentryCrashMachineContext *NAME \ + = (struct SentryCrashMachineContext *)sentrycrashmc_##NAME##_storage + +struct SentryCrashMachineContext; + +/** Get the internal size of a machine context. + */ +int sentrycrashmc_contextSize(void); + +/** Fill in a machine context from a thread. + * + * @param thread The thread to get information from. + * @param destinationContext The context to fill. + * @param isCrashedContext Used to indicate that this is the thread that + * crashed, + * + * @return true if successful. + */ +bool sentrycrashmc_getContextForThread(SentryCrashThread thread, + struct SentryCrashMachineContext *destinationContext, bool isCrashedContext); + +/** Fill in a machine context from a signal handler. + * A signal handler context is always assumed to be a crashed context. + * + * @param signalUserContext The signal context to get information from. + * @param destinationContext The context to fill. + * + * @return true if successful. + */ +bool sentrycrashmc_getContextForSignal( + void *signalUserContext, struct SentryCrashMachineContext *destinationContext); + +/** Get the thread associated with a machine context. + * + * @param context The machine context. + * + * @return The associated thread. + */ +SentryCrashThread sentrycrashmc_getThreadFromContext( + const struct SentryCrashMachineContext *const context); + +/** Get the number of threads stored in a machine context. + * + * @param context The machine context. + * + * @return The number of threads. + */ +int sentrycrashmc_getThreadCount(const struct SentryCrashMachineContext *const context); + +/** Get a thread from a machine context. + * + * @param context The machine context. + * @param index The index of the thread to retrieve. + * + * @return The thread. + */ +SentryCrashThread sentrycrashmc_getThreadAtIndex( + const struct SentryCrashMachineContext *const context, int index); + +/** Get the index of a thread. + * + * @param context The machine context. + * @param thread The thread. + * + * @return The thread's index, or -1 if it couldn't be determined. + */ +int sentrycrashmc_indexOfThread( + const struct SentryCrashMachineContext *const context, SentryCrashThread thread); + +/** Check if this is a crashed context. + */ +bool sentrycrashmc_isCrashedContext(const struct SentryCrashMachineContext *const context); + +/** Check if this context can have stored CPU state. + */ +bool sentrycrashmc_canHaveCPUState(const struct SentryCrashMachineContext *const context); + +/** Check if this context has valid exception registers. + */ +bool sentrycrashmc_hasValidExceptionRegisters( + const struct SentryCrashMachineContext *const context); + +/** Add a thread to the reserved threads list. + * + * @param thread The thread to add to the list. + */ +void sentrycrashmc_addReservedThread(SentryCrashThread thread); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMachineContext_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext_Apple.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext_Apple.h new file mode 100644 index 00000000..15c2d057 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext_Apple.h @@ -0,0 +1,59 @@ +// +// SentryCrashMachineContext_Apple.h +// +// Created by Karl Stenerud on 2016-12-02. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashMachineContext_Apple_h +#define HDR_SentryCrashMachineContext_Apple_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#ifdef __arm64__ +# define STRUCT_MCONTEXT_L _STRUCT_MCONTEXT64 +#else +# define STRUCT_MCONTEXT_L _STRUCT_MCONTEXT +#endif + +typedef struct SentryCrashMachineContext { + thread_t thisThread; + thread_t allThreads[100]; + int threadCount; + bool isCrashedContext; + bool isCurrentThread; + bool isStackOverflow; + bool isSignalContext; + STRUCT_MCONTEXT_L machineContext; +} SentryCrashMachineContext; + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashMachineContext_Apple_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMemory.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMemory.c new file mode 100644 index 00000000..3e728572 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMemory.c @@ -0,0 +1,139 @@ +// +// SentryCrashMemory.c +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashMemory.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include <_types/_uint8_t.h> +#include + +static inline int +copySafely(const void *restrict const src, void *restrict const dst, const int byteCount) +{ + vm_size_t bytesCopied = 0; + kern_return_t result = vm_read_overwrite( + mach_task_self(), (vm_address_t)src, (vm_size_t)byteCount, (vm_address_t)dst, &bytesCopied); + if (result != KERN_SUCCESS) { + return 0; + } + return (int)bytesCopied; +} + +static inline int +copyMaxPossible(const void *restrict const src, void *restrict const dst, const int byteCount) +{ + const uint8_t *pSrc = src; + const uint8_t *pSrcMax = (uint8_t *)src + byteCount; + const uint8_t *pSrcEnd = (uint8_t *)src + byteCount; + uint8_t *pDst = dst; + + int bytesCopied = 0; + + // Short-circuit if no memory is readable + if (copySafely(src, dst, 1) != 1) { + return 0; + } else if (byteCount <= 1) { + return byteCount; + } + + for (;;) { + int copyLength = (int)(pSrcEnd - pSrc); + if (copyLength <= 0) { + break; + } + + if (copySafely(pSrc, pDst, copyLength) == copyLength) { + bytesCopied += copyLength; + pSrc += copyLength; + pDst += copyLength; + pSrcEnd = pSrc + (pSrcMax - pSrc) / 2; + } else { + if (copyLength <= 1) { + break; + } + pSrcMax = pSrcEnd; + pSrcEnd = pSrc + copyLength / 2; + } + } + return bytesCopied; +} + +static char g_memoryTestBuffer[10240]; +static inline bool +isMemoryReadable(const void *const memory, const int byteCount) +{ + const int testBufferSize = sizeof(g_memoryTestBuffer); + int bytesRemaining = byteCount; + + while (bytesRemaining > 0) { + int bytesToCopy = bytesRemaining > testBufferSize ? testBufferSize : bytesRemaining; + if (copySafely(memory, g_memoryTestBuffer, bytesToCopy) != bytesToCopy) { + break; + } + bytesRemaining -= bytesToCopy; + } + return bytesRemaining == 0; +} + +int +sentrycrashmem_maxReadableBytes(const void *const memory, const int tryByteCount) +{ + const int testBufferSize = sizeof(g_memoryTestBuffer); + const uint8_t *currentPosition = memory; + int bytesRemaining = tryByteCount; + + while (bytesRemaining > testBufferSize) { + if (!isMemoryReadable(currentPosition, testBufferSize)) { + break; + } + currentPosition += testBufferSize; + bytesRemaining -= testBufferSize; + } + bytesRemaining -= copyMaxPossible(currentPosition, g_memoryTestBuffer, testBufferSize); + return tryByteCount - bytesRemaining; +} + +bool +sentrycrashmem_isMemoryReadable(const void *const memory, const int byteCount) +{ + return isMemoryReadable(memory, byteCount); +} + +int +sentrycrashmem_copyMaxPossible( + const void *restrict const src, void *restrict const dst, const int byteCount) +{ + return copyMaxPossible(src, dst, byteCount); +} + +bool +sentrycrashmem_copySafely( + const void *restrict const src, void *restrict const dst, const int byteCount) +{ + return copySafely(src, dst, byteCount); +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMemory.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMemory.h new file mode 100644 index 00000000..b9c9a5d6 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashMemory.h @@ -0,0 +1,89 @@ +// +// SentryCrashMemory.h +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Utility functions for querying the mach kernel. + */ + +#ifndef HDR_sentrycrashmemory_h +#define HDR_sentrycrashmemory_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** Test if the specified memory is safe to read from. + * + * @param memory A pointer to the memory to test. + * @param byteCount The number of bytes to test. + * + * @return True if the memory can be safely read. + */ +bool sentrycrashmem_isMemoryReadable(const void *const memory, const int byteCount); + +/** Test how much memory is readable from the specified pointer. + * + * @param memory A pointer to the memory to test. + * @param tryByteCount The number of bytes to test. + * + * @return The number of bytes that are readable from that address. + */ +int sentrycrashmem_maxReadableBytes(const void *const memory, const int tryByteCount); + +/** Copy memory safely. If the memory is not accessible, returns false + * rather than crashing. + * + * @param src The source location to copy from. + * + * @param dst The location to copy to. + * + * @param byteCount The number of bytes to copy. + * + * @return true if successful. + */ +bool sentrycrashmem_copySafely( + const void *restrict const src, void *restrict const dst, int byteCount); + +/** Copies up to numBytes of data from src to dest, stopping if memory + * becomes inaccessible. + * + * @param src The source location to copy from. + * + * @param dst The location to copy to. + * + * @param byteCount The number of bytes to copy. + * + * @return The number of bytes actually copied. + */ +int sentrycrashmem_copyMaxPossible( + const void *restrict const src, void *restrict const dst, int byteCount); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_sentrycrashmemory_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjC.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjC.c new file mode 100644 index 00000000..a614b30f --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjC.c @@ -0,0 +1,1952 @@ +// +// SentryCrashObjC.c +// +// Created by Karl Stenerud on 2012-08-30. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashObjC.h" +#include "SentryCrashObjCApple.h" + +#include "SentryCrashMemory.h" +#include "SentryCrashString.h" + +#include "SentryCrashLogger.h" + +#if __IPHONE_OS_VERSION_MAX_ALLOWED > 70000 +# include +#else +# if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 \ + || NS_BUILD_32_LIKE_64 +typedef long NSInteger; +typedef unsigned long NSUInteger; +# else +typedef int NSInteger; +typedef unsigned int NSUInteger; +# endif +#endif +#include +#include +#include +#include + +#define kMaxNameLength 128 + +//====================================================================== +#pragma mark - Macros - +//====================================================================== + +// Compiler hints for "if" statements +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) + +//====================================================================== +#pragma mark - Types - +//====================================================================== + +typedef enum { + ClassSubtypeNone = 0, + ClassSubtypeCFArray, + ClassSubtypeNSArrayMutable, + ClassSubtypeNSArrayImmutable, + ClassSubtypeCFString, +} ClassSubtype; + +typedef struct { + const char *name; + SentryCrashObjCClassType type; + ClassSubtype subtype; + bool isMutable; + bool (*isValidObject)(const void *object); + int (*description)(const void *object, char *buffer, int bufferLength); + const void *class; +} ClassData; + +//====================================================================== +#pragma mark - Globals - +//====================================================================== + +// Forward references +static bool objectIsValid(const void *object); +static bool taggedObjectIsValid(const void *object); +static bool stringIsValid(const void *object); +static bool urlIsValid(const void *object); +static bool arrayIsValid(const void *object); +static bool dateIsValid(const void *object); +static bool numberIsValid(const void *object); +static bool taggedDateIsValid(const void *object); +static bool taggedNumberIsValid(const void *object); +static bool taggedStringIsValid(const void *object); + +static int objectDescription(const void *object, char *buffer, int bufferLength); +static int taggedObjectDescription(const void *object, char *buffer, int bufferLength); +static int stringDescription(const void *object, char *buffer, int bufferLength); +static int urlDescription(const void *object, char *buffer, int bufferLength); +static int arrayDescription(const void *object, char *buffer, int bufferLength); +static int dateDescription(const void *object, char *buffer, int bufferLength); +static int numberDescription(const void *object, char *buffer, int bufferLength); +static int taggedDateDescription(const void *object, char *buffer, int bufferLength); +static int taggedNumberDescription(const void *object, char *buffer, int bufferLength); +static int taggedStringDescription(const void *object, char *buffer, int bufferLength); + +static ClassData g_classData[] = { + { "__NSCFString", SentryCrashObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, + stringDescription }, + { "NSCFString", SentryCrashObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, + stringDescription }, + { "__NSCFConstantString", SentryCrashObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, + stringDescription }, + { "NSCFConstantString", SentryCrashObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, + stringDescription }, + { "__NSArray0", SentryCrashObjCClassTypeArray, ClassSubtypeNSArrayImmutable, false, + arrayIsValid, arrayDescription }, + { "__NSArrayI", SentryCrashObjCClassTypeArray, ClassSubtypeNSArrayImmutable, false, + arrayIsValid, arrayDescription }, + { "__NSArrayM", SentryCrashObjCClassTypeArray, ClassSubtypeNSArrayMutable, true, arrayIsValid, + arrayDescription }, + { "__NSCFArray", SentryCrashObjCClassTypeArray, ClassSubtypeCFArray, false, arrayIsValid, + arrayDescription }, + { "NSCFArray", SentryCrashObjCClassTypeArray, ClassSubtypeCFArray, false, arrayIsValid, + arrayDescription }, + { "__NSDate", SentryCrashObjCClassTypeDate, ClassSubtypeNone, false, dateIsValid, + dateDescription }, + { "NSDate", SentryCrashObjCClassTypeDate, ClassSubtypeNone, false, dateIsValid, + dateDescription }, + { "__NSCFNumber", SentryCrashObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, + numberDescription }, + { "NSCFNumber", SentryCrashObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, + numberDescription }, + { "NSNumber", SentryCrashObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, + numberDescription }, + { "NSURL", SentryCrashObjCClassTypeURL, ClassSubtypeNone, false, urlIsValid, urlDescription }, + { NULL, SentryCrashObjCClassTypeUnknown, ClassSubtypeNone, false, objectIsValid, + objectDescription }, +}; + +static ClassData g_taggedClassData[] = { + { "NSAtom", SentryCrashObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, + taggedObjectDescription }, + { NULL, SentryCrashObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, + taggedObjectDescription }, + { "NSString", SentryCrashObjCClassTypeString, ClassSubtypeNone, false, taggedStringIsValid, + taggedStringDescription }, + { "NSNumber", SentryCrashObjCClassTypeNumber, ClassSubtypeNone, false, taggedNumberIsValid, + taggedNumberDescription }, + { "NSIndexPath", SentryCrashObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, + taggedObjectDescription }, + { "NSManagedObjectID", SentryCrashObjCClassTypeUnknown, ClassSubtypeNone, false, + taggedObjectIsValid, taggedObjectDescription }, + { "NSDate", SentryCrashObjCClassTypeDate, ClassSubtypeNone, false, taggedDateIsValid, + taggedDateDescription }, + { NULL, SentryCrashObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, + taggedObjectDescription }, +}; +static int g_taggedClassDataCount = sizeof(g_taggedClassData) / sizeof(*g_taggedClassData); + +static const char *g_blockBaseClassName = "NSBlock"; + +//====================================================================== +#pragma mark - Utility - +//====================================================================== + +#if SUPPORT_TAGGED_POINTERS +static bool +isTaggedPointer(const void *pointer) +{ + return (((uintptr_t)pointer) & TAG_MASK) != 0; +} +static int +getTaggedSlot(const void *pointer) +{ + return (int)((((uintptr_t)pointer) >> TAG_SLOT_SHIFT) & TAG_SLOT_MASK); +} +static uintptr_t +getTaggedPayload(const void *pointer) +{ + return (((uintptr_t)pointer) << TAG_PAYLOAD_LSHIFT) >> TAG_PAYLOAD_RSHIFT; +} +#else +static bool +isTaggedPointer(__unused const void *pointer) +{ + return false; +} +static int +getTaggedSlot(__unused const void *pointer) +{ + return 0; +} +static uintptr_t +getTaggedPayload(const void *pointer) +{ + return (uintptr_t)pointer; +} +#endif + +/** Get class data for a tagged pointer. + * + * @param object The tagged pointer. + * @return The class data. + */ +static const ClassData * +getClassDataFromTaggedPointer(const void *const object) +{ + int slot = getTaggedSlot(object); + return &g_taggedClassData[slot]; +} + +static bool +isValidTaggedPointer(const void *object) +{ + if (isTaggedPointer(object)) { + if (getTaggedSlot(object) <= g_taggedClassDataCount) { + const ClassData *classData = getClassDataFromTaggedPointer(object); + return classData->type != SentryCrashObjCClassTypeUnknown; + } + } + return false; +} + +static const struct class_t * +decodeIsaPointer(const void *const isaPointer) +{ +#if ISA_TAG_MASK + uintptr_t isa = (uintptr_t)isaPointer; + if (isa & ISA_TAG_MASK) { +# if TARGET_OS_IOS && defined(__arm64__) + if (floor(kCFCoreFoundationVersionNumber) <= kCFCoreFoundationVersionNumber_iOS_8_x_Max) { + return (const struct class_t *)(isa & ISA_MASK_OLD); + } + return (const struct class_t *)(isa & ISA_MASK); +# else + return (const struct class_t *)(isa & ISA_MASK); +# endif + } +#endif + return (const struct class_t *)isaPointer; +} + +static const void * +getIsaPointer(const void *const objectOrClassPtr) +{ + // This is wrong. Should not get class data here. + // if(sentrycrashobjc_isTaggedPointer(objectOrClassPtr)) + // { + // return getClassDataFromTaggedPointer(objectOrClassPtr)->class; + // } + + const struct class_t *ptr = objectOrClassPtr; + return decodeIsaPointer(ptr->isa); +} + +static inline struct class_rw_t * +getClassRW(const struct class_t *const class) +{ + uintptr_t ptr = class->data_NEVER_USE & (~WORD_MASK); + return (struct class_rw_t *)ptr; +} + +static inline const struct class_ro_t * +getClassRO(const struct class_t *const class) +{ + class_rw_t *rw = getClassRW(class); + uintptr_t ext_ptr = rw->ro_or_rw_ext; + /* When objc_class_abi_version >= 1, it's a tagged union based on the low bit: + * 0: class_ro_t 1: class_rw_ext_t + * @see https://opensource.apple.com/source/objc4/objc4-781/runtime/objc-runtime-new.h */ + if (ext_ptr & 0x1UL) { + ext_ptr &= ~0x1UL; + struct class_rw_ext_t *rw_ext = (struct class_rw_ext_t *)ext_ptr; + return rw_ext->ro; + } else { + struct class_ro_t *ro = (struct class_ro_t *)ext_ptr; + return ro; + } +} + +static inline const void * +getSuperClass(const void *const classPtr) +{ + const struct class_t *class = classPtr; + return class->superclass; +} + +static inline bool +isMetaClass(const void *const classPtr) +{ + return (getClassRO(classPtr)->flags & RO_META) != 0; +} + +static inline bool +isRootClass(const void *const classPtr) +{ + return (getClassRO(classPtr)->flags & RO_ROOT) != 0; +} + +static inline const char * +getClassName(const void *classPtr) +{ + const struct class_ro_t *ro = getClassRO(classPtr); + return ro->name; +} + +/** Check if a tagged pointer is a number. + * + * @param object The object to query. + * @return true if the tagged pointer is an NSNumber. + */ +static bool +isTaggedPointerNSNumber(const void *const object) +{ + return getTaggedSlot(object) == OBJC_TAG_NSNumber; +} + +/** Check if a tagged pointer is a string. + * + * @param object The object to query. + * @return true if the tagged pointer is an NSString. + */ +static bool +isTaggedPointerNSString(const void *const object) +{ + return getTaggedSlot(object) == OBJC_TAG_NSString; +} + +/** Check if a tagged pointer is a date. + * + * @param object The object to query. + * @return true if the tagged pointer is an NSDate. + */ +static bool +isTaggedPointerNSDate(const void *const object) +{ + return getTaggedSlot(object) == OBJC_TAG_NSDate; +} + +/** Extract an integer from a tagged NSNumber. + * + * @param object The NSNumber object (must be a tagged pointer). + * @return The integer value. + */ +static int64_t +extractTaggedNSNumber(const void *const object) +{ + intptr_t signedPointer = (intptr_t)object; +#if SUPPORT_TAGGED_POINTERS + intptr_t value = (signedPointer << TAG_PAYLOAD_LSHIFT) >> TAG_PAYLOAD_RSHIFT; +#else + intptr_t value = signedPointer & 0; +#endif + + // The lower 4 bits encode type information so shift them out. + return (int64_t)(value >> 4); +} + +static int +getTaggedNSStringLength(const void *const object) +{ + uintptr_t payload = getTaggedPayload(object); + return (int)(payload & 0xf); +} + +static int +extractTaggedNSString(const void *const object, char *buffer, int bufferLength) +{ + int length = getTaggedNSStringLength(object); + int copyLength = ((length + 1) > bufferLength) ? (bufferLength - 1) : length; + uintptr_t payload = getTaggedPayload(object); + uintptr_t value = payload >> 4; + static char *alphabet = "eilotrm.apdnsIc ufkMShjTRxgC4013bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX"; + if (length <= 7) { + for (int i = 0; i < copyLength; i++) { + // ASCII case, limit to bottom 7 bits just in case + buffer[i] = (char)(value & 0x7f); + value >>= 8; + } + } else if (length <= 9) { + for (int i = 0; i < copyLength; i++) { + uintptr_t index = (value >> ((length - 1 - i) * 6)) & 0x3f; + buffer[i] = alphabet[index]; + } + } else if (length <= 11) { + for (int i = 0; i < copyLength; i++) { + uintptr_t index = (value >> ((length - 1 - i) * 5)) & 0x1f; + buffer[i] = alphabet[index]; + } + } else { + buffer[0] = 0; + } + buffer[length] = 0; + + return length; +} + +/** Extract a tagged NSDate's time value as an absolute time. + * + * @param object The NSDate object (must be a tagged pointer). + * @return The date's absolute time. + */ +static CFAbsoluteTime +extractTaggedNSDate(const void *const object) +{ + uintptr_t payload = getTaggedPayload(object); + // Payload is a 60-bit float. Fortunately we can just cast across from + // an integer pointer after shifting out the upper 4 bits. + payload <<= 4; + CFAbsoluteTime value = *((CFAbsoluteTime *)&payload); + return value; +} + +/** Get any special class metadata we have about the specified class. + * It will return a generic metadata object if the type is not recognized. + * + * Note: The Objective-C runtime is free to change a class address, + * so I can't just blindly store class pointers at application start + * and then compare against them later. However, comparing strings is + * slow, so I've reached a compromise. Since I'm omly using this at + * crash time, I can assume that the Objective-C environment is frozen. + * As such, I can keep a cache of discovered classes. If, however, this + * library is used outside of a frozen environment, caching will be + * unreliable. + * + * @param class The class to examine. + * + * @return The associated class data. + */ +static ClassData * +getClassData(const void *class) +{ + const char *className = getClassName(class); + for (ClassData *data = g_classData;; data++) { + unlikely_if(data->name == NULL) { return data; } + unlikely_if(class == data->class) { return data; } + unlikely_if(data->class == NULL && strcmp(className, data->name) == 0) + { + data->class = class; + return data; + } + } +} + +static inline const ClassData * +getClassDataFromObject(const void *object) +{ + if (isTaggedPointer(object)) { + return getClassDataFromTaggedPointer(object); + } + const struct class_t *obj = object; + return getClassData(getIsaPointer(obj)); +} + +static int +stringPrintf(char *buffer, int bufferLength, const char *fmt, ...) +{ + unlikely_if(bufferLength == 0) { return 0; } + + va_list args; + va_start(args, fmt); + int printLength = vsnprintf(buffer, bufferLength, fmt, args); + va_end(args); + + unlikely_if(printLength < 0) + { + *buffer = 0; + return 0; + } + unlikely_if(printLength > bufferLength) { return bufferLength - 1; } + return printLength; +} + +//====================================================================== +#pragma mark - Validation - +//====================================================================== + +// Lookup table for validating class/ivar names and objc @encode types. +// An ivar name must start with a letter, and can contain letters & numbers. +// An ivar type can in theory be any combination of numbers, letters, and +// symbols in the ASCII range (0x21-0x7e). +#define INV 0 // Invalid. +#define N_C 5 // Name character: Valid for anything except the first letter of a name. +#define N_S 7 // Name start character: Valid for anything. +#define T_C 4 // Type character: Valid for types only. + +static const unsigned int g_nameChars[] = { + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + N_C, + N_C, + N_C, + N_C, + N_C, + N_C, + N_C, + N_C, + N_C, + N_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + T_C, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + T_C, + T_C, + T_C, + T_C, + N_S, + T_C, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + N_S, + T_C, + T_C, + T_C, + T_C, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, +}; + +#define VALID_NAME_CHAR(A) ((g_nameChars[(uint8_t)(A)] & 1) != 0) +#define VALID_NAME_START_CHAR(A) ((g_nameChars[(uint8_t)(A)] & 2) != 0) +#define VALID_TYPE_CHAR(A) ((g_nameChars[(uint8_t)(A)] & 7) != 0) + +static bool +isValidName(const char *const name, const int maxLength) +{ + if ((uintptr_t)name + (unsigned)maxLength < (uintptr_t)name) { + // Wrapped around address space. + return false; + } + + char buffer[maxLength]; + int length = sentrycrashmem_copyMaxPossible(name, buffer, maxLength); + if (length == 0 || !VALID_NAME_START_CHAR(name[0])) { + return false; + } + for (int i = 1; i < length; i++) { + unlikely_if(!VALID_NAME_CHAR(name[i])) + { + if (name[i] == 0) { + return true; + } + return false; + } + } + return false; +} + +static bool +isValidIvarType(const char *const type) +{ + char buffer[100]; + const int maxLength = sizeof(buffer); + + if ((uintptr_t)type + maxLength < (uintptr_t)type) { + // Wrapped around address space. + return false; + } + + int length = sentrycrashmem_copyMaxPossible(type, buffer, maxLength); + if (length == 0 || !VALID_TYPE_CHAR(type[0])) { + return false; + } + for (int i = 0; i < length; i++) { + unlikely_if(!VALID_TYPE_CHAR(type[i])) + { + if (type[i] == 0) { + return true; + } + } + } + return false; +} + +static bool +containsValidExtData(class_rw_t *rw) +{ + uintptr_t ext_ptr = rw->ro_or_rw_ext; + if (ext_ptr & 0x1UL) { + ext_ptr &= ~0x1UL; + struct class_rw_ext_t *rw_ext = (struct class_rw_ext_t *)ext_ptr; + if (!sentrycrashmem_isMemoryReadable(rw_ext, sizeof(*rw_ext))) { + return false; + } + } + + return true; +} + +static bool +containsValidROData(const void *const classPtr) +{ + const struct class_t *const class = classPtr; + if (!sentrycrashmem_isMemoryReadable(class, sizeof(*class))) { + return false; + } + class_rw_t *rw = getClassRW(class); + if (!sentrycrashmem_isMemoryReadable(rw, sizeof(*rw))) { + return false; + } + if (!containsValidExtData(rw)) { + return false; + } + const class_ro_t *ro = getClassRO(class); + if (!sentrycrashmem_isMemoryReadable(ro, sizeof(*ro))) { + return false; + } + return true; +} + +static bool +containsValidIvarData(const void *const classPtr) +{ + const struct class_ro_t *ro = getClassRO(classPtr); + const struct ivar_list_t *ivars = ro->ivars; + if (ivars == NULL) { + return true; + } + if (!sentrycrashmem_isMemoryReadable(ivars, sizeof(*ivars))) { + return false; + } + + if (ivars->count > 0) { + struct ivar_t ivar; + uint8_t *ivarPtr = (uint8_t *)(&ivars->first) + ivars->entsizeAndFlags; + for (uint32_t i = 1; i < ivars->count; i++) { + if (!sentrycrashmem_copySafely(ivarPtr, &ivar, sizeof(ivar))) { + return false; + } + if (!sentrycrashmem_isMemoryReadable(ivarPtr, (int)ivars->entsizeAndFlags)) { + return false; + } + if (!sentrycrashmem_isMemoryReadable(ivar.offset, sizeof(*ivar.offset))) { + return false; + } + if (!isValidName(ivar.name, kMaxNameLength)) { + return false; + } + if (!isValidIvarType(ivar.type)) { + return false; + } + ivarPtr += ivars->entsizeAndFlags; + } + } + return true; +} + +static bool +containsValidClassName(const void *const classPtr) +{ + const struct class_ro_t *ro = getClassRO(classPtr); + return isValidName(ro->name, kMaxNameLength); +} + +static bool +hasValidIsaPointer(const void *object) +{ + const struct class_t *isaPtr = getIsaPointer(object); + return sentrycrashmem_isMemoryReadable(isaPtr, sizeof(*isaPtr)); +} + +static inline bool +isValidClass(const void *classPtr) +{ + const class_t *class = classPtr; + if (!sentrycrashmem_isMemoryReadable(class, sizeof(*class))) { + return false; + } + if (!containsValidROData(class)) { + return false; + } + if (!containsValidClassName(class)) { + return false; + } + if (!containsValidIvarData(class)) { + return false; + } + return true; +} + +static inline bool +isValidObject(const void *objectPtr) +{ + if (isTaggedPointer(objectPtr)) { + return isValidTaggedPointer(objectPtr); + } + const class_t *object = objectPtr; + if (!sentrycrashmem_isMemoryReadable(object, sizeof(*object))) { + return false; + } + if (!hasValidIsaPointer(object)) { + return false; + } + if (!isValidClass(getIsaPointer(object))) { + return false; + } + return true; +} + +//====================================================================== +#pragma mark - Basic Objective-C Queries - +//====================================================================== + +const void * +sentrycrashobjc_isaPointer(const void *const objectOrClassPtr) +{ + return getIsaPointer(objectOrClassPtr); +} + +const void * +sentrycrashobjc_superClass(const void *const classPtr) +{ + return getSuperClass(classPtr); +} + +bool +sentrycrashobjc_isMetaClass(const void *const classPtr) +{ + return isMetaClass(classPtr); +} + +bool +sentrycrashobjc_isRootClass(const void *const classPtr) +{ + return isRootClass(classPtr); +} + +const char * +sentrycrashobjc_className(const void *classPtr) +{ + return getClassName(classPtr); +} + +const char * +sentrycrashobjc_objectClassName(const void *objectPtr) +{ + if (isTaggedPointer(objectPtr)) { + if (isValidTaggedPointer(objectPtr)) { + const ClassData *class = getClassDataFromTaggedPointer(objectPtr); + return class->name; + } + return NULL; + } + const void *isaPtr = getIsaPointer(objectPtr); + return getClassName(isaPtr); +} + +bool +sentrycrashobjc_isClassNamed(const void *const classPtr, const char *const className) +{ + const char *name = getClassName(classPtr); + if (name == NULL || className == NULL) { + return false; + } + return strcmp(name, className) == 0; +} + +bool +sentrycrashobjc_isKindOfClass(const void *const classPtr, const char *const className) +{ + if (className == NULL) { + return false; + } + + const struct class_t *class = (const struct class_t *)classPtr; + + for (int i = 0; i < 20; i++) { + const char *name = getClassName(class); + if (name == NULL) { + return false; + } + if (strcmp(className, name) == 0) { + return true; + } + class = class->superclass; + if (!containsValidROData(class)) { + return false; + } + } + return false; +} + +const void * +sentrycrashobjc_baseClass(const void *const classPtr) +{ + const struct class_t *superClass = classPtr; + const struct class_t *subClass = classPtr; + + for (int i = 0; i < 20; i++) { + if (isRootClass(superClass)) { + return subClass; + } + subClass = superClass; + superClass = superClass->superclass; + if (!containsValidROData(superClass)) { + return NULL; + } + } + return NULL; +} + +int +sentrycrashobjc_ivarCount(const void *const classPtr) +{ + const struct ivar_list_t *ivars = getClassRO(classPtr)->ivars; + if (ivars == NULL) { + return 0; + } + return (int)ivars->count; +} + +int +sentrycrashobjc_ivarList(const void *const classPtr, SentryCrashObjCIvar *dstIvars, int ivarsCount) +{ + // TODO: Check this for a possible bad access. + if (dstIvars == NULL) { + return 0; + } + + int count = sentrycrashobjc_ivarCount(classPtr); + if (count == 0) { + return 0; + } + + if (ivarsCount < count) { + count = ivarsCount; + } + const struct ivar_list_t *srcIvars = getClassRO(classPtr)->ivars; + uintptr_t srcPtr = (uintptr_t)&srcIvars->first; + const struct ivar_t *src = (void *)srcPtr; + for (int i = 0; i < count; i++) { + SentryCrashObjCIvar *dst = &dstIvars[i]; + dst->name = src->name; + dst->type = src->type; + dst->index = i; + srcPtr += srcIvars->entsizeAndFlags; + src = (void *)srcPtr; + } + return count; +} + +bool +sentrycrashobjc_ivarNamed(const void *const classPtr, const char *name, SentryCrashObjCIvar *dst) +{ + if (name == NULL) { + return false; + } + const struct ivar_list_t *ivars = getClassRO(classPtr)->ivars; + uintptr_t ivarPtr = (uintptr_t)&ivars->first; + const struct ivar_t *ivar = (void *)ivarPtr; + // For unknown reasons sometimes ivars is null and tests become flakey + if (ivars == NULL) { + return false; + } + for (int i = 0; i < (int)ivars->count; i++) { + if (ivar->name != NULL && strcmp(name, ivar->name) == 0) { + dst->name = ivar->name; + dst->type = ivar->type; + dst->index = i; + return true; + } + ivarPtr += ivars->entsizeAndFlags; + ivar = (void *)ivarPtr; + } + return false; +} + +bool +sentrycrashobjc_ivarValue(const void *const objectPtr, int ivarIndex, void *dst) +{ + if (isTaggedPointer(objectPtr)) { + // Naively assume they want "value". + if (isTaggedPointerNSDate(objectPtr)) { + CFTimeInterval value = extractTaggedNSDate(objectPtr); + memcpy(dst, &value, sizeof(value)); + return true; + } + if (isTaggedPointerNSNumber(objectPtr)) { + // TODO: Correct to assume 64-bit signed int? What does the actual + // ivar say? + int64_t value = extractTaggedNSNumber(objectPtr); + memcpy(dst, &value, sizeof(value)); + return true; + } + return false; + } + + const void *const classPtr = getIsaPointer(objectPtr); + const struct ivar_list_t *ivars = getClassRO(classPtr)->ivars; + if (ivarIndex >= (int)ivars->count) { + return false; + } + uintptr_t ivarPtr = (uintptr_t)&ivars->first; + const struct ivar_t *ivar = (void *)(ivarPtr + ivars->entsizeAndFlags * (unsigned)ivarIndex); + + uintptr_t valuePtr = (uintptr_t)objectPtr + (uintptr_t)*ivar->offset; + if (!sentrycrashmem_copySafely((void *)valuePtr, dst, (int)ivar->size)) { + return false; + } + return true; +} + +uintptr_t +sentrycrashobjc_taggedPointerPayload(const void *taggedObjectPtr) +{ + return getTaggedPayload(taggedObjectPtr); +} + +static inline bool +isBlockClass(const void *class) +{ + const void *baseClass = sentrycrashobjc_baseClass(class); + if (baseClass == NULL) { + return false; + } + const char *name = getClassName(baseClass); + if (name == NULL) { + return false; + } + return strcmp(name, g_blockBaseClassName) == 0; +} + +SentryCrashObjCType +sentrycrashobjc_objectType(const void *objectOrClassPtr) +{ + if (objectOrClassPtr == NULL) { + return SentryCrashObjCTypeUnknown; + } + + if (isTaggedPointer(objectOrClassPtr)) { + return SentryCrashObjCTypeObject; + } + + if (!isValidObject(objectOrClassPtr)) { + return SentryCrashObjCTypeUnknown; + } + + if (!isValidClass(objectOrClassPtr)) { + return SentryCrashObjCTypeUnknown; + } + + const struct class_t *isa = getIsaPointer(objectOrClassPtr); + + if (isBlockClass(isa)) { + return SentryCrashObjCTypeBlock; + } + if (!isMetaClass(isa)) { + return SentryCrashObjCTypeObject; + } + + return SentryCrashObjCTypeClass; +} + +//====================================================================== +#pragma mark - Unknown Object - +//====================================================================== + +static bool +objectIsValid(__unused const void *object) +{ + // If it passed sentrycrashobjc_objectType, it's been validated as much as + // possible. + return true; +} + +static bool +taggedObjectIsValid(const void *object) +{ + return isValidTaggedPointer(object); +} + +static int +objectDescription(const void *object, char *buffer, int bufferLength) +{ + const void *class = getIsaPointer(object); + const char *name = getClassName(class); + uintptr_t objPointer = (uintptr_t)object; + const char *fmt = sizeof(uintptr_t) == sizeof(uint32_t) ? "<%s: 0x%08x>" : "<%s: 0x%016x>"; + return stringPrintf(buffer, bufferLength, fmt, name, objPointer); +} + +static int +taggedObjectDescription(const void *object, char *buffer, int bufferLength) +{ + const ClassData *data = getClassDataFromTaggedPointer(object); + const char *name = data->name; + uintptr_t objPointer = (uintptr_t)object; + const char *fmt = sizeof(uintptr_t) == sizeof(uint32_t) ? "<%s: 0x%08x>" : "<%s: 0x%016x>"; + return stringPrintf(buffer, bufferLength, fmt, name, objPointer); +} + +//====================================================================== +#pragma mark - NSString - +//====================================================================== + +static inline const char * +stringStart(const struct __CFString *str) +{ + return (const char *)__CFStrContents(str) + (__CFStrHasLengthByte(str) ? 1 : 0); +} + +static bool +stringIsValid(const void *const stringPtr) +{ + const struct __CFString *string = stringPtr; + struct __CFString temp; + uint8_t oneByte; + CFIndex length = -1; + if (!sentrycrashmem_copySafely(string, &temp, sizeof(string->base))) { + return false; + } + + if (__CFStrIsInline(string)) { + if (!sentrycrashmem_copySafely( + &string->variants.inline1, &temp, sizeof(string->variants.inline1))) { + return false; + } + length = string->variants.inline1.length; + } else if (__CFStrIsMutable(string)) { + if (!sentrycrashmem_copySafely(&string->variants.notInlineMutable, &temp, + sizeof(string->variants.notInlineMutable))) { + return false; + } + length = string->variants.notInlineMutable.length; + } else if (!__CFStrHasLengthByte(string)) { + if (!sentrycrashmem_copySafely(&string->variants.notInlineImmutable1, &temp, + sizeof(string->variants.notInlineImmutable1))) { + return false; + } + length = string->variants.notInlineImmutable1.length; + } else { + if (!sentrycrashmem_copySafely(&string->variants.notInlineImmutable2, &temp, + sizeof(string->variants.notInlineImmutable2))) { + return false; + } + if (!sentrycrashmem_copySafely(__CFStrContents(string), &oneByte, sizeof(oneByte))) { + return false; + } + length = oneByte; + } + + if (length < 0) { + return false; + } else if (length > 0) { + if (!sentrycrashmem_copySafely(stringStart(string), &oneByte, sizeof(oneByte))) { + return false; + } + } + return true; +} + +int +sentrycrashobjc_stringLength(const void *const stringPtr) +{ + if (isTaggedPointer(stringPtr) && isTaggedPointerNSString(stringPtr)) { + return getTaggedNSStringLength(stringPtr); + } + + const struct __CFString *string = stringPtr; + + if (__CFStrHasExplicitLength(string)) { + if (__CFStrIsInline(string)) { + return (int)string->variants.inline1.length; + } else { + return (int)string->variants.notInlineImmutable1.length; + } + } else { + return *((uint8_t *)__CFStrContents(string)); + } +} + +#define kUTF16_LeadSurrogateStart 0xd800u +#define kUTF16_LeadSurrogateEnd 0xdbffu +#define kUTF16_TailSurrogateStart 0xdc00u +#define kUTF16_TailSurrogateEnd 0xdfffu +#define kUTF16_FirstSupplementaryPlane 0x10000u + +static int +copyAndConvertUTF16StringToUTF8( + const void *const src, void *const dst, int charCount, int maxByteCount) +{ + const uint16_t *pSrc = src; + uint8_t *pDst = dst; + const uint8_t *const pDstEnd = pDst + maxByteCount - 1; // Leave room for null termination. + for (int charsRemaining = charCount; charsRemaining > 0 && pDst < pDstEnd; charsRemaining--) { + // Decode UTF-16 + uint32_t character = 0; + uint16_t leadSurrogate = *pSrc++; + likely_if( + leadSurrogate < kUTF16_LeadSurrogateStart || leadSurrogate > kUTF16_TailSurrogateEnd) + { + character = leadSurrogate; + } + else if (leadSurrogate > kUTF16_LeadSurrogateEnd) + { + // Inverted surrogate + *((uint8_t *)dst) = 0; + return 0; + } + else + { + uint16_t tailSurrogate = *pSrc++; + if (tailSurrogate < kUTF16_TailSurrogateStart + || tailSurrogate > kUTF16_TailSurrogateEnd) { + // Invalid tail surrogate + *((uint8_t *)dst) = 0; + return 0; + } + character = ((leadSurrogate - kUTF16_LeadSurrogateStart) << 10) + + (tailSurrogate - kUTF16_TailSurrogateStart); + character += kUTF16_FirstSupplementaryPlane; + charsRemaining--; + } + + // Encode UTF-8 + likely_if(character <= 0x7f) { *pDst++ = (uint8_t)character; } + else if (character <= 0x7ff) + { + if (pDstEnd - pDst >= 2) { + *pDst++ = (uint8_t)(0xc0 | (character >> 6)); + *pDst++ = (uint8_t)(0x80 | (character & 0x3f)); + } else { + break; + } + } + else if (character <= 0xffff) + { + if (pDstEnd - pDst >= 3) { + *pDst++ = (uint8_t)(0xe0 | (character >> 12)); + *pDst++ = (uint8_t)(0x80 | ((character >> 6) & 0x3f)); + *pDst++ = (uint8_t)(0x80 | (character & 0x3f)); + } else { + break; + } + } + // RFC3629 restricts UTF-8 to end at 0x10ffff. + else if (character <= 0x10ffff) + { + if (pDstEnd - pDst >= 4) { + *pDst++ = (uint8_t)(0xf0 | (character >> 18)); + *pDst++ = (uint8_t)(0x80 | ((character >> 12) & 0x3f)); + *pDst++ = (uint8_t)(0x80 | ((character >> 6) & 0x3f)); + *pDst++ = (uint8_t)(0x80 | (character & 0x3f)); + } else { + break; + } + } + else + { + // Invalid unicode. + *((uint8_t *)dst) = 0; + return 0; + } + } + + // Null terminate and return. + *pDst = 0; + return (int)(pDst - (uint8_t *)dst); +} + +static int +copy8BitString(const void *const src, void *const dst, int charCount, int maxByteCount) +{ + unlikely_if(maxByteCount == 0) { return 0; } + unlikely_if(charCount == 0) + { + *((uint8_t *)dst) = 0; + return 0; + } + + unlikely_if(charCount >= maxByteCount) { charCount = maxByteCount - 1; } + unlikely_if(!sentrycrashmem_copySafely(src, dst, charCount)) + { + *((uint8_t *)dst) = 0; + return 0; + } + uint8_t *charDst = dst; + charDst[charCount] = 0; + return charCount; +} + +int +sentrycrashobjc_copyStringContents(const void *stringPtr, char *dst, int maxByteCount) +{ + if (isTaggedPointer(stringPtr) && isTaggedPointerNSString(stringPtr)) { + return extractTaggedNSString(stringPtr, dst, maxByteCount); + } + const struct __CFString *string = stringPtr; + int charCount = sentrycrashobjc_stringLength(string); + + const char *src = stringStart(string); + if (__CFStrIsUnicode(string)) { + return copyAndConvertUTF16StringToUTF8(src, dst, charCount, maxByteCount); + } + + return copy8BitString(src, dst, charCount, maxByteCount); +} + +static int +stringDescription(const void *object, char *buffer, int bufferLength) +{ + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + + pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": \""); + pBuffer += sentrycrashobjc_copyStringContents(object, pBuffer, (int)(pEnd - pBuffer)); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), "\""); + + return (int)(pBuffer - buffer); +} + +static bool +taggedStringIsValid(const void *const object) +{ + return isValidTaggedPointer(object) && isTaggedPointerNSString(object); +} + +static int +taggedStringDescription(const void *object, char *buffer, __unused int bufferLength) +{ + return extractTaggedNSString(object, buffer, bufferLength); +} + +//====================================================================== +#pragma mark - NSURL - +//====================================================================== + +static bool +urlIsValid(const void *const urlPtr) +{ + struct __CFURL url; + if (!sentrycrashmem_copySafely(urlPtr, &url, sizeof(url))) { + return false; + } + return stringIsValid(url._string); +} + +int +sentrycrashobjc_copyURLContents(const void *const urlPtr, char *dst, int maxLength) +{ + const struct __CFURL *url = urlPtr; + return sentrycrashobjc_copyStringContents(url->_string, dst, maxLength); +} + +static int +urlDescription(const void *object, char *buffer, int bufferLength) +{ + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + + pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": \""); + pBuffer += sentrycrashobjc_copyURLContents(object, pBuffer, (int)(pEnd - pBuffer)); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), "\""); + + return (int)(pBuffer - buffer); +} + +//====================================================================== +#pragma mark - NSDate - +//====================================================================== + +static bool +dateIsValid(const void *const datePtr) +{ + struct __CFDate temp; + return sentrycrashmem_copySafely(datePtr, &temp, sizeof(temp)); +} + +CFAbsoluteTime +sentrycrashobjc_dateContents(const void *const datePtr) +{ + if (isValidTaggedPointer(datePtr)) { + return extractTaggedNSDate(datePtr); + } + const struct __CFDate *date = datePtr; + return date->_time; +} + +static int +dateDescription(const void *object, char *buffer, int bufferLength) +{ + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + + CFAbsoluteTime time = sentrycrashobjc_dateContents(object); + pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": %f", time); + + return (int)(pBuffer - buffer); +} + +static bool +taggedDateIsValid(const void *const datePtr) +{ + return isValidTaggedPointer(datePtr) && isTaggedPointerNSDate(datePtr); +} + +static int +taggedDateDescription(const void *object, char *buffer, int bufferLength) +{ + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + + CFAbsoluteTime time = extractTaggedNSDate(object); + pBuffer += taggedObjectDescription(object, pBuffer, (int)(pEnd - pBuffer)); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": %f", time); + + return (int)(pBuffer - buffer); +} + +//====================================================================== +#pragma mark - NSNumber - +//====================================================================== + +#define NSNUMBER_CASE(CFTYPE, RETURN_TYPE, CAST_TYPE, DATA) \ + case CFTYPE: { \ + RETURN_TYPE result; \ + memcpy(&result, DATA, sizeof(result)); \ + return (CAST_TYPE)result; \ + } + +#define EXTRACT_AND_RETURN_NSNUMBER(OBJECT, RETURN_TYPE) \ + if (isValidTaggedPointer(object)) { \ + return extractTaggedNSNumber(object); \ + } \ + const struct __CFNumber *number = OBJECT; \ + CFNumberType cftype = CFNumberGetType((CFNumberRef)OBJECT); \ + const void *data = &(number->_pad); \ + switch (cftype) { \ + NSNUMBER_CASE(kCFNumberSInt8Type, int8_t, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberSInt16Type, int16_t, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberSInt32Type, int32_t, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberSInt64Type, int64_t, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberFloat32Type, Float32, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberFloat64Type, Float64, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberCharType, char, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberShortType, short, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberIntType, int, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberLongType, long, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberLongLongType, long long, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberFloatType, float, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberDoubleType, double, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberCFIndexType, CFIndex, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberNSIntegerType, NSInteger, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberCGFloatType, CGFloat, RETURN_TYPE, data) \ + } + +Float64 +sentrycrashobjc_numberAsFloat(const void *object) +{ + EXTRACT_AND_RETURN_NSNUMBER(object, Float64); + return NAN; +} + +int64_t +sentrycrashobjc_numberAsInteger(const void *object) +{ + EXTRACT_AND_RETURN_NSNUMBER(object, int64_t); + return 0; +} + +bool +sentrycrashobjc_numberIsFloat(const void *object) +{ + return CFNumberIsFloatType((CFNumberRef)object); +} + +static bool +numberIsValid(const void *const datePtr) +{ + struct __CFNumber temp; + return sentrycrashmem_copySafely(datePtr, &temp, sizeof(temp)); +} + +static int +numberDescription(const void *object, char *buffer, int bufferLength) +{ + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + + pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); + + if (sentrycrashobjc_numberIsFloat(object)) { + Float64 value = sentrycrashobjc_numberAsFloat(object); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": %lf", value); + } else { + int64_t value = sentrycrashobjc_numberAsInteger(object); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": %" PRId64, value); + } + + return (int)(pBuffer - buffer); +} + +static bool +taggedNumberIsValid(const void *const object) +{ + return isValidTaggedPointer(object) && isTaggedPointerNSNumber(object); +} + +static int +taggedNumberDescription(const void *object, char *buffer, int bufferLength) +{ + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + + int64_t value = extractTaggedNSNumber(object); + pBuffer += taggedObjectDescription(object, pBuffer, (int)(pEnd - pBuffer)); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": %" PRId64, value); + + return (int)(pBuffer - buffer); +} + +//====================================================================== +#pragma mark - NSArray - +//====================================================================== + +struct NSArray { + struct { + void *isa; + CFIndex count; + id firstEntry; + } basic; +}; + +static inline bool +nsarrayIsMutable(const void *const arrayPtr) +{ + return getClassDataFromObject(arrayPtr)->isMutable; +} + +static inline bool +nsarrayIsValid(const void *const arrayPtr) +{ + struct NSArray temp; + return sentrycrashmem_copySafely(arrayPtr, &temp, sizeof(temp.basic)); +} + +static inline int +nsarrayCount(const void *const arrayPtr) +{ + const struct NSArray *array = arrayPtr; + return array->basic.count < 0 ? 0 : (int)array->basic.count; +} + +static int +nsarrayContents(const void *const arrayPtr, uintptr_t *contents, int count) +{ + const struct NSArray *array = arrayPtr; + + if (array->basic.count < (CFIndex)count) { + if (array->basic.count <= 0) { + return 0; + } + count = (int)array->basic.count; + } + // TODO: implement this (requires bit-field unpacking) in + // sentrycrashobj_ivarValue + if (nsarrayIsMutable(arrayPtr)) { + return 0; + } + + if (!sentrycrashmem_copySafely( + &array->basic.firstEntry, contents, (int)sizeof(*contents) * count)) { + return 0; + } + return count; +} + +static inline bool +cfarrayIsValid(const void *const arrayPtr) +{ + struct __CFArray temp; + if (!sentrycrashmem_copySafely(arrayPtr, &temp, sizeof(temp))) { + return false; + } + const struct __CFArray *array = arrayPtr; + if (__CFArrayGetType(array) == __kCFArrayDeque) { + if (array->_store != NULL) { + struct __CFArrayDeque deque; + if (!sentrycrashmem_copySafely(array->_store, &deque, sizeof(deque))) { + return false; + } + } + } + return true; +} + +static inline const void * +cfarrayData(const void *const arrayPtr) +{ + return __CFArrayGetBucketsPtr(arrayPtr); +} + +static inline int +cfarrayCount(const void *const arrayPtr) +{ + const struct __CFArray *array = arrayPtr; + return array->_count < 0 ? 0 : (int)array->_count; +} + +static int +cfarrayContents(const void *const arrayPtr, uintptr_t *contents, int count) +{ + const struct __CFArray *array = arrayPtr; + if (array->_count < (CFIndex)count) { + if (array->_count <= 0) { + return 0; + } + count = (int)array->_count; + } + + const void *firstEntry = cfarrayData(array); + if (!sentrycrashmem_copySafely(firstEntry, contents, (int)sizeof(*contents) * count)) { + return 0; + } + return count; +} + +static bool +isCFArray(const void *const arrayPtr) +{ + const ClassData *data = getClassDataFromObject(arrayPtr); + return data->subtype == ClassSubtypeCFArray; +} + +int +sentrycrashobjc_arrayCount(const void *const arrayPtr) +{ + if (isCFArray(arrayPtr)) { + return cfarrayCount(arrayPtr); + } + return nsarrayCount(arrayPtr); +} + +int +sentrycrashobjc_arrayContents(const void *const arrayPtr, uintptr_t *contents, int count) +{ + if (isCFArray(arrayPtr)) { + return cfarrayContents(arrayPtr, contents, count); + } + return nsarrayContents(arrayPtr, contents, count); +} + +bool +arrayIsValid(const void *object) +{ + if (isCFArray(object)) { + return cfarrayIsValid(object); + } + return nsarrayIsValid(object); +} + +static int +arrayDescription(const void *object, char *buffer, int bufferLength) +{ + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + + pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": ["); + + if (pBuffer < pEnd - 1 && sentrycrashobjc_arrayCount(object) > 0) { + uintptr_t contents = 0; + if (sentrycrashobjc_arrayContents(object, &contents, 1) == 1) { + pBuffer + += sentrycrashobjc_getDescription((void *)contents, pBuffer, (int)(pEnd - pBuffer)); + } + } + pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), "]"); + + return (int)(pBuffer - buffer); +} + +//====================================================================== +#pragma mark - NSDictionary (BROKEN) - +//====================================================================== + +bool +sentrycrashobjc_dictionaryFirstEntry(const void *dict, uintptr_t *key, uintptr_t *value) +{ + // TODO: This is broken. + + // Ensure memory is valid. + struct __CFBasicHash copy; + if (!sentrycrashmem_copySafely(dict, ©, sizeof(copy))) { + return false; + } + + struct __CFBasicHash *ht = (struct __CFBasicHash *)dict; + uintptr_t *keys = (uintptr_t *)ht->pointers + ht->bits.keys_offset; + uintptr_t *values = (uintptr_t *)ht->pointers; + + // Dereference key and value pointers. + if (!sentrycrashmem_copySafely(keys, &keys, sizeof(keys))) { + return false; + } + + if (!sentrycrashmem_copySafely(values, &values, sizeof(values))) { + return false; + } + + // Copy to destination. + if (!sentrycrashmem_copySafely(keys, key, sizeof(*key))) { + return false; + } + if (!sentrycrashmem_copySafely(values, value, sizeof(*value))) { + return false; + } + return true; +} + +int +sentrycrashobjc_dictionaryCount(const void *dict) +{ + // TODO: Implement me +#pragma unused(dict) + return 0; +} + +//====================================================================== +#pragma mark - General Queries - +//====================================================================== + +int +sentrycrashobjc_getDescription(void *object, char *buffer, int bufferLength) +{ + const ClassData *data = getClassDataFromObject(object); + return data->description(object, buffer, bufferLength); +} + +bool +sentrycrashobjc_isTaggedPointer(const void *const pointer) +{ + return isTaggedPointer(pointer); +} + +bool +sentrycrashobjc_isValidTaggedPointer(const void *const pointer) +{ + return isValidTaggedPointer(pointer); +} + +bool +sentrycrashobjc_isValidObject(const void *object) +{ + if (!isValidObject(object)) { + return false; + } + const ClassData *data = getClassDataFromObject(object); + return data->isValidObject(object); +} + +SentryCrashObjCClassType +sentrycrashobjc_objectClassType(const void *object) +{ + const ClassData *data = getClassDataFromObject(object); + return data->type; +} + +//__NSArrayReversed +//__NSCFBoolean +//__NSCFDictionary +//__NSCFError +//__NSCFNumber +//__NSCFSet +//__NSCFString +//__NSDate +//__NSDictionaryI +//__NSDictionaryM +//__NSOrderedSetArrayProxy +//__NSOrderedSetI +//__NSOrderedSetM +//__NSOrderedSetReversed +//__NSOrderedSetSetProxy +//__NSPlaceholderArray +//__NSPlaceholderDate +//__NSPlaceholderDictionary +//__NSPlaceholderOrderedSet +//__NSPlaceholderSet +//__NSSetI +//__NSSetM +// NSArray +// NSCFArray +// NSCFBoolean +// NSCFDictionary +// NSCFError +// NSCFNumber +// NSCFSet +// NSCheapMutableString +// NSClassicHashTable +// NSClassicMapTable +// SConcreteHashTable +// NSConcreteMapTable +// NSConcreteValue +// NSDate +// NSDecimalNumber +// NSDecimalNumberPlaceholder +// NSDictionary +// NSError +// NSException +// NSHashTable +// NSMutableArray +// NSMutableDictionary +// NSMutableIndexSet +// NSMutableOrderedSet +// NSMutableRLEArray +// NSMutableSet +// NSMutableString +// NSMutableStringProxy +// NSNumber +// NSOrderedSet +// NSPlaceholderMutableString +// NSPlaceholderNumber +// NSPlaceholderString +// NSRLEArray +// NSSet +// NSSimpleCString +// NSString +// NSURL diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjC.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjC.h new file mode 100644 index 00000000..70d5f582 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjC.h @@ -0,0 +1,397 @@ +// +// SentryCrashObjC.h +// +// Created by Karl Stenerud on 2012-08-30. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashObjC_h +#define HDR_SentryCrashObjC_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef enum { + SentryCrashObjCTypeUnknown = 0, + SentryCrashObjCTypeClass, + SentryCrashObjCTypeObject, + SentryCrashObjCTypeBlock, +} SentryCrashObjCType; + +typedef enum { + SentryCrashObjCClassTypeUnknown = 0, + SentryCrashObjCClassTypeString, + SentryCrashObjCClassTypeDate, + SentryCrashObjCClassTypeURL, + SentryCrashObjCClassTypeArray, + SentryCrashObjCClassTypeDictionary, + SentryCrashObjCClassTypeNumber, + SentryCrashObjCClassTypeException, +} SentryCrashObjCClassType; + +typedef struct { + const char *name; + const char *type; + int index; +} SentryCrashObjCIvar; + +//====================================================================== +#pragma mark - Basic Objective-C Queries - +//====================================================================== + +/** Check if a pointer is a tagged pointer or not. + * + * @param pointer The pointer to check. + * @return true if it's a tagged pointer. + */ +bool sentrycrashobjc_isTaggedPointer(const void *const pointer); + +/** Check if a pointer is a valid tagged pointer. + * + * @param pointer The pointer to check. + * @return true if it's a valid tagged pointer. + */ +bool sentrycrashobjc_isValidTaggedPointer(const void *const pointer); + +/** Query a pointer to see what kind of object it points to. + * If the pointer points to a class, this method will verify that its basic + * class data and ivars are valid, + * If the pointer points to an object, it will verify the object data (if + * recognized as a common class), and the isa's basic class info (everything + * except ivars). + * + * Warning: In order to ensure that an object is both valid and accessible, + * always call this method on an object or class pointer (including + * those returned by sentrycrashobjc_isaPointer() and + * sentrycrashobjc_superclass()) BEFORE calling any other function in this + * module. + * + * @param objectOrClassPtr Pointer to something that may be an object or class. + * + * @return The type of object, or SentryCrashObjCTypeNone if it was not an + * object or was inaccessible. + */ +SentryCrashObjCType sentrycrashobjc_objectType(const void *objectOrClassPtr); + +/** Check that an object contains valid data. + * If the object is of a recognized type (string, date, array, etc), + * this function will verify that its internal data is intact. + * + * Call this function before calling any object-specific functions. + * + * @param object The object to verify. + * + * @return true if the object is valid. + */ +bool sentrycrashobjc_isValidObject(const void *object); + +/** Fetch the isa pointer from an object or class. + * + * @param objectOrClassPtr Pointer to a valid object or class. + * + * @return The isa pointer. + */ +const void *sentrycrashobjc_isaPointer(const void *objectOrClassPtr); + +/** Fetch the super class pointer from a class. + * + * @param classPtr Pointer to a valid class. + * + * @return the super class. + */ +const void *sentrycrashobjc_superClass(const void *classPtr); + +/** Get the base class this class is derived from. + * It will always return the highest level non-root class in the hierarchy + * (one below NSObject or NSProxy), unless the passed in object or class + * actually is a root class. + * + * @param classPtr Pointer to a valid class. + * + * @return The base class. + */ +const void *sentrycrashobjc_baseClass(const void *const classPtr); + +/** Check if a class is a meta class. + * + * @param classPtr Pointer to a valid class. + * + * @return true if the class is a meta class. + */ +bool sentrycrashobjc_isMetaClass(const void *classPtr); + +/** Check if a class is a root class. + * + * @param classPtr Pointer to a valid class. + * + * @return true if the class is a root class. + */ +bool sentrycrashobjc_isRootClass(const void *classPtr); + +/** Get the name of a class. + * + * @param classPtr Pointer to a valid class. + * + * @return the name, or NULL if the name inaccessible. + */ +const char *sentrycrashobjc_className(const void *classPtr); + +/** Get the name of an object's class. + * This also handles tagged pointers. + * + * @param objectPtr Pointer to a valid object. + * + * @return the name, or NULL if the name is inaccessible. + */ +const char *sentrycrashobjc_objectClassName(const void *objectPtr); + +/** Check if a class has a specific name. + * + * @param classPtr Pointer to a valid class. + * + * @param className The class name to compare against. + * + * @return true if the class has the specified name. + */ +bool sentrycrashobjc_isClassNamed(const void *const classPtr, const char *const className); + +/** Check if a class is of the specified type or a subclass thereof. + * Note: This function is considerably slower than + * sentrycrashobjc_baseClassName(). + * + * @param classPtr Pointer to a valid class. + * + * @param className The class name to compare against. + * + * @return true if the class is of the specified type or a subclass of that + * type. + */ +bool sentrycrashobjc_isKindOfClass(const void *classPtr, const char *className); + +/** Get the number of ivars registered with a class. + * + * @param classPtr Pointer to a valid class. + * + * @return The number of ivars. + */ +int sentrycrashobjc_ivarCount(const void *classPtr); + +/** Get information about ivars in a class. + * + * @param classPtr Pointer to a valid class. + * + * @param dstIvars Buffer to hold ivar data. + * + * @param ivarsCount The number of ivars the buffer can hold. + * + * @return The number of ivars copied. + */ +int sentrycrashobjc_ivarList(const void *classPtr, SentryCrashObjCIvar *dstIvars, int ivarsCount); + +/** Get ivar information by name/ + * + * @param classPtr Pointer to a valid class. + * + * @param name The name of the ivar to get information about. + * + * @param dst Buffer to hold the result. + * + * @return true if the operation was successful. + */ +bool sentrycrashobjc_ivarNamed( + const void *const classPtr, const char *name, SentryCrashObjCIvar *dst); + +/** Get the value of an ivar in an object. + * + * @param objectPtr Pointer to a valid object. + * + * @param ivarIndex The index of the ivar to fetch. + * + * @param dst Pointer to buffer big enough to contain the data. + * + * @return true if the operation was successful. + */ +bool sentrycrashobjc_ivarValue(const void *objectPtr, int ivarIndex, void *dst); + +/* Get the payload from a tagged pointer. + * + * @param objectPtr Pointer to a valid object. + * + * @return the payload value. + */ +uintptr_t sentrycrashobjc_taggedPointerPayload(const void *taggedObjectPtr); + +/** Generate a description of an object. + * + * For known common object classes it will print extra information. + * For all other objects, it will print a standard + * + * For containers, it will only print the first object in the container. + * + * buffer will be null terminated unless bufferLength is 0. + * If the string doesn't fit, it will be truncated. + * + * @param object the object to generate a description for. + * + * @param buffer The buffer to copy into. + * + * @param bufferLength The length of the buffer. + * + * @return the number of bytes copied (not including null terminator). + */ +int sentrycrashobjc_getDescription(void *object, char *buffer, int bufferLength); + +/** Get the class type of an object. + * There are a number of common class types that SentryCrashObjC understamds, + * listed in SentryCrashObjCClassType. + * + * @param object The object to query. + * + * @return The class type, or SentryCrashObjCClassTypeUnknown if it couldn't be + * determined. + */ +SentryCrashObjCClassType sentrycrashobjc_objectClassType(const void *object); + +//====================================================================== +#pragma mark - Object-Specific Queries - +//====================================================================== + +/** Check if a number was stored as floating point. + * + * @param object The number to query. + * @return true if the number is floating point. + */ +bool sentrycrashobjc_numberIsFloat(const void *object); + +/** Get the contents of a number as a floating point value. + * + * @param object The number. + * @return The value. + */ +double sentrycrashobjc_numberAsFloat(const void *object); + +/** Get the contents of a number as an integer value. + * If the number was stored as floating point, it will be + * truncated as per C's conversion rules. + * + * @param object The number. + * @return The value. + */ +int64_t sentrycrashobjc_numberAsInteger(const void *object); + +/** Copy the contents of a date object. + * + * @param datePtr The date to copy data from. + * + * @return Time interval since Jan 1 2001 00:00:00 GMT. + */ +double sentrycrashobjc_dateContents(const void *datePtr); + +/** Copy the contents of a URL object. + * + * dst will be null terminated unless maxLength is 0. + * If the string doesn't fit, it will be truncated. + * + * @param nsurl The URL to copy data from. + * + * @param dst The destination to copy into. + * + * @param maxLength The size of the buffer. + * + * @return the number of bytes copied (not including null terminator). + */ +int sentrycrashobjc_copyURLContents(const void *nsurl, char *dst, int maxLength); + +/** Get the length of a string in characters. + * + * @param stringPtr Pointer to a string. + * + * @return The length of the string. + */ +int sentrycrashobjc_stringLength(const void *const stringPtr); + +/** Copy the contents of a string object. + * + * dst will be null terminated unless maxLength is 0. + * If the string doesn't fit, it will be truncated. + * + * @param string The string to copy data from. + * + * @param dst The destination to copy into. + * + * @param maxLength The size of the buffer. + * + * @return the number of bytes copied (not including null terminator). + */ +int sentrycrashobjc_copyStringContents(const void *string, char *dst, int maxLength); + +/** Get an NSArray's count. + * + * @param arrayPtr The array to get the count from. + * + * @return The array's count. + */ +int sentrycrashobjc_arrayCount(const void *arrayPtr); + +/** Get an NSArray's contents. + * + * @param arrayPtr The array to get the contents of. + * + * @param contents Location to copy the array's contents into. + * + * @param count The number of objects to copy. + * + * @return The number of items copied. + */ +int sentrycrashobjc_arrayContents(const void *arrayPtr, uintptr_t *contents, int count); + +//====================================================================== +#pragma mark - Broken/Unimplemented Stuff - +//====================================================================== + +/** Get the first entry from an NSDictionary. + * + * WARNING: This function is broken! + * + * @param dict The dictionary to copy from. + * + * @param key Location to copy the first key into. + * + * @param value Location to copy the first value into. + * + * @return true if the operation was successful. + */ +bool sentrycrashobjc_dictionaryFirstEntry(const void *dict, uintptr_t *key, uintptr_t *value); + +/** UNIMPLEMENTED + */ +int sentrycrashobjc_dictionaryCount(const void *dict); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashObjC_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjCApple.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjCApple.h new file mode 100644 index 00000000..7a5e419e --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashObjCApple.h @@ -0,0 +1,768 @@ +// +// SentryCrashObjCApple.h +// +// Created by Karl Stenerud on 2012-08-30. +// +// Copyright (c) 2011 Apple Inc. All rights reserved. +// +// This file contains Original Code and/or Modifications of Original Code +// as defined in and that are subject to the Apple Public Source License +// Version 2.0 (the 'License'). You may not use this file except in +// compliance with the License. Please obtain a copy of the License at +// http://www.opensource.apple.com/apsl/ and read it before using this +// file. +// + +// This file contains structures and constants copied from Apple header +// files, arranged for use in SentryCrashObjC. + +#ifndef HDR_SentryCrashObjCApple_h +#define HDR_SentryCrashObjCApple_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define MAKE_LIST_T(TYPE) \ + typedef struct TYPE##_list_t { \ + uint32_t entsizeAndFlags; \ + uint32_t count; \ + TYPE##_t first; \ + } TYPE##_list_t; \ + typedef TYPE##_list_t TYPE##_array_t + +#define OBJC_OBJECT(NAME) \ + NAME \ + { \ + Class isa OBJC_ISA_AVAILABILITY; + +// ====================================================================== +#pragma mark - objc4-680/runtime/objc-msg-x86_64.s - +// and objc4-680/runtime/objc-msg-arm64.s +// ====================================================================== + +#if __x86_64__ +# define ISA_TAG_MASK 1UL +# define ISA_MASK 0x00007ffffffffff8UL +#elif defined(__arm64__) +# define ISA_TAG_MASK 1UL +# define ISA_MASK_OLD 0x00000001fffffff8UL +# define ISA_MASK 0x0000000ffffffff8UL +#else +# define ISA_TAG_MASK 0UL +# define ISA_MASK ~1UL +#endif + +// ====================================================================== +#pragma mark - objc4-680/runtime/objc-config.h - +// ====================================================================== + +// Define SUPPORT_TAGGED_POINTERS=1 to enable tagged pointer objects +// Be sure to edit tagged pointer SPI in objc-internal.h as well. +#if !(__LP64__) +# define SUPPORT_TAGGED_POINTERS 0 +#else +# define SUPPORT_TAGGED_POINTERS 1 +#endif + +// Define SUPPORT_MSB_TAGGED_POINTERS to use the MSB +// as the tagged pointer marker instead of the LSB. +// Be sure to edit tagged pointer SPI in objc-internal.h as well. +#if !SUPPORT_TAGGED_POINTERS || !TARGET_OS_IPHONE +# define SUPPORT_MSB_TAGGED_POINTERS 0 +#else +# define SUPPORT_MSB_TAGGED_POINTERS 1 +#endif + +// ====================================================================== +#pragma mark - objc4-680/runtime/objc-object.h - +// ====================================================================== + +#if SUPPORT_TAGGED_POINTERS + +// SentryCrash: The original values wouldn't have worked. The slot shift and +// mask were incorrect. +# define TAG_COUNT 8 +//#define TAG_SLOT_MASK 0xf +# define TAG_SLOT_MASK 0x07 + +# if SUPPORT_MSB_TAGGED_POINTERS +# define TAG_MASK (1ULL << 63) +# define TAG_SLOT_SHIFT 60 +# define TAG_PAYLOAD_LSHIFT 4 +# define TAG_PAYLOAD_RSHIFT 4 +# else +# define TAG_MASK 1 +//# define TAG_SLOT_SHIFT 0 +# define TAG_SLOT_SHIFT 1 +# define TAG_PAYLOAD_LSHIFT 0 +# define TAG_PAYLOAD_RSHIFT 4 +# endif + +#endif + +// ====================================================================== +#pragma mark - objc4-781/runtime/objc-internal.h - +// ====================================================================== +#if __ARM_ARCH_7K__ >= 2 || (__arm64__ && !__LP64__) +# define SUPPORT_INDEXED_ISA 1 +#else +# define SUPPORT_INDEXED_ISA 0 +#endif + +// ====================================================================== +#pragma mark - objc4-680/runtime/objc-internal.h - +// ====================================================================== + +enum { + OBJC_TAG_NSAtom = 0, + OBJC_TAG_1 = 1, + OBJC_TAG_NSString = 2, + OBJC_TAG_NSNumber = 3, + OBJC_TAG_NSIndexPath = 4, + OBJC_TAG_NSManagedObjectID = 5, + OBJC_TAG_NSDate = 6, + OBJC_TAG_7 = 7 +}; + +// ====================================================================== +#pragma mark - objc4-680/runtime/objc-os.h - +// ====================================================================== + +#ifdef __LP64__ +# define WORD_SHIFT 3UL +# define WORD_MASK 7UL +# define WORD_BITS 64 +#else +# define WORD_SHIFT 2UL +# define WORD_MASK 3UL +# define WORD_BITS 32 +#endif + +// ====================================================================== +#pragma mark - objc4-680/runtime/runtime.h - +// ====================================================================== + +typedef struct objc_cache *Cache; + +// ====================================================================== +#pragma mark - objc4-680/runtime/objc-runtime-new.h - +// ====================================================================== + +typedef struct method_t { + SEL name; + const char *types; + IMP imp; +} method_t; + +MAKE_LIST_T(method); + +typedef struct ivar_t { +#if __x86_64__ + // *offset was originally 64-bit on some x86_64 platforms. + // We read and write only 32 bits of it. + // Some metadata provides all 64 bits. This is harmless for unsigned + // little-endian values. + // Some code uses all 64 bits. class_addIvar() over-allocates the + // offset for their benefit. +#endif + int32_t *offset; + const char *name; + const char *type; + // alignment is sometimes -1; use alignment() instead + uint32_t alignment_raw; + uint32_t size; +} ivar_t; + +MAKE_LIST_T(ivar); + +typedef struct property_t { + const char *name; + const char *attributes; +} property_t; + +MAKE_LIST_T(property); + +typedef struct OBJC_OBJECT(protocol_t) const char *mangledName; +struct protocol_list_t *protocols; +method_list_t *instanceMethods; +method_list_t *classMethods; +method_list_t *optionalInstanceMethods; +method_list_t *optionalClassMethods; +property_list_t *instanceProperties; +uint32_t size; // sizeof(protocol_t) +uint32_t flags; +// Fields below this point are not always present on disk. +const char **extendedMethodTypes; +const char *_demangledName; +} +protocol_t; + +MAKE_LIST_T(protocol); + +// Values for class_ro_t->flags +// These are emitted by the compiler and are part of the ABI. +// class is a metaclass +#define RO_META (1 << 0) +// class is a root class +#define RO_ROOT (1 << 1) + +typedef struct class_ro_t { + uint32_t flags; + uint32_t instanceStart; + uint32_t instanceSize; +#ifdef __LP64__ + uint32_t reserved; +#endif + + const uint8_t *ivarLayout; + + const char *name; + method_list_t *baseMethodList; + protocol_list_t *baseProtocols; + const ivar_list_t *ivars; + + const uint8_t *weakIvarLayout; + property_list_t *baseProperties; +} class_ro_t; + +struct class_rw_ext_t { + const class_ro_t *ro; + method_array_t methods; + property_array_t properties; + protocol_array_t protocols; + char *demangledName; + uint32_t version; +}; + +typedef struct class_rw_t { + uint32_t flags; + uint16_t witness; +#if SUPPORT_INDEXED_ISA + uint16_t index; +#endif + uintptr_t ro_or_rw_ext; + Class firstSubclass; + Class nextSiblingClass; +} class_rw_t; + +typedef struct class_t { + struct class_t *isa; + struct class_t *superclass; +#pragma clang diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + Cache cache; +#pragma clang diagnostic pop + IMP *vtable; + uintptr_t data_NEVER_USE; // class_rw_t * plus custom rr/alloc flags +} class_t; + +// ====================================================================== +#pragma mark - CF-1153.18/CFRuntime.h - +// ====================================================================== + +typedef struct __CFRuntimeBase { + uintptr_t _cfisa; + uint8_t _cfinfo[4]; +#if __LP64__ + uint32_t _rc; +#endif +} CFRuntimeBase; + +// ====================================================================== +#pragma mark - CF-1153.18/CFInternal.h - +// ====================================================================== + +#if defined(__BIG_ENDIAN__) +# define __CF_BIG_ENDIAN__ 1 +# define __CF_LITTLE_ENDIAN__ 0 +#endif + +#if defined(__LITTLE_ENDIAN__) +# define __CF_LITTLE_ENDIAN__ 1 +# define __CF_BIG_ENDIAN__ 0 +#endif + +#define CF_INFO_BITS (!!(__CF_BIG_ENDIAN__)*3) +#define CF_RC_BITS (!!(__CF_LITTLE_ENDIAN__)*3) + +/* Bit manipulation macros */ +/* Bits are numbered from 31 on left to 0 on right */ +/* May or may not work if you use them on bitfields in types other than UInt32, + * bitfields the full width of a UInt32, or anything else for which they were + * not designed. */ +/* In the following, N1 and N2 specify an inclusive range N2..N1 with N1 >= N2 + */ +#define __CFBitfieldMask(N1, N2) ((((UInt32)~0UL) << (31UL - (N1) + (N2))) >> (31UL - N1)) +#define __CFBitfieldGetValue(V, N1, N2) (((V)&__CFBitfieldMask(N1, N2)) >> (N2)) + +// ====================================================================== +#pragma mark - CF-1153.18/CFString.c - +// ====================================================================== + +// This is separate for C++ +struct __notInlineMutable { + void *buffer; + CFIndex length; + CFIndex capacity; // Capacity in bytes + unsigned int hasGap : 1; // Currently unused + unsigned int isFixedCapacity : 1; + unsigned int isExternalMutable : 1; + unsigned int capacityProvidedExternally : 1; +#if __LP64__ + unsigned long desiredCapacity : 60; +#else + unsigned long desiredCapacity : 28; +#endif + CFAllocatorRef contentsAllocator; // Optional +}; // The only mutable variant for CFString + +/* !!! Never do sizeof(CFString); the union is here just to make it easier to + * access some fields. + */ +struct __CFString { + CFRuntimeBase base; + union { // In many cases the allocated structs are smaller than these + struct __inline1 { + CFIndex length; + } inline1; // Bytes follow the length + struct __notInlineImmutable1 { + void *buffer; // Note that the buffer is in the same place for all + // non-inline variants of CFString + CFIndex length; + CFAllocatorRef contentsDeallocator; // Optional; just the dealloc func is used + } notInlineImmutable1; // This is the usual not-inline immutable + // CFString + struct __notInlineImmutable2 { + void *buffer; + CFAllocatorRef contentsDeallocator; // Optional; just the dealloc func is used + } notInlineImmutable2; // This is the not-inline immutable CFString when + // length is stored with the contents (first + // byte) + struct __notInlineMutable notInlineMutable; + } variants; +}; + +/* + I = is immutable + E = not inline contents + U = is Unicode + N = has NULL byte + L = has length byte + D = explicit deallocator for contents (for mutable objects, allocator) + C = length field is CFIndex (rather than UInt32); only meaningful for 64-bit, + really if needed this bit (valuable real-estate) can be given up for another + bit elsewhere, since this info is needed just for 64-bit + + Also need (only for mutable) + F = is fixed + G = has gap + Cap, DesCap = capacity + + B7 B6 B5 B4 B3 B2 B1 B0 + U N L C I + + B6 B5 + 0 0 inline contents + 0 1 E (freed with default allocator) + 1 0 E (not freed) + 1 1 E D + + !!! Note: Constant CFStrings use the bit patterns: + C8 (11001000 = default allocator, not inline, not freed contents; 8-bit; has + NULL byte; doesn't have length; is immutable) D0 (11010000 = default allocator, + not inline, not freed contents; Unicode; is immutable) The bit usages should + not be modified in a way that would effect these bit patterns. + */ + +enum { + __kCFFreeContentsWhenDoneMask = 0x020, + __kCFFreeContentsWhenDone = 0x020, + __kCFContentsMask = 0x060, + __kCFHasInlineContents = 0x000, + __kCFNotInlineContentsNoFree = 0x040, // Don't free + __kCFNotInlineContentsDefaultFree = 0x020, // Use allocator's free function + __kCFNotInlineContentsCustomFree = 0x060, // Use a specially provided free function + __kCFHasContentsAllocatorMask = 0x060, + __kCFHasContentsAllocator = 0x060, // (For mutable strings) use a specially provided allocator + __kCFHasContentsDeallocatorMask = 0x060, + __kCFHasContentsDeallocator = 0x060, + __kCFIsMutableMask = 0x01, + __kCFIsMutable = 0x01, + __kCFIsUnicodeMask = 0x10, + __kCFIsUnicode = 0x10, + __kCFHasNullByteMask = 0x08, + __kCFHasNullByte = 0x08, + __kCFHasLengthByteMask = 0x04, + __kCFHasLengthByte = 0x04, + // !!! Bit 0x02 has been freed up +}; + +// !!! Assumptions: +// Mutable strings are not inline +// Compile-time constant strings are not inline +// Mutable strings always have explicit length (but they might also have length +// byte and null byte) If there is an explicit length, always use that instead +// of the length byte (length byte is useful for quickly returning pascal +// strings) Never look at the length byte for the length; use __CFStrLength or +// __CFStrLength2 + +/* The following set of functions and macros need to be updated on change to the + * bit configuration + */ +CF_INLINE Boolean +__CFStrIsMutable(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsMutableMask) == __kCFIsMutable; +} +CF_INLINE Boolean +__CFStrIsInline(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & __kCFContentsMask) == __kCFHasInlineContents; +} +CF_INLINE Boolean +__CFStrFreeContentsWhenDone(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & __kCFFreeContentsWhenDoneMask) + == __kCFFreeContentsWhenDone; +} +CF_INLINE Boolean +__CFStrHasContentsDeallocator(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasContentsDeallocatorMask) + == __kCFHasContentsDeallocator; +} +CF_INLINE Boolean +__CFStrIsUnicode(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsUnicodeMask) == __kCFIsUnicode; +} +CF_INLINE Boolean +__CFStrIsEightBit(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsUnicodeMask) != __kCFIsUnicode; +} +CF_INLINE Boolean +__CFStrHasNullByte(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasNullByteMask) == __kCFHasNullByte; +} +CF_INLINE Boolean +__CFStrHasLengthByte(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasLengthByteMask) == __kCFHasLengthByte; +} +CF_INLINE Boolean +__CFStrHasExplicitLength(CFStringRef str) +{ + return (str->base._cfinfo[CF_INFO_BITS] & (__kCFIsMutableMask | __kCFHasLengthByteMask)) + != __kCFHasLengthByte; +} // Has explicit length if (1) mutable or (2) not mutable and no length byte +CF_INLINE Boolean +__CFStrIsConstant(CFStringRef str) +{ +#if __LP64__ + return str->base._rc == 0; +#else + return (str->base._cfinfo[CF_RC_BITS]) == 0; +#endif +} + +/* Returns ptr to the buffer (which might include the length byte). + */ +CF_INLINE const void * +__CFStrContents(CFStringRef str) +{ + if (__CFStrIsInline(str)) { + return (const void *)(((uintptr_t) & (str->variants)) + + (__CFStrHasExplicitLength(str) ? sizeof(CFIndex) : 0)); + } else { // Not inline; pointer is always word 2 + return str->variants.notInlineImmutable1.buffer; + } +} + +// ====================================================================== +#pragma mark - CF-1153.18/CFURL.c - +// ====================================================================== + +struct __CFURL { + CFRuntimeBase _cfBase; + UInt32 _flags; + CFStringEncoding _encoding; // The encoding to use when asked to remove percent escapes + CFStringRef _string; // Never NULL + CFURLRef _base; + struct _CFURLAdditionalData *_extra; + void *_resourceInfo; // For use by CoreServicesInternal to cache property + // values. Retained and released by CFURL. + CFRange _ranges[1]; // variable length (1 to 9) array of ranges +}; + +// ====================================================================== +#pragma mark - CF-1153.18/CFDate.c - +// ====================================================================== + +struct __CFDate { + // According to CFDate.c the structure is a CFRuntimeBase followed + // by the time. In fact, it's only an isa pointer followed by the time. + // struct CFRuntimeBase _base; + uintptr_t _cfisa; + CFAbsoluteTime _time; /* immutable */ +}; + +// ====================================================================== +#pragma mark - CF-1153.18/CFNumber.c - +// ====================================================================== + +struct __CFNumber { + CFRuntimeBase _base; + uint64_t _pad; // need this space here for the constant objects + /* 0 or 8 more bytes allocated here */ +}; + +// ====================================================================== +#pragma mark - CF-1153.18/CFArray.c - +// ====================================================================== + +struct __CFArrayBucket { + const void *_item; +}; + +struct __CFArrayDeque { + uintptr_t _leftIdx; + uintptr_t _capacity; + /* struct __CFArrayBucket buckets follow here */ +}; + +struct __CFArray { + CFRuntimeBase _base; + CFIndex _count; /* number of objects */ + CFIndex _mutations; + int32_t _mutInProgress; + /* __strong */ void *_store; /* can be NULL when MutableDeque */ +}; + +/* Flag bits */ +enum { /* Bits 0-1 */ + __kCFArrayImmutable = 0, + __kCFArrayDeque = 2, +}; + +enum { /* Bits 2-3 */ + __kCFArrayHasNullCallBacks = 0, + __kCFArrayHasCFTypeCallBacks = 1, + __kCFArrayHasCustomCallBacks = 3 /* callbacks are at end of header */ +}; + +CF_INLINE CFIndex +__CFArrayGetType(CFArrayRef array) +{ + return __CFBitfieldGetValue(((const CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 1, 0); +} + +CF_INLINE CFIndex +__CFArrayGetSizeOfType(CFIndex t) +{ + CFIndex size = 0; + size += sizeof(struct __CFArray); + if (__CFBitfieldGetValue((unsigned long)t, 3, 2) == __kCFArrayHasCustomCallBacks) { + size += sizeof(CFArrayCallBacks); + } + return size; +} + +/* Only applies to immutable and mutable-deque-using arrays; + * Returns the bucket holding the left-most real value in the latter case. */ +CF_INLINE struct __CFArrayBucket * +__CFArrayGetBucketsPtr(CFArrayRef array) +{ + switch (__CFArrayGetType(array)) { + case __kCFArrayImmutable: + return (struct __CFArrayBucket *)((uint8_t *)array + + __CFArrayGetSizeOfType(((CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS])); + case __kCFArrayDeque: { + struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store; + return (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque) + + deque->_leftIdx * sizeof(struct __CFArrayBucket)); + } + } + return NULL; +} + +// ====================================================================== +#pragma mark - CF-1153.18/CFBasicHash.h - +// ====================================================================== + +typedef struct __CFBasicHash *CFBasicHashRef; +typedef const struct __CFBasicHash *CFConstBasicHashRef; + +typedef struct __CFBasicHashCallbacks CFBasicHashCallbacks; + +struct __CFBasicHashCallbacks { + uintptr_t (*retainValue)(CFAllocatorRef alloc, + uintptr_t stack_value); // Return 2nd arg or new value + uintptr_t (*retainKey)(CFAllocatorRef alloc, uintptr_t stack_key); // Return 2nd arg or new key + void (*releaseValue)(CFAllocatorRef alloc, uintptr_t stack_value); + void (*releaseKey)(CFAllocatorRef alloc, uintptr_t stack_key); + Boolean (*equateValues)(uintptr_t coll_value1, + uintptr_t stack_value2); // 1st arg is in-collection value, 2nd arg is + // probe parameter OR in-collection value for a + // second collection + Boolean (*equateKeys)(uintptr_t coll_key1, + uintptr_t stack_key2); // 1st arg is in-collection key, 2nd arg is probe + // parameter + CFHashCode (*hashKey)(uintptr_t stack_key); + uintptr_t (*getIndirectKey)(uintptr_t coll_value); // Return key; 1st arg is in-collection value + CFStringRef (*copyValueDescription)(uintptr_t stack_value); + CFStringRef (*copyKeyDescription)(uintptr_t stack_key); +}; + +// ====================================================================== +#pragma mark - CF-1153.18/CFBasicHash.c - +// ====================================================================== + +// Prime numbers. Values above 100 have been adjusted up so that the +// malloced block size will be just below a multiple of 512; values +// above 1200 have been adjusted up to just below a multiple of 4096. +static const uintptr_t __CFBasicHashTableSizes[64] = { + 0, + 3, + 7, + 13, + 23, + 41, + 71, + 127, + 191, + 251, + 383, + 631, + 1087, + 1723, + 2803, + 4523, + 7351, + 11959, + 19447, + 31231, + 50683, + 81919, + 132607, + 214519, + 346607, + 561109, + 907759, + 1468927, + 2376191, + 3845119, + 6221311, + 10066421, + 16287743, + 26354171, + 42641881, + 68996069, + 111638519, + 180634607, + 292272623, + 472907251, +#if __LP64__ + 765180413UL, + 1238087663UL, + 2003267557UL, + 3241355263UL, + 5244622819UL, +# if 0 + 8485977589UL, 13730600407UL, 22216578047UL, 35947178479UL, + 58163756537UL, 94110934997UL, 152274691561UL, 246385626107UL, + 398660317687UL, 645045943807UL, 1043706260983UL, 1688752204787UL, + 2732458465769UL, 4421210670577UL, 7153669136377UL, + 11574879807461UL, 18728548943849UL, 30303428750843UL +# endif +#endif +}; + +typedef union { + uintptr_t neutral; + void *Xstrong; // Changed from type 'id' + void *Xweak; // Changed from type 'id' +} CFBasicHashValue; + +struct __CFBasicHash { + CFRuntimeBase base; + struct { // 192 bits + uint16_t mutations; + uint8_t hash_style : 2; + uint8_t keys_offset : 1; + uint8_t counts_offset : 2; + uint8_t counts_width : 2; + uint8_t hashes_offset : 2; + uint8_t strong_values : 1; + uint8_t strong_keys : 1; + uint8_t weak_values : 1; + uint8_t weak_keys : 1; + uint8_t int_values : 1; + uint8_t int_keys : 1; + uint8_t indirect_keys : 1; + uint32_t used_buckets; /* number of used buckets */ + uint64_t deleted : 16; + uint64_t num_buckets_idx : 8; /* index to number of buckets */ + uint64_t __kret : 10; + uint64_t __vret : 10; + uint64_t __krel : 10; + uint64_t __vrel : 10; + uint64_t __ : 1; + uint64_t null_rc : 1; + uint64_t fast_grow : 1; + uint64_t finalized : 1; + uint64_t __kdes : 10; + uint64_t __vdes : 10; + uint64_t __kequ : 10; + uint64_t __vequ : 10; + uint64_t __khas : 10; + uint64_t __kget : 10; + } bits; + void *pointers[1]; +}; + +CF_INLINE CFBasicHashValue * +__CFBasicHashGetValues(CFConstBasicHashRef ht) +{ + return (CFBasicHashValue *)ht->pointers[0]; +} + +CF_INLINE CFBasicHashValue * +__CFBasicHashGetKeys(CFConstBasicHashRef ht) +{ + return (CFBasicHashValue *)ht->pointers[ht->bits.keys_offset]; +} + +CF_INLINE void * +__CFBasicHashGetCounts(CFConstBasicHashRef ht) +{ + return (void *)ht->pointers[ht->bits.counts_offset]; +} + +CF_INLINE uintptr_t +__CFBasicHashGetSlotCount(CFConstBasicHashRef ht, CFIndex idx) +{ + void *counts = __CFBasicHashGetCounts(ht); + switch (ht->bits.counts_width) { + case 0: + return ((uint8_t *)counts)[idx]; + case 1: + return ((uint16_t *)counts)[idx]; + case 2: + return ((uint32_t *)counts)[idx]; + case 3: + return (uintptr_t)((uint64_t *)counts)[idx]; + } + return 0; +} + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashObjCApple_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.c new file mode 100644 index 00000000..c8c5069f --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.c @@ -0,0 +1,170 @@ +// +// SentryCrashSignalInfo.c +// +// Created by Karl Stenerud on 2012-02-03. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashSignalInfo.h" + +#include +#include + +typedef struct { + const int code; + const char *const name; +} SentryCrashSignalCodeInfo; + +typedef struct { + const int sigNum; + const char *const name; + const SentryCrashSignalCodeInfo *const codes; + const int numCodes; +} SentryCrashSignalInfo; + +#define ENUM_NAME_MAPPING(A) \ + { \ + A, #A \ + } + +static const SentryCrashSignalCodeInfo g_sigIllCodes[] = { +#ifdef ILL_NOOP + ENUM_NAME_MAPPING(ILL_NOOP), +#endif + ENUM_NAME_MAPPING(ILL_ILLOPC), + ENUM_NAME_MAPPING(ILL_ILLTRP), + ENUM_NAME_MAPPING(ILL_PRVOPC), + ENUM_NAME_MAPPING(ILL_ILLOPN), + ENUM_NAME_MAPPING(ILL_ILLADR), + ENUM_NAME_MAPPING(ILL_PRVREG), + ENUM_NAME_MAPPING(ILL_COPROC), + ENUM_NAME_MAPPING(ILL_BADSTK), +}; + +static const SentryCrashSignalCodeInfo g_sigTrapCodes[] = { + ENUM_NAME_MAPPING(0), + ENUM_NAME_MAPPING(TRAP_BRKPT), + ENUM_NAME_MAPPING(TRAP_TRACE), +}; + +static const SentryCrashSignalCodeInfo g_sigFPECodes[] = { +#ifdef FPE_NOOP + ENUM_NAME_MAPPING(FPE_NOOP), +#endif + ENUM_NAME_MAPPING(FPE_FLTDIV), + ENUM_NAME_MAPPING(FPE_FLTOVF), + ENUM_NAME_MAPPING(FPE_FLTUND), + ENUM_NAME_MAPPING(FPE_FLTRES), + ENUM_NAME_MAPPING(FPE_FLTINV), + ENUM_NAME_MAPPING(FPE_FLTSUB), + ENUM_NAME_MAPPING(FPE_INTDIV), + ENUM_NAME_MAPPING(FPE_INTOVF), +}; + +static const SentryCrashSignalCodeInfo g_sigBusCodes[] = { +#ifdef BUS_NOOP + ENUM_NAME_MAPPING(BUS_NOOP), +#endif + ENUM_NAME_MAPPING(BUS_ADRALN), + ENUM_NAME_MAPPING(BUS_ADRERR), + ENUM_NAME_MAPPING(BUS_OBJERR), +}; + +static const SentryCrashSignalCodeInfo g_sigSegVCodes[] = { +#ifdef SEGV_NOOP + ENUM_NAME_MAPPING(SEGV_NOOP), +#endif + ENUM_NAME_MAPPING(SEGV_MAPERR), + ENUM_NAME_MAPPING(SEGV_ACCERR), +}; + +#define SIGNAL_INFO(SIGNAL, CODES) \ + { \ + SIGNAL, #SIGNAL, CODES, sizeof(CODES) / sizeof(*CODES) \ + } +#define SIGNAL_INFO_NOCODES(SIGNAL) \ + { \ + SIGNAL, #SIGNAL, 0, 0 \ + } + +static const SentryCrashSignalInfo g_fatalSignalData[] = { + SIGNAL_INFO_NOCODES(SIGABRT), + SIGNAL_INFO(SIGBUS, g_sigBusCodes), + SIGNAL_INFO(SIGFPE, g_sigFPECodes), + SIGNAL_INFO(SIGILL, g_sigIllCodes), + SIGNAL_INFO_NOCODES(SIGPIPE), + SIGNAL_INFO(SIGSEGV, g_sigSegVCodes), + SIGNAL_INFO_NOCODES(SIGSYS), + SIGNAL_INFO(SIGTERM, g_sigTrapCodes), +}; +static const int g_fatalSignalsCount = sizeof(g_fatalSignalData) / sizeof(*g_fatalSignalData); + +// Note: Dereferencing a NULL pointer causes SIGILL, ILL_ILLOPC on i386 +// but causes SIGTRAP, 0 on arm. +static const int g_fatalSignals[] = { + SIGABRT, + SIGBUS, + SIGFPE, + SIGILL, + SIGPIPE, + SIGSEGV, + SIGSYS, + SIGTRAP, +}; + +const char * +sentrycrashsignal_signalName(const int sigNum) +{ + for (int i = 0; i < g_fatalSignalsCount; i++) { + if (g_fatalSignalData[i].sigNum == sigNum) { + return g_fatalSignalData[i].name; + } + } + return NULL; +} + +const char * +sentrycrashsignal_signalCodeName(const int sigNum, const int code) +{ + for (int si = 0; si < g_fatalSignalsCount; si++) { + if (g_fatalSignalData[si].sigNum == sigNum) { + for (int ci = 0; ci < g_fatalSignalData[si].numCodes; ci++) { + if (g_fatalSignalData[si].codes[ci].code == code) { + return g_fatalSignalData[si].codes[ci].name; + } + } + } + } + return NULL; +} + +const int * +sentrycrashsignal_fatalSignals(void) +{ + return g_fatalSignals; +} + +int +sentrycrashsignal_numFatalSignals(void) +{ + return g_fatalSignalsCount; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.h new file mode 100644 index 00000000..5965a1b0 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSignalInfo.h @@ -0,0 +1,73 @@ +// +// SentryCrashSignalInfo.h +// +// Created by Karl Stenerud on 2012-02-03. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Information about the signals we are interested in for a crash reporter. + */ + +#ifndef HDR_SentryCrashSignalInfo_h +#define HDR_SentryCrashSignalInfo_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** Get the name of a signal. + * + * @param signal The signal. + * + * @return The signal's name or NULL if not found. + */ +const char *sentrycrashsignal_signalName(int signal); + +/** Get the name of a signal's subcode. + * + * @param signal The signal. + * + * @param code The signal's code. + * + * @return The code's name or NULL if not found. + */ +const char *sentrycrashsignal_signalCodeName(int signal, int code); + +/** Get a list of fatal signals. + * + * @return A list of fatal signals. + */ +const int *sentrycrashsignal_fatalSignals(void); + +/** Get the size of the fatal signals list. + * + * @return The size of the fatal signals list. + */ +int sentrycrashsignal_numFatalSignals(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashSignalInfo_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.c new file mode 100644 index 00000000..79d56067 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.c @@ -0,0 +1,87 @@ +// +// SentryCrashStackCursor.h +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashStackCursor.h" +#include "SentryCrashCPU.h" +#include "SentryCrashSymbolicator.h" +#include + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +static bool +g_advanceCursor(__unused SentryCrashStackCursor *cursor) +{ + SentryCrashLOG_WARN("No stack cursor has been set. For C++, this means that hooking " + "__cxa_throw() failed for some reason. Embedded frameworks can cause " + "this: https://github.com/getsentry/SentryCrash/issues/205"); + return false; +} + +void +sentrycrashsc_resetCursor(SentryCrashStackCursor *cursor) +{ + cursor->state.currentDepth = 0; + cursor->state.hasGivenUp = false; + cursor->state.current_async_caller = NULL; + cursor->stackEntry.address = 0; + cursor->stackEntry.imageAddress = 0; + cursor->stackEntry.imageName = NULL; + cursor->stackEntry.symbolAddress = 0; + cursor->stackEntry.symbolName = NULL; +} + +void +sentrycrashsc_initCursor(SentryCrashStackCursor *cursor, + void (*resetCursor)(SentryCrashStackCursor *), bool (*advanceCursor)(SentryCrashStackCursor *)) +{ + cursor->symbolicate = sentrycrashsymbolicator_symbolicate; + cursor->advanceCursor = advanceCursor != NULL ? advanceCursor : g_advanceCursor; + cursor->async_caller = NULL; + cursor->resetCursor = resetCursor != NULL ? resetCursor : sentrycrashsc_resetCursor; + cursor->resetCursor(cursor); +} + +bool +sentrycrashsc_advanceAsyncCursor(SentryCrashStackCursor *cursor) +{ + sentrycrash_async_backtrace_t *async_caller = cursor->state.current_async_caller; + if (async_caller) { + if (cursor->state.currentDepth < async_caller->len) { + uintptr_t nextAddress = (uintptr_t)async_caller->backtrace[cursor->state.currentDepth]; + if (nextAddress > 1) { + cursor->stackEntry.address + = sentrycrashcpu_normaliseInstructionPointer(nextAddress); + cursor->state.currentDepth++; + return true; + } + } + if (async_caller->async_caller) { + cursor->state.current_async_caller = async_caller->async_caller; + cursor->state.currentDepth = 0; + return sentrycrashsc_advanceAsyncCursor(cursor); + } + } + return false; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.h new file mode 100644 index 00000000..3c43c51d --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor.h @@ -0,0 +1,119 @@ +// +// SentryCrashStackCursor.h +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef SentryCrashStackCursor_h +#define SentryCrashStackCursor_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashMachineContext.h" +#include "SentryHook.h" + +#include +#include + +#define SentryCrashSC_CONTEXT_SIZE 100 + +/** Point at which to give up walking a stack and consider it a stack overflow. + */ +#define SentryCrashSC_STACK_OVERFLOW_THRESHOLD 150 + +typedef struct SentryCrashStackCursor { + struct { + /** Current address in the stack trace. */ + uintptr_t address; + + /** The name (if any) of the binary image the current address falls + * inside. */ + const char *imageName; + + /** The starting address of the binary image the current address falls + * inside. */ + uintptr_t imageAddress; + + /** The name (if any) of the closest symbol to the current address. */ + const char *symbolName; + + /** The address of the closest symbol to the current address. */ + uintptr_t symbolAddress; + } stackEntry; + struct { + /** Current depth as we walk the stack (1-based). */ + int currentDepth; + + /** If true, cursor has given up walking the stack. */ + bool hasGivenUp; + + /** The current async caller we are chaining to. */ + sentrycrash_async_backtrace_t *current_async_caller; + } state; + + /** Reset the cursor back to the beginning. */ + void (*resetCursor)(struct SentryCrashStackCursor *); + + /** Advance the cursor to the next stack entry. */ + bool (*advanceCursor)(struct SentryCrashStackCursor *); + + /** Attempt to symbolicate the current address, filling in the fields in + * stackEntry. */ + bool (*symbolicate)(struct SentryCrashStackCursor *); + + /** Pointer to an optional async stacktrace. */ + sentrycrash_async_backtrace_t *async_caller; + + /** Internal context-specific information. */ + void *context[SentryCrashSC_CONTEXT_SIZE]; +} SentryCrashStackCursor; + +/** Common initialization routine for a stack cursor. + * Note: This is intended primarily for other cursors to call. + * + * @param cursor The cursor to initialize. + * + * @param resetCursor Function that will reset the cursor (NULL = default: Do + * nothing). + * + * @param advanceCursor Function to advance the cursor (NULL = default: Do + * nothing and return false). + */ +void sentrycrashsc_initCursor(SentryCrashStackCursor *cursor, + void (*resetCursor)(SentryCrashStackCursor *), bool (*advanceCursor)(SentryCrashStackCursor *)); + +/** Reset a cursor. + * INTERNAL METHOD. Do not call! + * + * @param cursor The cursor to reset. + */ +void sentrycrashsc_resetCursor(SentryCrashStackCursor *cursor); + +/** Advance the cursor to the next stack entry in a chained async stacktrace. */ +bool sentrycrashsc_advanceAsyncCursor(SentryCrashStackCursor *cursor); + +#ifdef __cplusplus +} +#endif + +#endif // SentryCrashStackCursor_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.c new file mode 100644 index 00000000..b0a7c758 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.c @@ -0,0 +1,70 @@ +// +// SentryCrashStackCursor_Backtrace.c +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashStackCursor_Backtrace.h" +#include "SentryCrashCPU.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +static bool +advanceCursor(SentryCrashStackCursor *cursor) +{ + sentrycrash_async_backtrace_t *async_caller = cursor->state.current_async_caller; + if (async_caller) { + return sentrycrashsc_advanceAsyncCursor(cursor); + } + + SentryCrashStackCursor_Backtrace_Context *context + = (SentryCrashStackCursor_Backtrace_Context *)cursor->context; + int endDepth = context->backtraceLength - context->skippedEntries; + if (cursor->state.currentDepth < endDepth) { + int currentIndex = cursor->state.currentDepth + context->skippedEntries; + uintptr_t nextAddress = context->backtrace[currentIndex]; + // Bug: The system sometimes gives a backtrace with an extra 0x00000001 + // at the end. + if (nextAddress > 1) { + cursor->stackEntry.address = sentrycrashcpu_normaliseInstructionPointer(nextAddress); + cursor->state.currentDepth++; + return true; + } + } else if (cursor->async_caller) { + cursor->state.current_async_caller = cursor->async_caller; + cursor->state.currentDepth = 0; + return cursor->advanceCursor(cursor); + } + return false; +} + +void +sentrycrashsc_initWithBacktrace(SentryCrashStackCursor *cursor, const uintptr_t *backtrace, + int backtraceLength, int skipEntries) +{ + sentrycrashsc_initCursor(cursor, sentrycrashsc_resetCursor, advanceCursor); + SentryCrashStackCursor_Backtrace_Context *context + = (SentryCrashStackCursor_Backtrace_Context *)cursor->context; + context->skippedEntries = skipEntries; + context->backtraceLength = backtraceLength; + context->backtrace = backtrace; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.h new file mode 100644 index 00000000..1110e9e4 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_Backtrace.h @@ -0,0 +1,59 @@ +// +// SentryCrashStackCursor_Backtrace.h +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef SentryCrashStackCursor_Backtrace_h +#define SentryCrashStackCursor_Backtrace_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashStackCursor.h" + +/** Exposed for other internal systems to use. + */ +typedef struct { + int skippedEntries; + int backtraceLength; + const uintptr_t *backtrace; +} SentryCrashStackCursor_Backtrace_Context; + +/** Initialize a stack cursor for an existing backtrace (array of addresses). + * + * @param cursor The stack cursor to initialize. + * + * @param backtrace The existing backtrace to walk. + * + * @param backtraceLength The length of the backtrace. + * + * @param skipEntries The number of stack entries to skip. + */ +void sentrycrashsc_initWithBacktrace(SentryCrashStackCursor *cursor, const uintptr_t *backtrace, + int backtraceLength, int skipEntries); + +#ifdef __cplusplus +} +#endif + +#endif // SentryCrashStackCursor_Backtrace_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.c new file mode 100644 index 00000000..dab49f98 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.c @@ -0,0 +1,148 @@ +// +// SentryCrashStackCursor_MachineContext.c +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashStackCursor_MachineContext.h" + +#include "SentryCrashCPU.h" +#include "SentryCrashMemory.h" + +#include + +#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +/** Represents an entry in a frame list. + * This is modeled after the various i386/x64 frame walkers in the xnu source, + * and seems to work fine in ARM as well. I haven't included the args pointer + * since it's not needed in this context. + */ +typedef struct FrameEntry { + /** The previous frame in the list. */ + struct FrameEntry *previous; + + /** The instruction address. */ + uintptr_t return_address; +} FrameEntry; + +typedef struct { + const struct SentryCrashMachineContext *machineContext; + int maxStackDepth; + FrameEntry currentFrame; + uintptr_t instructionAddress; + uintptr_t linkRegister; + bool isPastFramePointer; +} MachineContextCursor; + +static bool +advanceCursor(SentryCrashStackCursor *cursor) +{ + sentrycrash_async_backtrace_t *async_caller = cursor->state.current_async_caller; + if (async_caller) { + return sentrycrashsc_advanceAsyncCursor(cursor); + } + + MachineContextCursor *context = (MachineContextCursor *)cursor->context; + uintptr_t nextAddress = 0; + + if (cursor->state.currentDepth >= context->maxStackDepth) { + cursor->state.hasGivenUp = true; + return false; + } + + if (context->instructionAddress == 0) { + context->instructionAddress = sentrycrashcpu_instructionAddress(context->machineContext); + if (context->instructionAddress == 0) { + goto tryAsyncChain; + } + nextAddress = context->instructionAddress; + goto successfulExit; + } + + if (context->linkRegister == 0 && !context->isPastFramePointer) { + // Link register, if available, is the second address in the trace. + context->linkRegister = sentrycrashcpu_linkRegister(context->machineContext); + if (context->linkRegister != 0) { + nextAddress = context->linkRegister; + goto successfulExit; + } + } + + if (context->currentFrame.previous == NULL) { + if (context->isPastFramePointer) { + goto tryAsyncChain; + } + context->currentFrame.previous + = (struct FrameEntry *)sentrycrashcpu_framePointer(context->machineContext); + context->isPastFramePointer = true; + } + + if (!sentrycrashmem_copySafely(context->currentFrame.previous, &context->currentFrame, + sizeof(context->currentFrame))) { + return false; + } + if (context->currentFrame.previous == 0 || context->currentFrame.return_address == 0) { + goto tryAsyncChain; + } + + nextAddress = context->currentFrame.return_address; + +successfulExit: + cursor->stackEntry.address = sentrycrashcpu_normaliseInstructionPointer(nextAddress); + cursor->state.currentDepth++; + return true; + +tryAsyncChain: + if (cursor->async_caller) { + cursor->state.current_async_caller = cursor->async_caller; + cursor->state.currentDepth = 0; + return cursor->advanceCursor(cursor); + } + return false; +} + +static void +resetCursor(SentryCrashStackCursor *cursor) +{ + sentrycrashsc_resetCursor(cursor); + MachineContextCursor *context = (MachineContextCursor *)cursor->context; + context->currentFrame.previous = 0; + context->currentFrame.return_address = 0; + context->instructionAddress = 0; + context->linkRegister = 0; + context->isPastFramePointer = 0; +} + +void +sentrycrashsc_initWithMachineContext(SentryCrashStackCursor *cursor, int maxStackDepth, + const struct SentryCrashMachineContext *machineContext) +{ + sentrycrashsc_initCursor(cursor, resetCursor, advanceCursor); + MachineContextCursor *context = (MachineContextCursor *)cursor->context; + context->machineContext = machineContext; + context->maxStackDepth = maxStackDepth; + context->instructionAddress = cursor->stackEntry.address; + + SentryCrashThread thread = sentrycrashmc_getThreadFromContext(machineContext); + cursor->async_caller = sentrycrash_get_async_caller_for_thread(thread); +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.h new file mode 100644 index 00000000..8ebbce2e --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.h @@ -0,0 +1,49 @@ +// +// SentryCrashStackCursor_MachineContext.h +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef SentryCrashStackCursor_MachineContext_h +#define SentryCrashStackCursor_MachineContext_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashStackCursor.h" + +/** Initialize a stack cursor for a machine context. + * + * @param cursor The stack cursor to initialize. + * + * @param maxStackDepth The max depth to search before giving up. + * + * @param machineContext The machine context whose stack to walk. + */ +void sentrycrashsc_initWithMachineContext(SentryCrashStackCursor *cursor, int maxStackDepth, + const struct SentryCrashMachineContext *machineContext); + +#ifdef __cplusplus +} +#endif + +#endif // SentryCrashStackCursor_MachineContext_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.c new file mode 100644 index 00000000..38af9638 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.c @@ -0,0 +1,49 @@ +// +// SentryCrashStackCursor_SelfThread.c +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashStackCursor_SelfThread.h" +#include "SentryCrashStackCursor_Backtrace.h" +#include + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#define MAX_BACKTRACE_LENGTH \ + (SentryCrashSC_CONTEXT_SIZE \ + - sizeof(SentryCrashStackCursor_Backtrace_Context) / sizeof(void *) - 1) + +typedef struct { + SentryCrashStackCursor_Backtrace_Context SelfThreadContextSpacer; + uintptr_t backtrace[0]; +} SelfThreadContext; + +void +sentrycrashsc_initSelfThread(SentryCrashStackCursor *cursor, int skipEntries) +{ + SelfThreadContext *context = (SelfThreadContext *)cursor->context; + int backtraceLength = backtrace((void **)context->backtrace, MAX_BACKTRACE_LENGTH); + sentrycrashsc_initWithBacktrace(cursor, context->backtrace, backtraceLength, skipEntries + 1); + + cursor->async_caller = sentrycrash_get_async_caller_for_thread(sentrycrashthread_self()); +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h new file mode 100644 index 00000000..c5cc261e --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h @@ -0,0 +1,48 @@ +// +// SentryCrashStackCursor_SelfThread.h +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef SentryCrashStackCursor_SelfThread_h +#define SentryCrashStackCursor_SelfThread_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashStackCursor.h" + +/** Initialize a stack cursor for the current thread. + * You may want to skip some entries to account for the trace immediately + * leading up to this init function. + * + * @param cursor The stack cursor to initialize. + * + * @param skipEntries The number of stack entries to skip. + */ +void sentrycrashsc_initSelfThread(SentryCrashStackCursor *cursor, int skipEntries); + +#ifdef __cplusplus +} +#endif + +#endif // SentryCrashStackCursor_SelfThread_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashString.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashString.c new file mode 100644 index 00000000..010efc64 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashString.c @@ -0,0 +1,470 @@ +// +// SentryCrashString.m +// +// Created by Karl Stenerud on 2012-09-15. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashString.h" +#include "SentryCrashSystemCapabilities.h" +#include +#include + +// Compiler hints for "if" statements +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) + +static const int g_printableControlChars[0x20] = { + // Only tab, CR, and LF are considered printable + // 1 2 3 4 5 6 7 8 9 a b c d e f + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const int g_continuationByteCount[0x40] = { + /* + --0xxxxx = 1 (00-1f) + --10xxxx = 2 (20-2f) + --110xxx = 3 (30-37) + --1110xx = 4 (38-3b) + --11110x = 5 (3c-3d) + */ + // 1 2 3 4 5 6 7 8 9 a b c d e f + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 4, + 4, + 4, + 4, + 5, + 5, + 0, + 0, +}; + +bool +sentrycrashstring_isNullTerminatedUTF8String(const void *memory, int minLength, int maxLength) +{ + const unsigned char *ptr = memory; + const unsigned char *const end = ptr + maxLength; + + for (; ptr < end; ptr++) { + unsigned char ch = *ptr; + unlikely_if(ch == 0) { return (ptr - (const unsigned char *)memory) >= minLength; } + unlikely_if(ch & 0x80) + { + unlikely_if((ch & 0xc0) != 0xc0) { return false; } + int continuationBytes = g_continuationByteCount[ch & 0x3f]; + unlikely_if(continuationBytes == 0 || ptr + continuationBytes >= end) { return false; } + for (int i = 0; i < continuationBytes; i++) { + ptr++; + unlikely_if((*ptr & 0xc0) != 0x80) { return false; } + } + } + else unlikely_if(ch < 0x20 && !g_printableControlChars[ch]) { return false; } + } + return false; +} + +#define INV 0xff + +/** Lookup table for converting hex values to integers. + * INV (0x11111) is used to mark invalid characters so that any attempted + * invalid nybble conversion is always > 0xffff. + */ +static const unsigned int g_hexConversion[] = { + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + 0x0, + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + 0x9, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + 0xa, + 0xb, + 0xc, + 0xd, + 0xe, + 0xf, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + 0xa, + 0xb, + 0xc, + 0xd, + 0xe, + 0xf, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, + INV, +}; + +bool +sentrycrashstring_extractHexValue(const char *string, int stringLength, uint64_t *const result) +{ + if (stringLength > 0) { + const unsigned char *current = (const unsigned char *)string; + const unsigned char *const end = current + stringLength; + for (;;) { +#if SentryCrashCRASH_HAS_STRNSTR + current = (const unsigned char *)strnstr( + (const char *)current, "0x", (unsigned)(end - current)); +#else + current = (const unsigned char *)strstr((const char *)current, "0x"); + unlikely_if(current >= end) { return false; } +#endif + unlikely_if(!current) { return false; } + current += 2; + + // Must have at least one valid digit after "0x". + unlikely_if(g_hexConversion[*current] == INV) { continue; } + + uint64_t accum = 0; + unsigned int nybble = 0; + while (current < end) { + nybble = g_hexConversion[*current++]; + unlikely_if(nybble == INV) { break; } + accum <<= 4; + accum += nybble; + } + *result = accum; + return true; + } + } + return false; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashString.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashString.h new file mode 100644 index 00000000..426c9cbd --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashString.h @@ -0,0 +1,63 @@ +// +// SentryCrashString.h +// +// Created by Karl Stenerud on 2012-09-15. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashString_h +#define HDR_SentryCrashString_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** Check if a memory location contains a null terminated UTF-8 string. + * + * @param memory The memory location to test. + * + * @param minLength The minimum length to be considered a valid string. + * + * @param maxLength The maximum length to be considered a valid string. + */ +bool sentrycrashstring_isNullTerminatedUTF8String(const void *memory, int minLength, int maxLength); + +/** Extract a hex value in the form "0x123456789abcdef" from a string. + * + * @param string The string to search. + * + * @param stringLength The length of the string. + * + * @param result Buffer to hold the resulting value. + * + * @return true if the operation was successful. + */ +bool sentrycrashstring_extractHexValue(const char *string, int stringLength, uint64_t *result); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashString_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.c new file mode 100644 index 00000000..b988e976 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.c @@ -0,0 +1,69 @@ +// +// SentryCrashSymbolicator.c +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashSymbolicator.h" +#include "SentryCrashDynamicLinker.h" + +/** Remove any pointer tagging from an instruction address + * On armv7 the least significant bit of the pointer distinguishes + * between thumb mode (2-byte instructions) and normal mode (4-byte + * instructions). On arm64 all instructions are 4-bytes wide so the two least + * significant bytes should always be 0. On x86_64 and i386, instructions are + * variable length so all bits are signficant. + */ +#if defined(__arm__) +# define DETAG_INSTRUCTION_ADDRESS(A) ((A) & ~(1UL)) +#elif defined(__arm64__) +# define DETAG_INSTRUCTION_ADDRESS(A) ((A) & ~(3UL)) +#else +# define DETAG_INSTRUCTION_ADDRESS(A) (A) +#endif + +/** Step backwards by one instruction. + * The backtrace of an objective-C program is expected to contain return + * addresses not call instructions, as that is what can easily be read from + * the stack. This is not a problem except for a few cases where the return + * address is inside a different symbol than the call address. + */ +#define CALL_INSTRUCTION_FROM_RETURN_ADDRESS(A) (DETAG_INSTRUCTION_ADDRESS((A)) - 1) + +bool +sentrycrashsymbolicator_symbolicate(SentryCrashStackCursor *cursor) +{ + Dl_info symbolsBuffer; + if (sentrycrashdl_dladdr( + CALL_INSTRUCTION_FROM_RETURN_ADDRESS(cursor->stackEntry.address), &symbolsBuffer)) { + cursor->stackEntry.imageAddress = (uintptr_t)symbolsBuffer.dli_fbase; + cursor->stackEntry.imageName = symbolsBuffer.dli_fname; + cursor->stackEntry.symbolAddress = (uintptr_t)symbolsBuffer.dli_saddr; + cursor->stackEntry.symbolName = symbolsBuffer.dli_sname; + return true; + } + + cursor->stackEntry.imageAddress = 0; + cursor->stackEntry.imageName = 0; + cursor->stackEntry.symbolAddress = 0; + cursor->stackEntry.symbolName = 0; + return false; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.h new file mode 100644 index 00000000..eb6083bd --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSymbolicator.h @@ -0,0 +1,47 @@ +// +// SentryCrashSymbolicator.h +// +// Copyright (c) 2016 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef SentryCrashSymbolicator_h +#define SentryCrashSymbolicator_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SentryCrashStackCursor.h" +#include + +/** Symbolicate a stack cursor. + * + * @param cursor The cursor to symbolicate. + * + * @return True if successful. + */ +bool sentrycrashsymbolicator_symbolicate(SentryCrashStackCursor *cursor); + +#ifdef __cplusplus +} +#endif + +#endif // SentryCrashSymbolicator_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.c new file mode 100644 index 00000000..48bb4076 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.c @@ -0,0 +1,243 @@ +// +// SentryCrashSysCtl.m +// +// Created by Karl Stenerud on 2012-02-19. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashSysCtl.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include +#include + +#define CHECK_SYSCTL_NAME(TYPE, CALL) \ + if (0 != (CALL)) { \ + SentryCrashLOG_ERROR("Could not get %s value for %s: %s", #CALL, name, strerror(errno)); \ + return 0; \ + } + +#define CHECK_SYSCTL_CMD(TYPE, CALL) \ + if (0 != (CALL)) { \ + SentryCrashLOG_ERROR( \ + "Could not get %s value for %d,%d: %s", #CALL, major_cmd, minor_cmd, strerror(errno)); \ + return 0; \ + } + +int32_t +sentrycrashsysctl_int32(const int major_cmd, const int minor_cmd) +{ + int cmd[2] = { major_cmd, minor_cmd }; + int32_t value = 0; + size_t size = sizeof(value); + + CHECK_SYSCTL_CMD(int32, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)); + + return value; +} + +int32_t +sentrycrashsysctl_int32ForName(const char *const name) +{ + int32_t value = 0; + size_t size = sizeof(value); + + CHECK_SYSCTL_NAME(int32, sysctlbyname(name, &value, &size, NULL, 0)); + + return value; +} + +uint32_t +sentrycrashsysctl_uint32(const int major_cmd, const int minor_cmd) +{ + int cmd[2] = { major_cmd, minor_cmd }; + uint32_t value = 0; + size_t size = sizeof(value); + + CHECK_SYSCTL_CMD(uint32, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)); + + return value; +} + +uint32_t +sentrycrashsysctl_uint32ForName(const char *const name) +{ + uint32_t value = 0; + size_t size = sizeof(value); + + CHECK_SYSCTL_NAME(uint32, sysctlbyname(name, &value, &size, NULL, 0)); + + return value; +} + +int64_t +sentrycrashsysctl_int64(const int major_cmd, const int minor_cmd) +{ + int cmd[2] = { major_cmd, minor_cmd }; + int64_t value = 0; + size_t size = sizeof(value); + + CHECK_SYSCTL_CMD(int64, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)); + + return value; +} + +int64_t +sentrycrashsysctl_int64ForName(const char *const name) +{ + int64_t value = 0; + size_t size = sizeof(value); + + CHECK_SYSCTL_NAME(int64, sysctlbyname(name, &value, &size, NULL, 0)); + + return value; +} + +uint64_t +sentrycrashsysctl_uint64(const int major_cmd, const int minor_cmd) +{ + int cmd[2] = { major_cmd, minor_cmd }; + uint64_t value = 0; + size_t size = sizeof(value); + + CHECK_SYSCTL_CMD(uint64, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)); + + return value; +} + +uint64_t +sentrycrashsysctl_uint64ForName(const char *const name) +{ + uint64_t value = 0; + size_t size = sizeof(value); + + CHECK_SYSCTL_NAME(uint64, sysctlbyname(name, &value, &size, NULL, 0)); + + return value; +} + +int +sentrycrashsysctl_string( + const int major_cmd, const int minor_cmd, char *const value, const int maxSize) +{ + int cmd[2] = { major_cmd, minor_cmd }; + size_t size = value == NULL ? 0 : (size_t)maxSize; + + CHECK_SYSCTL_CMD(string, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), value, &size, NULL, 0)); + + return (int)size; +} + +int +sentrycrashsysctl_stringForName(const char *const name, char *const value, const int maxSize) +{ + size_t size = value == NULL ? 0 : (size_t)maxSize; + + CHECK_SYSCTL_NAME(string, sysctlbyname(name, value, &size, NULL, 0)); + + return (int)size; +} + +struct timeval +sentrycrashsysctl_timeval(const int major_cmd, const int minor_cmd) +{ + int cmd[2] = { major_cmd, minor_cmd }; + struct timeval value = { 0 }; + size_t size = sizeof(value); + + if (0 != sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)) { + SentryCrashLOG_ERROR( + "Could not get timeval value for %d,%d: %s", major_cmd, minor_cmd, strerror(errno)); + } + + return value; +} + +struct timeval +sentrycrashsysctl_timevalForName(const char *const name) +{ + struct timeval value = { 0 }; + size_t size = sizeof(value); + + if (0 != sysctlbyname(name, &value, &size, NULL, 0)) { + SentryCrashLOG_ERROR("Could not get timeval value for %s: %s", name, strerror(errno)); + } + + return value; +} + +bool +sentrycrashsysctl_getProcessInfo(const int pid, struct kinfo_proc *const procInfo) +{ + int cmd[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; + size_t size = sizeof(*procInfo); + + if (0 != sysctl(cmd, sizeof(cmd) / sizeof(*cmd), procInfo, &size, NULL, 0)) { + SentryCrashLOG_ERROR("Could not get the name for process %d: %s", pid, strerror(errno)); + return false; + } + return true; +} + +bool +sentrycrashsysctl_getMacAddress(const char *const name, char *const macAddressBuffer) +{ + // Based off + // http://iphonedevelopertips.com/device/determine-mac-address.html + + int mib[6] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, (int)if_nametoindex(name) }; + if (mib[5] == 0) { + SentryCrashLOG_ERROR("Could not get interface index for %s: %s", name, strerror(errno)); + return false; + } + + size_t length; + if (sysctl(mib, 6, NULL, &length, NULL, 0) != 0) { + SentryCrashLOG_ERROR("Could not get interface data for %s: %s", name, strerror(errno)); + return false; + } + + void *ifBuffer = malloc(length); + if (ifBuffer == NULL) { + SentryCrashLOG_ERROR("Out of memory"); + return false; + } + + if (sysctl(mib, 6, ifBuffer, &length, NULL, 0) != 0) { + SentryCrashLOG_ERROR("Could not get interface data for %s: %s", name, strerror(errno)); + free(ifBuffer); + return false; + } + + struct if_msghdr *msgHdr = (struct if_msghdr *)ifBuffer; + struct sockaddr_dl *sockaddr = (struct sockaddr_dl *)&msgHdr[1]; + memcpy(macAddressBuffer, LLADDR(sockaddr), 6); + + free(ifBuffer); + + return true; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.h new file mode 100644 index 00000000..9bb68c56 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashSysCtl.h @@ -0,0 +1,186 @@ +// +// SentryCrashSysCtl.h +// +// Created by Karl Stenerud on 2012-02-19. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* Convenience wrapper functions for sysctl calls. + */ + +#ifndef HDR_SentryCrashSysCtl_h +#define HDR_SentryCrashSysCtl_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** Get an int32 value via sysctl. + * + * @param major_cmd The major part of the command or name. + * + * @param minor_cmd The minor part of the command or name. + * + * @return The value returned by sysctl. + */ +int32_t sentrycrashsysctl_int32(int major_cmd, int minor_cmd); + +/** Get an int32 value via sysctl by name. + * + * @param name The name of the command. + * + * @return The value returned by sysctl. + */ +int32_t sentrycrashsysctl_int32ForName(const char *name); + +/** Get a uint32 value via sysctl. + * + * @param major_cmd The major part of the command or name. + * + * @param minor_cmd The minor part of the command or name. + * + * @return The value returned by sysctl. + */ +uint32_t sentrycrashsysctl_uint32(int major_cmd, int minor_cmd); + +/** Get a uint32 value via sysctl by name. + * + * @param name The name of the command. + * + * @return The value returned by sysctl. + */ +uint32_t sentrycrashsysctl_uint32ForName(const char *name); + +/** Get an int64 value via sysctl. + * + * @param major_cmd The major part of the command or name. + * + * @param minor_cmd The minor part of the command or name. + * + * @return The value returned by sysctl. + */ +int64_t sentrycrashsysctl_int64(int major_cmd, int minor_cmd); + +/** Get an int64 value via sysctl by name. + * + * @param name The name of the command. + * + * @return The value returned by sysctl. + */ +int64_t sentrycrashsysctl_int64ForName(const char *name); + +/** Get a uint64 value via sysctl. + * + * @param major_cmd The major part of the command or name. + * + * @param minor_cmd The minor part of the command or name. + * + * @return The value returned by sysctl. + */ +uint64_t sentrycrashsysctl_uint64(int major_cmd, int minor_cmd); + +/** Get a uint64 value via sysctl by name. + * + * @param name The name of the command. + * + * @return The value returned by sysctl. + */ +uint64_t sentrycrashsysctl_uint64ForName(const char *name); + +/** Get a string value via sysctl. + * + * @param major_cmd The major part of the command or name. + * + * @param minor_cmd The minor part of the command or name. + * + * @param value Pointer to a buffer to fill out. If NULL, does not fill + * anything out. + * + * @param maxSize The size of the buffer pointed to by value. + * + * @return The number of bytes written (or that would have been written if + * value is NULL). + */ +int sentrycrashsysctl_string(int major_cmd, int minor_cmd, char *value, int maxSize); + +/** Get a string value via sysctl by name. + * + * @param name The name of the command. + * + * @param value Pointer to a buffer to fill out. If NULL, does not fill + * anything out. + * + * @param maxSize The size of the buffer pointed to by value. + * + * @return The number of bytes written (or that would have been written if + * value is NULL). + */ +int sentrycrashsysctl_stringForName(const char *name, char *value, int maxSize); + +/** Get a timeval value via sysctl. + * + * @param major_cmd The major part of the command or name. + * + * @param minor_cmd The minor part of the command or name. + * + * @return The value returned by sysctl. + */ +struct timeval sentrycrashsysctl_timeval(int major_cmd, int minor_cmd); + +/** Get a timeval value via sysctl by name. + * + * @param name The name of the command. + * + * @return The value returned by sysctl. + */ +struct timeval sentrycrashsysctl_timevalForName(const char *name); + +/** Get information about a process. + * + * @param pid The process ID. + * + * @param procInfo Struct to hold the proces information. + * + * @return true if the operation was successful. + */ +bool sentrycrashsysctl_getProcessInfo(int pid, struct kinfo_proc *procInfo); + +/** Get the MAC address of the specified interface. + * Note: As of iOS 7 this will always return a fixed value of 02:00:00:00:00:00. + * + * @param name Interface name (e.g. "en1"). + * + * @param macAddressBuffer 6 bytes of storage to hold the MAC address. + * + * @return true if the address was successfully retrieved. + */ +bool sentrycrashsysctl_getMacAddress(const char *name, char *macAddressBuffer); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashSysCtl_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashThread.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashThread.c new file mode 100644 index 00000000..79a3ba4f --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashThread.c @@ -0,0 +1,55 @@ +// +// SentryCrashThread.c +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "SentryCrashThread.h" + +#include "SentryCrashMemory.h" +#include "SentryCrashSystemCapabilities.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#include "SentryCrashLogger.h" + +#include +#include +#include +#include + +SentryCrashThread +sentrycrashthread_self() +{ + thread_t thread_self = mach_thread_self(); + mach_port_deallocate(mach_task_self(), thread_self); + return (SentryCrashThread)thread_self; +} + +bool +sentrycrashthread_getThreadName(const SentryCrashThread thread, char *const buffer, int bufLength) +{ + // WARNING: This implementation is no longer async-safe! + + const pthread_t pthread = pthread_from_mach_thread_np((thread_t)thread); + return pthread_getname_np(pthread, buffer, (unsigned)bufLength) == 0; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashThread.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashThread.h new file mode 100644 index 00000000..656d12c3 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashThread.h @@ -0,0 +1,66 @@ +// +// SentryCrashThread.h +// +// Created by Karl Stenerud on 2012-01-29. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef HDR_SentryCrashThread_h +#define HDR_SentryCrashThread_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef uintptr_t SentryCrashThread; + +/** Get a thread's name. Internally, a thread name will + * never be more than 64 characters long. + * + * @param thread The thread whose name to get. + * + * @oaram buffer Buffer to hold the name. + * + * @param bufLength The length of the buffer. + * + * @return true if a name was found. + */ +bool sentrycrashthread_getThreadName( + const SentryCrashThread thread, char *const buffer, int bufLength); + +/* Get the current mach thread ID. + * mach_thread_self() receives a send right for the thread port which needs to + * be deallocated to balance the reference count. This function takes care of + * all of that for you. + * + * @return The current thread ID. + */ +SentryCrashThread sentrycrashthread_self(void); + +#ifdef __cplusplus +} +#endif + +#endif // HDR_SentryCrashThread_h diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.c new file mode 100644 index 00000000..98018b64 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.c @@ -0,0 +1,34 @@ +#include "SentryCrashUUIDConversion.h" + +void +sentrycrashdl_convertBinaryImageUUID(const unsigned char *src, char *dst) +{ + const char g_hexNybbles[] + = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + for (int i = 0; i < 4; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; + } + *dst++ = '-'; + for (int i = 0; i < 2; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; + } + *dst++ = '-'; + for (int i = 0; i < 2; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; + } + *dst++ = '-'; + for (int i = 0; i < 2; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; + } + *dst++ = '-'; + for (int i = 0; i < 6; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; + } + *dst++ = '\0'; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.h new file mode 100644 index 00000000..96f07ce2 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryCrashUUIDConversion.h @@ -0,0 +1,22 @@ +#ifndef SENTRY_SENTRYCRASHUUIDCONVERSION_H +#define SENTRY_SENTRYCRASHUUIDCONVERSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Converts SentryCrashBinaryImage.uuid to a human readable 36 charactacters long hex + * representation. + * + * @param src The pointer to an UUID + * + * @param dst A buffer with the length of 37 to hold the human readable UUID. + * + */ +void sentrycrashdl_convertBinaryImageUUID(const unsigned char *src, char *dst); + +#ifdef __cplusplus +} +#endif + +#endif // SENTRY_SENTRYCRASHUUIDCONVERSION_H diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryHook.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryHook.c new file mode 100644 index 00000000..1c5c14dc --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryHook.c @@ -0,0 +1,239 @@ +#include "SentryHook.h" +#include "fishhook.h" +#include +#include +#include +#include + +// NOTE on accessing thread-locals across threads: +// We save the async stacktrace as a thread local when dispatching async calls, +// but the various crash handlers need to access these thread-locals across threads +// sometimes, which we do here: +// While `pthread_t` is an opaque type, the offset of `thread specific data` (tsd) +// is fixed due to backwards compatibility. +// See: +// https://github.com/apple/darwin-libpthread/blob/c60d249cc84dfd6097a7e71c68a36b47cbe076d1/src/types_internal.h#L409-L432 + +#if __LP64__ +# define TSD_OFFSET 224 +#else +# define TSD_OFFSET 176 +#endif + +static pthread_key_t async_caller_key = 0; + +sentrycrash_async_backtrace_t * +sentrycrash_get_async_caller_for_thread(SentryCrashThread thread) +{ + const pthread_t pthread = pthread_from_mach_thread_np((thread_t)thread); + void **tsd_slots = (void *)((uint8_t *)pthread + TSD_OFFSET); + + return (sentrycrash_async_backtrace_t *)__atomic_load_n( + &tsd_slots[async_caller_key], __ATOMIC_SEQ_CST); +} + +void +sentrycrash__async_backtrace_incref(sentrycrash_async_backtrace_t *bt) +{ + if (!bt) { + return; + } + __atomic_fetch_add(&bt->refcount, 1, __ATOMIC_SEQ_CST); +} + +void +sentrycrash__async_backtrace_decref(sentrycrash_async_backtrace_t *bt) +{ + if (!bt) { + return; + } + if (__atomic_fetch_add(&bt->refcount, -1, __ATOMIC_SEQ_CST) == 1) { + sentrycrash__async_backtrace_decref(bt->async_caller); + free(bt); + } +} + +sentrycrash_async_backtrace_t * +sentrycrash__async_backtrace_capture(void) +{ + sentrycrash_async_backtrace_t *bt = malloc(sizeof(sentrycrash_async_backtrace_t)); + bt->refcount = 1; + + bt->len = backtrace(bt->backtrace, MAX_BACKTRACE_FRAMES); + + sentrycrash_async_backtrace_t *caller = pthread_getspecific(async_caller_key); + sentrycrash__async_backtrace_incref(caller); + bt->async_caller = caller; + + return bt; +} + +static bool hooks_active = true; + +static void (*real_dispatch_async)(dispatch_queue_t queue, dispatch_block_t block); + +void +sentrycrash__hook_dispatch_async(dispatch_queue_t queue, dispatch_block_t block) +{ + if (!__atomic_load_n(&hooks_active, __ATOMIC_RELAXED)) { + return real_dispatch_async(queue, block); + } + + // create a backtrace, capturing the async callsite + sentrycrash_async_backtrace_t *bt = sentrycrash__async_backtrace_capture(); + + return real_dispatch_async(queue, ^{ + // inside the async context, save the backtrace in a thread local for later consumption + pthread_setspecific(async_caller_key, bt); + + // call through to the original block + block(); + + // and decref our current backtrace + pthread_setspecific(async_caller_key, NULL); + sentrycrash__async_backtrace_decref(bt); + }); +} + +static void (*real_dispatch_async_f)( + dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work); + +void +sentrycrash__hook_dispatch_async_f( + dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work) +{ + if (!__atomic_load_n(&hooks_active, __ATOMIC_RELAXED)) { + return real_dispatch_async_f(queue, context, work); + } + sentrycrash__hook_dispatch_async(queue, ^{ work(context); }); +} + +static void (*real_dispatch_after)( + dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block); + +void +sentrycrash__hook_dispatch_after( + dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block) +{ + if (!__atomic_load_n(&hooks_active, __ATOMIC_RELAXED)) { + return real_dispatch_after(when, queue, block); + } + + // create a backtrace, capturing the async callsite + sentrycrash_async_backtrace_t *bt = sentrycrash__async_backtrace_capture(); + + return real_dispatch_after(when, queue, ^{ + // inside the async context, save the backtrace in a thread local for later consumption + pthread_setspecific(async_caller_key, bt); + + // call through to the original block + block(); + + // and decref our current backtrace + pthread_setspecific(async_caller_key, NULL); + sentrycrash__async_backtrace_decref(bt); + }); +} + +static void (*real_dispatch_after_f)(dispatch_time_t when, dispatch_queue_t queue, + void *_Nullable context, dispatch_function_t work); + +void +sentrycrash__hook_dispatch_after_f( + dispatch_time_t when, dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work) +{ + if (!__atomic_load_n(&hooks_active, __ATOMIC_RELAXED)) { + return real_dispatch_after_f(when, queue, context, work); + } + sentrycrash__hook_dispatch_after(when, queue, ^{ work(context); }); +} + +static void (*real_dispatch_barrier_async)(dispatch_queue_t queue, dispatch_block_t block); + +void +sentrycrash__hook_dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block) +{ + if (!__atomic_load_n(&hooks_active, __ATOMIC_RELAXED)) { + return real_dispatch_barrier_async(queue, block); + } + + // create a backtrace, capturing the async callsite + sentrycrash_async_backtrace_t *bt = sentrycrash__async_backtrace_capture(); + + return real_dispatch_barrier_async(queue, ^{ + // inside the async context, save the backtrace in a thread local for later consumption + pthread_setspecific(async_caller_key, bt); + + // call through to the original block + block(); + + // and decref our current backtrace + pthread_setspecific(async_caller_key, NULL); + sentrycrash__async_backtrace_decref(bt); + }); +} + +static void (*real_dispatch_barrier_async_f)( + dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work); + +void +sentrycrash__hook_dispatch_barrier_async_f( + dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work) +{ + if (!__atomic_load_n(&hooks_active, __ATOMIC_RELAXED)) { + return real_dispatch_barrier_async_f(queue, context, work); + } + sentrycrash__hook_dispatch_barrier_async(queue, ^{ work(context); }); +} + +static bool hooks_installed = false; + +void +sentrycrash_install_async_hooks(void) +{ + __atomic_store_n(&hooks_active, true, __ATOMIC_RELAXED); + + if (__atomic_exchange_n(&hooks_installed, true, __ATOMIC_SEQ_CST)) { + return; + } + if (pthread_key_create(&async_caller_key, NULL) != 0) { + return; + } + + sentrycrash__hook_rebind_symbols( + (struct rebinding[6]) { + { "dispatch_async", sentrycrash__hook_dispatch_async, (void *)&real_dispatch_async }, + { "dispatch_async_f", sentrycrash__hook_dispatch_async_f, + (void *)&real_dispatch_async_f }, + { "dispatch_after", sentrycrash__hook_dispatch_after, (void *)&real_dispatch_after }, + { "dispatch_after_f", sentrycrash__hook_dispatch_after_f, + (void *)&real_dispatch_after_f }, + { "dispatch_barrier_async", sentrycrash__hook_dispatch_barrier_async, + (void *)&real_dispatch_barrier_async }, + { "dispatch_barrier_async_f", sentrycrash__hook_dispatch_barrier_async_f, + (void *)&real_dispatch_barrier_async_f }, + }, + 6); + + // NOTE: We will *not* hook the following functions: + // + // - dispatch_async_and_wait + // - dispatch_async_and_wait_f + // - dispatch_barrier_async_and_wait + // - dispatch_barrier_async_and_wait_f + // + // Because these functions `will use the stack of the submitting thread` in some cases + // and our thread tracking logic would do the wrong thing in that case. + // + // See: + // https://github.com/apple/swift-corelibs-libdispatch/blob/f13ea5dcc055e5d2d7c02e90d8c9907ca9dc72e1/private/workloop_private.h#L321-L326 +} + +void +sentrycrash_deactivate_async_hooks() +{ + // Instead of reverting the rebinding (which is not really possible), we rather + // deactivate the hooks. They still exist, and still get called, but they will just + // call through to the real libdispatch functions immediately. + __atomic_store_n(&hooks_active, false, __ATOMIC_RELAXED); +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryHook.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryHook.h new file mode 100644 index 00000000..ef866cfa --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/SentryHook.h @@ -0,0 +1,46 @@ +#ifndef SENRTY_HOOK_h +#define SENRTY_HOOK_h + +#include "SentryCrashThread.h" +#include + +#define MAX_BACKTRACE_FRAMES 128 + +/** + * This represents a stacktrace that can optionally have an `async_caller` and form an async call + * chain. + */ +typedef struct sentrycrash_async_backtrace_s sentrycrash_async_backtrace_t; +struct sentrycrash_async_backtrace_s { + size_t refcount; + sentrycrash_async_backtrace_t *async_caller; + size_t len; + void *backtrace[MAX_BACKTRACE_FRAMES]; +}; + +/** + * Returns the async caller of the current calling context, if any. + */ +sentrycrash_async_backtrace_t *sentrycrash_get_async_caller_for_thread(SentryCrashThread); + +/** + * Installs the various async hooks that sentry offers. + * + * The hooks work like this: + * We overwrite the `libdispatch/dispatch_async`, etc functions with our own wrapper. + * Those wrappers create a stacktrace in the calling thread, and pass that stacktrace via a closure + * into the callee thread. In the callee, the stacktrace is saved as a thread-local before invoking + * the original block/function. The thread local can be accessed for inspection and is also used for + * chained async calls. + */ +void sentrycrash_install_async_hooks(void); + +/** + * Deactivates the previously installed hooks. + * + * It is not really possible to uninstall the previously installed hooks, so we rather just + * deactivate them. + */ +void sentrycrash_deactivate_async_hooks(void); + +#endif /* SENRTY_HOOK_h */ diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/fishhook.c b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/fishhook.c new file mode 100644 index 00000000..cb64e81d --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/fishhook.c @@ -0,0 +1,268 @@ +// Copyright (c) 2013, Facebook, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name Facebook nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific +// prior written permission. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "fishhook.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __LP64__ +typedef struct mach_header_64 mach_header_t; +typedef struct segment_command_64 segment_command_t; +typedef struct section_64 section_t; +typedef struct nlist_64 nlist_t; +# define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 +#else +typedef struct mach_header mach_header_t; +typedef struct segment_command segment_command_t; +typedef struct section section_t; +typedef struct nlist nlist_t; +# define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT +#endif + +#ifndef SEG_DATA_CONST +# define SEG_DATA_CONST "__DATA_CONST" +#endif + +#ifndef SEG_AUTH_CONST +# define SEG_AUTH_CONST "__AUTH_CONST" +#endif + +struct rebindings_entry { + struct rebinding *rebindings; + size_t rebindings_nel; + struct rebindings_entry *next; +}; + +static struct rebindings_entry *_rebindings_head; + +static int +prepend_rebindings( + struct rebindings_entry **rebindings_head, struct rebinding rebindings[], size_t nel) +{ + struct rebindings_entry *new_entry + = (struct rebindings_entry *)malloc(sizeof(struct rebindings_entry)); + if (!new_entry) { + return -1; + } + new_entry->rebindings = (struct rebinding *)malloc(sizeof(struct rebinding) * nel); + if (!new_entry->rebindings) { + free(new_entry); + return -1; + } + memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel); + new_entry->rebindings_nel = nel; + new_entry->next = *rebindings_head; + *rebindings_head = new_entry; + return 0; +} + +static vm_prot_t +get_protection(void *sectionStart) +{ + mach_port_t task = mach_task_self(); + vm_size_t size = 0; + vm_address_t address = (vm_address_t)sectionStart; + memory_object_name_t object; +#if __LP64__ + mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; + vm_region_basic_info_data_64_t info; + kern_return_t info_ret = vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO_64, + (vm_region_info_64_t)&info, &count, &object); +#else + mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT; + vm_region_basic_info_data_t info; + kern_return_t info_ret = vm_region( + task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object); +#endif + if (info_ret == KERN_SUCCESS) { + return info.protection; + } else { + return VM_PROT_READ; + } +} + +static void +perform_rebinding_with_section(struct rebindings_entry *rebindings, section_t *section, + intptr_t slide, nlist_t *symtab, char *strtab, uint32_t *indirect_symtab) +{ + uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; + void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); + for (uint i = 0; i < section->size / sizeof(void *); i++) { + uint32_t symtab_index = indirect_symbol_indices[i]; + if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL + || symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { + continue; + } + uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; + char *symbol_name = strtab + strtab_offset; + bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1]; + struct rebindings_entry *cur = rebindings; + while (cur) { + for (uint j = 0; j < cur->rebindings_nel; j++) { + if (symbol_name_longer_than_1 + && strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { + if (cur->rebindings[j].replaced != NULL + && indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { + *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; + } + bool is_prot_changed = false; + void **address_to_write = indirect_symbol_bindings + i; + vm_prot_t prot = get_protection(address_to_write); + if ((prot & VM_PROT_WRITE) == 0) { + is_prot_changed = true; + kern_return_t success + = vm_protect(mach_task_self(), (vm_address_t)address_to_write, + sizeof(void *), false, prot | VM_PROT_WRITE); + if (success != KERN_SUCCESS) { + goto symbol_loop; + } + } + indirect_symbol_bindings[i] = cur->rebindings[j].replacement; + if (is_prot_changed) { + vm_protect(mach_task_self(), (vm_address_t)address_to_write, sizeof(void *), + false, prot); + } + goto symbol_loop; + } + } + cur = cur->next; + } + symbol_loop:; + } +} + +static void +rebind_symbols_for_image( + struct rebindings_entry *rebindings, const struct mach_header *header, intptr_t slide) +{ + Dl_info info; + if (dladdr(header, &info) == 0) { + return; + } + + segment_command_t *cur_seg_cmd; + segment_command_t *linkedit_segment = NULL; + struct symtab_command *symtab_cmd = NULL; + struct dysymtab_command *dysymtab_cmd = NULL; + + uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); + for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { + cur_seg_cmd = (segment_command_t *)cur; + if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { + if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) { + linkedit_segment = cur_seg_cmd; + } + } else if (cur_seg_cmd->cmd == LC_SYMTAB) { + symtab_cmd = (struct symtab_command *)cur_seg_cmd; + } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) { + dysymtab_cmd = (struct dysymtab_command *)cur_seg_cmd; + } + } + + if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment || !dysymtab_cmd->nindirectsyms) { + return; + } + + // Find base symbol/string table addresses + uintptr_t linkedit_base + = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; + nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); + char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); + + // Get indirect symbol table (array of uint32_t indices into symbol table) + uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); + + cur = (uintptr_t)header + sizeof(mach_header_t); + for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { + cur_seg_cmd = (segment_command_t *)cur; + if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { + if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 + && strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0 + && strcmp(cur_seg_cmd->segname, SEG_AUTH_CONST) != 0) { + continue; + } + for (uint j = 0; j < cur_seg_cmd->nsects; j++) { + section_t *sect = (section_t *)(cur + sizeof(segment_command_t)) + j; + if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { + perform_rebinding_with_section( + rebindings, sect, slide, symtab, strtab, indirect_symtab); + } + if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { + perform_rebinding_with_section( + rebindings, sect, slide, symtab, strtab, indirect_symtab); + } + } + } + } +} + +static void +_rebind_symbols_for_image(const struct mach_header *header, intptr_t slide) +{ + rebind_symbols_for_image(_rebindings_head, header, slide); +} + +int +sentrycrash__hook_rebind_symbols_image( + void *header, intptr_t slide, struct rebinding rebindings[], size_t rebindings_nel) +{ + struct rebindings_entry *rebindings_head = NULL; + int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); + rebind_symbols_for_image(rebindings_head, (const struct mach_header *)header, slide); + if (rebindings_head) { + free(rebindings_head->rebindings); + } + free(rebindings_head); + return retval; +} + +int +sentrycrash__hook_rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) +{ + int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel); + if (retval < 0) { + return retval; + } + // If this was the first call, register callback for image additions (which is also invoked for + // existing images, otherwise, just run on existing images + if (!_rebindings_head->next) { + _dyld_register_func_for_add_image(_rebind_symbols_for_image); + } else { + uint32_t c = _dyld_image_count(); + for (uint32_t i = 0; i < c; i++) { + _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); + } + } + return retval; +} diff --git a/Pods/Sentry/Sources/SentryCrash/Recording/Tools/fishhook.h b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/fishhook.h new file mode 100644 index 00000000..eba1b877 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Recording/Tools/fishhook.h @@ -0,0 +1,73 @@ +// Copyright (c) 2013, Facebook, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name Facebook nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific +// prior written permission. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef fishhook_h +#define fishhook_h + +#include +#include + +#if !defined(FISHHOOK_EXPORT) +# define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) +#else +# define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) +#endif + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +/* + * A structure representing a particular intended rebinding from a symbol + * name to its replacement + */ +struct rebinding { + const char *name; + void *replacement; + void **replaced; +}; + +/* + * For each rebinding in rebindings, rebinds references to external, indirect + * symbols with the specified name to instead point at replacement for each + * image in the calling process as well as for all future images that are loaded + * by the process. If rebind_functions is called more than once, the symbols to + * rebind are added to the existing list of rebindings, and if a given symbol + * is rebound more than once, the later rebinding will take precedence. + */ +FISHHOOK_VISIBILITY +int sentrycrash__hook_rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); + +/* + * Rebinds as above, but only in the specified image. The header should point + * to the mach-o header, the slide should be the slide offset. Others as above. + */ +FISHHOOK_VISIBILITY +int sentrycrash__hook_rebind_symbols_image( + void *header, intptr_t slide, struct rebinding rebindings[], size_t rebindings_nel); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif // fishhook_h diff --git a/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilter.h b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilter.h new file mode 100644 index 00000000..9934ff4f --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilter.h @@ -0,0 +1,71 @@ +// +// SentryCrashReportFilter.h +// +// Created by Karl Stenerud on 2012-02-18. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +/** Callback for filter operations. + * + * @param filteredReports The filtered reports (may be incomplete if "completed" + * is false). + * @param completed True if filtering completed. + * Can be false due to a non-erroneous condition (such as a + * user cancelling the operation). + * @param error Non-nil if an error occurred. + */ +typedef void (^SentryCrashReportFilterCompletion)( + NSArray *filteredReports, BOOL completed, NSError *error); + +/** + * A filter receives a set of reports, possibly transforms them, and then + * calls a completion method. + */ +@protocol SentryCrashReportFilter + +/** Filter the specified reports. + * + * @param reports The reports to process. + * @param onCompletion Block to call when processing is complete. + */ +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion; + +@end + +/** Conditionally call a completion method if it's not nil. + * + * @param onCompletion The completion block. If nil, this function does nothing. + * @param filteredReports The parameter to send as "filteredReports". + * @param completed The parameter to send as "completed". + * @param error The parameter to send as "error". + */ +static inline void +sentrycrash_callCompletion(SentryCrashReportFilterCompletion onCompletion, NSArray *filteredReports, + BOOL completed, NSError *error) +{ + if (onCompletion) { + onCompletion(filteredReports, completed, error); + } +} diff --git a/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.h b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.h new file mode 100644 index 00000000..c3626342 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.h @@ -0,0 +1,200 @@ +// +// SentryCrashReportFilterBasic.h +// +// Created by Karl Stenerud on 2012-05-11. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashReportFilter.h" + +/** + * Very basic filter that passes through reports untouched. + * + * Input: Anything. + * Output: Same as input (passthrough). + */ +@interface SentryCrashReportFilterPassthrough : NSObject + ++ (SentryCrashReportFilterPassthrough *)filter; + +@end + +/** + * Passes reports to a series of subfilters, then stores the results of those + * operations as keyed values in final master reports. + * + * Input: Anything + * Output: NSDictionary + */ +@interface SentryCrashReportFilterCombine : NSObject + +/** Constructor. + * + * @param firstFilter The first filter, followed by key, filter, key, ... + * Each "filter" can be id or an + * NSArray of filters (which gets wrapped in a pipeline filter). + */ ++ (SentryCrashReportFilterCombine *)filterWithFiltersAndKeys:(id)firstFilter, + ... NS_REQUIRES_NIL_TERMINATION; + +/** Initializer. + * + * @param firstFilter The first filter, followed by key, filter, key, ... + * Each "filter" can be id or an + * NSArray of filters (which gets wrapped in a pipeline filter). + */ +- (id)initWithFiltersAndKeys:(id)firstFilter, ... NS_REQUIRES_NIL_TERMINATION; + +@end + +/** + * A pipeline of filters. Reports get passed through each subfilter in order. + * + * Input: Depends on what's in the pipeline. + * Output: Depends on what's in the pipeline. + */ +@interface SentryCrashReportFilterPipeline : NSObject + +/** The filters in this pipeline. */ +@property (nonatomic, readonly, retain) NSArray *filters; + +/** Constructor. + * + * @param firstFilter The first filter, followed by filter, filter, ... + */ ++ (SentryCrashReportFilterPipeline *)filterWithFilters:(id)firstFilter, + ... NS_REQUIRES_NIL_TERMINATION; + +/** Initializer. + * + * @param firstFilter The first filter, followed by filter, filter, ... + */ +- (id)initWithFilters:(id)firstFilter, ... NS_REQUIRES_NIL_TERMINATION; + +- (void)addFilter:(id)filter; + +@end + +/** + * Extracts data associated with a key from each report. + */ +@interface SentryCrashReportFilterObjectForKey : NSObject + +/** Constructor. + * + * @param key The key to search for in each report. If the key is a string, + * it will be interpreted as a key path. + * @param allowNotFound If NO, filtering will stop with an error if the key + * was not found in a report. + */ ++ (SentryCrashReportFilterObjectForKey *)filterWithKey:(id)key allowNotFound:(BOOL)allowNotFound; + +/** Initializer. + * + * @param key The key to search for in each report. If the key is a string, + * it will be interpreted as a key path. + * @param allowNotFound If NO, filtering will stop with an error if the key + * was not found in a report. + */ +- (id)initWithKey:(id)key allowNotFound:(BOOL)allowNotFound; + +@end + +/** + * Takes values by key from the report and concatenates their string + * representations. + * + * Input: NSDictionary + * Output: NSString + */ +@interface SentryCrashReportFilterConcatenate : NSObject + +/** Constructor. + * + * @param separatorFmt Formatting text to use when separating the values. You + * may include + * %@ in the formatting text to include the key name as + * well. + * @param firstKey Series of keys to extract from the source report. + */ ++ (SentryCrashReportFilterConcatenate *)filterWithSeparatorFmt:(NSString *)separatorFmt + keys:(id)firstKey, + ... NS_REQUIRES_NIL_TERMINATION; + +/** Constructor. + * + * @param separatorFmt Formatting text to use when separating the values. You + * may include + * %@ in the formatting text to include the key name as + * well. + * @param firstKey Series of keys to extract from the source report. + */ +- (id)initWithSeparatorFmt:(NSString *)separatorFmt + keys:(id)firstKey, ... NS_REQUIRES_NIL_TERMINATION; + +@end + +/** + * Fetches subsets of data from the source reports. All other data is discarded. + * + * Input: NSDictionary + * Output: NSDictionary + */ +@interface SentryCrashReportFilterSubset : NSObject + +/** Constructor. + * + * @param firstKeyPath Series of key paths to search in the source reports. + */ ++ (SentryCrashReportFilterSubset *)filterWithKeys:(id)firstKeyPath, ... NS_REQUIRES_NIL_TERMINATION; + +/** Initializer. + * + * @param firstKeyPath Series of key paths to search in the source reports. + */ +- (id)initWithKeys:(id)firstKeyPath, ... NS_REQUIRES_NIL_TERMINATION; + +@end + +/** + * Convert UTF-8 data to an NSString. + * + * Input: NSData + * Output: NSString + */ +@interface SentryCrashReportFilterDataToString : NSObject + ++ (SentryCrashReportFilterDataToString *)filter; + +@end + +/** + * Convert NSString to UTF-8 encoded NSData. + * + * Input: NSString + * Output: NSData + */ +@interface SentryCrashReportFilterStringToData : NSObject + ++ (SentryCrashReportFilterStringToData *)filter; + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.m b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.m new file mode 100644 index 00000000..b2ed90c7 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/SentryCrashReportFilterBasic.m @@ -0,0 +1,531 @@ +// +// SentryCrashReportFilterBasic.m +// +// Created by Karl Stenerud on 2012-05-11. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashReportFilterBasic.h" +#import "Container+SentryDeepSearch.h" +#import "NSError+SentrySimpleConstructor.h" +#import "SentryCrashVarArgs.h" + +//#define SentryCrashLogger_LocalLevel TRACE +#import "SentryCrashLogger.h" + +@implementation SentryCrashReportFilterPassthrough + ++ (SentryCrashReportFilterPassthrough *)filter +{ + return [[self alloc] init]; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + sentrycrash_callCompletion(onCompletion, reports, YES, nil); +} + +@end + +@interface +SentryCrashReportFilterCombine () + +@property (nonatomic, readwrite, retain) NSArray *filters; +@property (nonatomic, readwrite, retain) NSArray *keys; + +- (id)initWithFilters:(NSArray *)filters keys:(NSArray *)keys; + +@end + +@implementation SentryCrashReportFilterCombine + +@synthesize filters = _filters; +@synthesize keys = _keys; + +- (id)initWithFilters:(NSArray *)filters keys:(NSArray *)keys +{ + if ((self = [super init])) { + self.filters = filters; + self.keys = keys; + } + return self; +} + ++ (SentryCrashVA_Block)argBlockWithFilters:(NSMutableArray *)filters andKeys:(NSMutableArray *)keys +{ + __block BOOL isKey = FALSE; + SentryCrashVA_Block block = ^(id entry) { + if (isKey) { + if (entry == nil) { + SentryCrashLOG_ERROR(@"key entry was nil"); + } else { + [keys addObject:entry]; + } + } else { + if ([entry isKindOfClass:[NSArray class]]) { + entry = [SentryCrashReportFilterPipeline filterWithFilters:entry, nil]; + } + if (![entry conformsToProtocol:@protocol(SentryCrashReportFilter)]) { + SentryCrashLOG_ERROR(@"Not a filter: %@", entry); + // Cause next key entry to fail as well. + return; + } else { + [filters addObject:entry]; + } + } + isKey = !isKey; + }; + return [block copy]; +} + ++ (SentryCrashReportFilterCombine *)filterWithFiltersAndKeys:(id)firstFilter, ... +{ + NSMutableArray *filters = [NSMutableArray array]; + NSMutableArray *keys = [NSMutableArray array]; + sentrycrashva_iterate_list(firstFilter, [self argBlockWithFilters:filters andKeys:keys]); + return [[self alloc] initWithFilters:filters keys:keys]; +} + +- (id)initWithFiltersAndKeys:(id)firstFilter, ... +{ + NSMutableArray *filters = [NSMutableArray array]; + NSMutableArray *keys = [NSMutableArray array]; + sentrycrashva_iterate_list( + firstFilter, [[self class] argBlockWithFilters:filters andKeys:keys]); + return [self initWithFilters:filters keys:keys]; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSArray *filters = self.filters; + NSArray *keys = self.keys; + NSUInteger filterCount = [filters count]; + + if (filterCount == 0) { + sentrycrash_callCompletion(onCompletion, reports, YES, nil); + return; + } + + if (filterCount != [keys count]) { + sentrycrash_callCompletion(onCompletion, reports, NO, + [NSError sentryErrorWithDomain:[[self class] description] + code:0 + description:@"Key/filter mismatch (%d keys, %d filters", + [keys count], filterCount]); + return; + } + + NSMutableArray *reportSets = [NSMutableArray arrayWithCapacity:filterCount]; + + __block NSUInteger iFilter = 0; + __block SentryCrashReportFilterCompletion filterCompletion = nil; + __block __weak SentryCrashReportFilterCompletion weakFilterCompletion = nil; + dispatch_block_t disposeOfCompletion = [^{ + // Release self-reference on the main thread. + dispatch_async(dispatch_get_main_queue(), ^{ filterCompletion = nil; }); + } copy]; + filterCompletion = [^(NSArray *filteredReports, BOOL completed, NSError *filterError) { + if (!completed || filteredReports == nil) { + if (!completed) { + sentrycrash_callCompletion(onCompletion, filteredReports, completed, filterError); + } else if (filteredReports == nil) { + sentrycrash_callCompletion(onCompletion, filteredReports, NO, + [NSError sentryErrorWithDomain:[[self class] description] + code:0 + description:@"filteredReports was nil"]); + } + disposeOfCompletion(); + return; + } + + // Normal run until all filters exhausted. + [reportSets addObject:filteredReports]; + if (++iFilter < filterCount) { + id filter = [filters objectAtIndex:iFilter]; + [filter filterReports:reports onCompletion:weakFilterCompletion]; + return; + } + + // All filters complete, or a filter failed. + // Build final "filteredReports" array. + NSUInteger reportCount = [(NSArray *)[reportSets objectAtIndex:0] count]; + NSMutableArray *combinedReports = [NSMutableArray arrayWithCapacity:reportCount]; + for (NSUInteger iReport = 0; iReport < reportCount; iReport++) { + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:filterCount]; + for (NSUInteger iSet = 0; iSet < filterCount; iSet++) { + NSArray *reportSet = [reportSets objectAtIndex:iSet]; + if (reportSet.count > iReport) { + NSDictionary *report = [reportSet objectAtIndex:iReport]; + [dict setObject:report forKey:[keys objectAtIndex:iSet]]; + } + } + [combinedReports addObject:dict]; + } + + sentrycrash_callCompletion(onCompletion, combinedReports, completed, filterError); + disposeOfCompletion(); + } copy]; + weakFilterCompletion = filterCompletion; + + // Initial call with first filter to start everything going. + id filter = [filters objectAtIndex:iFilter]; + [filter filterReports:reports onCompletion:filterCompletion]; +} + +@end + +@interface +SentryCrashReportFilterPipeline () + +@property (nonatomic, readwrite, retain) NSArray *filters; + +@end + +@implementation SentryCrashReportFilterPipeline + +@synthesize filters = _filters; + ++ (SentryCrashReportFilterPipeline *)filterWithFilters:(id)firstFilter, ... +{ + sentrycrashva_list_to_nsarray(firstFilter, filters); + return [[self alloc] initWithFiltersArray:filters]; +} + +- (id)initWithFilters:(id)firstFilter, ... +{ + sentrycrashva_list_to_nsarray(firstFilter, filters); + return [self initWithFiltersArray:filters]; +} + +- (id)initWithFiltersArray:(NSArray *)filters +{ + if ((self = [super init])) { + NSMutableArray *expandedFilters = [NSMutableArray array]; + for (id filter in filters) { + if ([filter isKindOfClass:[NSArray class]]) { + [expandedFilters addObjectsFromArray:(NSArray *)filter]; + } else { + [expandedFilters addObject:filter]; + } + } + self.filters = expandedFilters; + } + return self; +} + +- (void)addFilter:(id)filter +{ + NSMutableArray *mutableFilters = (NSMutableArray *)self.filters; // Shh! Don't tell anyone! + [mutableFilters insertObject:filter atIndex:0]; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSArray *filters = self.filters; + NSUInteger filterCount = [filters count]; + + if (filterCount == 0) { + sentrycrash_callCompletion(onCompletion, reports, YES, nil); + return; + } + + __block NSUInteger iFilter = 0; + __block SentryCrashReportFilterCompletion filterCompletion; + __block __weak SentryCrashReportFilterCompletion weakFilterCompletion = nil; + dispatch_block_t disposeOfCompletion = [^{ + // Release self-reference on the main thread. + dispatch_async(dispatch_get_main_queue(), ^{ filterCompletion = nil; }); + } copy]; + filterCompletion = [^(NSArray *filteredReports, BOOL completed, NSError *filterError) { + if (!completed || filteredReports == nil) { + if (!completed) { + sentrycrash_callCompletion(onCompletion, filteredReports, completed, filterError); + } else if (filteredReports == nil) { + sentrycrash_callCompletion(onCompletion, filteredReports, NO, + [NSError sentryErrorWithDomain:[[self class] description] + code:0 + description:@"filteredReports was nil"]); + } + disposeOfCompletion(); + return; + } + + // Normal run until all filters exhausted or one + // filter fails to complete. + if (++iFilter < filterCount) { + id filter = [filters objectAtIndex:iFilter]; + [filter filterReports:filteredReports onCompletion:weakFilterCompletion]; + return; + } + + // All filters complete, or a filter failed. + sentrycrash_callCompletion(onCompletion, filteredReports, completed, filterError); + disposeOfCompletion(); + } copy]; + weakFilterCompletion = filterCompletion; + + // Initial call with first filter to start everything going. + id filter = [filters objectAtIndex:iFilter]; + [filter filterReports:reports onCompletion:filterCompletion]; +} + +@end + +@interface +SentryCrashReportFilterObjectForKey () + +@property (nonatomic, readwrite, retain) id key; +@property (nonatomic, readwrite, assign) BOOL allowNotFound; + +@end + +@implementation SentryCrashReportFilterObjectForKey + +@synthesize key = _key; +@synthesize allowNotFound = _allowNotFound; + ++ (SentryCrashReportFilterObjectForKey *)filterWithKey:(id)key allowNotFound:(BOOL)allowNotFound +{ + return [[self alloc] initWithKey:key allowNotFound:allowNotFound]; +} + +- (id)initWithKey:(id)key allowNotFound:(BOOL)allowNotFound +{ + if ((self = [super init])) { + self.key = key; + self.allowNotFound = allowNotFound; + } + return self; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (NSDictionary *report in reports) { + id object = nil; + if ([self.key isKindOfClass:[NSString class]]) { + object = [report sentry_objectForKeyPath:self.key]; + } else { + object = [report objectForKey:self.key]; + } + if (object == nil) { + if (!self.allowNotFound) { + sentrycrash_callCompletion(onCompletion, filteredReports, NO, + [NSError sentryErrorWithDomain:[[self class] description] + code:0 + description:@"Key not found: %@", self.key]); + return; + } + [filteredReports addObject:[NSDictionary dictionary]]; + } else { + [filteredReports addObject:object]; + } + } + sentrycrash_callCompletion(onCompletion, filteredReports, YES, nil); +} + +@end + +@interface +SentryCrashReportFilterConcatenate () + +@property (nonatomic, readwrite, retain) NSString *separatorFmt; +@property (nonatomic, readwrite, retain) NSArray *keys; + +@end + +@implementation SentryCrashReportFilterConcatenate + +@synthesize separatorFmt = _separatorFmt; +@synthesize keys = _keys; + ++ (SentryCrashReportFilterConcatenate *)filterWithSeparatorFmt:(NSString *)separatorFmt + keys:(id)firstKey, ... +{ + sentrycrashva_list_to_nsarray(firstKey, keys); + return [[self alloc] initWithSeparatorFmt:separatorFmt keysArray:keys]; +} + +- (id)initWithSeparatorFmt:(NSString *)separatorFmt keys:(id)firstKey, ... +{ + sentrycrashva_list_to_nsarray(firstKey, keys); + return [self initWithSeparatorFmt:separatorFmt keysArray:keys]; +} + +- (id)initWithSeparatorFmt:(NSString *)separatorFmt keysArray:(NSArray *)keys +{ + if ((self = [super init])) { + NSMutableArray *realKeys = [NSMutableArray array]; + for (id key in keys) { + if ([key isKindOfClass:[NSArray class]]) { + [realKeys addObjectsFromArray:(NSArray *)key]; + } else { + [realKeys addObject:key]; + } + } + + self.separatorFmt = separatorFmt; + self.keys = realKeys; + } + return self; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (NSDictionary *report in reports) { + BOOL firstEntry = YES; + NSMutableString *concatenated = [NSMutableString string]; + for (NSString *key in self.keys) { + if (firstEntry) { + firstEntry = NO; + } else { + [concatenated appendFormat:self.separatorFmt, key]; + } + id object = [report sentry_objectForKeyPath:key]; + [concatenated appendFormat:@"%@", object]; + } + [filteredReports addObject:concatenated]; + } + sentrycrash_callCompletion(onCompletion, filteredReports, YES, nil); +} + +@end + +@interface +SentryCrashReportFilterSubset () + +@property (nonatomic, readwrite, retain) NSArray *keyPaths; + +@end + +@implementation SentryCrashReportFilterSubset + +@synthesize keyPaths = _keyPaths; + ++ (SentryCrashReportFilterSubset *)filterWithKeys:(id)firstKeyPath, ... +{ + sentrycrashva_list_to_nsarray(firstKeyPath, keyPaths); + return [[self alloc] initWithKeysArray:keyPaths]; +} + +- (id)initWithKeys:(id)firstKeyPath, ... +{ + sentrycrashva_list_to_nsarray(firstKeyPath, keyPaths); + return [self initWithKeysArray:keyPaths]; +} + +- (id)initWithKeysArray:(NSArray *)keyPaths +{ + if ((self = [super init])) { + NSMutableArray *realKeyPaths = [NSMutableArray array]; + for (id keyPath in keyPaths) { + if ([keyPath isKindOfClass:[NSArray class]]) { + [realKeyPaths addObjectsFromArray:(NSArray *)keyPath]; + } else { + [realKeyPaths addObject:keyPath]; + } + } + + self.keyPaths = realKeyPaths; + } + return self; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (NSDictionary *report in reports) { + NSMutableDictionary *subset = [NSMutableDictionary dictionary]; + for (NSString *keyPath in self.keyPaths) { + id object = [report sentry_objectForKeyPath:keyPath]; + if (object == nil) { + sentrycrash_callCompletion(onCompletion, filteredReports, NO, + [NSError sentryErrorWithDomain:[[self class] description] + code:0 + description:@"Report did not have key path %@", keyPath]); + return; + } + [subset setObject:object forKey:[keyPath lastPathComponent]]; + } + [filteredReports addObject:subset]; + } + sentrycrash_callCompletion(onCompletion, filteredReports, YES, nil); +} + +@end + +@implementation SentryCrashReportFilterDataToString + ++ (SentryCrashReportFilterDataToString *)filter +{ + return [[self alloc] init]; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (NSData *report in reports) { + NSString *converted = [[NSString alloc] initWithData:report encoding:NSUTF8StringEncoding]; + [filteredReports addObject:converted]; + } + + sentrycrash_callCompletion(onCompletion, filteredReports, YES, nil); +} + +@end + +@implementation SentryCrashReportFilterStringToData + ++ (SentryCrashReportFilterStringToData *)filter +{ + return [[self alloc] init]; +} + +- (void)filterReports:(NSArray *)reports + onCompletion:(SentryCrashReportFilterCompletion)onCompletion +{ + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (NSString *report in reports) { + NSData *converted = [report dataUsingEncoding:NSUTF8StringEncoding]; + if (converted == nil) { + sentrycrash_callCompletion(onCompletion, filteredReports, NO, + [NSError sentryErrorWithDomain:[[self class] description] + code:0 + description:@"Could not convert report to UTF-8"]); + return; + } else { + [filteredReports addObject:converted]; + } + } + + sentrycrash_callCompletion(onCompletion, filteredReports, YES, nil); +} + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.h b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.h new file mode 100644 index 00000000..33505dd0 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.h @@ -0,0 +1,203 @@ +// +// Container+DeepSearch +// +// Created by Karl Stenerud on 2012-08-25. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/** Deep key search based methods for hierarchical container structures. + * + * A deep key search works like a normal search, except that the "key" is + * interpreted as a series of keys, to be recursively applied in a "drill down" + * fashion. There are two variants of each: the "deep key" variant, where the + * key series is passed as an array, and the "key path" variant, where the + * key series is passed as a serialized path, similar to filesystem paths + * (a string where entries are separated by slashes). + * + * For example, if objectForDeepKey were called with [@"top", @"sublevel", @"2", + * @"item] (or objectForKeyPath were called with @"top/sublevel/2/item"), it + * would search as follows: + * + * result = [self objectForKey:@"top"]; + * result = [result objectForKey:@"sublevel"]; + * result = [result objectForKey:@"2"]; + * result = [result objectForKey:@"item"]; + * + * Note that if any potential container along the way does not respond to + * "objectForKey:", it will check to see if the container responds to + * "objectAtIndex:" AND the current key responds to "intValue". If both do + * respond, it will retrieve the current result using an array lookup: + * + * result = [result objectAtIndex:[currentKey intValue]]; + */ + +#import + +#pragma mark - NSDictionary - + +/** + * Deep key search methods for NSDictionary. + */ +@interface NSDictionary (SentryDeepSearch) + +#pragma mark - Lookups + +/** Do a deep search using the specified keys. + * + * A failed lookup returns nil, except in the case of a failed array-style + * lookup, in which case it may throw an "index out of range" exception. + * + * @param deepKey A set of keys to drill down with. + */ +- (id)sentry_objectForDeepKey:(NSArray *)deepKey; + +/** Do a deep search using the specified keys. + * + * A failed lookup returns nil, except in the case of a failed array-style + * lookup, in which case it may throw an "index out of range" exception. + * + * @param keyPath A full key path, separated by slash (e.g. @"a/b/c") + */ +- (id)sentry_objectForKeyPath:(NSString *)keyPath; + +#pragma mark - Mutators + +/** Set an associated object at the specified deep key. + * + * The object will be stored either dictionary style "setObject:forKey:" or + * array style "replaceObjectAtIndex:withObject:", depending on what the + * final container object responds to. + * + * If the lookup fails at any level, it will throw an exception describing which + * object in the hierarchy did not respond to any object accessor methods. + */ +- (void)sentry_setObject:(id)anObject forDeepKey:(NSArray *)deepKey; + +/** Set an associated object at the specified key path. + * + * The object will be stored either dictionary style "setObject:forKey:" or + * array style "replaceObjectAtIndex:withObject:", depending on what the + * final container object responds to. + * + * If the lookup fails at any level, it will throw an exception describing which + * object in the hierarchy did not respond to any object accessor methods. + */ +- (void)sentry_setObject:(id)anObject forKeyPath:(NSString *)keyPath; + +/** Remove an associated object at the specified deep key. + * + * The object will be stored either dictionary style "removeObjectForKey:" or + * array style "removeObjectAtIndex:", depending on what the final container + * object responds to. + * + * If the lookup fails at any level, it will throw an exception describing which + * object in the hierarchy did not respond to any object accessor methods. + */ +- (void)sentry_removeObjectForDeepKey:(NSArray *)deepKey; + +/** Remove an associated object at the specified key path. + * + * The object will be stored either dictionary style "removeObjectForKey:" or + * array style "removeObjectAtIndex:", depending on what the final container + * object responds to. + * + * If the lookup fails at any level, it will throw an exception describing which + * object in the hierarchy did not respond to any object accessor methods. + */ +- (void)sentry_removeObjectForKeyPath:(NSString *)keyPath; + +@end + +#pragma mark - NSArray - + +/** + * Deep key search methods for NSDictionary. + */ +@interface NSArray (DeepSearch) + +#pragma mark - Lookups + +/** Do a deep search using the specified keys. + * + * A failed lookup returns nil, except in the case of a failed array-style + * lookup, in which case it may throw an "index out of range" exception. + * + * @param deepKey A set of keys to drill down with. + */ +- (id)sentry_objectForDeepKey:(NSArray *)deepKey; + +/** Do a deep search using the specified keys. + * + * A failed lookup returns nil, except in the case of a failed array-style + * lookup, in which case it may throw an "index out of range" exception. + * + * @param keyPath A full key path, separated by slash (e.g. @"a/b/c") + */ +- (id)sentry_objectForKeyPath:(NSString *)keyPath; + +#pragma mark - Mutators + +/** Set an associated object at the specified deep key. + * + * The object will be stored either dictionary style "setObject:forKey:" or + * array style "replaceObjectAtIndex:withObject:", depending on what the + * final container object responds to. + * + * If the lookup fails at any level, it will throw an exception describing which + * object in the hierarchy did not respond to any object accessor methods. + */ +- (void)sentry_setObject:(id)anObject forDeepKey:(NSArray *)deepKey; + +/** Set an associated object at the specified key path. + * + * The object will be stored either dictionary style "setObject:forKey:" or + * array style "replaceObjectAtIndex:withObject:", depending on what the + * final container object responds to. + * + * If the lookup fails at any level, it will throw an exception describing which + * object in the hierarchy did not respond to any object accessor methods. + */ +- (void)sentry_setObject:(id)anObject forKeyPath:(NSString *)keyPath; + +/** Remove an associated object at the specified deep key. + * + * The object will be stored either dictionary style "removeObjectForKey:" or + * array style "removeObjectAtIndex:", depending on what the final container + * object responds to. + * + * If the lookup fails at any level, it will throw an exception describing which + * object in the hierarchy did not respond to any object accessor methods. + */ +- (void)sentry_removeObjectForDeepKey:(NSArray *)deepKey; + +/** Remove an associated object at the specified key path. + * + * The object will be stored either dictionary style "removeObjectForKey:" or + * array style "removeObjectAtIndex:", depending on what the final container + * object responds to. + * + * If the lookup fails at any level, it will throw an exception describing which + * object in the hierarchy did not respond to any object accessor methods. + */ +- (void)sentry_removeObjectForKeyPath:(NSString *)keyPath; + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.m b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.m new file mode 100644 index 00000000..397dc5d1 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/Container+SentryDeepSearch.m @@ -0,0 +1,249 @@ +// +// Container+DeepSearch +// +// Created by Karl Stenerud on 2012-08-25. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "Container+SentryDeepSearch.h" + +#pragma mark - Base functionality + +static BOOL +isNumericString(NSString *str) +{ + if ([str length] == 0) { + return YES; + } + unichar ch = [str characterAtIndex:0]; + return ch >= '0' && ch <= '9'; +} + +static id +objectForDeepKey(id container, NSArray *deepKey) +{ + for (id key in deepKey) { + if ([container respondsToSelector:@selector(objectForKey:)]) { + container = [(NSDictionary *)container objectForKey:key]; + } else { + if ([container respondsToSelector:@selector(objectAtIndex:)] && + [key respondsToSelector:@selector(intValue)]) { + if ([key isKindOfClass:[NSString class]] && !isNumericString(key)) { + return nil; + } + NSUInteger index = (NSUInteger)[key intValue]; + container = [container objectAtIndex:index]; + } else { + return nil; + } + } + if (container == nil) { + break; + } + } + return container; +} + +static id +objectForKeyPath(id container, NSString *keyPath) +{ + while ([keyPath length] > 0 && [keyPath characterAtIndex:0] == '/') { + keyPath = [keyPath substringFromIndex:1]; + } + return objectForDeepKey(container, [keyPath componentsSeparatedByString:@"/"]); +} + +static id +parentOfDeepKey(id container, NSArray *deepKey) +{ + NSUInteger deepKeyCount = [deepKey count]; + if (deepKeyCount == 1) { + return container; + } + + NSArray *parentKey = [deepKey subarrayWithRange:NSMakeRange(0, deepKeyCount - 1)]; + id parent = objectForDeepKey(container, parentKey); + if (parent == nil) { + NSString *reason = + [NSString stringWithFormat:@"Parent %@ does not resolve to a valid object", parentKey]; + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:reason + userInfo:nil]; + } + return parent; +} + +static void +setObjectForDeepKey(id container, id object, NSArray *deepKey) +{ + if ([deepKey count] == 0) { + @throw [NSException exceptionWithName:NSInvalidArgumentException + reason:[NSString stringWithFormat:@"deepKey %@ must contain " + @"at least one key", + deepKey] + userInfo:nil]; + } + NSString *excFormat = nil; + id lastKey = [deepKey objectAtIndex:[deepKey count] - 1]; + id parentContainer = parentOfDeepKey(container, deepKey); + if ([parentContainer respondsToSelector:@selector(setObject:forKey:)]) { + [(NSMutableDictionary *)parentContainer setObject:object forKey:lastKey]; + return; + } else if ([lastKey respondsToSelector:@selector(intValue)]) { + if ([parentContainer respondsToSelector:@selector(replaceObjectAtIndex:withObject:)]) { + NSUInteger index = (NSUInteger)[lastKey intValue]; + [(NSMutableArray *)parentContainer replaceObjectAtIndex:index withObject:object]; + return; + } else { + excFormat = @"Parent %@ of type %@ does not respond to " + @"\"setObject:forKey:\" or " + @"\"replaceObjectAtIndex:withObject:\""; + } + } else { + excFormat = @"Parent %@ of type %@ does not respond to \"setObject:forKey:\""; + } + + NSArray *parentKey = [deepKey subarrayWithRange:NSMakeRange(0, [deepKey count] - 1)]; + NSString *reason = [NSString stringWithFormat:excFormat, parentKey, [parentContainer class]]; + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:reason + userInfo:nil]; +} + +static void +setObjectForKeyPath(id container, id object, NSString *keyPath) +{ + setObjectForDeepKey(container, object, [keyPath componentsSeparatedByString:@"/"]); +} + +static void +removeObjectForDeepKey(id container, NSArray *deepKey) +{ + NSString *excFormat = nil; + id lastKey = [deepKey objectAtIndex:[deepKey count] - 1]; + id parentContainer = parentOfDeepKey(container, deepKey); + if ([parentContainer respondsToSelector:@selector(removeObjectForKey:)]) { + [(NSMutableDictionary *)parentContainer removeObjectForKey:lastKey]; + return; + } else if ([lastKey respondsToSelector:@selector(intValue)]) { + if ([parentContainer respondsToSelector:@selector(removeObjectAtIndex:)]) { + NSUInteger index = (NSUInteger)[lastKey intValue]; + [(NSMutableArray *)parentContainer removeObjectAtIndex:index]; + return; + } else { + excFormat = @"Parent %@ of type %@ does not respond to " + @"\"removeObjectForKey:\" or \"removeObjectAtIndex:\""; + } + } else { + excFormat = @"Parent %@ of type %@ does not respond to " + @"\"removeObjectForKey:\""; + } + + NSArray *parentKey = [deepKey subarrayWithRange:NSMakeRange(0, [deepKey count] - 1)]; + NSString *reason = [NSString stringWithFormat:excFormat, parentKey, [parentContainer class]]; + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:reason + userInfo:nil]; +} + +static void +removeObjectForKeyPath(id container, NSString *keyPath) +{ + removeObjectForDeepKey(container, [keyPath componentsSeparatedByString:@"/"]); +} + +#pragma mark - NSDictionary Category + +@implementation NSDictionary (DeepSearch) + +- (id)sentry_objectForDeepKey:(NSArray *)deepKey +{ + return objectForDeepKey(self, deepKey); +} + +- (id)sentry_objectForKeyPath:(NSString *)keyPath +{ + return objectForKeyPath(self, keyPath); +} + +- (void)sentry_setObject:(id)anObject forDeepKey:(NSArray *)deepKey +{ + setObjectForDeepKey(self, anObject, deepKey); +} + +- (void)sentry_setObject:(id)anObject forKeyPath:(NSString *)keyPath +{ + setObjectForKeyPath(self, anObject, keyPath); +} + +- (void)sentry_removeObjectForDeepKey:(NSArray *)deepKey +{ + removeObjectForDeepKey(self, deepKey); +} + +- (void)sentry_removeObjectForKeyPath:(NSString *)keyPath +{ + removeObjectForKeyPath(self, keyPath); +} + +@end + +#pragma mark - NSArray Category + +@implementation NSArray (DeepSearch) + +- (id)sentry_objectForDeepKey:(NSArray *)deepKey +{ + return objectForDeepKey(self, deepKey); +} + +- (id)sentry_objectForKeyPath:(NSString *)keyPath +{ + return objectForKeyPath(self, keyPath); +} + +- (void)sentry_setObject:(id)anObject forDeepKey:(NSArray *)deepKey +{ + setObjectForDeepKey(self, anObject, deepKey); +} + +- (void)sentry_setObject:(id)anObject forKeyPath:(NSString *)keyPath +{ + setObjectForKeyPath(self, anObject, keyPath); +} + +- (void)sentry_removeObjectForDeepKey:(NSArray *)deepKey +{ + removeObjectForDeepKey(self, deepKey); +} + +- (void)sentry_removeObjectForKeyPath:(NSString *)keyPath +{ + removeObjectForKeyPath(self, keyPath); +} + +@end + +@interface sentrycrashobjc_DeepSearchP5EM1B9 : NSObject +@end +@implementation sentrycrashobjc_DeepSearchP5EM1B9 +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/SentryCrashVarArgs.h b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/SentryCrashVarArgs.h new file mode 100644 index 00000000..cb6e5f7f --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Reporting/Filters/Tools/SentryCrashVarArgs.h @@ -0,0 +1,95 @@ +// +// SentryCrashVarArgs.h +// +// Created by Karl Stenerud on 2012-08-19. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/* SentryCrashVarArgs is a set of macros designed to make dealing with variable + * arguments easier in Objective-C. All macros assume that the varargs list + * contains only objective-c objects or object-like structures (assignable to + * type id). + * + * The base macro sentrycrashva_iterate_list() iterates over the variable + * arguments, invoking a block for each argument, until it encounters a + * terminating nil. + * + * The other macros are for convenience when converting to common collections. + */ + +/** Block type used by sentrycrashva_iterate_list. + * + * @param entry The current argument in the vararg list. + */ +typedef void (^SentryCrashVA_Block)(id entry); + +/** + * Iterate over a va_list, executing the specified code block for each entry. + * + * @param FIRST_ARG_NAME The name of the first argument in the vararg list. + * @param BLOCK A code block of type SentryCrashVA_Block. + */ +#define sentrycrashva_iterate_list(FIRST_ARG_NAME, BLOCK) \ + { \ + SentryCrashVA_Block sentrycrashva_block = BLOCK; \ + va_list sentrycrashva_args; \ + va_start(sentrycrashva_args, FIRST_ARG_NAME); \ + for (id sentrycrashva_arg = FIRST_ARG_NAME; sentrycrashva_arg != nil; \ + sentrycrashva_arg = va_arg(sentrycrashva_args, id)) { \ + sentrycrashva_block(sentrycrashva_arg); \ + } \ + va_end(sentrycrashva_args); \ + } + +/** + * Convert a variable argument list into an array. An autoreleased + * NSMutableArray will be created in the current scope with the specified name. + * + * @param FIRST_ARG_NAME The name of the first argument in the vararg list. + * @param ARRAY_NAME The name of the array to create in the current scope. + */ +#define sentrycrashva_list_to_nsarray(FIRST_ARG_NAME, ARRAY_NAME) \ + NSMutableArray *ARRAY_NAME = [NSMutableArray array]; \ + sentrycrashva_iterate_list(FIRST_ARG_NAME, ^(id entry) { [ARRAY_NAME addObject:entry]; }) + +/** + * Convert a variable argument list into a dictionary, interpreting the vararg + * list as object, key, object, key, ... + * An autoreleased NSMutableDictionary will be created in the current scope with + * the specified name. + * + * @param FIRST_ARG_NAME The name of the first argument in the vararg list. + * @param DICT_NAME The name of the dictionary to create in the current scope. + */ +#define sentrycrashva_list_to_nsdictionary(FIRST_ARG_NAME, DICT_NAME) \ + NSMutableDictionary *DICT_NAME = [NSMutableDictionary dictionary]; \ + { \ + __block id sentrycrashva_object = nil; \ + sentrycrashva_iterate_list(FIRST_ARG_NAME, ^(id entry) { \ + if (sentrycrashva_object == nil) { \ + sentrycrashva_object = entry; \ + } else { \ + [DICT_NAME setObject:sentrycrashva_object forKey:entry]; \ + sentrycrashva_object = nil; \ + } \ + }); \ + } diff --git a/Pods/Sentry/Sources/SentryCrash/Reporting/Tools/SentryCrashCString.h b/Pods/Sentry/Sources/SentryCrash/Reporting/Tools/SentryCrashCString.h new file mode 100644 index 00000000..e5d8da87 --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Reporting/Tools/SentryCrashCString.h @@ -0,0 +1,58 @@ +// +// SentryCrashCString.h +// +// Created by Karl Stenerud on 2013-02-23. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +/** + * A string, stored C style with null termination. + */ +@interface SentryCrashCString : NSObject + +/** Length of the string in bytes (not characters!). Length does not include + * null terminator. */ +@property (nonatomic, readonly, assign) NSUInteger length; + +/** String contents, including null terminator */ +@property (nonatomic, readonly, assign) const char *bytes; + +/** Constructor for NSString */ ++ (SentryCrashCString *)stringWithString:(NSString *)string; + +/** Constructor for null-terminated C string (assumes UTF-8 encoding). */ ++ (SentryCrashCString *)stringWithCString:(const char *)string; + +/** Constructor for string contained in NSData (assumes UTF-8 encoding). */ ++ (SentryCrashCString *)stringWithData:(NSData *)data; + +/** Constructor for non-terminated string (assumes UTF-8 encoding). */ ++ (SentryCrashCString *)stringWithData:(const char *)data length:(NSUInteger)length; + +- (id)initWithString:(NSString *)string; +- (id)initWithCString:(const char *)string; +- (id)initWithData:(NSData *)data; +- (id)initWithData:(const char *)data length:(NSUInteger)length; + +@end diff --git a/Pods/Sentry/Sources/SentryCrash/Reporting/Tools/SentryCrashCString.m b/Pods/Sentry/Sources/SentryCrash/Reporting/Tools/SentryCrashCString.m new file mode 100644 index 00000000..af11161c --- /dev/null +++ b/Pods/Sentry/Sources/SentryCrash/Reporting/Tools/SentryCrashCString.m @@ -0,0 +1,98 @@ +// +// SentryCrashCString.m +// +// Created by Karl Stenerud on 2013-02-23. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SentryCrashCString.h" + +@implementation SentryCrashCString + +@synthesize length = _length; +@synthesize bytes = _bytes; + ++ (SentryCrashCString *)stringWithString:(NSString *)string +{ + return [[self alloc] initWithString:string]; +} + ++ (SentryCrashCString *)stringWithCString:(const char *)string +{ + return [[self alloc] initWithCString:string]; +} + ++ (SentryCrashCString *)stringWithData:(NSData *)data +{ + return [[self alloc] initWithData:data]; +} + ++ (SentryCrashCString *)stringWithData:(const char *)data length:(NSUInteger)length +{ + return [[self alloc] initWithData:data length:length]; +} + +- (id)initWithString:(NSString *)string +{ + return [self initWithCString:[string cStringUsingEncoding:NSUTF8StringEncoding]]; +} + +- (id)initWithCString:(const char *)string +{ + if ((self = [super init])) { + _bytes = strdup(string); + if (_bytes != NULL) { + _length = strlen(_bytes); + } + } + return self; +} + +- (id)initWithData:(NSData *)data +{ + return [self initWithData:data.bytes length:data.length]; +} + +- (id)initWithData:(const char *)data length:(NSUInteger)length +{ + if ((self = [super init])) { + _length = length; + char *bytes = malloc((unsigned)_length + 1); + if (bytes != NULL) { + memcpy(bytes, data, _length); + bytes[_length] = 0; + _bytes = bytes; + } else { + _length = 0; + } + } + return self; +} + +- (void)dealloc +{ + if (_bytes != NULL) { + free((void *)_bytes); + } +} + +@end diff --git a/Pods/Target Support Files/EasyMapping-macOS/EasyMapping-macOS.debug.xcconfig b/Pods/Target Support Files/EasyMapping-macOS/EasyMapping-macOS.debug.xcconfig index 93a7baf4..cfa0eec6 100644 --- a/Pods/Target Support Files/EasyMapping-macOS/EasyMapping-macOS.debug.xcconfig +++ b/Pods/Target Support Files/EasyMapping-macOS/EasyMapping-macOS.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-macOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/EasyMapping" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/EasyMapping +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/EasyMapping-macOS/EasyMapping-macOS.release.xcconfig b/Pods/Target Support Files/EasyMapping-macOS/EasyMapping-macOS.release.xcconfig index 93a7baf4..cfa0eec6 100644 --- a/Pods/Target Support Files/EasyMapping-macOS/EasyMapping-macOS.release.xcconfig +++ b/Pods/Target Support Files/EasyMapping-macOS/EasyMapping-macOS.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-macOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/EasyMapping" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/EasyMapping +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS.debug.xcconfig b/Pods/Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS.debug.xcconfig index 5f13afdc..b00faa67 100644 --- a/Pods/Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS.debug.xcconfig +++ b/Pods/Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-tvOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/EasyMapping" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/EasyMapping +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS.release.xcconfig b/Pods/Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS.release.xcconfig index 5f13afdc..b00faa67 100644 --- a/Pods/Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS.release.xcconfig +++ b/Pods/Target Support Files/EasyMapping-tvOS/EasyMapping-tvOS.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-tvOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/EasyMapping" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/EasyMapping +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Expecta/Expecta.debug.xcconfig b/Pods/Target Support Files/Expecta/Expecta.debug.xcconfig index 525d2597..1c9298ec 100644 --- a/Pods/Target Support Files/Expecta/Expecta.debug.xcconfig +++ b/Pods/Target Support Files/Expecta/Expecta.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Expecta ENABLE_BITCODE = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" @@ -7,6 +8,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Expecta +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Expecta/Expecta.release.xcconfig b/Pods/Target Support Files/Expecta/Expecta.release.xcconfig index 525d2597..1c9298ec 100644 --- a/Pods/Target Support Files/Expecta/Expecta.release.xcconfig +++ b/Pods/Target Support Files/Expecta/Expecta.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Expecta ENABLE_BITCODE = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" @@ -7,6 +8,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Expecta +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Kingfisher/Kingfisher.debug.xcconfig b/Pods/Target Support Files/Kingfisher/Kingfisher.debug.xcconfig index cfd49ecd..4d6d1cbb 100644 --- a/Pods/Target Support Files/Kingfisher/Kingfisher.debug.xcconfig +++ b/Pods/Target Support Files/Kingfisher/Kingfisher.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Kingfisher" "${PODS_ROOT}/Headers/Public" @@ -6,6 +7,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Kingfisher +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Kingfisher/Kingfisher.release.xcconfig b/Pods/Target Support Files/Kingfisher/Kingfisher.release.xcconfig index cfd49ecd..4d6d1cbb 100644 --- a/Pods/Target Support Files/Kingfisher/Kingfisher.release.xcconfig +++ b/Pods/Target Support Files/Kingfisher/Kingfisher.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Kingfisher" "${PODS_ROOT}/Headers/Public" @@ -6,6 +7,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Kingfisher +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Mixpanel-macOS/Mixpanel-macOS.debug.xcconfig b/Pods/Target Support Files/Mixpanel-macOS/Mixpanel-macOS.debug.xcconfig index c0fe3266..a3fafd94 100644 --- a/Pods/Target Support Files/Mixpanel-macOS/Mixpanel-macOS.debug.xcconfig +++ b/Pods/Target Support Files/Mixpanel-macOS/Mixpanel-macOS.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-macOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_MACOS HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Mixpanel" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Mixpanel" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Mixpanel +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Mixpanel-macOS/Mixpanel-macOS.release.xcconfig b/Pods/Target Support Files/Mixpanel-macOS/Mixpanel-macOS.release.xcconfig index c0fe3266..a3fafd94 100644 --- a/Pods/Target Support Files/Mixpanel-macOS/Mixpanel-macOS.release.xcconfig +++ b/Pods/Target Support Files/Mixpanel-macOS/Mixpanel-macOS.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-macOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_MACOS HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Mixpanel" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Mixpanel" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Mixpanel +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS.debug.xcconfig b/Pods/Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS.debug.xcconfig index 50cf2097..dbb72f35 100644 --- a/Pods/Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS.debug.xcconfig +++ b/Pods/Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-tvOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_TVOS HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Mixpanel" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Mixpanel" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Mixpanel +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS.release.xcconfig b/Pods/Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS.release.xcconfig index 50cf2097..dbb72f35 100644 --- a/Pods/Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS.release.xcconfig +++ b/Pods/Target Support Files/Mixpanel-tvOS/Mixpanel-tvOS.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-tvOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_TVOS HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Mixpanel" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Mixpanel" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Mixpanel +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView.debug.xcconfig b/Pods/Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView.debug.xcconfig index fdfdc716..337fcaf3 100644 --- a/Pods/Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView.debug.xcconfig +++ b/Pods/Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/NSPopover+MISSINGBackgroundView GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/NSPopover+MISSINGBackgroundView +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView.release.xcconfig b/Pods/Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView.release.xcconfig index fdfdc716..337fcaf3 100644 --- a/Pods/Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView.release.xcconfig +++ b/Pods/Target Support Files/NSPopover+MISSINGBackgroundView/NSPopover+MISSINGBackgroundView.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/NSPopover+MISSINGBackgroundView GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/NSPopover+MISSINGBackgroundView +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/OCMock/OCMock.debug.xcconfig b/Pods/Target Support Files/OCMock/OCMock.debug.xcconfig index 733e3135..19d5344d 100644 --- a/Pods/Target Support Files/OCMock/OCMock.debug.xcconfig +++ b/Pods/Target Support Files/OCMock/OCMock.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/OCMock GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/OCMock" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/OCMock" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/OCMock +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/OCMock/OCMock.release.xcconfig b/Pods/Target Support Files/OCMock/OCMock.release.xcconfig index 733e3135..19d5344d 100644 --- a/Pods/Target Support Files/OCMock/OCMock.release.xcconfig +++ b/Pods/Target Support Files/OCMock/OCMock.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/OCMock GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/OCMock" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/OCMock" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/OCMock +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-BitBot/Pods-BitBot-acknowledgements.markdown b/Pods/Target Support Files/Pods-BitBot/Pods-BitBot-acknowledgements.markdown index f021ddbf..afdc9c67 100644 --- a/Pods/Target Support Files/Pods-BitBot/Pods-BitBot-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-BitBot/Pods-BitBot-acknowledgements.markdown @@ -339,4 +339,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Sentry + +The MIT License (MIT) + +Copyright (c) 2015 Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-BitBot/Pods-BitBot-acknowledgements.plist b/Pods/Target Support Files/Pods-BitBot/Pods-BitBot-acknowledgements.plist index 62b5102e..1b247827 100644 --- a/Pods/Target Support Files/Pods-BitBot/Pods-BitBot-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-BitBot/Pods-BitBot-acknowledgements.plist @@ -375,6 +375,38 @@ THE SOFTWARE. Type PSGroupSpecifier + + FooterText + The MIT License (MIT) + +Copyright (c) 2015 Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + License + mit + Title + Sentry + Type + PSGroupSpecifier + FooterText Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-BitBot/Pods-BitBot.debug.xcconfig b/Pods/Target Support Files/Pods-BitBot/Pods-BitBot.debug.xcconfig index c04ae6b1..6bd06251 100644 --- a/Pods/Target Support Files/Pods-BitBot/Pods-BitBot.debug.xcconfig +++ b/Pods/Target Support Files/Pods-BitBot/Pods-BitBot.debug.xcconfig @@ -1,9 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +GCC_ENABLE_CPP_EXCEPTIONS = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_MACOS -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public/OCMock" "${PODS_ROOT}/Headers/Public/SDWebImage" -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-macOS" "${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-macOS" "${PODS_CONFIGURATION_BUILD_DIR}/NSPopover+MISSINGBackgroundView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" -OTHER_LDFLAGS = $(inherited) -ObjC -l"EasyMapping-macOS" -l"Mixpanel-macOS" -l"NSPopover+MISSINGBackgroundView" -l"SDWebImage" -l"icucore" -framework "AppKit" -framework "Cocoa" -framework "CoreData" -framework "Foundation" -framework "IOKit" -framework "ImageIO" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public/OCMock" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/Sentry" +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-macOS" "${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-macOS" "${PODS_CONFIGURATION_BUILD_DIR}/NSPopover+MISSINGBackgroundView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Sentry-macOS" +OTHER_LDFLAGS = $(inherited) -ObjC -l"EasyMapping-macOS" -l"Mixpanel-macOS" -l"NSPopover+MISSINGBackgroundView" -l"SDWebImage" -l"Sentry-macOS" -l"c++" -l"icucore" -l"z" -framework "AppKit" -framework "Cocoa" -framework "CoreData" -framework "Foundation" -framework "IOKit" -framework "ImageIO" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-BitBot/Pods-BitBot.release.xcconfig b/Pods/Target Support Files/Pods-BitBot/Pods-BitBot.release.xcconfig index c04ae6b1..6bd06251 100644 --- a/Pods/Target Support Files/Pods-BitBot/Pods-BitBot.release.xcconfig +++ b/Pods/Target Support Files/Pods-BitBot/Pods-BitBot.release.xcconfig @@ -1,9 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +GCC_ENABLE_CPP_EXCEPTIONS = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_MACOS -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public/OCMock" "${PODS_ROOT}/Headers/Public/SDWebImage" -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-macOS" "${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-macOS" "${PODS_CONFIGURATION_BUILD_DIR}/NSPopover+MISSINGBackgroundView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" -OTHER_LDFLAGS = $(inherited) -ObjC -l"EasyMapping-macOS" -l"Mixpanel-macOS" -l"NSPopover+MISSINGBackgroundView" -l"SDWebImage" -l"icucore" -framework "AppKit" -framework "Cocoa" -framework "CoreData" -framework "Foundation" -framework "IOKit" -framework "ImageIO" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public/OCMock" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/Sentry" +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-macOS" "${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-macOS" "${PODS_CONFIGURATION_BUILD_DIR}/NSPopover+MISSINGBackgroundView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Sentry-macOS" +OTHER_LDFLAGS = $(inherited) -ObjC -l"EasyMapping-macOS" -l"Mixpanel-macOS" -l"NSPopover+MISSINGBackgroundView" -l"SDWebImage" -l"Sentry-macOS" -l"c++" -l"icucore" -l"z" -framework "AppKit" -framework "Cocoa" -framework "CoreData" -framework "Foundation" -framework "IOKit" -framework "ImageIO" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-acknowledgements.markdown b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-acknowledgements.markdown similarity index 93% rename from Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-acknowledgements.markdown rename to Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-acknowledgements.markdown index b0588bc7..a3a75d31 100644 --- a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-acknowledgements.markdown @@ -290,6 +290,32 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## Sentry + +The MIT License (MIT) + +Copyright (c) 2015 Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + ## Kingfisher The MIT License (MIT) diff --git a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-acknowledgements.plist b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-acknowledgements.plist similarity index 93% rename from Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-acknowledgements.plist rename to Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-acknowledgements.plist index 73cafce1..0f96d1cd 100644 --- a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-acknowledgements.plist @@ -317,6 +317,38 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. FooterText The MIT License (MIT) +Copyright (c) 2015 Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + License + mit + Title + Sentry + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + Copyright (c) 2019 Wei Wang Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-dummy.m b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-dummy.m new file mode 100644 index 00000000..49fa2387 --- /dev/null +++ b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_BitBotATV : NSObject +@end +@implementation PodsDummy_Pods_BitBotATV +@end diff --git a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-umbrella.h b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-umbrella.h similarity index 61% rename from Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-umbrella.h rename to Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-umbrella.h index d429f868..44528e07 100644 --- a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-umbrella.h +++ b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV-umbrella.h @@ -11,6 +11,6 @@ #endif -FOUNDATION_EXPORT double Pods_BitriseATVVersionNumber; -FOUNDATION_EXPORT const unsigned char Pods_BitriseATVVersionString[]; +FOUNDATION_EXPORT double Pods_BitBotATVVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_BitBotATVVersionString[]; diff --git a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.debug.xcconfig b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.debug.xcconfig similarity index 65% rename from Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.debug.xcconfig rename to Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.debug.xcconfig index 51330e6a..0bc6c8f2 100644 --- a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.debug.xcconfig +++ b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.debug.xcconfig @@ -1,13 +1,16 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +GCC_ENABLE_CPP_EXCEPTIONS = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_TVOS -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Kingfisher" "${PODS_ROOT}/Headers/Public/Mixpanel" -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-tvOS" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-tvOS" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Kingfisher" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/Sentry" +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-tvOS" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-tvOS" "${PODS_CONFIGURATION_BUILD_DIR}/Sentry-tvOS" OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.modulemap" -OTHER_LDFLAGS = $(inherited) -ObjC -l"EasyMapping-tvOS" -l"Kingfisher" -l"Mixpanel-tvOS" -l"icucore" -framework "Accelerate" -framework "CFNetwork" -framework "CoreData" -framework "Foundation" -framework "UIKit" +OTHER_LDFLAGS = $(inherited) -ObjC -l"EasyMapping-tvOS" -l"Kingfisher" -l"Mixpanel-tvOS" -l"Sentry-tvOS" -l"c++" -l"icucore" -l"z" -framework "Accelerate" -framework "CFNetwork" -framework "CoreData" -framework "Foundation" -framework "UIKit" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.modulemap" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates SWIFT_INCLUDE_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.modulemap b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.modulemap new file mode 100644 index 00000000..3abcbf06 --- /dev/null +++ b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.modulemap @@ -0,0 +1,6 @@ +module Pods_BitBotATV { + umbrella header "Pods-BitBotATV-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.release.xcconfig b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.release.xcconfig similarity index 65% rename from Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.release.xcconfig rename to Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.release.xcconfig index 51330e6a..0bc6c8f2 100644 --- a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.release.xcconfig +++ b/Pods/Target Support Files/Pods-BitBotATV/Pods-BitBotATV.release.xcconfig @@ -1,13 +1,16 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +GCC_ENABLE_CPP_EXCEPTIONS = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_TVOS -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Kingfisher" "${PODS_ROOT}/Headers/Public/Mixpanel" -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-tvOS" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-tvOS" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Kingfisher" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/Sentry" +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyMapping-tvOS" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/Mixpanel-tvOS" "${PODS_CONFIGURATION_BUILD_DIR}/Sentry-tvOS" OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.modulemap" -OTHER_LDFLAGS = $(inherited) -ObjC -l"EasyMapping-tvOS" -l"Kingfisher" -l"Mixpanel-tvOS" -l"icucore" -framework "Accelerate" -framework "CFNetwork" -framework "CoreData" -framework "Foundation" -framework "UIKit" +OTHER_LDFLAGS = $(inherited) -ObjC -l"EasyMapping-tvOS" -l"Kingfisher" -l"Mixpanel-tvOS" -l"Sentry-tvOS" -l"c++" -l"icucore" -l"z" -framework "Accelerate" -framework "CFNetwork" -framework "CoreData" -framework "Foundation" -framework "UIKit" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.modulemap" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates SWIFT_INCLUDE_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-BitBotTests/Pods-BitBotTests.debug.xcconfig b/Pods/Target Support Files/Pods-BitBotTests/Pods-BitBotTests.debug.xcconfig index c1920e25..98c65ab4 100644 --- a/Pods/Target Support Files/Pods-BitBotTests/Pods-BitBotTests.debug.xcconfig +++ b/Pods/Target Support Files/Pods-BitBotTests/Pods-BitBotTests.debug.xcconfig @@ -1,10 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" +GCC_ENABLE_CPP_EXCEPTIONS = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_MACOS -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public/OCMock" "${PODS_ROOT}/Headers/Public/SDWebImage" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public/OCMock" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/Sentry" LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Expecta" "${PODS_CONFIGURATION_BUILD_DIR}/OCMock" -OTHER_LDFLAGS = $(inherited) -ObjC -l"Expecta" -l"OCMock" -l"icucore" -framework "AppKit" -framework "Cocoa" -framework "CoreData" -framework "Foundation" -framework "IOKit" -framework "ImageIO" -framework "XCTest" +OTHER_LDFLAGS = $(inherited) -ObjC -l"Expecta" -l"OCMock" -l"c++" -l"icucore" -l"z" -framework "AppKit" -framework "Cocoa" -framework "CoreData" -framework "Foundation" -framework "IOKit" -framework "ImageIO" -framework "XCTest" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-BitBotTests/Pods-BitBotTests.release.xcconfig b/Pods/Target Support Files/Pods-BitBotTests/Pods-BitBotTests.release.xcconfig index c1920e25..98c65ab4 100644 --- a/Pods/Target Support Files/Pods-BitBotTests/Pods-BitBotTests.release.xcconfig +++ b/Pods/Target Support Files/Pods-BitBotTests/Pods-BitBotTests.release.xcconfig @@ -1,10 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" +GCC_ENABLE_CPP_EXCEPTIONS = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) MIXPANEL_MACOS -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public/OCMock" "${PODS_ROOT}/Headers/Public/SDWebImage" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EasyMapping" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Mixpanel" "${PODS_ROOT}/Headers/Public/NSPopover+MISSINGBackgroundView" "${PODS_ROOT}/Headers/Public/OCMock" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/Sentry" LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Expecta" "${PODS_CONFIGURATION_BUILD_DIR}/OCMock" -OTHER_LDFLAGS = $(inherited) -ObjC -l"Expecta" -l"OCMock" -l"icucore" -framework "AppKit" -framework "Cocoa" -framework "CoreData" -framework "Foundation" -framework "IOKit" -framework "ImageIO" -framework "XCTest" +OTHER_LDFLAGS = $(inherited) -ObjC -l"Expecta" -l"OCMock" -l"c++" -l"icucore" -l"z" -framework "AppKit" -framework "Cocoa" -framework "CoreData" -framework "Foundation" -framework "IOKit" -framework "ImageIO" -framework "XCTest" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-dummy.m b/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-dummy.m deleted file mode 100644 index 020fa975..00000000 --- a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV-dummy.m +++ /dev/null @@ -1,5 +0,0 @@ -#import -@interface PodsDummy_Pods_BitriseATV : NSObject -@end -@implementation PodsDummy_Pods_BitriseATV -@end diff --git a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.modulemap b/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.modulemap deleted file mode 100644 index 893b1dd3..00000000 --- a/Pods/Target Support Files/Pods-BitriseATV/Pods-BitriseATV.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -module Pods_BitriseATV { - umbrella header "Pods-BitriseATV-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig b/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig index ea069159..e1700314 100644 --- a/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig +++ b/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SDWebImage" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig b/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig index ea069159..e1700314 100644 --- a/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig +++ b/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig @@ -1,3 +1,4 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SDWebImage" @@ -5,6 +6,7 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Sentry-macOS/Sentry-macOS-dummy.m b/Pods/Target Support Files/Sentry-macOS/Sentry-macOS-dummy.m new file mode 100644 index 00000000..fea7d5f2 --- /dev/null +++ b/Pods/Target Support Files/Sentry-macOS/Sentry-macOS-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Sentry_macOS : NSObject +@end +@implementation PodsDummy_Sentry_macOS +@end diff --git a/Pods/Target Support Files/Sentry-macOS/Sentry-macOS-prefix.pch b/Pods/Target Support Files/Sentry-macOS/Sentry-macOS-prefix.pch new file mode 100644 index 00000000..082f8af2 --- /dev/null +++ b/Pods/Target Support Files/Sentry-macOS/Sentry-macOS-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/Sentry-macOS/Sentry-macOS.debug.xcconfig b/Pods/Target Support Files/Sentry-macOS/Sentry-macOS.debug.xcconfig new file mode 100644 index 00000000..4a64ce33 --- /dev/null +++ b/Pods/Target Support Files/Sentry-macOS/Sentry-macOS.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Sentry-macOS +GCC_ENABLE_CPP_EXCEPTIONS = YES +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Sentry" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Sentry" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Sentry +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Sentry-macOS/Sentry-macOS.release.xcconfig b/Pods/Target Support Files/Sentry-macOS/Sentry-macOS.release.xcconfig new file mode 100644 index 00000000..4a64ce33 --- /dev/null +++ b/Pods/Target Support Files/Sentry-macOS/Sentry-macOS.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Sentry-macOS +GCC_ENABLE_CPP_EXCEPTIONS = YES +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Sentry" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Sentry" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Sentry +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS-dummy.m b/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS-dummy.m new file mode 100644 index 00000000..2bd0e152 --- /dev/null +++ b/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Sentry_tvOS : NSObject +@end +@implementation PodsDummy_Sentry_tvOS +@end diff --git a/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS-prefix.pch b/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS.debug.xcconfig b/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS.debug.xcconfig new file mode 100644 index 00000000..f2c5149d --- /dev/null +++ b/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Sentry-tvOS +GCC_ENABLE_CPP_EXCEPTIONS = YES +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Sentry" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Sentry" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Sentry +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS.release.xcconfig b/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS.release.xcconfig new file mode 100644 index 00000000..f2c5149d --- /dev/null +++ b/Pods/Target Support Files/Sentry-tvOS/Sentry-tvOS.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Sentry-tvOS +GCC_ENABLE_CPP_EXCEPTIONS = YES +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Sentry" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Sentry" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Sentry +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES