From 974c0f1599785c6887f23b16031143ebc2c4a1e1 Mon Sep 17 00:00:00 2001 From: Noah Martin Date: Mon, 20 Oct 2025 15:07:22 -0400 Subject: [PATCH] ref: Convert SentryANRTracker to class --- .../Profiling/SentryContinuousProfiler.mm | 6 ++-- .../Sentry/Profiling/SentryProfilerState.mm | 4 +-- .../Sentry/Profiling/SentryTraceProfiler.mm | 5 ++- Sources/Sentry/SentryANRTrackerV1.m | 16 +++++---- Sources/Sentry/SentryANRTrackerV2.m | 17 +++++---- Sources/Sentry/SentryANRTrackingIntegration.m | 2 +- .../SentryAutoBreadcrumbTrackingIntegration.m | 1 + .../SentryCoreDataTrackingIntegration.m | 1 + Sources/Sentry/SentryDelayedFramesTracker.m | 8 +++++ Sources/Sentry/SentryDependencyContainer.m | 36 ++++++++++++------- .../SentryDependencyContainerSwiftHelper.m | 5 +++ Sources/Sentry/SentryProfiler.mm | 4 +-- ...ryWatchdogTerminationTrackingIntegration.m | 3 +- .../HybridPublic/SentryDependencyContainer.h | 6 ++-- Sources/Sentry/include/SentryANRTrackerV1.h | 8 +++-- Sources/Sentry/include/SentryANRTrackerV2.h | 8 +++-- .../include/SentryDelayedFramesTracker.h | 9 +++++ .../SentryDependencyContainerSwiftHelper.h | 2 ++ .../Integrations/ANR/SentryANRTracker.swift | 30 ++++++++++++---- ...yAppStartProfilingConfigurationTests.swift | 1 + .../SentryProfileTestFixture.swift | 2 +- .../SentryDependencyContainerTests.swift | 14 ++++---- .../SentryExtraContextProviderTests.swift | 2 +- .../SentryANRTrackerV1IntegrationTests.swift | 4 +-- .../ANR/SentryANRTrackerV1Tests.swift | 8 +++-- .../ANR/SentryANRTrackerV2Tests.swift | 9 +++-- .../SentryANRTrackingIntegrationTests.swift | 10 +++--- .../CoreData/SentryCoreDataTrackerTest.swift | 2 +- .../UIEvents/SentryUIEventTrackerTests.swift | 2 +- .../SentryTransportFactoryTests.swift | 2 +- Tests/SentryTests/SentryClient+TestInit.h | 1 + .../SentryScreenshotSourceTests.swift | 2 +- .../State/SentryInstallationTests.swift | 1 + 33 files changed, 154 insertions(+), 77 deletions(-) diff --git a/Sources/Sentry/Profiling/SentryContinuousProfiler.mm b/Sources/Sentry/Profiling/SentryContinuousProfiler.mm index d028a114a1b..8d47f1aa394 100644 --- a/Sources/Sentry/Profiling/SentryContinuousProfiler.mm +++ b/Sources/Sentry/Profiling/SentryContinuousProfiler.mm @@ -2,7 +2,7 @@ #if SENTRY_TARGET_PROFILING_SUPPORTED -# import "SentryDependencyContainer.h" +# import "SentryDependencyContainerSwiftHelper.h" # import "SentryInternalDefines.h" # import "SentryLogC.h" # import "SentryMetricProfiler.h" @@ -83,7 +83,7 @@ // Move the serialization work to a background queue to avoid potentially // blocking the main thread. The serialization can take several milliseconds. - sentry_dispatchAsync(SentryDependencyContainer.sharedInstance.dispatchQueueWrapper, ^{ + sentry_dispatchAsync(SentryDependencyContainerSwiftHelper.dispatchQueueWrapper, ^{ NSDictionary *_Nonnull serializedMetrics = serializeContinuousProfileMetrics(metricProfilerState); SentryEnvelope *_Nullable envelope @@ -199,7 +199,7 @@ + (nullable SentryId *)currentProfilerID + (void)scheduleTimer { sentry_dispatchAsyncOnMainIfNotMainThread( - SentryDependencyContainer.sharedInstance.dispatchQueueWrapper, ^{ + SentryDependencyContainerSwiftHelper.dispatchQueueWrapper, ^{ std::lock_guard l(_threadUnsafe_gContinuousProfilerLock); if (_chunkTimer != nil) { SENTRY_LOG_WARN( diff --git a/Sources/Sentry/Profiling/SentryProfilerState.mm b/Sources/Sentry/Profiling/SentryProfilerState.mm index 78d10c1f562..05028db4bee 100644 --- a/Sources/Sentry/Profiling/SentryProfilerState.mm +++ b/Sources/Sentry/Profiling/SentryProfilerState.mm @@ -2,7 +2,7 @@ #if SENTRY_TARGET_PROFILING_SUPPORTED # import "SentryAsyncSafeLog.h" # import "SentryBacktrace.hpp" -# import "SentryDependencyContainer.h" +# import "SentryDependencyContainerSwiftHelper.h" # import "SentryFormatter.h" # import "SentryInternalDefines.h" # import "SentryProfileTimeseries.h" @@ -73,7 +73,7 @@ - (instancetype)init _mutableState = [[SentryProfilerMutableState alloc] init]; _mainThreadID = 0; sentry_dispatchAsyncOnMainIfNotMainThread( - SentryDependencyContainer.sharedInstance.dispatchQueueWrapper, + SentryDependencyContainerSwiftHelper.dispatchQueueWrapper, ^{ [self cacheMainThreadID]; }); } return self; diff --git a/Sources/Sentry/Profiling/SentryTraceProfiler.mm b/Sources/Sentry/Profiling/SentryTraceProfiler.mm index 80f6418dbf5..e17b9558092 100644 --- a/Sources/Sentry/Profiling/SentryTraceProfiler.mm +++ b/Sources/Sentry/Profiling/SentryTraceProfiler.mm @@ -2,8 +2,7 @@ #if SENTRY_TARGET_PROFILING_SUPPORTED -# import "SentryDependencyContainer.h" - +# import "SentryDependencyContainerSwiftHelper.h" # import "SentryInternalDefines.h" # import "SentryLogC.h" # import "SentryMetricProfiler.h" @@ -85,7 +84,7 @@ + (void)recordMetrics + (void)scheduleTimeoutTimer { sentry_dispatchAsyncOnMainIfNotMainThread( - SentryDependencyContainer.sharedInstance.dispatchQueueWrapper, ^{ + SentryDependencyContainerSwiftHelper.dispatchQueueWrapper, ^{ std::lock_guard l(_threadUnsafe_gTraceProfilerLock); if (_sentry_threadUnsafe_traceProfileTimeoutTimer != nil) { return; diff --git a/Sources/Sentry/SentryANRTrackerV1.m b/Sources/Sentry/SentryANRTrackerV1.m index a1c419ede74..0e5b4098b00 100644 --- a/Sources/Sentry/SentryANRTrackerV1.m +++ b/Sources/Sentry/SentryANRTrackerV1.m @@ -13,7 +13,7 @@ typedef NS_ENUM(NSInteger, SentryANRTrackerState) { kSentryANRTrackerStopping }; -@interface SentryANRTrackerV1 () +@interface SentryANRTrackerV1 () @property (nonatomic, strong) SentryCrashWrapper *crashWrapper; @property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueueWrapper; @@ -28,6 +28,15 @@ @implementation SentryANRTrackerV1 { SentryANRTrackerState state; } +- (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval +{ + return + [self initWithTimeoutInterval:timeoutInterval + crashWrapper:SentryDependencyContainer.sharedInstance.crashWrapper + dispatchQueueWrapper:SentryDependencyContainer.sharedInstance.dispatchQueueWrapper + threadWrapper:SentryDependencyContainer.sharedInstance.threadWrapper]; +} + - (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval crashWrapper:(SentryCrashWrapper *)crashWrapper dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper @@ -45,11 +54,6 @@ - (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval return self; } -- (id)asProtocol -{ - return self; -} - - (void)detectANRs { NSUUID *threadID = [NSUUID UUID]; diff --git a/Sources/Sentry/SentryANRTrackerV2.m b/Sources/Sentry/SentryANRTrackerV2.m index 16c31178fe8..c358cb5e1dd 100644 --- a/Sources/Sentry/SentryANRTrackerV2.m +++ b/Sources/Sentry/SentryANRTrackerV2.m @@ -17,7 +17,7 @@ typedef NS_ENUM(NSInteger, SentryANRTrackerState) { kSentryANRTrackerStopping }; -@interface SentryANRTrackerV2 () +@interface SentryANRTrackerV2 () @property (nonatomic, strong) SentryCrashWrapper *crashWrapper; @property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueueWrapper; @@ -33,6 +33,16 @@ @implementation SentryANRTrackerV2 { SentryANRTrackerState state; } +- (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval +{ + return + [self initWithTimeoutInterval:timeoutInterval + crashWrapper:SentryDependencyContainer.sharedInstance.crashWrapper + dispatchQueueWrapper:SentryDependencyContainer.sharedInstance.dispatchQueueWrapper + threadWrapper:SentryDependencyContainer.sharedInstance.threadWrapper + framesTracker:SentryDependencyContainer.sharedInstance.framesTracker]; +} + - (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval crashWrapper:(SentryCrashWrapper *)crashWrapper dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper @@ -52,11 +62,6 @@ - (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval return self; } -- (id)asProtocol -{ - return self; -} - - (void)detectANRs { NSUUID *threadID = [NSUUID UUID]; diff --git a/Sources/Sentry/SentryANRTrackingIntegration.m b/Sources/Sentry/SentryANRTrackingIntegration.m index a56f823cd21..ee751db88ee 100644 --- a/Sources/Sentry/SentryANRTrackingIntegration.m +++ b/Sources/Sentry/SentryANRTrackingIntegration.m @@ -24,7 +24,7 @@ @interface SentryANRTrackingIntegration () -@property (nonatomic, strong) id tracker; +@property (nonatomic, strong) SentryANRTracker *tracker; @property (nonatomic, strong) SentryOptions *options; @property (nonatomic, strong) SentryFileManager *fileManager; @property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueueWrapper; diff --git a/Sources/Sentry/SentryAutoBreadcrumbTrackingIntegration.m b/Sources/Sentry/SentryAutoBreadcrumbTrackingIntegration.m index e3d4d2d8eae..78a0673c72b 100644 --- a/Sources/Sentry/SentryAutoBreadcrumbTrackingIntegration.m +++ b/Sources/Sentry/SentryAutoBreadcrumbTrackingIntegration.m @@ -4,6 +4,7 @@ #import "SentryLogC.h" #import "SentryOptions.h" #import "SentrySDKInternal.h" +#import "SentrySwift.h" #import "SentrySystemEventBreadcrumbs.h" NS_ASSUME_NONNULL_BEGIN diff --git a/Sources/Sentry/SentryCoreDataTrackingIntegration.m b/Sources/Sentry/SentryCoreDataTrackingIntegration.m index f49f1bed6d7..724666ecc76 100644 --- a/Sources/Sentry/SentryCoreDataTrackingIntegration.m +++ b/Sources/Sentry/SentryCoreDataTrackingIntegration.m @@ -6,6 +6,7 @@ #import "SentryLogC.h" #import "SentryNSDataSwizzling.h" #import "SentryOptions.h" +#import "SentrySwift.h" @interface SentryCoreDataTrackingIntegration () diff --git a/Sources/Sentry/SentryDelayedFramesTracker.m b/Sources/Sentry/SentryDelayedFramesTracker.m index 4974b2b4a41..57f29cfb174 100644 --- a/Sources/Sentry/SentryDelayedFramesTracker.m +++ b/Sources/Sentry/SentryDelayedFramesTracker.m @@ -3,6 +3,7 @@ #if SENTRY_HAS_UIKIT # import "SentryDelayedFrame.h" +# import "SentryDependencyContainer.h" # import "SentryInternalCDefines.h" # import "SentryLogC.h" # import "SentrySwift.h" @@ -22,6 +23,13 @@ @interface SentryDelayedFramesTracker () @implementation SentryDelayedFramesTracker +- (instancetype)initWithKeepDelayedFramesDuration:(CFTimeInterval)keepDelayedFramesDuration +{ + return [self + initWithKeepDelayedFramesDuration:keepDelayedFramesDuration + dateProvider:SentryDependencyContainer.sharedInstance.dateProvider]; +} + - (instancetype)initWithKeepDelayedFramesDuration:(CFTimeInterval)keepDelayedFramesDuration dateProvider:(id)dateProvider { diff --git a/Sources/Sentry/SentryDependencyContainer.m b/Sources/Sentry/SentryDependencyContainer.m index a52e839f908..1c0f1571d80 100644 --- a/Sources/Sentry/SentryDependencyContainer.m +++ b/Sources/Sentry/SentryDependencyContainer.m @@ -53,6 +53,9 @@ return nil; }; +@interface SentryANRTrackerV1 () +@end + @interface SentryFileManager () @end @@ -62,11 +65,14 @@ @interface SentryWatchdogTerminationScopeObserver () @interface SentryDelayedFramesTracker () @end + +@interface SentryANRTrackerV2 () +@end #endif @interface SentryDependencyContainer () -@property (nonatomic, strong) id anrTracker; +@property (nonatomic, strong) SentryANRTracker *anrTracker; @end @@ -236,27 +242,31 @@ - (SentryCrashSwift *)crashReporter SENTRY_THREAD_SANITIZER_DOUBLE_CHECKED_LOCK [[SentryCrashSwift alloc] initWith:SentrySDKInternal.options.cacheDirectoryPath]); } -- (id)getANRTracker:(NSTimeInterval)timeout +- (SentryANRTracker *)getANRTracker:(NSTimeInterval)timeout SENTRY_THREAD_SANITIZER_DOUBLE_CHECKED_LOCK { SENTRY_LAZY_INIT(_anrTracker, - [[[SentryANRTrackerV1 alloc] initWithTimeoutInterval:timeout - crashWrapper:self.crashWrapper - dispatchQueueWrapper:self.dispatchQueueWrapper - threadWrapper:self.threadWrapper] asProtocol]); + [[SentryANRTracker alloc] + initWithHelper:[[SentryANRTrackerV1 alloc] + initWithTimeoutInterval:timeout + crashWrapper:self.crashWrapper + dispatchQueueWrapper:self.dispatchQueueWrapper + threadWrapper:self.threadWrapper]]); } #if SENTRY_HAS_UIKIT -- (id)getANRTracker:(NSTimeInterval)timeout - isV2Enabled:(BOOL)isV2Enabled SENTRY_THREAD_SANITIZER_DOUBLE_CHECKED_LOCK +- (SentryANRTracker *)getANRTracker:(NSTimeInterval)timeout + isV2Enabled:(BOOL)isV2Enabled SENTRY_THREAD_SANITIZER_DOUBLE_CHECKED_LOCK { if (isV2Enabled) { SENTRY_LAZY_INIT(_anrTracker, - [[[SentryANRTrackerV2 alloc] initWithTimeoutInterval:timeout - crashWrapper:self.crashWrapper - dispatchQueueWrapper:self.dispatchQueueWrapper - threadWrapper:self.threadWrapper - framesTracker:self.framesTracker] asProtocol]); + [[SentryANRTracker alloc] + initWithHelper:[[SentryANRTrackerV2 alloc] + initWithTimeoutInterval:timeout + crashWrapper:self.crashWrapper + dispatchQueueWrapper:self.dispatchQueueWrapper + threadWrapper:self.threadWrapper + framesTracker:self.framesTracker]]); } else { return [self getANRTracker:timeout]; } diff --git a/Sources/Sentry/SentryDependencyContainerSwiftHelper.m b/Sources/Sentry/SentryDependencyContainerSwiftHelper.m index 610d03d3dc1..336dd0ea549 100644 --- a/Sources/Sentry/SentryDependencyContainerSwiftHelper.m +++ b/Sources/Sentry/SentryDependencyContainerSwiftHelper.m @@ -17,6 +17,11 @@ @implementation SentryDependencyContainerSwiftHelper #endif // SENTRY_HAS_UIKIT ++ (SentryDispatchQueueWrapper *)dispatchQueueWrapper +{ + return SentryDependencyContainer.sharedInstance.dispatchQueueWrapper; +} + + (void)dispatchSyncOnMainQueue:(void (^)(void))block { [SentryDependencyContainer.sharedInstance.dispatchQueueWrapper dispatchSyncOnMainQueue:block]; diff --git a/Sources/Sentry/SentryProfiler.mm b/Sources/Sentry/SentryProfiler.mm index 75186133aa5..7f0a0b7cb9f 100644 --- a/Sources/Sentry/SentryProfiler.mm +++ b/Sources/Sentry/SentryProfiler.mm @@ -3,7 +3,7 @@ #if SENTRY_TARGET_PROFILING_SUPPORTED # import "SentryClient+Private.h" # import "SentryContinuousProfiler.h" -# import "SentryDependencyContainer.h" +# import "SentryDependencyContainerSwiftHelper.h" # import "SentryFileManagerHelper.h" # import "SentryHub+Private.h" # import "SentryInternalDefines.h" @@ -121,7 +121,7 @@ sentry_configureContinuousProfiling(options); - sentry_dispatchAsync(SentryDependencyContainer.sharedInstance.dispatchQueueWrapper, ^{ + sentry_dispatchAsync(SentryDependencyContainerSwiftHelper.dispatchQueueWrapper, ^{ if (configurationFromLaunch.isProfilingThisLaunch) { BOOL shouldStopAndTransmitLaunchProfile = YES; diff --git a/Sources/Sentry/SentryWatchdogTerminationTrackingIntegration.m b/Sources/Sentry/SentryWatchdogTerminationTrackingIntegration.m index ce0c9ba6b28..a20d27df83b 100644 --- a/Sources/Sentry/SentryWatchdogTerminationTrackingIntegration.m +++ b/Sources/Sentry/SentryWatchdogTerminationTrackingIntegration.m @@ -13,14 +13,13 @@ # import # import # import -# import # import NS_ASSUME_NONNULL_BEGIN @interface SentryWatchdogTerminationTrackingIntegration () @property (nonatomic, strong) SentryWatchdogTerminationTracker *tracker; -@property (nonatomic, strong) id anrTracker; +@property (nonatomic, strong) SentryANRTracker *anrTracker; @property (nullable, nonatomic, copy) NSString *testConfigurationFilePath; @property (nonatomic, strong) SentryAppStateManager *appStateManager; diff --git a/Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h b/Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h index dbdb68598e3..24232a4ee42 100644 --- a/Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h +++ b/Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h @@ -24,9 +24,9 @@ @class SentrySessionTracker; @class SentryGlobalEventProcessor; @class SentryThreadInspector; +@class SentryANRTracker; @class SentryReachability; -@protocol SentryANRTracker; @protocol SentryRandomProtocol; @protocol SentryCurrentDateProvider; @protocol SentryRateLimits; @@ -106,9 +106,9 @@ SENTRY_NO_INIT @property (nonatomic, strong, nullable) SentryScopePersistentStore *scopePersistentStore; @property (nonatomic, strong) SentryDebugImageProvider *debugImageProvider; -- (id)getANRTracker:(NSTimeInterval)timeout; +- (SentryANRTracker *)getANRTracker:(NSTimeInterval)timeout; #if SENTRY_HAS_UIKIT -- (id)getANRTracker:(NSTimeInterval)timeout isV2Enabled:(BOOL)isV2Enabled; +- (SentryANRTracker *)getANRTracker:(NSTimeInterval)timeout isV2Enabled:(BOOL)isV2Enabled; #endif // SENTRY_HAS_UIKIT - (nullable id)application; diff --git a/Sources/Sentry/include/SentryANRTrackerV1.h b/Sources/Sentry/include/SentryANRTrackerV1.h index 2953c34ad1e..072f47e6b58 100644 --- a/Sources/Sentry/include/SentryANRTrackerV1.h +++ b/Sources/Sentry/include/SentryANRTrackerV1.h @@ -4,7 +4,7 @@ @class SentryCrashWrapper; @class SentryDispatchQueueWrapper; @class SentryThreadWrapper; -@protocol SentryANRTracker; +@protocol SentryANRTrackerDelegate; NS_ASSUME_NONNULL_BEGIN @@ -24,12 +24,16 @@ NS_ASSUME_NONNULL_BEGIN @interface SentryANRTrackerV1 : NSObject SENTRY_NO_INIT +- (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval; + - (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval crashWrapper:(SentryCrashWrapper *)crashWrapper dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper threadWrapper:(SentryThreadWrapper *)threadWrapper; -- (id)asProtocol; +- (void)addListener:(id)listener; +- (void)removeListener:(id)listener; +- (void)clear; @end diff --git a/Sources/Sentry/include/SentryANRTrackerV2.h b/Sources/Sentry/include/SentryANRTrackerV2.h index 145a717f274..ce8dd7f5038 100644 --- a/Sources/Sentry/include/SentryANRTrackerV2.h +++ b/Sources/Sentry/include/SentryANRTrackerV2.h @@ -6,7 +6,7 @@ @class SentryDispatchQueueWrapper; @class SentryThreadWrapper; @class SentryFramesTracker; -@protocol SentryANRTracker; +@protocol SentryANRTrackerDelegate; NS_ASSUME_NONNULL_BEGIN @@ -23,13 +23,17 @@ NS_ASSUME_NONNULL_BEGIN @interface SentryANRTrackerV2 : NSObject SENTRY_NO_INIT +- (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval; + - (instancetype)initWithTimeoutInterval:(NSTimeInterval)timeoutInterval crashWrapper:(SentryCrashWrapper *)crashWrapper dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper threadWrapper:(SentryThreadWrapper *)threadWrapper framesTracker:(SentryFramesTracker *)framesTracker; -- (id)asProtocol; +- (void)addListener:(id)listener; +- (void)removeListener:(id)listener; +- (void)clear; @end diff --git a/Sources/Sentry/include/SentryDelayedFramesTracker.h b/Sources/Sentry/include/SentryDelayedFramesTracker.h index ab36c529005..2ebd15029a1 100644 --- a/Sources/Sentry/include/SentryDelayedFramesTracker.h +++ b/Sources/Sentry/include/SentryDelayedFramesTracker.h @@ -10,6 +10,15 @@ NS_ASSUME_NONNULL_BEGIN @interface SentryDelayedFramesTracker : NSObject SENTRY_NO_INIT +/** + * Initializes a @c SentryDelayedFramesTracker. This class keeps track of information on delayed + * frames. Whenever a new delayed frame is recorded, it removes recorded delayed frames older than + * the current time minus the @c keepDelayedFramesDuration. + * + * @param keepDelayedFramesDuration The maximum duration to keep delayed frames records in memory. + */ +- (instancetype)initWithKeepDelayedFramesDuration:(CFTimeInterval)keepDelayedFramesDuration; + /** * Initializes a @c SentryDelayedFramesTracker. This class keeps track of information on delayed * frames. Whenever a new delayed frame is recorded, it removes recorded delayed frames older than diff --git a/Sources/Sentry/include/SentryDependencyContainerSwiftHelper.h b/Sources/Sentry/include/SentryDependencyContainerSwiftHelper.h index f6756c3fd46..9e59befc351 100644 --- a/Sources/Sentry/include/SentryDependencyContainerSwiftHelper.h +++ b/Sources/Sentry/include/SentryDependencyContainerSwiftHelper.h @@ -11,6 +11,7 @@ @class SentryHub; @class SentryCrash; @class SentryNSProcessInfoWrapper; +@class SentryDispatchQueueWrapper; NS_ASSUME_NONNULL_BEGIN @@ -26,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN #endif // SENTRY_HAS_UIKIT ++ (SentryDispatchQueueWrapper *)dispatchQueueWrapper; + (void)dispatchSyncOnMainQueue:(void (^)(void))block; + (id)objcRuntimeWrapper; + (SentryHub *)currentHub; diff --git a/Sources/Swift/Core/Integrations/ANR/SentryANRTracker.swift b/Sources/Swift/Core/Integrations/ANR/SentryANRTracker.swift index 62392afe359..2431083f6e3 100644 --- a/Sources/Swift/Core/Integrations/ANR/SentryANRTracker.swift +++ b/Sources/Swift/Core/Integrations/ANR/SentryANRTracker.swift @@ -1,11 +1,29 @@ import Foundation -@objc -@_spi(Private) public protocol SentryANRTracker { - @objc(addListener:) - func add(listener: SentryANRTrackerDelegate) - @objc(removeListener:) - func remove(listener: SentryANRTrackerDelegate) +@_spi(Private) @objc public final class SentryANRTracker: NSObject { + + let helper: SentryANRTrackerProtocol + + @objc public init(helper: SentryANRTrackerProtocol) { + self.helper = helper + } + + @objc(addListener:) public func add(listener: SentryANRTrackerDelegate) { + helper.addListener(listener) + } + + @objc(removeListener:) public func remove(listener: SentryANRTrackerDelegate) { + helper.removeListener(listener) + } + + @objc public func clear() { + helper.clear() + } +} + +@_spi(Private) @objc public protocol SentryANRTrackerProtocol { + @objc func addListener(_ listender: SentryANRTrackerDelegate) + @objc func removeListener(_ listener: SentryANRTrackerDelegate) /// Only used for tests. func clear() diff --git a/Tests/SentryProfilerTests/SentryAppStartProfilingConfigurationTests.swift b/Tests/SentryProfilerTests/SentryAppStartProfilingConfigurationTests.swift index 49918691751..15cbe8e9d27 100644 --- a/Tests/SentryProfilerTests/SentryAppStartProfilingConfigurationTests.swift +++ b/Tests/SentryProfilerTests/SentryAppStartProfilingConfigurationTests.swift @@ -1,3 +1,4 @@ +@_spi(Private) import Sentry @_spi(Private) import SentryTestUtils import XCTest diff --git a/Tests/SentryProfilerTests/SentryProfileTestFixture.swift b/Tests/SentryProfilerTests/SentryProfileTestFixture.swift index ee2e65639e7..53a6bca97e2 100644 --- a/Tests/SentryProfilerTests/SentryProfileTestFixture.swift +++ b/Tests/SentryProfilerTests/SentryProfileTestFixture.swift @@ -1,6 +1,6 @@ import _SentryPrivate @_spi(Private) @testable import Sentry -@_spi(Private) import SentryTestUtils +@_spi(Private) @testable import SentryTestUtils import XCTest #if os(iOS) || os(macOS) || targetEnvironment(macCatalyst) diff --git a/Tests/SentryTests/Helper/SentryDependencyContainerTests.swift b/Tests/SentryTests/Helper/SentryDependencyContainerTests.swift index 0e0941647b8..df7de98c929 100644 --- a/Tests/SentryTests/Helper/SentryDependencyContainerTests.swift +++ b/Tests/SentryTests/Helper/SentryDependencyContainerTests.swift @@ -21,7 +21,7 @@ final class SentryDependencyContainerTests: XCTestCase { func testGetANRTrackerV2() { let instance = SentryDependencyContainer.sharedInstance().getANRTracker(2.0, isV2Enabled: true) - XCTAssertTrue(instance is SentryANRTrackerV2) + XCTAssertTrue(instance.helper is SentryANRTrackerV2) SentryDependencyContainer.reset() @@ -29,27 +29,27 @@ final class SentryDependencyContainerTests: XCTestCase { func testGetANRTrackerV1() { let instance = SentryDependencyContainer.sharedInstance().getANRTracker(2.0, isV2Enabled: false) - XCTAssertTrue(instance is SentryANRTrackerV1) + XCTAssertTrue(instance.helper is SentryANRTrackerV1) SentryDependencyContainer.reset() } func testGetANRTrackerV2AndThenV1_FirstCalledVersionStaysTheSame() { let instance1 = SentryDependencyContainer.sharedInstance().getANRTracker(2.0, isV2Enabled: true) - XCTAssertTrue(instance1 is SentryANRTrackerV2) + XCTAssertTrue(instance1.helper is SentryANRTrackerV2) let instance2 = SentryDependencyContainer.sharedInstance().getANRTracker(2.0, isV2Enabled: false) - XCTAssertTrue(instance2 is SentryANRTrackerV2) + XCTAssertTrue(instance2.helper is SentryANRTrackerV2) SentryDependencyContainer.reset() } func testGetANRTrackerV1AndThenV2_FirstCalledVersionStaysTheSame() { let instance1 = SentryDependencyContainer.sharedInstance().getANRTracker(2.0, isV2Enabled: false) - XCTAssertTrue(instance1 is SentryANRTrackerV1) + XCTAssertTrue(instance1.helper is SentryANRTrackerV1) let instance2 = SentryDependencyContainer.sharedInstance().getANRTracker(2.0, isV2Enabled: true) - XCTAssertTrue(instance2 is SentryANRTrackerV1) + XCTAssertTrue(instance2.helper is SentryANRTrackerV1) SentryDependencyContainer.reset() } @@ -59,7 +59,7 @@ final class SentryDependencyContainerTests: XCTestCase { func testGetANRTracker_ReturnsV1() { let instance = SentryDependencyContainer.sharedInstance().getANRTracker(2.0) - XCTAssertTrue(instance is SentryANRTrackerV1) + XCTAssertTrue(instance.helper is SentryANRTrackerV1) SentryDependencyContainer.reset() } diff --git a/Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift b/Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift index 0e79092633e..d992a22545d 100644 --- a/Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift +++ b/Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift @@ -1,4 +1,4 @@ -@_spi(Private) import Sentry +@_spi(Private) @testable import Sentry @_spi(Private) import SentryTestUtils import XCTest diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV1IntegrationTests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV1IntegrationTests.swift index a4a63780a64..fdfce44f94f 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV1IntegrationTests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV1IntegrationTests.swift @@ -12,11 +12,11 @@ final class SentryANRTrackerV1IntegrationTests: XCTestCase { let listener = SentryANRTrackerTestDelegate() - let anrTracker: SentryANRTracker = SentryANRTrackerV1( + let anrTracker = SentryANRTracker(helper: SentryANRTrackerV1( timeoutInterval: 0.01, crashWrapper: TestSentryCrashWrapper(processInfoWrapper: ProcessInfo.processInfo), dispatchQueueWrapper: SentryDispatchQueueWrapper(), - threadWrapper: SentryThreadWrapper()) as! SentryANRTracker + threadWrapper: SentryThreadWrapper())) anrTracker.add(listener: listener) diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV1Tests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV1Tests.swift index 66a49bf571a..95cd67e7ce8 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV1Tests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV1Tests.swift @@ -2,6 +2,8 @@ @_spi(Private) import SentryTestUtils import XCTest +@_spi(Private) extension SentryANRTrackerV1: SentryANRTrackerProtocol { } + #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) class SentryANRTrackerV1Tests: XCTestCase, SentryANRTrackerDelegate { @@ -40,11 +42,11 @@ class SentryANRTrackerV1Tests: XCTestCase, SentryANRTrackerDelegate { fixture = Fixture() - sut = SentryANRTrackerV1( + sut = SentryANRTracker(helper: SentryANRTrackerV1( timeoutInterval: fixture.timeoutInterval, crashWrapper: fixture.crashWrapper, dispatchQueueWrapper: fixture.dispatchQueue, - threadWrapper: fixture.threadWrapper) as? SentryANRTracker + threadWrapper: fixture.threadWrapper)) } override func tearDown() { @@ -198,7 +200,7 @@ class SentryANRTrackerV1Tests: XCTestCase, SentryANRTrackerDelegate { sut.add(listener: self) sut.remove(listener: self) - let listeners = Dynamic(sut).listeners.asObject as? NSHashTable + let listeners = Dynamic(sut.helper).listeners.asObject as? NSHashTable XCTAssertGreaterThan(addListenersCount, listeners?.count ?? addListenersCount) diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV2Tests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV2Tests.swift index 2ab69b1fdf9..5cfafb462f3 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV2Tests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerV2Tests.swift @@ -3,6 +3,9 @@ import XCTest #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) + +@_spi(Private) extension SentryANRTrackerV2: SentryANRTrackerProtocol { } + class SentryANRTrackerV2Tests: XCTestCase { private let waitTimeout: TimeInterval = 10.0 @@ -30,12 +33,12 @@ class SentryANRTrackerV2Tests: XCTestCase { displayLinkWrapper.normalFrame() } - return (SentryANRTrackerV2( + return (SentryANRTracker(helper: SentryANRTrackerV2( timeoutInterval: timeoutInterval, crashWrapper: crashWrapper, dispatchQueueWrapper: dispatchQueue, threadWrapper: threadWrapper, - framesTracker: framesTracker) as! SentryANRTracker, currentDate, displayLinkWrapper, crashWrapper, threadWrapper, framesTracker) + framesTracker: framesTracker)), currentDate, displayLinkWrapper, crashWrapper, threadWrapper, framesTracker) } /// When no frame gets rendered its a fully blocking app hang. @@ -447,7 +450,7 @@ class SentryANRTrackerV2Tests: XCTestCase { triggerFullyBlockingAppHang(currentDate) - let listeners = Dynamic(sut).listeners.asObject as? NSHashTable + let listeners = Dynamic(sut.helper).listeners.asObject as? NSHashTable XCTAssertGreaterThan(addListenersCount, listeners?.count ?? addListenersCount) diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift index 0792ca49079..eb65b5c99ee 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift @@ -52,8 +52,8 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { givenInitializedTracker() let tracker = Dynamic(sut).tracker.asAnyObject - XCTAssertNotNil(tracker) - XCTAssertTrue(tracker is SentryANRTrackerV1) + XCTAssertNotNil(tracker as? SentryANRTracker) + XCTAssertTrue((tracker as? SentryANRTracker)?.helper is SentryANRTrackerV1) } func test_enableAppHangsTracking_Disabled() { @@ -88,8 +88,8 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { XCTAssertTrue(result) let tracker = Dynamic(sut).tracker.asAnyObject - XCTAssertNotNil(tracker) - XCTAssertTrue(tracker is SentryANRTrackerV2) + XCTAssertNotNil(tracker as? SentryANRTracker) + XCTAssertTrue((tracker as? SentryANRTracker)?.helper is SentryANRTrackerV2) } #endif @@ -350,7 +350,7 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { let tracker = SentryDependencyContainer.sharedInstance().getANRTracker(self.options.appHangTimeoutInterval) - let listeners = try XCTUnwrap(Dynamic(tracker).listeners.asObject as? NSHashTable) + let listeners = try XCTUnwrap(Dynamic(tracker.helper).listeners.asObject as? NSHashTable) XCTAssertEqual(1, listeners.count) } diff --git a/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerTest.swift b/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerTest.swift index 41d2a52ffab..fdecd434b3d 100644 --- a/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerTest.swift +++ b/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerTest.swift @@ -1,5 +1,5 @@ import CoreData -@testable import Sentry +@_spi(Private) @testable import Sentry @_spi(Private) import SentryTestUtils import XCTest diff --git a/Tests/SentryTests/Integrations/UIEvents/SentryUIEventTrackerTests.swift b/Tests/SentryTests/Integrations/UIEvents/SentryUIEventTrackerTests.swift index 75d51ab0a51..3ab40a4ee98 100644 --- a/Tests/SentryTests/Integrations/UIEvents/SentryUIEventTrackerTests.swift +++ b/Tests/SentryTests/Integrations/UIEvents/SentryUIEventTrackerTests.swift @@ -1,4 +1,4 @@ -import Sentry +@_spi(Private) import Sentry @_spi(Private) import SentryTestUtils import XCTest diff --git a/Tests/SentryTests/Networking/SentryTransportFactoryTests.swift b/Tests/SentryTests/Networking/SentryTransportFactoryTests.swift index 9225b670dfc..f147c618a97 100644 --- a/Tests/SentryTests/Networking/SentryTransportFactoryTests.swift +++ b/Tests/SentryTests/Networking/SentryTransportFactoryTests.swift @@ -1,4 +1,4 @@ -@_spi(Private) import Sentry +@_spi(Private) @testable import Sentry @_spi(Private) import SentryTestUtils import XCTest diff --git a/Tests/SentryTests/SentryClient+TestInit.h b/Tests/SentryTests/SentryClient+TestInit.h index 5117e657baf..af3e0b834a7 100644 --- a/Tests/SentryTests/SentryClient+TestInit.h +++ b/Tests/SentryTests/SentryClient+TestInit.h @@ -1,5 +1,6 @@ #import "SentryTransport.h" +@protocol SentryCurrentDateProvider; @protocol SentryRandomProtocol; @class SentryCrashWrapper; diff --git a/Tests/SentryTests/SentryScreenshotSourceTests.swift b/Tests/SentryTests/SentryScreenshotSourceTests.swift index 53fb022deb4..9c752e433a2 100644 --- a/Tests/SentryTests/SentryScreenshotSourceTests.swift +++ b/Tests/SentryTests/SentryScreenshotSourceTests.swift @@ -1,4 +1,4 @@ -@_spi(Private) import Sentry +@_spi(Private) @testable import Sentry @_spi(Private) import SentryTestUtils import XCTest diff --git a/Tests/SentryTests/State/SentryInstallationTests.swift b/Tests/SentryTests/State/SentryInstallationTests.swift index b088df1986c..8a33b48af7f 100644 --- a/Tests/SentryTests/State/SentryInstallationTests.swift +++ b/Tests/SentryTests/State/SentryInstallationTests.swift @@ -1,3 +1,4 @@ +@_spi(Private) import Sentry @_spi(Private) import SentryTestUtils import XCTest