From 79779928f46de58cd3cdb19a4059cbc343e64204 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 6 Oct 2022 13:10:36 -0500 Subject: [PATCH 01/13] test: use Test/TestCI configs for fastfile test runs (#2257) * test: use Test/TestCI configs for fastfile test runs of sample app UI tests * add Test/TestCI configs to some sample app projects * set ONLY_ACTIVE_ARCH to YES for Test/CI configs; properly link Sentry into tvOS-Swift and iOS-SwiftUI --- .../iOS-ObjectiveC.xcodeproj/project.pbxproj | 204 ++++++++ .../iOS-Swift.xcodeproj/project.pbxproj | 460 ++++++++++++++++++ .../iOS-SwiftUI.xcodeproj/project.pbxproj | 279 ++++++++++- .../tvOS-Swift.xcodeproj/project.pbxproj | 352 +++++++++++++- fastlane/Fastfile | 13 +- 5 files changed, 1298 insertions(+), 10 deletions(-) diff --git a/Samples/iOS-ObjectiveC/iOS-ObjectiveC.xcodeproj/project.pbxproj b/Samples/iOS-ObjectiveC/iOS-ObjectiveC.xcodeproj/project.pbxproj index fc80306717e..7a23119d6b7 100644 --- a/Samples/iOS-ObjectiveC/iOS-ObjectiveC.xcodeproj/project.pbxproj +++ b/Samples/iOS-ObjectiveC/iOS-ObjectiveC.xcodeproj/project.pbxproj @@ -547,6 +547,204 @@ }; name = Release; }; + 84D4FE9928ECD21F00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "c++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 = "TEST=1"; + 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; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Test; + }; + 84D4FE9A28ECD21F00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "iOS-ObjectiveC/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-ObjectiveC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Test; + }; + 84D4FE9B28ECD21F00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "iOS-ObjectiveCUITests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-ObjectiveCUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS-ObjectiveC"; + }; + name = Test; + }; + 84D4FE9D28ECD22300EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "c++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 = "TESTCI=1"; + 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; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = TestCI; + }; + 84D4FE9E28ECD22300EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "iOS-ObjectiveC/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-ObjectiveC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = TestCI; + }; + 84D4FE9F28ECD22300EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "iOS-ObjectiveCUITests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-ObjectiveCUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS-ObjectiveC"; + }; + name = TestCI; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -555,6 +753,8 @@ buildConfigurations = ( 637AFDDD243B036D0034958B /* Debug */, 637AFDDE243B036D0034958B /* Release */, + 84D4FE9D28ECD22300EDAAFE /* TestCI */, + 84D4FE9928ECD21F00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -564,6 +764,8 @@ buildConfigurations = ( 637AFDE0243B036D0034958B /* Debug */, 637AFDE1243B036D0034958B /* Release */, + 84D4FE9E28ECD22300EDAAFE /* TestCI */, + 84D4FE9A28ECD21F00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -573,6 +775,8 @@ buildConfigurations = ( 7B64387E26A6C69F000D0F65 /* Debug */, 7B64387F26A6C69F000D0F65 /* Release */, + 84D4FE9F28ECD22300EDAAFE /* TestCI */, + 84D4FE9B28ECD21F00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj index c1b595b7b5d..b8f2cc0e2d9 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj @@ -1221,6 +1221,452 @@ }; name = Release; }; + 84D4FE8028ECD1EA00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "c++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 = "TEST=1"; + 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; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Test; + }; + 84D4FE8128ECD1EA00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = "iOS-Swift/iOS-Swift.entitlements"; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "iOS-Swift/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 7.27.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.sample.iOS-Swift"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SUPPORTS_MACCATALYST = YES; + SWIFT_OBJC_BRIDGING_HEADER = "iOS-Swift/Tools/iOS-Swift-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 84D4FE8228ECD1EA00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "iOS-SwiftUITests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-SwiftUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.iOS-SwiftUITests.xctrunner"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS-Swift"; + }; + name = Test; + }; + 84D4FE8328ECD1EA00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "PerformanceBenchmarks/PerformanceBenchmarks-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-Benchmarking"; + PRODUCT_NAME = "$(TARGET_NAME)"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS-Swift"; + }; + name = Test; + }; + 84D4FE8428ECD1EA00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "iOS-SwiftClip/iOS_SwiftClip.entitlements"; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 97JCY7859U; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "iOS-SwiftClip/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "iOS-Swift"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UIRequiresFullScreen = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 7.27.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift.Clip"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.sample.iOS-Swift.Clip"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 84D4FE8528ECD1EA00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "iOS13-Swift/iOS13-Swift.entitlements"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "iOS13-Swift/Info.plist"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = ""; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.Sentry.iOS13-Swift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "iOS13-Swift/iOS13-Swift-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 84D4FE8628ECD1EA00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.Sentry.iOS13-SwiftTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS13-Swift"; + }; + name = Test; + }; + 84D4FE8828ECD1ED00EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "c++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 = "TESTCI=1"; + 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; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = TestCI; + }; + 84D4FE8928ECD1ED00EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = "iOS-Swift/iOS-Swift.entitlements"; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "iOS-Swift/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 7.27.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.sample.iOS-Swift"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SUPPORTS_MACCATALYST = YES; + SWIFT_OBJC_BRIDGING_HEADER = "iOS-Swift/Tools/iOS-Swift-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = TestCI; + }; + 84D4FE8A28ECD1ED00EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "iOS-SwiftUITests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-SwiftUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.iOS-SwiftUITests.xctrunner"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS-Swift"; + }; + name = TestCI; + }; + 84D4FE8B28ECD1ED00EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "PerformanceBenchmarks/PerformanceBenchmarks-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-Benchmarking"; + PRODUCT_NAME = "$(TARGET_NAME)"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS-Swift"; + }; + name = TestCI; + }; + 84D4FE8C28ECD1ED00EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "iOS-SwiftClip/iOS_SwiftClip.entitlements"; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 97JCY7859U; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "iOS-SwiftClip/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "iOS-Swift"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UIRequiresFullScreen = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 7.27.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift.Clip"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.sample.iOS-Swift.Clip"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = TestCI; + }; + 84D4FE8D28ECD1ED00EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "iOS13-Swift/iOS13-Swift.entitlements"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "iOS13-Swift/Info.plist"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = ""; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.Sentry.iOS13-Swift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "iOS13-Swift/iOS13-Swift-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = TestCI; + }; + 84D4FE8E28ECD1ED00EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.Sentry.iOS13-SwiftTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS13-Swift"; + }; + name = TestCI; + }; D8269A4A274C096000BD5BD5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1407,6 +1853,8 @@ buildConfigurations = ( 637AFDB8243B02770034958B /* Debug */, 637AFDB9243B02770034958B /* Release */, + 84D4FE8828ECD1ED00EDAAFE /* TestCI */, + 84D4FE8028ECD1EA00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1416,6 +1864,8 @@ buildConfigurations = ( 637AFDBB243B02770034958B /* Debug */, 637AFDBC243B02770034958B /* Release */, + 84D4FE8928ECD1ED00EDAAFE /* TestCI */, + 84D4FE8128ECD1EA00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1425,6 +1875,8 @@ buildConfigurations = ( 7B64386F26A6C544000D0F65 /* Debug */, 7B64387026A6C544000D0F65 /* Release */, + 84D4FE8A28ECD1ED00EDAAFE /* TestCI */, + 84D4FE8228ECD1EA00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1434,6 +1886,8 @@ buildConfigurations = ( 848A2571286E3351008A8858 /* Debug */, 848A2572286E3351008A8858 /* Release */, + 84D4FE8B28ECD1ED00EDAAFE /* TestCI */, + 84D4FE8328ECD1EA00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1443,6 +1897,8 @@ buildConfigurations = ( D8269A4A274C096000BD5BD5 /* Debug */, D8269A4B274C096000BD5BD5 /* Release */, + 84D4FE8D28ECD1ED00EDAAFE /* TestCI */, + 84D4FE8528ECD1EA00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1452,6 +1908,8 @@ buildConfigurations = ( D840D536273A07F600CDF142 /* Debug */, D840D537273A07F600CDF142 /* Release */, + 84D4FE8C28ECD1ED00EDAAFE /* TestCI */, + 84D4FE8428ECD1EA00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1461,6 +1919,8 @@ buildConfigurations = ( D85DAA52274C244F004DF43C /* Debug */, D85DAA53274C244F004DF43C /* Release */, + 84D4FE8E28ECD1ED00EDAAFE /* TestCI */, + 84D4FE8628ECD1EA00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj b/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj index 8eb61630496..7f2fe9a967c 100644 --- a/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj +++ b/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj @@ -14,8 +14,8 @@ 7BB6224F26A56C4E00D0E75E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BB6224E26A56C4E00D0E75E /* ContentView.swift */; }; 7BB6225126A56C5000D0E75E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7BB6225026A56C5000D0E75E /* Assets.xcassets */; }; 7BB6225426A56C5000D0E75E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7BB6225326A56C5000D0E75E /* Preview Assets.xcassets */; }; - 7BB6225D26A56CB600D0E75E /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BB6225C26A56CB600D0E75E /* Sentry.framework */; }; 7BB6225E26A56CB600D0E75E /* Sentry.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BB6225C26A56CB600D0E75E /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 84D4FEB528ECD53500EDAAFE /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D4FEB228ECD52E00EDAAFE /* Sentry.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -26,6 +26,27 @@ remoteGlobalIDString = 7BB6224826A56C4E00D0E75E; remoteInfo = "iOS-SwiftUI"; }; + 84D4FEAD28ECD52E00EDAAFE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 63AA759A1EB8AEF500D153DE; + remoteInfo = Sentry; + }; + 84D4FEB128ECD52E00EDAAFE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 63AA759B1EB8AEF500D153DE; + remoteInfo = Sentry; + }; + 84D4FEB328ECD52E00EDAAFE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 63AA76651EB8CB2F00D153DE; + remoteInfo = SentryTests; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -56,6 +77,9 @@ 7BB6225526A56C5000D0E75E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7BB6225C26A56CB600D0E75E /* Sentry.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Sentry.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7BB6226026A56E1E00D0E75E /* iOS-SwiftUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "iOS-SwiftUI.entitlements"; sourceTree = ""; }; + 84D4FEA628ECD51800EDAAFE /* Sentry.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Sentry.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Sentry.xcodeproj; path = ../../Sentry.xcodeproj; sourceTree = ""; }; + 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Sentry.xcodeproj; path = "/Users/andrewmcknight/Code/organization/getsentry/repos/public/sentry-cocoa/Sentry.xcodeproj"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -70,7 +94,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7BB6225D26A56CB600D0E75E /* Sentry.framework in Frameworks */, + 84D4FEB528ECD53500EDAAFE /* Sentry.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -93,6 +117,7 @@ 7B64385826A6C0A6000D0F65 /* iOS-SwiftUI-UITests */, 7BB6224A26A56C4E00D0E75E /* Products */, 7BB6225B26A56CB600D0E75E /* Frameworks */, + 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */, ); sourceTree = ""; }; @@ -131,11 +156,22 @@ 7BB6225B26A56CB600D0E75E /* Frameworks */ = { isa = PBXGroup; children = ( + 84D4FEA628ECD51800EDAAFE /* Sentry.framework */, + 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */, 7BB6225C26A56CB600D0E75E /* Sentry.framework */, ); name = Frameworks; sourceTree = ""; }; + 84D4FEAB28ECD52E00EDAAFE /* Products */ = { + isa = PBXGroup; + children = ( + 84D4FEB228ECD52E00EDAAFE /* Sentry.framework */, + 84D4FEB428ECD52E00EDAAFE /* SentryTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -169,6 +205,7 @@ buildRules = ( ); dependencies = ( + 84D4FEAE28ECD52E00EDAAFE /* PBXTargetDependency */, ); name = "iOS-SwiftUI"; productName = "iOS-SwiftUI"; @@ -204,6 +241,12 @@ mainGroup = 7BB6224026A56C4E00D0E75E; productRefGroup = 7BB6224A26A56C4E00D0E75E /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 84D4FEAB28ECD52E00EDAAFE /* Products */; + ProjectRef = 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 7BB6224826A56C4E00D0E75E /* iOS-SwiftUI */, @@ -212,6 +255,23 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 84D4FEB228ECD52E00EDAAFE /* Sentry.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Sentry.framework; + remoteRef = 84D4FEB128ECD52E00EDAAFE /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84D4FEB428ECD52E00EDAAFE /* SentryTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = SentryTests.xctest; + remoteRef = 84D4FEB328ECD52E00EDAAFE /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 7B64385526A6C0A6000D0F65 /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -259,6 +319,11 @@ target = 7BB6224826A56C4E00D0E75E /* iOS-SwiftUI */; targetProxy = 7B64385C26A6C0A6000D0F65 /* PBXContainerItemProxy */; }; + 84D4FEAE28ECD52E00EDAAFE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Sentry; + targetProxy = 84D4FEAD28ECD52E00EDAAFE /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -468,6 +533,210 @@ }; name = Release; }; + 84D4FEA028ECD23400EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "c++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 = "TEST=1"; + 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; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Test; + }; + 84D4FEA128ECD23400EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "iOS-SwiftUI/iOS-SwiftUI.entitlements"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_ASSET_PATHS = "\"iOS-SwiftUI/Preview Content\""; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "iOS-SwiftUI/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-SwiftUI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SUPPORTS_MACCATALYST = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 84D4FEA228ECD23400EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "iOS-SwiftUI-UITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-SwiftUI-UITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS-SwiftUI"; + }; + name = Test; + }; + 84D4FEA328ECD23800EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "c++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 = "TESTCI=1"; + 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; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = TestCI; + }; + 84D4FEA428ECD23800EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "iOS-SwiftUI/iOS-SwiftUI.entitlements"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_ASSET_PATHS = "\"iOS-SwiftUI/Preview Content\""; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "iOS-SwiftUI/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-SwiftUI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SUPPORTS_MACCATALYST = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = TestCI; + }; + 84D4FEA528ECD23800EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "iOS-SwiftUI-UITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.iOS-SwiftUI-UITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "iOS-SwiftUI"; + }; + name = TestCI; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -476,6 +745,8 @@ buildConfigurations = ( 7B64385E26A6C0A6000D0F65 /* Debug */, 7B64385F26A6C0A6000D0F65 /* Release */, + 84D4FEA528ECD23800EDAAFE /* TestCI */, + 84D4FEA228ECD23400EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -485,6 +756,8 @@ buildConfigurations = ( 7BB6225626A56C5000D0E75E /* Debug */, 7BB6225726A56C5000D0E75E /* Release */, + 84D4FEA328ECD23800EDAAFE /* TestCI */, + 84D4FEA028ECD23400EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -494,6 +767,8 @@ buildConfigurations = ( 7BB6225926A56C5000D0E75E /* Debug */, 7BB6225A26A56C5000D0E75E /* Release */, + 84D4FEA428ECD23800EDAAFE /* TestCI */, + 84D4FEA128ECD23400EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Samples/tvOS-Swift/tvOS-Swift.xcodeproj/project.pbxproj b/Samples/tvOS-Swift/tvOS-Swift.xcodeproj/project.pbxproj index 5396f45a868..81a4e018119 100644 --- a/Samples/tvOS-Swift/tvOS-Swift.xcodeproj/project.pbxproj +++ b/Samples/tvOS-Swift/tvOS-Swift.xcodeproj/project.pbxproj @@ -13,14 +13,14 @@ 7BA61D68247FA32600C130A8 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA61D67247FA32600C130A8 /* ContentView.swift */; }; 7BA61D6A247FA32600C130A8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7BA61D69247FA32600C130A8 /* Assets.xcassets */; }; 7BA61D70247FA32600C130A8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7BA61D6E247FA32600C130A8 /* LaunchScreen.storyboard */; }; - 7BA61D79247FA35500C130A8 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BA61D78247FA35500C130A8 /* Sentry.framework */; }; 7BA61D7A247FA35500C130A8 /* Sentry.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BA61D78247FA35500C130A8 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 84D4FEBF28ECD8A800EDAAFE /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D4FEBC28ECD8A100EDAAFE /* Sentry.framework */; }; + 84D4FEC028ECD8AF00EDAAFE /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D4FEBC28ECD8A100EDAAFE /* Sentry.framework */; }; D822A4232760D15000E7B241 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D822A4222760D15000E7B241 /* AppDelegate.swift */; }; D822A4252760D15000E7B241 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D822A4242760D15000E7B241 /* ViewController.swift */; }; D822A4282760D15000E7B241 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D822A4262760D15000E7B241 /* Main.storyboard */; }; D822A42A2760D15100E7B241 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D822A4292760D15100E7B241 /* Assets.xcassets */; }; D822A42D2760D15100E7B241 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D822A42B2760D15100E7B241 /* LaunchScreen.storyboard */; }; - D822A4322760D7E100E7B241 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D822A4312760D7E100E7B241 /* Sentry.framework */; }; D822A4332760D7E100E7B241 /* Sentry.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D822A4312760D7E100E7B241 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D822A4362760DB1900E7B241 /* ActionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D822A4352760DB1900E7B241 /* ActionCell.swift */; }; D822A4392760E90B00E7B241 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D822A4382760E90B00E7B241 /* TableViewController.swift */; }; @@ -38,6 +38,20 @@ remoteGlobalIDString = 7BA61D61247FA32600C130A8; remoteInfo = "tvOS-Swift"; }; + 84D4FEBB28ECD8A100EDAAFE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEB628ECD8A100EDAAFE /* Sentry.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 63AA759B1EB8AEF500D153DE; + remoteInfo = Sentry; + }; + 84D4FEBD28ECD8A100EDAAFE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEB628ECD8A100EDAAFE /* Sentry.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 63AA76651EB8CB2F00D153DE; + remoteInfo = SentryTests; + }; D822A44A2760ED7100E7B241 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 7BA61D5A247FA32600C130A8 /* Project object */; @@ -84,6 +98,7 @@ 7BA61D6F247FA32600C130A8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 7BA61D71247FA32600C130A8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7BA61D78247FA35500C130A8 /* Sentry.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Sentry.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 84D4FEB628ECD8A100EDAAFE /* Sentry.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Sentry.xcodeproj; path = ../../Sentry.xcodeproj; sourceTree = ""; }; D822A4202760D15000E7B241 /* tvOS-SBSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "tvOS-SBSwift.app"; sourceTree = BUILT_PRODUCTS_DIR; }; D822A4222760D15000E7B241 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; D822A4242760D15000E7B241 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -112,7 +127,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7BA61D79247FA35500C130A8 /* Sentry.framework in Frameworks */, + 84D4FEBF28ECD8A800EDAAFE /* Sentry.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -120,7 +135,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D822A4322760D7E100E7B241 /* Sentry.framework in Frameworks */, + 84D4FEC028ECD8AF00EDAAFE /* Sentry.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -146,6 +161,7 @@ 7BA61D59247FA32600C130A8 = { isa = PBXGroup; children = ( + 84D4FEB628ECD8A100EDAAFE /* Sentry.xcodeproj */, 7BA61D64247FA32600C130A8 /* tvOS-Swift */, 7B64388726A6C71A000D0F65 /* tvOS-SwiftUITests */, D822A4212760D15000E7B241 /* tvOS-SBSwift */, @@ -188,6 +204,15 @@ name = Frameworks; sourceTree = ""; }; + 84D4FEB728ECD8A100EDAAFE /* Products */ = { + isa = PBXGroup; + children = ( + 84D4FEBC28ECD8A100EDAAFE /* Sentry.framework */, + 84D4FEBE28ECD8A100EDAAFE /* SentryTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; D822A4212760D15000E7B241 /* tvOS-SBSwift */ = { isa = PBXGroup; children = ( @@ -333,6 +358,12 @@ mainGroup = 7BA61D59247FA32600C130A8; productRefGroup = 7BA61D63247FA32600C130A8 /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 84D4FEB728ECD8A100EDAAFE /* Products */; + ProjectRef = 84D4FEB628ECD8A100EDAAFE /* Sentry.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 7BA61D61247FA32600C130A8 /* tvOS-Swift */, @@ -343,6 +374,23 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 84D4FEBC28ECD8A100EDAAFE /* Sentry.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Sentry.framework; + remoteRef = 84D4FEBB28ECD8A100EDAAFE /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84D4FEBE28ECD8A100EDAAFE /* SentryTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = SentryTests.xctest; + remoteRef = 84D4FEBD28ECD8A100EDAAFE /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 7B64388426A6C71A000D0F65 /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -657,6 +705,292 @@ }; name = Release; }; + 84D4FE8F28ECD1FD00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "c++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 = "TEST=1"; + 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; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = appletvos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TVOS_DEPLOYMENT_TARGET = 13.0; + VALIDATE_PRODUCT = YES; + }; + name = Test; + }; + 84D4FE9028ECD1FD00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = ""; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "tvOS-Swift/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.tvOS-Swift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Test; + }; + 84D4FE9128ECD1FD00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "tvOS-SwiftUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.tvOS-SwiftUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TEST_TARGET_NAME = "tvOS-Swift"; + }; + name = Test; + }; + 84D4FE9228ECD1FD00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.tvOS-SBSwift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 15.0; + }; + name = Test; + }; + 84D4FE9328ECD1FD00EDAAFE /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.tvOS-SBSwiftUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TEST_TARGET_NAME = "tvOS-SBSwift"; + TVOS_DEPLOYMENT_TARGET = 15.0; + }; + name = Test; + }; + 84D4FE9428ECD20000EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "c++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 = "TESTCI=1"; + 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; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = appletvos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TVOS_DEPLOYMENT_TARGET = 13.0; + VALIDATE_PRODUCT = YES; + }; + name = TestCI; + }; + 84D4FE9528ECD20000EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = ""; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "tvOS-Swift/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.tvOS-Swift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + }; + name = TestCI; + }; + 84D4FE9628ECD20000EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 97JCY7859U; + INFOPLIST_FILE = "tvOS-SwiftUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.tvOS-SwiftUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TEST_TARGET_NAME = "tvOS-Swift"; + }; + name = TestCI; + }; + 84D4FE9728ECD20000EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.tvOS-SBSwift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 15.0; + }; + name = TestCI; + }; + 84D4FE9828ECD20000EDAAFE /* TestCI */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.tvOS-SBSwiftUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TEST_TARGET_NAME = "tvOS-SBSwift"; + TVOS_DEPLOYMENT_TARGET = 15.0; + }; + name = TestCI; + }; D822A42E2760D15100E7B241 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -759,6 +1093,8 @@ buildConfigurations = ( 7B64388D26A6C71A000D0F65 /* Debug */, 7B64388E26A6C71A000D0F65 /* Release */, + 84D4FE9628ECD20000EDAAFE /* TestCI */, + 84D4FE9128ECD1FD00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -768,6 +1104,8 @@ buildConfigurations = ( 7BA61D72247FA32600C130A8 /* Debug */, 7BA61D73247FA32600C130A8 /* Release */, + 84D4FE9428ECD20000EDAAFE /* TestCI */, + 84D4FE8F28ECD1FD00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -777,6 +1115,8 @@ buildConfigurations = ( 7BA61D75247FA32600C130A8 /* Debug */, 7BA61D76247FA32600C130A8 /* Release */, + 84D4FE9528ECD20000EDAAFE /* TestCI */, + 84D4FE9028ECD1FD00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -786,6 +1126,8 @@ buildConfigurations = ( D822A42E2760D15100E7B241 /* Debug */, D822A42F2760D15100E7B241 /* Release */, + 84D4FE9728ECD20000EDAAFE /* TestCI */, + 84D4FE9228ECD1FD00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -795,6 +1137,8 @@ buildConfigurations = ( D822A44D2760ED7100E7B241 /* Debug */, D822A44E2760ED7100E7B241 /* Release */, + 84D4FE9828ECD20000EDAAFE /* TestCI */, + 84D4FE9328ECD1FD00EDAAFE /* Test */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 3a9063b012b..14ce22952df 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -3,6 +3,7 @@ default_platform(:ios) platform :ios do ios_swift_infoplist_path = "./Samples/iOS-Swift/iOS-Swift/Info.plist" ios_swift_clip_infoplist_path = "./Samples/iOS-Swift/iOS-SwiftClip/Info.plist" + configuration = if is_ci then 'TestCI' else 'Test' end lane :bump_build_number do increment_build_number( @@ -198,14 +199,16 @@ platform :ios do lane :ui_tests_ios_swiftui do run_tests( workspace: "Sentry.xcworkspace", - scheme: "iOS-SwiftUI" + scheme: "iOS-SwiftUI", + configuration: configuration ) end lane :ui_tests_ios_objc do run_tests( workspace: "Sentry.xcworkspace", - scheme: "iOS-ObjectiveC" + scheme: "iOS-ObjectiveC", + configuration: configuration ) end @@ -214,14 +217,16 @@ platform :ios do workspace: "Sentry.xcworkspace", scheme: "iOS-Swift", device: options[:device], - address_sanitizer: options[:address_sanitizer] + address_sanitizer: options[:address_sanitizer], + configuration: configuration ) end lane :ui_tests_tvos_swift do run_tests( workspace: "Sentry.xcworkspace", - scheme: "tvOS-Swift" + scheme: "tvOS-Swift", + configuration: configuration ) end From be47c6c37e25c3c5d92cceb875c6f408f76017f8 Mon Sep 17 00:00:00 2001 From: Kevin Renskers Date: Fri, 7 Oct 2022 10:07:26 +0200 Subject: [PATCH 02/13] ref: Use the new loadPreviousAppState in SentryAppStartTracker (#2261) --- Sentry.xcodeproj/project.pbxproj | 4 ++-- Sources/Sentry/SentryAppStartTracker.m | 2 +- Sources/Sentry/SentryAppStateManager.m | 5 ----- Sources/Sentry/include/SentryAppStateManager.h | 2 -- .../SentryAppStartTrackerTests.swift | 18 ++++++++++++------ 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 51b3821838b..058fb8510b7 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -1803,6 +1803,8 @@ 7BD729972463E93500EA3610 /* SentryDateUtil.m */, 7B98D7E325FB7A7200C5A389 /* SentryAppState.h */, 7B98D7E725FB7BCD00C5A389 /* SentryAppState.m */, + 7B8ECBF926498906005FE2EF /* SentryAppStateManager.h */, + 7B8ECBFB26498958005FE2EF /* SentryAppStateManager.m */, 7BD86EC4264A63F6005439DB /* SentrySysctl.h */, 7BD86EC6264A641D005439DB /* SentrySysctl.m */, 7BF9EF832722D07B00B5BBEF /* SentryObjCRuntimeWrapper.h */, @@ -2470,8 +2472,6 @@ 7B8713AF26415B22006D6004 /* SentryAppStartTrackingIntegration.m */, 7B8713B126415B7A006D6004 /* SentryAppStartTracker.h */, 7B8713B326415BAA006D6004 /* SentryAppStartTracker.m */, - 7B8ECBF926498906005FE2EF /* SentryAppStateManager.h */, - 7B8ECBFB26498958005FE2EF /* SentryAppStateManager.m */, 7BD86ECE264A7C77005439DB /* SentryAppStartMeasurement.h */, 7BD86ED0264A7CF6005439DB /* SentryAppStartMeasurement.m */, ); diff --git a/Sources/Sentry/SentryAppStartTracker.m b/Sources/Sentry/SentryAppStartTracker.m index 59292d739b2..433acb0c406 100644 --- a/Sources/Sentry/SentryAppStartTracker.m +++ b/Sources/Sentry/SentryAppStartTracker.m @@ -61,7 +61,7 @@ - (instancetype)initWithCurrentDateProvider:(id)curre self.dispatchQueue = dispatchQueueWrapper; self.appStateManager = appStateManager; self.sysctl = sysctl; - self.previousAppState = [self.appStateManager loadCurrentAppState]; + self.previousAppState = [self.appStateManager loadPreviousAppState]; self.wasInBackground = NO; self.didFinishLaunchingTimestamp = [currentDateProvider date]; } diff --git a/Sources/Sentry/SentryAppStateManager.m b/Sources/Sentry/SentryAppStateManager.m index 7c17d4ba17c..b3537e44e5e 100644 --- a/Sources/Sentry/SentryAppStateManager.m +++ b/Sources/Sentry/SentryAppStateManager.m @@ -62,11 +62,6 @@ - (SentryAppState *)loadPreviousAppState return [self.fileManager readPreviousAppState]; } -- (SentryAppState *)loadCurrentAppState -{ - return [self.fileManager readAppState]; -} - - (void)storeCurrentAppState { [self.fileManager storeAppState:[self buildCurrentAppState]]; diff --git a/Sources/Sentry/include/SentryAppStateManager.h b/Sources/Sentry/include/SentryAppStateManager.h index 14a49f7608f..bacc527457b 100644 --- a/Sources/Sentry/include/SentryAppStateManager.h +++ b/Sources/Sentry/include/SentryAppStateManager.h @@ -28,8 +28,6 @@ SENTRY_NO_INIT - (SentryAppState *)loadPreviousAppState; -- (SentryAppState *)loadCurrentAppState; - - (void)storeCurrentAppState; - (void)deleteAppState; diff --git a/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift b/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift index e2719265850..985f00f09dc 100644 --- a/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift +++ b/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift @@ -74,7 +74,8 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { func testSecondStart_SystemNotRebooted_IsWarmStart() { givenSystemNotRebooted() - + + fixture.fileManager.moveAppStateToPreviousAppState() startApp() assertValidStart(type: .warm) @@ -109,7 +110,8 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { let appState = SentryAppState(releaseName: "1.0.0", osVersion: "14.4.1", vendorId: TestData.someUUID, isDebugging: false, systemBootTimestamp: self.fixture.currentDate.date()) givenPreviousAppState(appState: appState) - + + fixture.fileManager.moveAppStateToPreviousAppState() startApp() assertValidStart(type: .warm) @@ -121,7 +123,8 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { func testAppLaunches_PreviousBootTimeInFuture_NoAppStartUp() { let appState = SentryAppState(releaseName: TestData.appState.releaseName, osVersion: UIDevice.current.systemVersion, vendorId: TestData.someUUID, isDebugging: false, systemBootTimestamp: fixture.currentDate.date().addingTimeInterval(1)) givenPreviousAppState(appState: appState) - + + fixture.fileManager.moveAppStateToPreviousAppState() startApp() assertNoAppStartUp() @@ -131,7 +134,8 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { setenv("ActivePrewarm", "1", 1) SentryAppStartTracker.load() givenSystemNotRebooted() - + + fixture.fileManager.moveAppStateToPreviousAppState() startApp() #if os(iOS) @@ -149,7 +153,8 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { setenv("ActivePrewarm", "0", 1) SentryAppStartTracker.load() givenSystemNotRebooted() - + + fixture.fileManager.moveAppStateToPreviousAppState() startApp() assertValidStart(type: .warm) @@ -220,7 +225,8 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { func testHybridSDKs_SecondStart_SystemNotRebooted_IsWarmStart() { givenSystemNotRebooted() - + + fixture.fileManager.moveAppStateToPreviousAppState() hybridAppStart() assertValidHybridStart(type: .warm) From c2a9b600dd98bb34fc25bdb421a05a1fc853c6a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Oct 2022 07:28:59 +0200 Subject: [PATCH 03/13] build(deps): bump github/codeql-action from 2.1.26 to 2.1.27 (#2272) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.1.26 to 2.1.27. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e0e5ded33cabb451ae0a9768fc7b0410bad9ad44...807578363a7869ca324a79039e6db9c843e0e100) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a7184e7b826..d2dd0370883 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@v3 - name: Initialize CodeQL - uses: github/codeql-action/init@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 # pin@v2 + uses: github/codeql-action/init@807578363a7869ca324a79039e6db9c843e0e100 # pin@v2 with: languages: ${{ matrix.language }} @@ -35,4 +35,4 @@ jobs: -destination platform="iOS Simulator,OS=latest,name=iPhone 11 Pro" - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 # pin@v2 + uses: github/codeql-action/analyze@807578363a7869ca324a79039e6db9c843e0e100 # pin@v2 From 3861500bda72e53ac23d287233ba15cccf9af1f5 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 11 Oct 2022 22:01:09 -0800 Subject: [PATCH 04/13] test: disable testStartUpCrash_CallsFlush as it flakes (#2275) --- Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme | 3 +++ .../SentryCrash/SentryCrashIntegrationTests.swift | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme b/Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme index b1bbd8edbd7..e2e8db46043 100644 --- a/Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme +++ b/Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme @@ -55,6 +55,9 @@ ReferencedContainer = "container:Sentry.xcodeproj"> + + diff --git a/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift b/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift index 79830269a9e..1e531017325 100644 --- a/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift @@ -264,8 +264,9 @@ class SentryCrashIntegrationTests: NotificationCenterTestCase { assertLocaleOnHub(locale: Locale.autoupdatingCurrent.identifier, hub: hub) } - - func testStartUpCrash_CallsFlush() throws { + + // !!!: Disabled until flakiness can be fixed + func testStartUpCrash_CallsFlush_disabled() throws { let (sut, hub) = givenSutWithGlobalHubAndCrashWrapper() sut.install(with: Options()) From 8b040e4b6faf9a16fa9264e43280c412016bb705 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 12 Oct 2022 08:49:24 -0800 Subject: [PATCH 05/13] test: generate profiles with different levels of efficiency (#2274) --- Brewfile.lock.json | 74 ++++++++----------- Gemfile.lock | 26 +++---- .../ProfileDataGeneratorUITest.m | 19 ++++- .../xcschemes/TrendingMovies.xcscheme | 6 ++ .../Movies/MovieCollectionViewCell.swift | 21 +++++- .../TrendingMovies/Utilities/Tracer.swift | 1 + 6 files changed, 86 insertions(+), 61 deletions(-) diff --git a/Brewfile.lock.json b/Brewfile.lock.json index 35bedb0562c..59d43636514 100644 --- a/Brewfile.lock.json +++ b/Brewfile.lock.json @@ -55,35 +55,25 @@ } }, "swiftlint": { - "version": "0.47.1", + "version": "0.49.1", "bottle": { "rebuild": 0, "root_url": "https://ghcr.io/v2/homebrew/core", "files": { "arm64_monterey": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:13b6b6d881b6cfa3f5399c14150ef6da0f1d1cec2b58fd24c6dcbc432c462106", - "sha256": "13b6b6d881b6cfa3f5399c14150ef6da0f1d1cec2b58fd24c6dcbc432c462106" - }, - "arm64_big_sur": { - "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:406fb7b019a5b7f0c052a7d4738f6cda5eaf15ef9c1bc1f89bdc3dc2efc719b6", - "sha256": "406fb7b019a5b7f0c052a7d4738f6cda5eaf15ef9c1bc1f89bdc3dc2efc719b6" + "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:d983879e2d9ea075bf80e223da5adb258f01d9fab4fc6f71f83c4add80490290", + "sha256": "d983879e2d9ea075bf80e223da5adb258f01d9fab4fc6f71f83c4add80490290" }, "monterey": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:3c02d2875bef6dbd474c60a4ce42cce5f9e1da64580c00c351753adeaece5700", - "sha256": "3c02d2875bef6dbd474c60a4ce42cce5f9e1da64580c00c351753adeaece5700" - }, - "big_sur": { - "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:775d4db3c21549bb18384be86ee82a43c92af12b74f9135e7b44f448cd6e0eff", - "sha256": "775d4db3c21549bb18384be86ee82a43c92af12b74f9135e7b44f448cd6e0eff" + "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:73a9664d8a62c7b5d506a70bf100e0289795df04ece6df12f0b77651e497d42b", + "sha256": "73a9664d8a62c7b5d506a70bf100e0289795df04ece6df12f0b77651e497d42b" }, "x86_64_linux": { "cellar": "/home/linuxbrew/.linuxbrew/Cellar", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:f00160b4eb1d370d6baf4341341f813af80ba2fcfa2e65657f96153713d1c774", - "sha256": "f00160b4eb1d370d6baf4341341f813af80ba2fcfa2e65657f96153713d1c774" + "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:705904346a73422be8f053d7b1c413e5d18623bd7244cb33d188d921a072e600", + "sha256": "705904346a73422be8f053d7b1c413e5d18623bd7244cb33d188d921a072e600" } } } @@ -172,40 +162,40 @@ } }, "pre-commit": { - "version": "2.19.0", + "version": "2.20.0", "bottle": { - "rebuild": 0, + "rebuild": 1, "root_url": "https://ghcr.io/v2/homebrew/core", "files": { "arm64_monterey": { - "cellar": ":any", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:35830ae8dc83700b547c078a43e0cae5b99c69d820e6a70b7dd43872105cc075", - "sha256": "35830ae8dc83700b547c078a43e0cae5b99c69d820e6a70b7dd43872105cc075" + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:4a480973522d0180cfd1414ec3d31f8aa284f26243a89036098dd3343ace6a96", + "sha256": "4a480973522d0180cfd1414ec3d31f8aa284f26243a89036098dd3343ace6a96" }, "arm64_big_sur": { - "cellar": ":any", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:ae925eb818c247559e36558216c63a5298653d65ecd528383340a0ee8b92c07e", - "sha256": "ae925eb818c247559e36558216c63a5298653d65ecd528383340a0ee8b92c07e" + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:cb061bc7f86b3149975d8bee8a209410c786d11ffa4091ad7769d6810a37ef5a", + "sha256": "cb061bc7f86b3149975d8bee8a209410c786d11ffa4091ad7769d6810a37ef5a" }, "monterey": { - "cellar": ":any", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:fa8795f2fc5231708ac69b3447732d3342ac77084c75d4cd92636e4cb3306918", - "sha256": "fa8795f2fc5231708ac69b3447732d3342ac77084c75d4cd92636e4cb3306918" + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:b822f396ca2e6523195d6c17ac8bf41eb6aee2e7ceac2ac0c18fbfd708c6a3ab", + "sha256": "b822f396ca2e6523195d6c17ac8bf41eb6aee2e7ceac2ac0c18fbfd708c6a3ab" }, "big_sur": { - "cellar": ":any", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:1eb31671ec49ce4703bdf821c46238a541ef5972f462174f4765dac8a2cf72c3", - "sha256": "1eb31671ec49ce4703bdf821c46238a541ef5972f462174f4765dac8a2cf72c3" + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:40508e1e583f42c3581c2488d8fcb4b88e4138bfb775e88041166ae8385f25a3", + "sha256": "40508e1e583f42c3581c2488d8fcb4b88e4138bfb775e88041166ae8385f25a3" }, "catalina": { - "cellar": ":any", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:4852270ec8f9249be28101899cfc2f5718b8b5ac79432089484af3e754a075cf", - "sha256": "4852270ec8f9249be28101899cfc2f5718b8b5ac79432089484af3e754a075cf" + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:4bd415259c3ca8fe8255c8116865d88e5841cd618d9e75ddfdf04ce79c19e53d", + "sha256": "4bd415259c3ca8fe8255c8116865d88e5841cd618d9e75ddfdf04ce79c19e53d" }, "x86_64_linux": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:6376d63fa6a158bd89dcf23bf75c6b684c542ca933c4c47e434287f92649cd17", - "sha256": "6376d63fa6a158bd89dcf23bf75c6b684c542ca933c4c47e434287f92649cd17" + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:95bb496c02885d65a8db70ad434fda479a99a146e0244308c9be91322b0a2dd3", + "sha256": "95bb496c02885d65a8db70ad434fda479a99a146e0244308c9be91322b0a2dd3" } } } @@ -215,12 +205,12 @@ "system": { "macos": { "monterey": { - "HOMEBREW_VERSION": "3.5.4", - "HOMEBREW_PREFIX": "/usr/local", - "Homebrew/homebrew-core": "5d8199d4653c34f7d06d716c762e23b19c27ffe3", - "CLT": "13.0.0.0.1.1627064638", - "Xcode": "13.4.1", - "macOS": "12.4" + "HOMEBREW_VERSION": "3.6.5", + "HOMEBREW_PREFIX": "/opt/homebrew", + "Homebrew/homebrew-core": "8953dee9c8266b88d45b1697cc931bdf0112342d", + "CLT": "14.0.0.0.1.1661618636", + "Xcode": "14.0", + "macOS": "12.6" } } } diff --git a/Gemfile.lock b/Gemfile.lock index 3672cac1952..f5ba5b055eb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ GEM specs: CFPropertyList (3.0.5) rexml - activesupport (6.1.6.1) + activesupport (6.1.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -17,8 +17,8 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.636.0) - aws-sdk-core (3.154.0) + aws-partitions (1.644.0) + aws-sdk-core (3.159.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) @@ -30,7 +30,7 @@ GEM aws-sdk-core (~> 3, >= 3.127.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sigv4 (1.5.1) + aws-sigv4 (1.5.2) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) claide (1.1.0) @@ -86,7 +86,7 @@ GEM escape (0.0.4) ethon (0.15.0) ffi (>= 1.15.0) - excon (0.92.5) + excon (0.93.0) faraday (1.10.2) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -155,13 +155,13 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) - fastlane-plugin-sentry (1.13.0) + fastlane-plugin-sentry (1.14.0) os (~> 1.1, >= 1.1.4) ffi (1.15.5) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.28.0) + google-apis-androidpublisher_v3 (0.29.0) google-apis-core (>= 0.9.0, < 2.a) google-apis-core (0.9.0) addressable (~> 2.5, >= 2.5.1) @@ -176,19 +176,19 @@ GEM google-apis-core (>= 0.9.0, < 2.a) google-apis-playcustomapp_v1 (0.11.0) google-apis-core (>= 0.9.0, < 2.a) - google-apis-storage_v1 (0.17.0) - google-apis-core (>= 0.7, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) google-cloud-errors (1.3.0) - google-cloud-storage (1.42.0) + google-cloud-storage (1.43.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.17.0) + google-apis-storage_v1 (~> 0.19.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) @@ -282,7 +282,7 @@ GEM rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.1) xcpretty (~> 0.2, >= 0.0.7) - zeitwerk (2.6.0) + zeitwerk (2.6.1) PLATFORMS ruby @@ -296,4 +296,4 @@ DEPENDENCIES xcpretty BUNDLED WITH - 2.3.21 + 2.3.23 diff --git a/Samples/TrendingMovies/ProfileDataGeneratorUITest/ProfileDataGeneratorUITest.m b/Samples/TrendingMovies/ProfileDataGeneratorUITest/ProfileDataGeneratorUITest.m index 0b106827a21..987cd6dbc9e 100644 --- a/Samples/TrendingMovies/ProfileDataGeneratorUITest/ProfileDataGeneratorUITest.m +++ b/Samples/TrendingMovies/ProfileDataGeneratorUITest/ProfileDataGeneratorUITest.m @@ -20,12 +20,14 @@ - (void)testGenerateProfileData { CFTimeInterval const startTime = CACurrentMediaTime(); CFTimeInterval const runDuration_seconds = 3.0 * 60.0; - generateProfileData(5 /* nCellsPerTab */, YES /* clearState */); + BOOL efficiently = NO; + generateProfileData(5 /* nCellsPerTab */, YES /* clearState */, efficiently); while (true) { if ((CACurrentMediaTime() - startTime) >= runDuration_seconds) { break; } - if (!generateProfileData(5 /* nCellsPerTab */, NO /* clearState */)) { + efficiently = !efficiently; + if (!generateProfileData(5 /* nCellsPerTab */, NO /* clearState */, efficiently)) { break; } } @@ -36,15 +38,24 @@ - (void)testGenerateProfileData * Sentry transaction with profiling enabled. * @param nCellsPerTab The number of cells to tap on, per tab. * @param clearState Whether to clear filesystem state when the app starts. + * @param efficiently Whether to perform certain operations in TrendingMovies using an efficient + * method or not, to help us demonstrate how to identify such issues in the profiling areas of the + * Sentry dashboard. * @return Whether the operation was successful or not. */ BOOL -generateProfileData(NSUInteger nCellsPerTab, BOOL clearState) +generateProfileData(NSUInteger nCellsPerTab, BOOL clearState, BOOL efficiently) { XCUIApplication *app = [[XCUIApplication alloc] init]; + NSMutableArray *launchArguments = app.launchArguments.mutableCopy; if (clearState) { - app.launchArguments = @[ @"--clear" ]; + [launchArguments addObject:@"--clear"]; } + if (efficiently) { + [launchArguments + addObject:@"--io.sentry.sample.trending-movies.launch-arg.blur-images-on-bg-thread"]; + } + app.launchArguments = launchArguments; [app launch]; if (![app waitForState:XCUIApplicationStateRunningForeground timeout:kWaitForAppStateTimeout]) { XCTFail("App failed to transition to Foreground state"); diff --git a/Samples/TrendingMovies/TrendingMovies.xcodeproj/xcshareddata/xcschemes/TrendingMovies.xcscheme b/Samples/TrendingMovies/TrendingMovies.xcodeproj/xcshareddata/xcschemes/TrendingMovies.xcscheme index 67c14f5de77..5dc59c560e2 100644 --- a/Samples/TrendingMovies/TrendingMovies.xcodeproj/xcshareddata/xcschemes/TrendingMovies.xcscheme +++ b/Samples/TrendingMovies/TrendingMovies.xcodeproj/xcshareddata/xcschemes/TrendingMovies.xcscheme @@ -60,6 +60,12 @@ ReferencedContainer = "container:TrendingMovies.xcodeproj"> + + + + Void) { - let blurredImage = ImageEffects.createBlurredBackdrop(image: image, downsamplingFactor: 1.0, blurRadius: 20.0, tintColor: nil, saturationDeltaFactor: 2.0) - completion(blurredImage) + let efficiently = ProcessInfo.processInfo.arguments.contains("--io.sentry.sample.trending-movies.launch-arg.blur-images-on-bg-thread") + func performBlur() { + let blurredImage = ImageEffects.createBlurredBackdrop(image: image, downsamplingFactor: 1.0, blurRadius: 20.0, tintColor: nil, saturationDeltaFactor: 2.0) + if efficiently { + DispatchQueue.main.async { + completion(blurredImage) + } + } else { + completion(blurredImage) + } + } + if efficiently { + MovieCollectionViewCell.blurWorkQueue.async { + performBlur() + } + } else { + performBlur() + } } diff --git a/Samples/TrendingMovies/TrendingMovies/Utilities/Tracer.swift b/Samples/TrendingMovies/TrendingMovies/Utilities/Tracer.swift index 27569860f10..2b0a04bcd61 100644 --- a/Samples/TrendingMovies/TrendingMovies/Utilities/Tracer.swift +++ b/Samples/TrendingMovies/TrendingMovies/Utilities/Tracer.swift @@ -43,6 +43,7 @@ extension Tracer { SentrySDK.configureScope { scope in scope.setTag(value: setUpInDidFinishLaunching ? "didFinishLaunching" : "willFinishLaunching", key: "launch-method") + scope.setTag(value: "\(ProcessInfo.processInfo.arguments.contains("--io.sentry.sample.trending-movies.launch-arg.blur-images-on-bg-thread"))", key: "efficient-implementation") } } } From 0e2e5938cd3bf4c83cc9158efea42b5988395d09 Mon Sep 17 00:00:00 2001 From: Kevin Renskers Date: Thu, 13 Oct 2022 10:33:13 +0200 Subject: [PATCH 06/13] ref: Don't only update App State in the OOM tracker (#2276) --- .../iOS-SwiftUI.xcodeproj/project.pbxproj | 41 +++++ Sentry.xcodeproj/project.pbxproj | 4 + Sources/Sentry/SentryAppStartTracker.m | 8 + Sources/Sentry/SentryAppStateManager.m | 143 ++++++++++++++++-- Sources/Sentry/SentryDependencyContainer.m | 11 +- Sources/Sentry/SentryOutOfMemoryTracker.m | 96 +----------- Sources/Sentry/SentrySessionTracker.m | 4 + .../Sentry/include/SentryAppStateManager.h | 9 +- .../Helper/SentryAppStateManagerTests.swift | 115 ++++++++++++++ .../SentryOutOfMemoryLogicTests.swift | 2 +- .../SentryOutOfMemoryTrackerTests.swift | 4 +- .../SentryAppStartTrackerTests.swift | 5 +- 12 files changed, 326 insertions(+), 116 deletions(-) create mode 100644 Tests/SentryTests/Helper/SentryAppStateManagerTests.swift diff --git a/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj b/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj index 7f2fe9a967c..62ed0d3c93f 100644 --- a/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj +++ b/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj @@ -19,6 +19,20 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 0A94157D28F6B893006A5DD1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 63AA759B1EB8AEF500D153DE; + remoteInfo = Sentry; + }; + 0A94157F28F6B893006A5DD1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 63AA76651EB8CB2F00D153DE; + remoteInfo = SentryTests; + }; 7B64385C26A6C0A6000D0F65 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 7BB6224126A56C4E00D0E75E /* Project object */; @@ -101,6 +115,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0A94157928F6B893006A5DD1 /* Products */ = { + isa = PBXGroup; + children = ( + 0A94157E28F6B893006A5DD1 /* Sentry.framework */, + 0A94158028F6B893006A5DD1 /* SentryTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; 7B64385826A6C0A6000D0F65 /* iOS-SwiftUI-UITests */ = { isa = PBXGroup; children = ( @@ -242,6 +265,10 @@ productRefGroup = 7BB6224A26A56C4E00D0E75E /* Products */; projectDirPath = ""; projectReferences = ( + { + ProductGroup = 0A94157928F6B893006A5DD1 /* Products */; + ProjectRef = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */; + }, { ProductGroup = 84D4FEAB28ECD52E00EDAAFE /* Products */; ProjectRef = 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */; @@ -256,6 +283,20 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ + 0A94157E28F6B893006A5DD1 /* Sentry.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Sentry.framework; + remoteRef = 0A94157D28F6B893006A5DD1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 0A94158028F6B893006A5DD1 /* SentryTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = SentryTests.xctest; + remoteRef = 0A94157F28F6B893006A5DD1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 84D4FEB228ECD52E00EDAAFE /* Sentry.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 058fb8510b7..5f225cfca8b 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -52,6 +52,7 @@ 0A56DA5F28ABA01B00C400D5 /* SentryTransactionContext+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A56DA5E28ABA01B00C400D5 /* SentryTransactionContext+Private.h */; }; 0A6EEADD28A657970076B469 /* UIViewRecursiveDescriptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6EEADC28A657970076B469 /* UIViewRecursiveDescriptionTests.swift */; }; 0A8F0A392886CC70000B15F6 /* SentryPermissionsObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AABE2EE288592750057ED69 /* SentryPermissionsObserver.h */; }; + 0A94158228F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */; }; 0A9BF4E228A114940068D266 /* SentryViewHierarchyIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A9BF4E128A114940068D266 /* SentryViewHierarchyIntegration.m */; }; 0A9BF4E428A114B50068D266 /* SentryViewHierarchyIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A9BF4E328A114B50068D266 /* SentryViewHierarchyIntegration.h */; }; 0A9BF4E928A125390068D266 /* TestSentryViewHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9BF4E628A123270068D266 /* TestSentryViewHierarchy.swift */; }; @@ -757,6 +758,7 @@ 0A5370A028A3EC2400B2DCDE /* SentryViewHierarchyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryViewHierarchyTests.swift; sourceTree = ""; }; 0A56DA5E28ABA01B00C400D5 /* SentryTransactionContext+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryTransactionContext+Private.h"; path = "include/SentryTransactionContext+Private.h"; sourceTree = ""; }; 0A6EEADC28A657970076B469 /* UIViewRecursiveDescriptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewRecursiveDescriptionTests.swift; sourceTree = ""; }; + 0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAppStateManagerTests.swift; sourceTree = ""; }; 0A9BF4E128A114940068D266 /* SentryViewHierarchyIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryViewHierarchyIntegration.m; sourceTree = ""; }; 0A9BF4E328A114B50068D266 /* SentryViewHierarchyIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryViewHierarchyIntegration.h; path = include/SentryViewHierarchyIntegration.h; sourceTree = ""; }; 0A9BF4E628A123270068D266 /* TestSentryViewHierarchy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentryViewHierarchy.swift; sourceTree = ""; }; @@ -2400,6 +2402,7 @@ 7B85BD8D24C5C3A6000A4225 /* SentryFileManagerTestExtension.swift */, 7B4C817124D1BC2B0076ACE4 /* SentryFileManager+TestProperties.h */, 7B98D7EB25FB7C4900C5A389 /* SentryAppStateTests.swift */, + 0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */, 69BEE6F62620729E006DF9DF /* UrlSessionDelegateSpy.swift */, 7BD86ECA264A6DB5005439DB /* TestSysctl.swift */, 7B16FD012654F86B008177D3 /* SentrySysctlTests.swift */, @@ -3612,6 +3615,7 @@ 7B88F30224BC5C6D00ADF90A /* SentrySdkInfoTests.swift in Sources */, 7BC8523B2458849E005A70F0 /* SentryDataCategoryMapperTests.swift in Sources */, 63FE721220DA66EC00CDBAE8 /* SentryCrashMach_Tests.m in Sources */, + 0A94158228F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift in Sources */, 7B6D98E924C6D336005502FA /* SentrySdkInfo+Equality.m in Sources */, 7BDB03BF25136A7D00BAE198 /* TestSentryDispatchQueueWrapper.swift in Sources */, 7B6438A726A70DDB000D0F65 /* UIViewControllerSentryTests.swift in Sources */, diff --git a/Sources/Sentry/SentryAppStartTracker.m b/Sources/Sentry/SentryAppStartTracker.m index 433acb0c406..cc9927c0f69 100644 --- a/Sources/Sentry/SentryAppStartTracker.m +++ b/Sources/Sentry/SentryAppStartTracker.m @@ -109,6 +109,10 @@ - (void)start if (PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode) { [self buildAppStartMeasurement]; } + +# if SENTRY_HAS_UIKIT + [self.appStateManager start]; +# endif } - (void)buildAppStartMeasurement @@ -259,6 +263,10 @@ - (void)stop [NSNotificationCenter.defaultCenter removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; + +# if SENTRY_HAS_UIKIT + [self.appStateManager stop]; +# endif } - (void)dealloc diff --git a/Sources/Sentry/SentryAppStateManager.m b/Sources/Sentry/SentryAppStateManager.m index b3537e44e5e..23889da8f66 100644 --- a/Sources/Sentry/SentryAppStateManager.m +++ b/Sources/Sentry/SentryAppStateManager.m @@ -5,10 +5,13 @@ #import #import #import +#import #import #import #if SENTRY_HAS_UIKIT +# import +# import # import #endif @@ -20,6 +23,8 @@ @property (nonatomic, strong) SentryFileManager *fileManager; @property (nonatomic, strong) id currentDate; @property (nonatomic, strong) SentrySysctl *sysctl; +@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueue; +@property (nonatomic) NSInteger startCount; @end @@ -30,6 +35,7 @@ - (instancetype)initWithOptions:(SentryOptions *)options fileManager:(SentryFileManager *)fileManager currentDateProvider:(id)currentDateProvider sysctl:(SentrySysctl *)sysctl + dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper { if (self = [super init]) { self.options = options; @@ -37,12 +43,138 @@ - (instancetype)initWithOptions:(SentryOptions *)options self.fileManager = fileManager; self.currentDate = currentDateProvider; self.sysctl = sysctl; + self.dispatchQueue = dispatchQueueWrapper; + self.startCount = 0; } return self; } #if SENTRY_HAS_UIKIT +- (void)start +{ + if (self.startCount == 0) { + [NSNotificationCenter.defaultCenter + addObserver:self + selector:@selector(didBecomeActive) + name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter + addObserver:self + selector:@selector(didBecomeActive) + name:SentryHybridSdkDidBecomeActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter + addObserver:self + selector:@selector(willResignActive) + name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter + addObserver:self + selector:@selector(willTerminate) + name:SentryNSNotificationCenterWrapper.willTerminateNotificationName + object:nil]; + + [self storeCurrentAppState]; + } + + self.startCount += 1; +} + +- (void)stop +{ + if (self.startCount <= 0) { + return; + } + + self.startCount -= 1; + + if (self.startCount == 0) { + // Remove the observers with the most specific detail possible, see + // https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver + [NSNotificationCenter.defaultCenter + removeObserver:self + name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter + removeObserver:self + name:SentryHybridSdkDidBecomeActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter + removeObserver:self + name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName + object:nil]; + + [NSNotificationCenter.defaultCenter + removeObserver:self + name:SentryNSNotificationCenterWrapper.willTerminateNotificationName + object:nil]; + + [self deleteAppState]; + } +} + +- (void)dealloc +{ + // In dealloc it's safe to unsubscribe for all, see + // https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver + [NSNotificationCenter.defaultCenter removeObserver:self]; + [self deleteAppState]; +} + +/** + * It is called when an app is receiving events / it is in the foreground and when we receive a + * SentryHybridSdkDidBecomeActiveNotification. + * + * This also works when using SwiftUI or Scenes, as UIKit posts a didBecomeActiveNotification + * regardless of whether your app uses scenes, see + * https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive. + */ +- (void)didBecomeActive +{ + [self updateAppStateInBackground:^(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 updateAppStateInBackground:^(SentryAppState *appState) { appState.isActive = NO; }]; +} + +- (void)willTerminate +{ + // The app is terminating so it is fine to do this on the main thread. + // Furthermore, so users can manually post UIApplicationWillTerminateNotification and then call + // exit(0), to avoid getting false OOM when using exit(0), see GH-1252. + [self updateAppState:^(SentryAppState *appState) { appState.wasTerminated = YES; }]; +} + +- (void)updateAppStateInBackground:(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:^{ [self updateAppState:block]; }]; +} + +- (void)updateAppState:(void (^)(SentryAppState *))block +{ + @synchronized(self) { + SentryAppState *appState = [self.fileManager readAppState]; + if (nil != appState) { + block(appState); + [self.fileManager storeAppState:appState]; + } + } +} + - (SentryAppState *)buildCurrentAppState { // Is the current process being traced or not? If it is a debugger is attached. @@ -72,17 +204,6 @@ - (void)deleteAppState [self.fileManager deleteAppState]; } -- (void)updateAppState:(void (^)(SentryAppState *))block -{ - @synchronized(self) { - SentryAppState *appState = [self.fileManager readAppState]; - if (nil != appState) { - block(appState); - [self.fileManager storeAppState:appState]; - } - } -} - #endif @end diff --git a/Sources/Sentry/SentryDependencyContainer.m b/Sources/Sentry/SentryDependencyContainer.m index 248a34cb066..17df37182b1 100644 --- a/Sources/Sentry/SentryDependencyContainer.m +++ b/Sources/Sentry/SentryDependencyContainer.m @@ -63,11 +63,12 @@ - (SentryAppStateManager *)appStateManager if (_appStateManager == nil) { SentryOptions *options = [[[SentrySDK currentHub] getClient] options]; _appStateManager = [[SentryAppStateManager alloc] - initWithOptions:options - crashWrapper:self.crashWrapper - fileManager:self.fileManager - currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance] - sysctl:[[SentrySysctl alloc] init]]; + initWithOptions:options + crashWrapper:self.crashWrapper + fileManager:self.fileManager + currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance] + sysctl:[[SentrySysctl alloc] init] + dispatchQueueWrapper:self.dispatchQueueWrapper]; } return _appStateManager; } diff --git a/Sources/Sentry/SentryOutOfMemoryTracker.m b/Sources/Sentry/SentryOutOfMemoryTracker.m index 15ca05e6c6f..65b9b372774 100644 --- a/Sources/Sentry/SentryOutOfMemoryTracker.m +++ b/Sources/Sentry/SentryOutOfMemoryTracker.m @@ -7,11 +7,9 @@ #import #import #import -#import #import #import #import -#import #import #import #import @@ -53,28 +51,7 @@ - (instancetype)initWithOptions:(SentryOptions *)options - (void)start { #if SENTRY_HAS_UIKIT - [NSNotificationCenter.defaultCenter - addObserver:self - selector:@selector(didBecomeActive) - name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName - object:nil]; - - [NSNotificationCenter.defaultCenter addObserver:self - selector:@selector(didBecomeActive) - name:SentryHybridSdkDidBecomeActiveNotificationName - object:nil]; - - [NSNotificationCenter.defaultCenter - addObserver:self - selector:@selector(willResignActive) - name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName - object:nil]; - - [NSNotificationCenter.defaultCenter - addObserver:self - selector:@selector(willTerminate) - name:SentryNSNotificationCenterWrapper.willTerminateNotificationName - object:nil]; + [self.appStateManager start]; [self.dispatchQueue dispatchAsyncWithBlock:^{ if ([self.outOfMemoryLogic isOOM]) { @@ -95,10 +72,7 @@ - (void)start // assume it's not an OOM when the releaseName changed between app starts. [SentrySDK captureCrashEvent:event]; } - - [self.appStateManager storeCurrentAppState]; }]; - #else SENTRY_LOG_INFO(@"NO UIKit -> SentryOutOfMemoryTracker will not track OOM."); return; @@ -108,74 +82,8 @@ - (void)start - (void)stop { #if SENTRY_HAS_UIKIT - // Remove the observers with the most specific detail possible, see - // https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver - [NSNotificationCenter.defaultCenter - removeObserver:self - name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName - object:nil]; - - [NSNotificationCenter.defaultCenter - removeObserver:self - name:SentryHybridSdkDidBecomeActiveNotificationName - object:nil]; - - [NSNotificationCenter.defaultCenter - removeObserver:self - name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName - object:nil]; - - [NSNotificationCenter.defaultCenter - removeObserver:self - name:SentryNSNotificationCenterWrapper.willTerminateNotificationName - object:nil]; - [self.appStateManager deleteAppState]; + [self.appStateManager stop]; #endif } -#if SENTRY_HAS_UIKIT -- (void)dealloc -{ - [self stop]; - // In dealloc it's safe to unsubscribe for all, see - // https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver - [NSNotificationCenter.defaultCenter removeObserver:self]; -} - -/** - * 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 -{ - // The app is terminating so it is fine to do this on the main thread. - // Furthermore, so users can manually post UIApplicationWillTerminateNotification and then call - // exit(0), to avoid getting false OOM when using exit(0), see GH-1252. - [self.appStateManager - 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:^{ [self.appStateManager updateAppState:block]; }]; -} - -#endif - @end diff --git a/Sources/Sentry/SentrySessionTracker.m b/Sources/Sentry/SentrySessionTracker.m index 313badc2ecb..f881a110b44 100644 --- a/Sources/Sentry/SentrySessionTracker.m +++ b/Sources/Sentry/SentrySessionTracker.m @@ -135,6 +135,10 @@ - (void)endCachedSession * SentryHybridSdkDidBecomeActiveNotification. There is no guarantee that this method is called once * or twice. We need to ensure that we execute it only once. * + * This also works when using SwiftUI or Scenes, as UIKit posts a didBecomeActiveNotification + * regardless of whether your app uses scenes, see + * https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive. + * * 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 diff --git a/Sources/Sentry/include/SentryAppStateManager.h b/Sources/Sentry/include/SentryAppStateManager.h index bacc527457b..3b9e9ac4efc 100644 --- a/Sources/Sentry/include/SentryAppStateManager.h +++ b/Sources/Sentry/include/SentryAppStateManager.h @@ -1,7 +1,8 @@ #import "SentryCurrentDateProvider.h" #import "SentryDefines.h" -@class SentryOptions, SentryCrashWrapper, SentryAppState, SentryFileManager, SentrySysctl; +@class SentryOptions, SentryCrashWrapper, SentryAppState, SentryFileManager, SentrySysctl, + SentryDispatchQueueWrapper; NS_ASSUME_NONNULL_BEGIN @@ -12,10 +13,14 @@ SENTRY_NO_INIT crashWrapper:(SentryCrashWrapper *)crashWrapper fileManager:(SentryFileManager *)fileManager currentDateProvider:(id)currentDateProvider - sysctl:(SentrySysctl *)sysctl; + sysctl:(SentrySysctl *)sysctl + dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper; #if SENTRY_HAS_UIKIT +- (void)start; +- (void)stop; + /** * Builds the current app state. * diff --git a/Tests/SentryTests/Helper/SentryAppStateManagerTests.swift b/Tests/SentryTests/Helper/SentryAppStateManagerTests.swift new file mode 100644 index 00000000000..98b5f854aa6 --- /dev/null +++ b/Tests/SentryTests/Helper/SentryAppStateManagerTests.swift @@ -0,0 +1,115 @@ +import XCTest + +#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +class SentryAppStateManagerTests: XCTestCase { + private static let dsnAsString = TestConstants.dsnAsString(username: "SentryOutOfMemoryTrackerTests") + private static let dsn = TestConstants.dsn(username: "SentryOutOfMemoryTrackerTests") + + private class Fixture { + + let options: Options + let fileManager: SentryFileManager + let currentDate = TestCurrentDateProvider() + + init() { + options = Options() + options.dsn = SentryAppStateManagerTests.dsnAsString + options.releaseName = TestData.appState.releaseName + + fileManager = try! SentryFileManager(options: options, andCurrentDateProvider: currentDate) + } + + func getSut() -> SentryAppStateManager { + return SentryAppStateManager( + options: options, + crashWrapper: TestSentryCrashWrapper.sharedInstance(), + fileManager: fileManager, + currentDateProvider: currentDate, + sysctl: TestSysctl(), + dispatchQueueWrapper: TestSentryDispatchQueueWrapper() + ) + } + } + + private var fixture: Fixture! + private var sut: SentryAppStateManager! + + override func setUp() { + super.setUp() + + fixture = Fixture() + sut = fixture.getSut() + } + + override func tearDown() { + super.tearDown() + fixture.fileManager.deleteAppState() + } + + func testStartStoresAppState() { + XCTAssertNil(fixture.fileManager.readAppState()) + + sut.start() + XCTAssertNotNil(fixture.fileManager.readAppState()) + } + + func testStartOnlyRunsLogicWhenStartCountBecomesOne() { + XCTAssertNil(fixture.fileManager.readAppState()) + + sut.start() + XCTAssertNotNil(fixture.fileManager.readAppState()) + + fixture.fileManager.deleteAppState() + + sut.start() + XCTAssertNil(fixture.fileManager.readAppState()) + } + + func testStopDeletesAppState() { + XCTAssertNil(fixture.fileManager.readAppState()) + + sut.start() + XCTAssertNotNil(fixture.fileManager.readAppState()) + + sut.stop() + XCTAssertNil(fixture.fileManager.readAppState()) + } + + func testStopOnlyRunsLogicWhenStartCountBecomesZero() { + XCTAssertNil(fixture.fileManager.readAppState()) + + sut.start() + XCTAssertNotNil(fixture.fileManager.readAppState()) + + sut.start() + + sut.stop() + XCTAssertNotNil(fixture.fileManager.readAppState()) + + sut.stop() + XCTAssertNil(fixture.fileManager.readAppState()) + } + + func testStoreAndDeleteAppState() { + XCTAssertNil(fixture.fileManager.readAppState()) + + sut.storeCurrentAppState() + XCTAssertNotNil(fixture.fileManager.readAppState()) + + sut.deleteAppState() + XCTAssertNil(fixture.fileManager.readAppState()) + } + + func testUpdateAppState() { + sut.storeCurrentAppState() + + XCTAssertEqual(fixture.fileManager.readAppState()!.wasTerminated, false) + + sut.updateAppState { state in + state.wasTerminated = true + } + + XCTAssertEqual(fixture.fileManager.readAppState()!.wasTerminated, true) + } +} +#endif diff --git a/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryLogicTests.swift b/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryLogicTests.swift index 1035741cacd..f34f3cdb6d4 100644 --- a/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryLogicTests.swift +++ b/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryLogicTests.swift @@ -28,7 +28,7 @@ class SentryOutOfMemoryLogicTests: XCTestCase { } func getSut() -> SentryOutOfMemoryLogic { - let appStateManager = SentryAppStateManager(options: options, crashWrapper: crashWrapper, fileManager: fileManager, currentDateProvider: currentDate, sysctl: sysctl) + let appStateManager = SentryAppStateManager(options: options, crashWrapper: crashWrapper, fileManager: fileManager, currentDateProvider: currentDate, sysctl: sysctl, dispatchQueueWrapper: self.dispatchQueue) return SentryOutOfMemoryLogic(options: options, crashAdapter: crashWrapper, appStateManager: appStateManager) } } diff --git a/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryTrackerTests.swift b/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryTrackerTests.swift index 7454e29ef05..fa72aeacfaf 100644 --- a/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryTrackerTests.swift +++ b/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryTrackerTests.swift @@ -36,7 +36,7 @@ class SentryOutOfMemoryTrackerTests: NotificationCenterTestCase { } func getSut(fileManager: SentryFileManager) -> SentryOutOfMemoryTracker { - let appStateManager = SentryAppStateManager(options: options, crashWrapper: crashWrapper, fileManager: fileManager, currentDateProvider: currentDate, sysctl: sysctl) + let appStateManager = SentryAppStateManager(options: options, crashWrapper: crashWrapper, fileManager: fileManager, currentDateProvider: currentDate, sysctl: sysctl, dispatchQueueWrapper: self.dispatchQueue) let logic = SentryOutOfMemoryLogic(options: options, crashAdapter: crashWrapper, appStateManager: appStateManager) return SentryOutOfMemoryTracker(options: options, outOfMemoryLogic: logic, appStateManager: appStateManager, dispatchQueueWrapper: dispatchQueue, fileManager: fileManager) } @@ -62,6 +62,8 @@ class SentryOutOfMemoryTrackerTests: NotificationCenterTestCase { } func testStart_StoresAppState() { + XCTAssertNil(fixture.fileManager.readAppState()) + sut.start() let actual = fixture.fileManager.readAppState() diff --git a/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift b/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift index 985f00f09dc..5616a5f7e1c 100644 --- a/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift +++ b/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift @@ -14,6 +14,7 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { let fileManager: SentryFileManager let crashWrapper = TestSentryCrashWrapper.sharedInstance() let appStateManager: SentryAppStateManager + let dispatchQueue = TestSentryDispatchQueueWrapper() let appStartDuration: TimeInterval = 0.4 var runtimeInitTimestamp: Date @@ -26,7 +27,7 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { fileManager = try! SentryFileManager(options: options, andCurrentDateProvider: currentDate) - appStateManager = SentryAppStateManager(options: options, crashWrapper: crashWrapper, fileManager: fileManager, currentDateProvider: currentDate, sysctl: sysctl) + appStateManager = SentryAppStateManager(options: options, crashWrapper: crashWrapper, fileManager: fileManager, currentDateProvider: currentDate, sysctl: sysctl, dispatchQueueWrapper: dispatchQueue) runtimeInitTimestamp = currentDate.date().addingTimeInterval(0.2) didFinishLaunchingTimestamp = currentDate.date().addingTimeInterval(0.3) @@ -55,7 +56,7 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase { fixture.fileManager.deleteAllFolders() clearTestState() } - + func testFirstStart_IsColdStart() { startApp() From 372ffbef48535f7179f7120c431887b8aa98018a Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Thu, 13 Oct 2022 14:27:28 +0200 Subject: [PATCH 07/13] feat: Custom measurements API (#2268) Add API to add custom measurements to transactions. --- CHANGELOG.md | 6 + .../iOS-Swift/iOS-Swift/ViewController.swift | 5 + .../iOS-SwiftUI.xcodeproj/project.pbxproj | 23 +++ Sentry.xcodeproj/project.pbxproj | 24 ++- Sources/Sentry/Public/Sentry.h | 1 + Sources/Sentry/Public/SentryMeasurementUnit.h | 138 +++++++++++++++ Sources/Sentry/Public/SentryOptions.h | 2 +- Sources/Sentry/Public/SentrySpanProtocol.h | 31 +++- Sources/Sentry/SentryMeasurementUnit.m | 159 ++++++++++++++++++ Sources/Sentry/SentryMeasurementValue.m | 36 ++++ Sources/Sentry/SentryNoOpSpan.m | 8 + Sources/Sentry/SentryOptions.m | 4 + Sources/Sentry/SentrySpan.m | 11 ++ Sources/Sentry/SentryTracer.m | 29 +++- Sources/Sentry/SentryTransaction.m | 18 +- .../Sentry/include/SentryMeasurementValue.h | 19 +++ Sources/Sentry/include/SentryTracer.h | 4 +- .../include/SentryTransaction+Private.h | 12 -- .../Performance/SentryTracerTests.swift | 25 +++ .../Protocol/SentryMeasurementUnitTests.swift | 62 +++++++ .../SentryTests/SentryTests-Bridging-Header.h | 1 - .../Transaction/SentryTransactionTests.swift | 56 ++++-- .../SentryTests/Transaction/TestSentrySpan.m | 8 + 23 files changed, 628 insertions(+), 54 deletions(-) create mode 100644 Sources/Sentry/Public/SentryMeasurementUnit.h create mode 100644 Sources/Sentry/SentryMeasurementUnit.m create mode 100644 Sources/Sentry/SentryMeasurementValue.m create mode 100644 Sources/Sentry/include/SentryMeasurementValue.h delete mode 100644 Sources/Sentry/include/SentryTransaction+Private.h create mode 100644 Tests/SentryTests/Protocol/SentryMeasurementUnitTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index e9e2ec4d81c..ecb1cfa779e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Features + +- [Custom measurements API](https://docs.sentry.io/platforms/apple/performance/instrumentation/custom-instrumentation/) (#2268) + ## 7.27.1 ### Fixes diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index e0f465e8bda..d3e87f34d99 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -141,6 +141,11 @@ class ViewController: UIViewController { @IBAction func captureTransaction(_ sender: Any) { let transaction = SentrySDK.startTransaction(name: "Some Transaction", operation: "Some Operation") + + transaction.setMeasurement(name: "duration", value: 44, unit: MeasurementUnitDuration.nanosecond) + transaction.setMeasurement(name: "information", value: 44, unit: MeasurementUnitInformation.bit) + transaction.setMeasurement(name: "duration-custom", value: 22, unit: MeasurementUnit(unit: "custom")) + let span = transaction.startChild(operation: "user", description: "calls out") DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: { diff --git a/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj b/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj index 62ed0d3c93f..0c5eda6143e 100644 --- a/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj +++ b/Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj @@ -40,6 +40,20 @@ remoteGlobalIDString = 7BB6224826A56C4E00D0E75E; remoteInfo = "iOS-SwiftUI"; }; + 7BF01DB528F536BC00302035 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 63AA759B1EB8AEF500D153DE; + remoteInfo = Sentry; + }; + 7BF01DB728F536BC00302035 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 63AA76651EB8CB2F00D153DE; + remoteInfo = SentryTests; + }; 84D4FEAD28ECD52E00EDAAFE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */; @@ -186,6 +200,15 @@ name = Frameworks; sourceTree = ""; }; + 7BF01DB128F536BC00302035 /* Products */ = { + isa = PBXGroup; + children = ( + 7BF01DB628F536BC00302035 /* Sentry.framework */, + 7BF01DB828F536BC00302035 /* SentryTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; 84D4FEAB28ECD52E00EDAAFE /* Products */ = { isa = PBXGroup; children = ( diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 5f225cfca8b..e74dfabcf1f 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -353,9 +353,9 @@ 7B6438A726A70DDB000D0F65 /* UIViewControllerSentryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6438A626A70DDB000D0F65 /* UIViewControllerSentryTests.swift */; }; 7B6438AA26A70F24000D0F65 /* UIViewController+Sentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B6438A826A70F24000D0F65 /* UIViewController+Sentry.h */; }; 7B6438AB26A70F24000D0F65 /* UIViewController+Sentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B6438A926A70F24000D0F65 /* UIViewController+Sentry.m */; }; + 7B68345128F7EB3D00FB7064 /* SentryMeasurementUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B68345028F7EB3D00FB7064 /* SentryMeasurementUnitTests.swift */; }; 7B68D93625FF5F1A0082D139 /* SentryAppState+Equality.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B68D93525FF5F1A0082D139 /* SentryAppState+Equality.m */; }; 7B6ADFCF26A02CAE0076C206 /* SentryCrashReportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6ADFCE26A02CAE0076C206 /* SentryCrashReportTests.swift */; }; - 7B6C5ED2264E5D6C0010D138 /* SentryTransaction+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B6C5ED0264E5D6C0010D138 /* SentryTransaction+Private.h */; }; 7B6C5ED6264E62CA0010D138 /* SentryTransactionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6C5ED5264E62CA0010D138 /* SentryTransactionTests.swift */; }; 7B6C5EDA264E8D860010D138 /* SentryFramesTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B6C5ED9264E8D860010D138 /* SentryFramesTrackingIntegration.h */; }; 7B6C5EDC264E8DA80010D138 /* SentryFramesTrackingIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B6C5EDB264E8DA80010D138 /* SentryFramesTrackingIntegration.m */; }; @@ -493,6 +493,10 @@ 7BC8523724588115005A70F0 /* SentryDataCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC8523624588115005A70F0 /* SentryDataCategory.h */; }; 7BC852392458830A005A70F0 /* SentryEnvelopeItemType.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC852382458830A005A70F0 /* SentryEnvelopeItemType.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7BC8523B2458849E005A70F0 /* SentryDataCategoryMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC8523A2458849E005A70F0 /* SentryDataCategoryMapperTests.swift */; }; + 7BC9A20028F41016001E7C4C /* SentryMeasurementValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC9A1FF28F41016001E7C4C /* SentryMeasurementValue.h */; }; + 7BC9A20228F41350001E7C4C /* SentryMeasurementUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC9A20128F41350001E7C4C /* SentryMeasurementUnit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7BC9A20428F4166D001E7C4C /* SentryMeasurementValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC9A20328F4166D001E7C4C /* SentryMeasurementValue.m */; }; + 7BC9A20628F41781001E7C4C /* SentryMeasurementUnit.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC9A20528F41781001E7C4C /* SentryMeasurementUnit.m */; }; 7BCFA71627D0BB50008C662C /* SentryANRTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BCFA71527D0BB50008C662C /* SentryANRTracker.m */; }; 7BCFBD672681C95000BC27D8 /* SentryScopeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BCFBD662681C95000BC27D8 /* SentryScopeObserver.h */; }; 7BCFBD6D2681D0A900BC27D8 /* SentryCrashScopeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BCFBD6C2681D0A900BC27D8 /* SentryCrashScopeObserver.h */; }; @@ -1079,10 +1083,10 @@ 7B6438A626A70DDB000D0F65 /* UIViewControllerSentryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = UIViewControllerSentryTests.swift; path = Tests/SentryTests/Categories/UIViewControllerSentryTests.swift; sourceTree = SOURCE_ROOT; }; 7B6438A826A70F24000D0F65 /* UIViewController+Sentry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "UIViewController+Sentry.h"; path = "include/UIViewController+Sentry.h"; sourceTree = ""; }; 7B6438A926A70F24000D0F65 /* UIViewController+Sentry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+Sentry.m"; sourceTree = ""; }; + 7B68345028F7EB3D00FB7064 /* SentryMeasurementUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryMeasurementUnitTests.swift; sourceTree = ""; }; 7B68D93425FF5F1A0082D139 /* SentryAppState+Equality.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryAppState+Equality.h"; sourceTree = ""; }; 7B68D93525FF5F1A0082D139 /* SentryAppState+Equality.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentryAppState+Equality.m"; sourceTree = ""; }; 7B6ADFCE26A02CAE0076C206 /* SentryCrashReportTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCrashReportTests.swift; sourceTree = ""; }; - 7B6C5ED0264E5D6C0010D138 /* SentryTransaction+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryTransaction+Private.h"; path = "include/SentryTransaction+Private.h"; sourceTree = ""; }; 7B6C5ED5264E62CA0010D138 /* SentryTransactionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTransactionTests.swift; sourceTree = ""; }; 7B6C5ED9264E8D860010D138 /* SentryFramesTrackingIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryFramesTrackingIntegration.h; path = include/SentryFramesTrackingIntegration.h; sourceTree = ""; }; 7B6C5EDB264E8DA80010D138 /* SentryFramesTrackingIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryFramesTrackingIntegration.m; sourceTree = ""; }; @@ -1226,6 +1230,10 @@ 7BC8523624588115005A70F0 /* SentryDataCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDataCategory.h; path = include/SentryDataCategory.h; sourceTree = ""; }; 7BC852382458830A005A70F0 /* SentryEnvelopeItemType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryEnvelopeItemType.h; path = Public/SentryEnvelopeItemType.h; sourceTree = ""; }; 7BC8523A2458849E005A70F0 /* SentryDataCategoryMapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryDataCategoryMapperTests.swift; sourceTree = ""; }; + 7BC9A1FF28F41016001E7C4C /* SentryMeasurementValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryMeasurementValue.h; path = include/SentryMeasurementValue.h; sourceTree = ""; }; + 7BC9A20128F41350001E7C4C /* SentryMeasurementUnit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryMeasurementUnit.h; path = Public/SentryMeasurementUnit.h; sourceTree = ""; }; + 7BC9A20328F4166D001E7C4C /* SentryMeasurementValue.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryMeasurementValue.m; sourceTree = ""; }; + 7BC9A20528F41781001E7C4C /* SentryMeasurementUnit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryMeasurementUnit.m; sourceTree = ""; }; 7BC9CD4326A99F660047518E /* SentryUIViewControllerSwizzling+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryUIViewControllerSwizzling+Test.h"; sourceTree = ""; }; 7BCFA71427D0BAB7008C662C /* SentryANRTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryANRTracker.h; path = include/SentryANRTracker.h; sourceTree = ""; }; 7BCFA71527D0BB50008C662C /* SentryANRTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryANRTracker.m; sourceTree = ""; }; @@ -1614,6 +1622,8 @@ 7BD4BD4427EB29F50071F4FF /* SentryClientReport.m */, 7BD4BD4627EB2A3D0071F4FF /* SentryDiscardedEvent.h */, 7BD4BD4827EB2A5D0071F4FF /* SentryDiscardedEvent.m */, + 7BC9A20128F41350001E7C4C /* SentryMeasurementUnit.h */, + 7BC9A20528F41781001E7C4C /* SentryMeasurementUnit.m */, ); name = Protocol; sourceTree = ""; @@ -2245,6 +2255,7 @@ 7B68D93525FF5F1A0082D139 /* SentryAppState+Equality.m */, 7BD4BD4A27EB2DC20071F4FF /* SentryDiscardedEventTests.swift */, 7BD4BD4C27EB31820071F4FF /* SentryClientReportTests.swift */, + 7B68345028F7EB3D00FB7064 /* SentryMeasurementUnitTests.swift */, ); path = Protocol; sourceTree = ""; @@ -2756,7 +2767,6 @@ 8ECC674525C23A20000E2BF6 /* SentrySpanId.m */, 8E4E7C6B25DAAAFE006AB9E2 /* SentryTransaction.h */, 8ECC674425C23A1F000E2BF6 /* SentryTransaction.m */, - 7B6C5ED0264E5D6C0010D138 /* SentryTransaction+Private.h */, 8ECC673B25C23996000E2BF6 /* SentryTransactionContext.h */, 8ECC674625C23A20000E2BF6 /* SentryTransactionContext.m */, 0A56DA5E28ABA01B00C400D5 /* SentryTransactionContext+Private.h */, @@ -2776,6 +2786,8 @@ D88817D626D7149100BF2251 /* SentryTraceContext.m */, D8603DD7284F894C000E1227 /* SentryBaggage.h */, D8603DD4284F8497000E1227 /* SentryBaggage.m */, + 7BC9A1FF28F41016001E7C4C /* SentryMeasurementValue.h */, + 7BC9A20328F4166D001E7C4C /* SentryMeasurementValue.m */, ); name = Transaction; sourceTree = ""; @@ -2898,6 +2910,7 @@ 0A2D8DA8289BC905008720F6 /* SentryViewHierarchy.h in Headers */, 8EAE980C261E9F530073B6B3 /* SentryUIViewControllerPerformanceTracker.h in Headers */, 63FE717D20DA4C1100CDBAE8 /* SentryCrashCachedData.h in Headers */, + 7BC9A20028F41016001E7C4C /* SentryMeasurementValue.h in Headers */, 7BBC826D25DFCFDE005F1ED8 /* SentryInAppLogic.h in Headers */, 03BCC38A27E1BF49003232C7 /* SentryTime.h in Headers */, 7B0A54222521C21E00A71716 /* SentryFrameRemover.h in Headers */, @@ -2990,6 +3003,7 @@ 7DC27EC523997EB7006998B5 /* SentryAutoBreadcrumbTrackingIntegration.h in Headers */, 63FE707F20DA4C1000CDBAE8 /* SentryCrashVarArgs.h in Headers */, 03F84D2627DD414C008FE43F /* SentryThreadMetadataCache.hpp in Headers */, + 7BC9A20228F41350001E7C4C /* SentryMeasurementUnit.h in Headers */, 7BB654FB253DC14A00887E87 /* SentryUserFeedback.h in Headers */, 7B8ECBFA26498907005FE2EF /* SentryAppStateManager.h in Headers */, 639FCFA01EBC804600778193 /* SentryException.h in Headers */, @@ -3043,7 +3057,6 @@ 8E5D38E3261D4B57000D363D /* SentryPerformanceTrackingIntegration.h in Headers */, 63FE70F920DA4C1000CDBAE8 /* SentryCrashMonitor.h in Headers */, 7B98D7CB25FB64EC00C5A389 /* SentryOutOfMemoryTrackingIntegration.h in Headers */, - 7B6C5ED2264E5D6C0010D138 /* SentryTransaction+Private.h in Headers */, 63FE710920DA4C1000CDBAE8 /* SentryCrashFileUtils.h in Headers */, 03F84D1F27DD414C008FE43F /* SentryAsyncSafeLogging.h in Headers */, 7BE3C76B2445C27A00A38442 /* SentryCurrentDateProvider.h in Headers */, @@ -3417,6 +3430,7 @@ 8EAE9806261E87120073B6B3 /* SentryUIViewControllerPerformanceTracker.m in Sources */, D88817D826D7149100BF2251 /* SentryTraceContext.m in Sources */, 8EBF870926140D37001A6853 /* SentryPerformanceTracker.m in Sources */, + 7BC9A20428F4166D001E7C4C /* SentryMeasurementValue.m in Sources */, D859696B27BECD8F0036A46E /* SentryCoreDataTrackingIntegration.m in Sources */, 7BD86EC7264A641D005439DB /* SentrySysctl.m in Sources */, D859697327BECDD20036A46E /* SentryCoreDataSwizzling.m in Sources */, @@ -3433,6 +3447,7 @@ 0356A571288B4612008BF593 /* SentryProfilesSampler.m in Sources */, 63FE710B20DA4C1000CDBAE8 /* SentryCrashMach.c in Sources */, 63FE707720DA4C1000CDBAE8 /* Container+SentryDeepSearch.m in Sources */, + 7BC9A20628F41781001E7C4C /* SentryMeasurementUnit.m in Sources */, 63FE71A020DA4C1100CDBAE8 /* SentryCrashInstallation.m in Sources */, 63FE713520DA4C1100CDBAE8 /* SentryCrashMemory.c in Sources */, 63FE714520DA4C1100CDBAE8 /* SentryCrashObjC.c in Sources */, @@ -3465,6 +3480,7 @@ 7B5AB65D27E48E5200F1D1BA /* TestThreadInspector.swift in Sources */, 7BF9EF742722A85B00B5BBEF /* SentryClassRegistrator.m in Sources */, 63B819141EC352A7002FDF4C /* SentryInterfacesTests.m in Sources */, + 7B68345128F7EB3D00FB7064 /* SentryMeasurementUnitTests.swift in Sources */, 7B14089A248791660035403D /* SentryCrashStackEntryMapperTests.swift in Sources */, 7B869EBC249B91D8004F4FDB /* SentryDebugMetaEquality.swift in Sources */, 7B01CE3D271993AC00B5AF31 /* SentryTransportFactoryTests.swift in Sources */, diff --git a/Sources/Sentry/Public/Sentry.h b/Sources/Sentry/Public/Sentry.h index 8fb98787446..01784d2553b 100644 --- a/Sources/Sentry/Public/Sentry.h +++ b/Sources/Sentry/Public/Sentry.h @@ -25,6 +25,7 @@ FOUNDATION_EXPORT const unsigned char SentryVersionString[]; #import "SentryHub.h" #import "SentryId.h" #import "SentryIntegrationProtocol.h" +#import "SentryMeasurementUnit.h" #import "SentryMechanism.h" #import "SentryMechanismMeta.h" #import "SentryMessage.h" diff --git a/Sources/Sentry/Public/SentryMeasurementUnit.h b/Sources/Sentry/Public/SentryMeasurementUnit.h new file mode 100644 index 00000000000..e7a5b3462af --- /dev/null +++ b/Sources/Sentry/Public/SentryMeasurementUnit.h @@ -0,0 +1,138 @@ +#import "SentryDefines.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * The unit of measurement of a metric value. + * + * Units augment metric values by giving them a magnitude and semantics. There are certain types + * of units that are subdivided in their precision, such as the ``SentryMeasurementUnitDuration`` + * for time measurements. The following unit types are available: ``SentryMeasurementUnitDuration``, + * ``SentryMeasurementUnitInformation``, and``SentryMeasurementUnitFraction``. + * + * When using the units to custom measurements, Sentry will apply formatting to display + * measurement values in the UI. + */ +NS_SWIFT_NAME(MeasurementUnit) +@interface SentryMeasurementUnit : NSObject +SENTRY_NO_INIT + +/** + * Returns an initialized SentryMeasurementUnit with a custom measurement unit. + * + * @param unit Your own custom unit without built-in conversion in Sentry. + */ +- (instancetype)initWithUnit:(NSString *)unit; + +/** + * The NSString representation of the measurement unit. + */ +@property (readonly, copy) NSString *unit; + +/** Untyped value without a unit. */ +@property (class, readonly, copy) SentryMeasurementUnit *none; + +@end + +/** + * Time duration units. + */ +NS_SWIFT_NAME(MeasurementUnitDuration) +@interface SentryMeasurementUnitDuration : SentryMeasurementUnit +SENTRY_NO_INIT + +/** Nanosecond, 10^-9 seconds. */ +@property (class, readonly, copy) SentryMeasurementUnitDuration *nanosecond; + +/** Microsecond , 10^-6 seconds. */ +@property (class, readonly, copy) SentryMeasurementUnitDuration *microsecond; + +/** Millisecond, 10^-3 seconds. */ +@property (class, readonly, copy) SentryMeasurementUnitDuration *millisecond; + +/** Full second. */ +@property (class, readonly, copy) SentryMeasurementUnitDuration *second; + +/** Minute, 60 seconds. */ +@property (class, readonly, copy) SentryMeasurementUnitDuration *minute; + +/** Hour, 3600 seconds. */ +@property (class, readonly, copy) SentryMeasurementUnitDuration *hour; + +/** Day, 86,400 seconds. */ +@property (class, readonly, copy) SentryMeasurementUnitDuration *day; + +/** Week, 604,800 seconds. */ +@property (class, readonly, copy) SentryMeasurementUnitDuration *week; + +@end + +/** + * Size of information units derived from bytes. + * + * See also [Units of information](https://en.wikipedia.org/wiki/Units_of_information) + */ +NS_SWIFT_NAME(MeasurementUnitInformation) +@interface SentryMeasurementUnitInformation : SentryMeasurementUnit +SENTRY_NO_INIT + +/** Bit, corresponding to 1/8 of a byte. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *bit; + +/** Byte. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *byte; + +/** Kilobyte, 10^3 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *kilobyte; + +/** Kibibyte, 2^10 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *kibibyte; + +/** Megabyte, 10^6 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *megabyte; + +/** Mebibyte, 2^20 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *mebibyte; + +/** Gigabyte, 10^9 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *gigabyte; + +/** Gibibyte, 2^30 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *gibibyte; + +/** Terabyte, 10^12 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *terabyte; + +/** Tebibyte, 2^40 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *tebibyte; + +/** Petabyte, 10^15 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *petabyte; + +/** Pebibyte, 2^50 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *pebibyte; + +/** Exabyte, 10^18 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *exabyte; + +/** Exbibyte, 2^60 bytes. */ +@property (class, readonly, copy) SentryMeasurementUnitInformation *exbibyte; + +@end + +/** + * Units of fraction. + */ +NS_SWIFT_NAME(MeasurementUnitFraction) +@interface SentryMeasurementUnitFraction : SentryMeasurementUnit +SENTRY_NO_INIT + +/** Floating point fraction of `1`. */ +@property (class, readonly, copy) SentryMeasurementUnitFraction *ratio; + +/** Ratio expressed as a fraction of `100`. `100%` equals a ratio of `1.0`. */ +@property (class, readonly, copy) SentryMeasurementUnitFraction *percent; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/Public/SentryOptions.h b/Sources/Sentry/Public/SentryOptions.h index fec00739085..0bdd4c97741 100644 --- a/Sources/Sentry/Public/SentryOptions.h +++ b/Sources/Sentry/Public/SentryOptions.h @@ -3,7 +3,7 @@ NS_ASSUME_NONNULL_BEGIN -@class SentryDsn, SentrySdkInfo; +@class SentryDsn, SentrySdkInfo, SentryMeasurementValue; NS_SWIFT_NAME(Options) @interface SentryOptions : NSObject diff --git a/Sources/Sentry/Public/SentrySpanProtocol.h b/Sources/Sentry/Public/SentrySpanProtocol.h index 4fbc1abf50f..ce206fe8778 100644 --- a/Sources/Sentry/Public/SentrySpanProtocol.h +++ b/Sources/Sentry/Public/SentrySpanProtocol.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN -@class SentrySpanId, SentryId, SentryTraceHeader; +@class SentrySpanId, SentryId, SentryTraceHeader, SentryMeasurementUnit; NS_SWIFT_NAME(Span) @protocol SentrySpan @@ -87,6 +87,35 @@ NS_SWIFT_NAME(Span) */ - (void)removeTagForKey:(NSString *)key NS_SWIFT_NAME(removeTag(key:)); +/** + * Set a measurement without unit. When setting the measurement without the unit, no formatting + * will be applied to the measurement value in the Sentry product, and the value will be shown as + * is. + * + * @discussion Setting a measurement with the same name on the same transaction multiple times only + * keeps the last value. + * + * @param name the name of the measurement + * @param value the value of the measurement + */ +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value NS_SWIFT_NAME(setMeasurement(name:value:)); + +/** + * Set a measurement with specific unit. + * + * @discussion Setting a measurement with the same name on the same transaction multiple times only + * keeps the last value. + * + * @param name the name of the measurement + * @param value the value of the measurement + * @param unit the unit the value is measured in + */ +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + unit:(SentryMeasurementUnit *)unit + NS_SWIFT_NAME(setMeasurement(name:value:unit:)); + /** * Finishes the span by setting the end time. */ diff --git a/Sources/Sentry/SentryMeasurementUnit.m b/Sources/Sentry/SentryMeasurementUnit.m new file mode 100644 index 00000000000..f9174857b4a --- /dev/null +++ b/Sources/Sentry/SentryMeasurementUnit.m @@ -0,0 +1,159 @@ +#import "SentryMeasurementUnit.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryMeasurementUnit + +- (instancetype)initWithUnit:(NSString *)unit +{ + if (self = [super init]) { + _unit = unit; + } + return self; +} + ++ (SentryMeasurementUnit *)none +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@""]; +} + +- (id)copyWithZone:(nullable NSZone *)zone +{ + return [[[self class] allocWithZone:zone] initWithUnit:self.unit]; +} + +@end + +@implementation SentryMeasurementUnitDuration + ++ (SentryMeasurementUnitDuration *)nanosecond +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@"nanosecond"]; +} + ++ (SentryMeasurementUnitDuration *)microsecond +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@"microsecond"]; +} + ++ (SentryMeasurementUnitDuration *)millisecond +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@"millisecond"]; +} + ++ (SentryMeasurementUnitDuration *)second +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@"second"]; +} + ++ (SentryMeasurementUnitDuration *)minute +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@"minute"]; +} + ++ (SentryMeasurementUnitDuration *)hour +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@"hour"]; +} + ++ (SentryMeasurementUnitDuration *)day +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@"day"]; +} + ++ (SentryMeasurementUnitDuration *)week +{ + return [[SentryMeasurementUnitDuration alloc] initWithUnit:@"week"]; +} + +@end + +@implementation SentryMeasurementUnitInformation + ++ (SentryMeasurementUnitInformation *)bit +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"bit"]; +} + ++ (SentryMeasurementUnitInformation *)byte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"byte"]; +} + ++ (SentryMeasurementUnitInformation *)kilobyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"kilobyte"]; +} + ++ (SentryMeasurementUnitInformation *)kibibyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"kibibyte"]; +} + ++ (SentryMeasurementUnitInformation *)megabyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"megabyte"]; +} + ++ (SentryMeasurementUnitInformation *)mebibyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"mebibyte"]; +} + ++ (SentryMeasurementUnitInformation *)gigabyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"gigabyte"]; +} + ++ (SentryMeasurementUnitInformation *)gibibyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"gibibyte"]; +} + ++ (SentryMeasurementUnitInformation *)terabyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"terabyte"]; +} + ++ (SentryMeasurementUnitInformation *)tebibyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"tebibyte"]; +} + ++ (SentryMeasurementUnitInformation *)petabyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"petabyte"]; +} + ++ (SentryMeasurementUnitInformation *)pebibyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"pebibyte"]; +} + ++ (SentryMeasurementUnitInformation *)exabyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"exabyte"]; +} + ++ (SentryMeasurementUnitInformation *)exbibyte +{ + return [[SentryMeasurementUnitInformation alloc] initWithUnit:@"exbibyte"]; +} + +@end + +@implementation SentryMeasurementUnitFraction + ++ (SentryMeasurementUnitFraction *)ratio +{ + return [[SentryMeasurementUnitFraction alloc] initWithUnit:@"ratio"]; +} + ++ (SentryMeasurementUnitFraction *)percent +{ + return [[SentryMeasurementUnitFraction alloc] initWithUnit:@"percent"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryMeasurementValue.m b/Sources/Sentry/SentryMeasurementValue.m new file mode 100644 index 00000000000..6099ede4ac5 --- /dev/null +++ b/Sources/Sentry/SentryMeasurementValue.m @@ -0,0 +1,36 @@ +#import "SentryMeasurementValue.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryMeasurementValue + +- (instancetype)initWithValue:(NSNumber *)value +{ + if (self = [super init]) { + _value = value; + } + return self; +} + +- (instancetype)initWithValue:(NSNumber *)value unit:(SentryMeasurementUnit *)unit +{ + if (self = [super init]) { + _value = value; + _unit = unit; + } + return self; +} + +- (NSDictionary *)serialize +{ + + if (self.unit != nil) { + return @{ @"value" : _value, @"unit" : _unit.unit }; + } else { + return @{ @"value" : _value }; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryNoOpSpan.m b/Sources/Sentry/SentryNoOpSpan.m index 0ad045b7596..e62d67a54c9 100644 --- a/Sources/Sentry/SentryNoOpSpan.m +++ b/Sources/Sentry/SentryNoOpSpan.m @@ -64,6 +64,14 @@ - (void)removeTagForKey:(NSString *)key { } +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value +{ +} + +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value unit:(SentryMeasurementUnit *)unit +{ +} + - (NSDictionary *)tags { return @{}; diff --git a/Sources/Sentry/SentryOptions.m b/Sources/Sentry/SentryOptions.m index 150b7f440a6..8f9bc0b5036 100644 --- a/Sources/Sentry/SentryOptions.m +++ b/Sources/Sentry/SentryOptions.m @@ -20,6 +20,10 @@ @implementation SentryOptions +- (void)setMeasurement:(SentryMeasurementValue *)measurement +{ +} + + (NSArray *)defaultIntegrations { return @[ diff --git a/Sources/Sentry/SentrySpan.m b/Sources/Sentry/SentrySpan.m index 2dab3697943..d0a0b656269 100644 --- a/Sources/Sentry/SentrySpan.m +++ b/Sources/Sentry/SentrySpan.m @@ -3,6 +3,7 @@ #import "NSDictionary+SentrySanitize.h" #import "SentryCurrentDate.h" #import "SentryLog.h" +#import "SentryMeasurementValue.h" #import "SentryNoOpSpan.h" #import "SentryTraceHeader.h" #import "SentryTracer.h" @@ -89,6 +90,16 @@ - (void)removeTagForKey:(NSString *)key } } +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value +{ + [self.tracer setMeasurement:name value:value]; +} + +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value unit:(SentryMeasurementUnit *)unit +{ + [self.tracer setMeasurement:name value:value unit:unit]; +} + - (NSDictionary *)tags { @synchronized(_tags) { diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index 167363dc263..6e999e97e4a 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -17,11 +17,11 @@ #import "SentrySpanContext.h" #import "SentrySpanId.h" #import "SentryTraceContext.h" -#import "SentryTransaction+Private.h" #import "SentryTransaction.h" #import "SentryTransactionContext.h" #import "SentryUIViewControllerPerformanceTracker.h" #import +#import #import #import @@ -61,6 +61,7 @@ @implementation SentryTracer { SentryAppStartMeasurement *appStartMeasurement; NSMutableDictionary *_tags; NSMutableDictionary *_data; + NSMutableDictionary *_measurements; dispatch_block_t _idleTimeoutBlock; NSMutableArray> *_children; @@ -160,6 +161,7 @@ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transacti _waitForChildren = waitForChildren; _tags = [[NSMutableDictionary alloc] init]; _data = [[NSMutableDictionary alloc] init]; + _measurements = [[NSMutableDictionary alloc] init]; self.finishStatus = kSentrySpanStatusUndefined; self.idleTimeout = idleTimeout; self.dispatchQueueWrapper = dispatchQueueWrapper; @@ -395,6 +397,19 @@ - (void)removeTagForKey:(NSString *)key } } +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value +{ + SentryMeasurementValue *measurement = [[SentryMeasurementValue alloc] initWithValue:value]; + _measurements[name] = measurement; +} + +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value unit:(SentryMeasurementUnit *)unit +{ + SentryMeasurementValue *measurement = [[SentryMeasurementValue alloc] initWithValue:value + unit:unit]; + _measurements[name] = measurement; +} + - (SentryTraceHeader *)toTraceHeader { return [self.rootSpan toTraceHeader]; @@ -687,8 +702,6 @@ - (nullable SentryAppStartMeasurement *)getAppStartMeasurement - (void)addMeasurements:(SentryTransaction *)transaction { - NSString *valueKey = @"value"; - if (appStartMeasurement != nil && appStartMeasurement.type != SentryAppStartTypeUnknown) { NSString *type = nil; if (appStartMeasurement.type == SentryAppStartTypeCold) { @@ -698,8 +711,7 @@ - (void)addMeasurements:(SentryTransaction *)transaction } if (type != nil) { - [transaction setMeasurementValue:@{ valueKey : @(appStartMeasurement.duration * 1000) } - forKey:type]; + [self setMeasurement:type value:@(appStartMeasurement.duration * 1000)]; } } @@ -717,10 +729,9 @@ - (void)addMeasurements:(SentryTransaction *)transaction BOOL oneBiggerThanZero = totalFrames > 0 || slowFrames > 0 || frozenFrames > 0; if (allBiggerThanZero && oneBiggerThanZero) { - [transaction setMeasurementValue:@{ valueKey : @(totalFrames) } forKey:@"frames_total"]; - [transaction setMeasurementValue:@{ valueKey : @(slowFrames) } forKey:@"frames_slow"]; - [transaction setMeasurementValue:@{ valueKey : @(frozenFrames) } - forKey:@"frames_frozen"]; + [self setMeasurement:@"frames_total" value:@(totalFrames)]; + [self setMeasurement:@"frames_slow" value:@(slowFrames)]; + [self setMeasurement:@"frames_frozen" value:@(frozenFrames)]; SENTRY_LOG_DEBUG(@"Frames for transaction \"%@\" Total:%ld Slow:%ld Frozen:%ld", self.context.operation, (long)totalFrames, (long)slowFrames, (long)frozenFrames); diff --git a/Sources/Sentry/SentryTransaction.m b/Sources/Sentry/SentryTransaction.m index a90f3935042..a9efc76bf7c 100644 --- a/Sources/Sentry/SentryTransaction.m +++ b/Sources/Sentry/SentryTransaction.m @@ -1,6 +1,7 @@ #import "SentryTransaction.h" #import "NSDictionary+SentrySanitize.h" #import "SentryEnvelopeItemType.h" +#import "SentryMeasurementValue.h" #import "SentryTransactionContext.h" NS_ASSUME_NONNULL_BEGIN @@ -9,7 +10,6 @@ SentryTransaction () @property (nonatomic, strong) NSArray> *spans; -@property (nonatomic, strong) NSMutableDictionary *measurements; @end @@ -23,16 +23,10 @@ - (instancetype)initWithTrace:(SentryTracer *)trace children:(NSArray *)serialize { NSMutableDictionary *serializedData = @@ -80,8 +74,14 @@ - (void)setMeasurementValue:(id)value forKey:(NSString *)key serializedData[@"extra"] = traceData; } - if (self.measurements.count > 0) { - serializedData[@"measurements"] = [self.measurements.copy sentry_sanitize]; + if (self.trace.measurements.count > 0) { + NSMutableDictionary *measurements = [NSMutableDictionary dictionary]; + + for (NSString *measurementName in self.trace.measurements.allKeys) { + measurements[measurementName] = [self.trace.measurements[measurementName] serialize]; + } + + serializedData[@"measurements"] = measurements; } if (self.trace) { diff --git a/Sources/Sentry/include/SentryMeasurementValue.h b/Sources/Sentry/include/SentryMeasurementValue.h new file mode 100644 index 00000000000..ec8a61bd275 --- /dev/null +++ b/Sources/Sentry/include/SentryMeasurementValue.h @@ -0,0 +1,19 @@ +#import "SentryDefines.h" +#import "SentryMeasurementUnit.h" +#import "SentrySerializable.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryMeasurementValue : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithValue:(NSNumber *)value; + +- (instancetype)initWithValue:(NSNumber *)value unit:(SentryMeasurementUnit *)unit; + +@property (nonatomic, copy, readonly) NSNumber *value; +@property (nullable, readonly, copy) SentryMeasurementUnit *unit; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/include/SentryTracer.h b/Sources/Sentry/include/SentryTracer.h index 2881ace6d50..c6dc2b7e110 100644 --- a/Sources/Sentry/include/SentryTracer.h +++ b/Sources/Sentry/include/SentryTracer.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN @class SentryHub, SentryTransactionContext, SentryTraceHeader, SentryTraceContext, - SentryDispatchQueueWrapper, SentryTracer, SentryProfilesSamplerDecision; + SentryDispatchQueueWrapper, SentryTracer, SentryProfilesSamplerDecision, SentryMeasurementValue; static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; @@ -76,6 +76,8 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; */ @property (nullable, nonatomic, weak) id delegate; +@property (nonatomic, readonly) NSDictionary *measurements; + /** * Init a SentryTracer with given transaction context and hub and set other fields by default * diff --git a/Sources/Sentry/include/SentryTransaction+Private.h b/Sources/Sentry/include/SentryTransaction+Private.h deleted file mode 100644 index 9d9f38ff096..00000000000 --- a/Sources/Sentry/include/SentryTransaction+Private.h +++ /dev/null @@ -1,12 +0,0 @@ -#import "SentryTransaction.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface -SentryTransaction (Private) - -- (void)setMeasurementValue:(id)value forKey:(NSString *)key; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/Performance/SentryTracerTests.swift b/Tests/SentryTests/Performance/SentryTracerTests.swift index c42763268ff..24f681a9ac8 100644 --- a/Tests/SentryTests/Performance/SentryTracerTests.swift +++ b/Tests/SentryTests/Performance/SentryTracerTests.swift @@ -546,6 +546,31 @@ class SentryTracerTests: XCTestCase { assertAppStartMeasurementNotPutOnTransaction() } + func testMeasurementOnChildSpan_SetTwice_OverwritesMeasurement() { + let name = "something" + let value: NSNumber = -12.34 + let unit = MeasurementUnitFraction.percent + + let sut = fixture.getSut() + let childSpan = sut.startChild(operation: "operation") + sut.setMeasurement(name: name, value: 12.0, unit: unit) + childSpan.setMeasurement(name: name, value: value, unit: unit) + childSpan.finish() + sut.finish() + fixture.hub.group.wait() + + XCTAssertEqual(1, fixture.hub.capturedEventsWithScopes.count) + let serializedTransaction = fixture.hub.capturedEventsWithScopes.first?.event.serialize() + + let measurements = serializedTransaction?["measurements"] as? [String: [String: Any]] + XCTAssertEqual(1, measurements?.count) + + let measurement = measurements?[name] + XCTAssertNotNil(measurement) + XCTAssertEqual(value, measurement?["value"] as! NSNumber) + XCTAssertEqual(unit.unit, measurement?["unit"] as! String) + } + func testFinish_WithUnfinishedChildren() { CurrentDate.setCurrentDateProvider(DefaultCurrentDateProvider.sharedInstance()) let sut = fixture.getSut(waitForChildren: false) diff --git a/Tests/SentryTests/Protocol/SentryMeasurementUnitTests.swift b/Tests/SentryTests/Protocol/SentryMeasurementUnitTests.swift new file mode 100644 index 00000000000..874ddf07ac7 --- /dev/null +++ b/Tests/SentryTests/Protocol/SentryMeasurementUnitTests.swift @@ -0,0 +1,62 @@ +import XCTest + +final class SentryMeasurementUnitTests: XCTestCase { + + func testCustomUnit() { + let unit = "custom" + let sut = MeasurementUnit(unit: unit) + + XCTAssertEqual(unit, sut.unit) + } + + func testUnitNone() { + XCTAssertEqual("", MeasurementUnit.none.unit) + } + + func testCopy() { + let unit = "custom" + let sut = MeasurementUnit(unit: unit).copy() as! MeasurementUnit + + XCTAssertEqual(unit, sut.unit) + } + + func testCopyOfSubclass() { + let unit = "custom" + let sut = MeasurementUnitDuration(unit: unit).copy() as! MeasurementUnitDuration + + XCTAssertEqual(unit, sut.unit) + } + + func testMeasurementUnitDuration() { + XCTAssertEqual("nanosecond", MeasurementUnitDuration.nanosecond.unit) + XCTAssertEqual("microsecond", MeasurementUnitDuration.microsecond.unit) + XCTAssertEqual("millisecond", MeasurementUnitDuration.millisecond.unit) + XCTAssertEqual("second", MeasurementUnitDuration.second.unit) + XCTAssertEqual("minute", MeasurementUnitDuration.minute.unit) + XCTAssertEqual("hour", MeasurementUnitDuration.hour.unit) + XCTAssertEqual("day", MeasurementUnitDuration.day.unit) + XCTAssertEqual("week", MeasurementUnitDuration.week.unit) + } + + func testMeasurementUnitInformation() { + XCTAssertEqual("bit", MeasurementUnitInformation.bit.unit) + XCTAssertEqual("byte", MeasurementUnitInformation.byte.unit) + XCTAssertEqual("kilobyte", MeasurementUnitInformation.kilobyte.unit) + XCTAssertEqual("kibibyte", MeasurementUnitInformation.kibibyte.unit) + XCTAssertEqual("megabyte", MeasurementUnitInformation.megabyte.unit) + XCTAssertEqual("mebibyte", MeasurementUnitInformation.mebibyte.unit) + XCTAssertEqual("gigabyte", MeasurementUnitInformation.gigabyte.unit) + XCTAssertEqual("gibibyte", MeasurementUnitInformation.gibibyte.unit) + XCTAssertEqual("terabyte", MeasurementUnitInformation.terabyte.unit) + XCTAssertEqual("tebibyte", MeasurementUnitInformation.tebibyte.unit) + XCTAssertEqual("petabyte", MeasurementUnitInformation.petabyte.unit) + XCTAssertEqual("pebibyte", MeasurementUnitInformation.pebibyte.unit) + XCTAssertEqual("exabyte", MeasurementUnitInformation.exabyte.unit) + XCTAssertEqual("exbibyte", MeasurementUnitInformation.exbibyte.unit) + } + + func testMeasurementUnitFraction() { + XCTAssertEqual("ratio", MeasurementUnitFraction.ratio.unit) + XCTAssertEqual("percent", MeasurementUnitFraction.percent.unit) + } +} diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index 9a335992fc6..4ad7b2c913a 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -149,7 +149,6 @@ #import "SentryTraceContext.h" #import "SentryTracer+Test.h" #import "SentryTracer.h" -#import "SentryTransaction+Private.h" #import "SentryTransaction.h" #import "SentryTransactionContext+Private.h" #import "SentryTransport.h" diff --git a/Tests/SentryTests/Transaction/SentryTransactionTests.swift b/Tests/SentryTests/Transaction/SentryTransactionTests.swift index 61747cfa02c..f6bd6da0ae1 100644 --- a/Tests/SentryTests/Transaction/SentryTransactionTests.swift +++ b/Tests/SentryTests/Transaction/SentryTransactionTests.swift @@ -8,8 +8,8 @@ class SentryTransactionTests: XCTestCase { let testKey = "extra_key" let testValue = "extra_value" - func getTransaction() -> Transaction { - return Transaction(trace: SentryTracer(), children: []) + func getTransaction(trace: SentryTracer = SentryTracer(transactionContext: TransactionContext(operation: "operation"), hub: TestHub(client: nil, andScope: nil))) -> Transaction { + return Transaction(trace: trace, children: []) } func getContext() -> TransactionContext { @@ -51,26 +51,50 @@ class SentryTransactionTests: XCTestCase { XCTAssertNil(actual["measurements"]) } - func testSerializeMeasurements_Measurements() { - let transaction = fixture.getTransaction() - - let appStart = ["value": 15_000.0] - transaction.setMeasurementValue(appStart, forKey: "app_start_cold") + func testSerializeMeasurements_DurationMeasurement() { + let name = "some_duration" + let value: NSNumber = 15_000.0 + let unit = MeasurementUnitDuration.millisecond + + let trace = SentryTracer(transactionContext: TransactionContext(operation: "operation"), hub: TestHub(client: nil, andScope: nil)) + trace.setMeasurement(name: name, value: value, unit: unit) + let transaction = fixture.getTransaction(trace: trace) + let actual = transaction.serialize() - let actualMeasurements = actual["measurements"] as? [String: [String: Double]] - XCTAssertEqual(appStart, actualMeasurements?["app_start_cold"] ) + let actualMeasurements = actual["measurements"] as? [String: [String: Any]] + XCTAssertNotNil(actualMeasurements) + + let coldStartMeasurement = actualMeasurements?[name] + XCTAssertEqual(value, coldStartMeasurement?["value"] as! NSNumber) + XCTAssertEqual(unit.unit, coldStartMeasurement?["unit"] as! String) } - - func testSerializeMeasurements_GarbageInMeasurements_GarbageSanitized() { - let transaction = fixture.getTransaction() + + func testSerializeMeasurements_MultipleMeasurements() { + let frameName = "frames_total" + let frameValue: NSNumber = 60 + + let customName = "custom-name" + let customValue: NSNumber = 20.1 + let customUnit = MeasurementUnit(unit: "custom") + + let trace = SentryTracer(transactionContext: TransactionContext(operation: "operation"), hub: TestHub(client: nil, andScope: nil)) + trace.setMeasurement(name: frameName, value: frameValue) + trace.setMeasurement(name: customName, value: customValue, unit: customUnit) + let transaction = fixture.getTransaction(trace: trace) - let appStart = ["value": self] - transaction.setMeasurementValue(appStart, forKey: "app_start_cold") let actual = transaction.serialize() - let actualMeasurements = actual["measurements"] as? [String: [String: String]] - XCTAssertEqual(["value": self.description], actualMeasurements?["app_start_cold"] ) + let actualMeasurements = actual["measurements"] as? [String: [String: Any]] + XCTAssertNotNil(actualMeasurements) + + let frameMeasurement = actualMeasurements?[frameName] + XCTAssertEqual(frameValue, frameMeasurement?["value"] as! NSNumber) + XCTAssertNil(frameMeasurement?["unit"]) + + let customMeasurement = actualMeasurements?[customName] + XCTAssertEqual(customValue, customMeasurement?["value"] as! NSNumber) + XCTAssertEqual(customUnit.unit, customMeasurement?["unit"] as! String) } func testSerialize_Tags() { diff --git a/Tests/SentryTests/Transaction/TestSentrySpan.m b/Tests/SentryTests/Transaction/TestSentrySpan.m index aeb14e8aeb4..21ad154bd5f 100644 --- a/Tests/SentryTests/Transaction/TestSentrySpan.m +++ b/Tests/SentryTests/Transaction/TestSentrySpan.m @@ -59,4 +59,12 @@ - (void)setTagValue:(nonnull NSString *)value forKey:(nonnull NSString *)key { } +- (void)setMeasurement:(nonnull NSString *)name value:(nonnull NSNumber *)value +{ +} + +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value unit:(SentryMeasurementUnit *)unit +{ +} + @end From 654f1806a50286d59fa33e8c43f83eb1390594ed Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Thu, 13 Oct 2022 18:41:43 +0200 Subject: [PATCH 08/13] test: Fix stuck tests on master branch (#2285) Some tests get stuck on the master branch which uses TestCI configuration. The code that gets stuck is accessing UIScreen.mainScreen in SentryCrashIntegration. This is just a workaround, the actual fix will be done with https://github.com/getsentry/sentry-cocoa/issues/2284. --- Tests/SentryTests/TestUtils/SentryTestObserver.m | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Tests/SentryTests/TestUtils/SentryTestObserver.m b/Tests/SentryTests/TestUtils/SentryTestObserver.m index a4fb1f95073..a58619fa81b 100644 --- a/Tests/SentryTests/TestUtils/SentryTestObserver.m +++ b/Tests/SentryTests/TestUtils/SentryTestObserver.m @@ -52,11 +52,16 @@ - (instancetype)init // The SentryCrashIntegration enriches the scope. We need to install the integration // once to get the scope data. - [SentrySDK startWithOptionsObject:options]; - self.scope = [[SentryScope alloc] init]; - [SentryCrashIntegration enrichScope:self.scope - crashWrapper:[SentryCrashWrapper sharedInstance]]; + // When running the SentryTestObserver the code gets stuck when accessing the + // UIScreen.mainScreen in SentryCrashIntegration. We disable adding extra context for now. + // Ideally we somehow check here if we can access UIScreen.mainScreen, see + // https://github.com/getsentry/sentry-cocoa/issues/2284 + // [SentrySDK startWithOptionsObject:options]; + // + // self.scope = [[SentryScope alloc] init]; + // [SentryCrashIntegration enrichScope:self.scope + // crashWrapper:[SentryCrashWrapper sharedInstance]]; self.options = options; } From fa64784ebe27cb2e150369eb8848124274e643d7 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 13 Oct 2022 09:51:47 -0800 Subject: [PATCH 09/13] test: use a longer span to compare efficient implementations (#2277) --- .../ProfileDataGeneratorUITest.m | 2 +- .../xcschemes/TrendingMovies.xcscheme | 6 ++-- .../Movies/MovieCellConfigurator.swift | 35 ++++++++++++++----- .../Movies/MovieCollectionViewCell.swift | 4 ++- .../Movies/MoviesViewController.swift | 10 ++++++ .../TrendingMovies/Utilities/Tracer.swift | 2 +- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/Samples/TrendingMovies/ProfileDataGeneratorUITest/ProfileDataGeneratorUITest.m b/Samples/TrendingMovies/ProfileDataGeneratorUITest/ProfileDataGeneratorUITest.m index 987cd6dbc9e..70c574b4b17 100644 --- a/Samples/TrendingMovies/ProfileDataGeneratorUITest/ProfileDataGeneratorUITest.m +++ b/Samples/TrendingMovies/ProfileDataGeneratorUITest/ProfileDataGeneratorUITest.m @@ -53,7 +53,7 @@ - (void)testGenerateProfileData } if (efficiently) { [launchArguments - addObject:@"--io.sentry.sample.trending-movies.launch-arg.blur-images-on-bg-thread"]; + addObject:@"--io.sentry.sample.trending-movies.launch-arg.efficient-implementation"]; } app.launchArguments = launchArguments; [app launch]; diff --git a/Samples/TrendingMovies/TrendingMovies.xcodeproj/xcshareddata/xcschemes/TrendingMovies.xcscheme b/Samples/TrendingMovies/TrendingMovies.xcodeproj/xcshareddata/xcschemes/TrendingMovies.xcscheme index 5dc59c560e2..c47c000cf2f 100644 --- a/Samples/TrendingMovies/TrendingMovies.xcodeproj/xcshareddata/xcschemes/TrendingMovies.xcscheme +++ b/Samples/TrendingMovies/TrendingMovies.xcodeproj/xcshareddata/xcschemes/TrendingMovies.xcscheme @@ -42,8 +42,8 @@ diff --git a/Samples/TrendingMovies/TrendingMovies/Movies/MovieCellConfigurator.swift b/Samples/TrendingMovies/TrendingMovies/Movies/MovieCellConfigurator.swift index 939a1649a91..523e53c711b 100644 --- a/Samples/TrendingMovies/TrendingMovies/Movies/MovieCellConfigurator.swift +++ b/Samples/TrendingMovies/TrendingMovies/Movies/MovieCellConfigurator.swift @@ -42,15 +42,34 @@ class MovieCellConfigurator { case let .success(url): if let url = url { print("[TrendingMovies] got poster image URL for movie: \(movie.id) (\(movie.title)): \(url)") - cell.downloadTask = KingfisherManager.shared.retrieveImage(with: url) { [weak cell] imageResult in - switch imageResult { - case let .success(image): - print("[TrendingMovies] set poster image for movie: \(movie.id) (\(movie.title))") - cell?.posterImage = image.image - case let .failure(error): - print(error) - cell?.posterImage = nil + if ProcessInfo.processInfo.arguments.contains("--io.sentry.sample.trending-movies.launch-arg.efficient-implementation") { + cell.downloadTask = KingfisherManager.shared.retrieveImage(with: url) { [weak cell] imageResult in + switch imageResult { + case let .success(image): + print("[TrendingMovies] set poster image for movie: \(movie.id) (\(movie.title))") + cell?.posterImage = image.image + case let .failure(error): + print(error) + cell?.posterImage = nil + } } + } else { + cell.uncachedDownloadTask = cell.uncachedURLSession.downloadTask(with: URLRequest(url: url), completionHandler: { [weak cell] downloadedURL, _, error in + if error != nil || downloadedURL == nil { + cell?.posterImage = nil + return + } + + guard let downloadedURLString = downloadedURL?.relativePath else { + cell?.posterImage = nil + return + } + + DispatchQueue.main.async { + cell?.posterImage = UIImage(contentsOfFile: downloadedURLString) + } + }) + cell.uncachedDownloadTask?.resume() } } else { cell.posterImage = nil diff --git a/Samples/TrendingMovies/TrendingMovies/Movies/MovieCollectionViewCell.swift b/Samples/TrendingMovies/TrendingMovies/Movies/MovieCollectionViewCell.swift index 18132dab9da..bc554ae7a44 100644 --- a/Samples/TrendingMovies/TrendingMovies/Movies/MovieCollectionViewCell.swift +++ b/Samples/TrendingMovies/TrendingMovies/Movies/MovieCollectionViewCell.swift @@ -51,6 +51,8 @@ class MovieCollectionViewCell: UICollectionViewCell { } var downloadTask: DownloadTask? + var uncachedDownloadTask: URLSessionDownloadTask? + let uncachedURLSession = URLSession(configuration: .ephemeral) private let posterImageView: UIImageView = { let imageView = UIImageView() @@ -151,7 +153,7 @@ class MovieCollectionViewCell: UICollectionViewCell { } private func blurPosterImage(_ image: UIImage, completion: @escaping (UIImage?) -> Void) { - let efficiently = ProcessInfo.processInfo.arguments.contains("--io.sentry.sample.trending-movies.launch-arg.blur-images-on-bg-thread") + let efficiently = ProcessInfo.processInfo.arguments.contains("--io.sentry.sample.trending-movies.launch-arg.efficient-implementation") func performBlur() { let blurredImage = ImageEffects.createBlurredBackdrop(image: image, downsamplingFactor: 1.0, blurRadius: 20.0, tintColor: nil, saturationDeltaFactor: 2.0) if efficiently { diff --git a/Samples/TrendingMovies/TrendingMovies/Movies/MoviesViewController.swift b/Samples/TrendingMovies/TrendingMovies/Movies/MoviesViewController.swift index 6e8d0b47b6d..cc482759994 100644 --- a/Samples/TrendingMovies/TrendingMovies/Movies/MoviesViewController.swift +++ b/Samples/TrendingMovies/TrendingMovies/Movies/MoviesViewController.swift @@ -35,6 +35,8 @@ class MoviesViewController: UICollectionViewController, UICollectionViewDelegate } } + private var scrollingSpan: Tracer.SpanHandle? + init(subtitleStyle: MovieCellConfigurator.SubtitleStyle = .genre, enableStartupTimeLogging: Bool, sortFunction: SortFunction? = nil, dataFetchingFunction: @escaping DataFetchingFunction) { let layout = UICollectionViewFlowLayout() layout.minimumInteritemSpacing = 0.0 @@ -167,11 +169,19 @@ class MoviesViewController: UICollectionViewController, UICollectionViewDelegate // MARK: UIScrollViewDelegate override func scrollViewDidScroll(_ scrollView: UIScrollView) { + if scrollingSpan == nil { + let efficiently = ProcessInfo.processInfo.arguments.contains("--io.sentry.sample.trending-movies.launch-arg.efficient-implementation") + scrollingSpan = Tracer.startSpan(name: "movie-list-scroll-\(efficiently ? "efficiently" : "inefficiently")") + } if scrollView.contentSize.height - (scrollView.contentOffset.y + scrollView.bounds.height) <= 300.0 { fetchNextPage() } } + override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + scrollingSpan?.end() + } + // MARK: Data private func fetchNextPage() { diff --git a/Samples/TrendingMovies/TrendingMovies/Utilities/Tracer.swift b/Samples/TrendingMovies/TrendingMovies/Utilities/Tracer.swift index 2b0a04bcd61..788bdcc76d1 100644 --- a/Samples/TrendingMovies/TrendingMovies/Utilities/Tracer.swift +++ b/Samples/TrendingMovies/TrendingMovies/Utilities/Tracer.swift @@ -43,7 +43,7 @@ extension Tracer { SentrySDK.configureScope { scope in scope.setTag(value: setUpInDidFinishLaunching ? "didFinishLaunching" : "willFinishLaunching", key: "launch-method") - scope.setTag(value: "\(ProcessInfo.processInfo.arguments.contains("--io.sentry.sample.trending-movies.launch-arg.blur-images-on-bg-thread"))", key: "efficient-implementation") + scope.setTag(value: "\(ProcessInfo.processInfo.arguments.contains("--io.sentry.sample.trending-movies.launch-arg.efficient-implementation"))", key: "efficient-implementation") } } } From 4a188b87a48dd8f0ca1afc2a3fae8e026177dfbd Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 13 Oct 2022 11:10:18 -0800 Subject: [PATCH 10/13] fix: model/architecture reporting for profiling (#2205) --- CHANGELOG.md | 4 + .../iOS-Swift.xcodeproj/project.pbxproj | 10 + .../tvOS-Swift.xcodeproj/project.pbxproj | 10 + .../watchOS-Swift WatchKit App.xcscheme | 25 +- Sentry.podspec | 5 +- Sentry.xcodeproj/project.pbxproj | 16 +- .../xcshareddata/xcschemes/Sentry.xcscheme | 2 +- Sources/Configuration/Sentry.xcconfig | 2 + Sources/Sentry/SentryDevice.mm | 266 ++++++++++++++++++ Sources/Sentry/SentryProfiler.mm | 54 +--- Sources/Sentry/include/SentryDevice.h | 48 ++++ Sources/Sentry/include/SentryLog.h | 17 ++ .../Sentry/include/SentryProfilingLogging.hpp | 17 -- .../Monitors/SentryCrashMonitor_System.m | 5 +- Tests/SentryTests/Helper/SentryDeviceTests.mm | 210 ++++++++++++++ scripts/add-sentry-to-homekit.patch | 12 + 16 files changed, 628 insertions(+), 75 deletions(-) create mode 100644 Sources/Sentry/SentryDevice.mm create mode 100644 Sources/Sentry/include/SentryDevice.h create mode 100644 Tests/SentryTests/Helper/SentryDeviceTests.mm diff --git a/CHANGELOG.md b/CHANGELOG.md index ecb1cfa779e..f78a7248079 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - [Custom measurements API](https://docs.sentry.io/platforms/apple/performance/instrumentation/custom-instrumentation/) (#2268) +### Fixes + +- Device info details for profiling (#2205) + ## 7.27.1 ### Fixes diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj index b8f2cc0e2d9..df7878a350c 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj @@ -23,6 +23,8 @@ 848A256B286E3351008A8858 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 630853322440C44F00DDE4CE /* Sentry.framework */; }; 848A256D286E3351008A8858 /* fatal-error-binary-images-message2.json in Resources */ = {isa = PBXBuildFile; fileRef = D83A30DF279F1F5C00372D0A /* fatal-error-binary-images-message2.json */; }; 848A256F286E3351008A8858 /* Sentry.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 630853322440C44F00DDE4CE /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 84B527B928DD24BA00475E8D /* SentryDeviceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84B527B728DD24BA00475E8D /* SentryDeviceTests.mm */; }; + 84B527BD28DD25E400475E8D /* SentryDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84B527BC28DD25E400475E8D /* SentryDevice.mm */; }; 84BE546F287503F100ACC735 /* SentrySDKPerformanceBenchmarkTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 84BE546E287503F100ACC735 /* SentrySDKPerformanceBenchmarkTests.m */; }; 84BE547E287645B900ACC735 /* SentryProcessInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 84BE54792876451D00ACC735 /* SentryProcessInfo.m */; }; 84FB8120283EEDB900F3A94A /* PerformanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FB811F283EEDB900F3A94A /* PerformanceViewController.swift */; }; @@ -241,6 +243,9 @@ 7BFC8B0526D4D24B000D3504 /* LoremIpsum.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = LoremIpsum.txt; sourceTree = ""; }; 848A2573286E3351008A8858 /* PerformanceBenchmarks.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerformanceBenchmarks.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 848A2578286E3490008A8858 /* PerformanceBenchmarks-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PerformanceBenchmarks-Info.plist"; sourceTree = ""; }; + 84B527B728DD24BA00475E8D /* SentryDeviceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SentryDeviceTests.mm; path = ../../../Tests/SentryTests/Helper/SentryDeviceTests.mm; sourceTree = ""; }; + 84B527BB28DD25E400475E8D /* SentryDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryDevice.h; path = ../../../Sources/Sentry/include/SentryDevice.h; sourceTree = ""; }; + 84B527BC28DD25E400475E8D /* SentryDevice.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SentryDevice.mm; path = ../../../Sources/Sentry/SentryDevice.mm; sourceTree = ""; }; 84BE546E287503F100ACC735 /* SentrySDKPerformanceBenchmarkTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySDKPerformanceBenchmarkTests.m; sourceTree = ""; }; 84BE54782876451D00ACC735 /* SentryProcessInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryProcessInfo.h; sourceTree = ""; }; 84BE54792876451D00ACC735 /* SentryProcessInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryProcessInfo.m; sourceTree = ""; }; @@ -411,6 +416,9 @@ D83A30DF279F1F5C00372D0A /* fatal-error-binary-images-message2.json */, 7B64386A26A6C544000D0F65 /* LaunchUITests.swift */, D83A30E5279FE21F00372D0A /* SentryFileIOTrackingIntegrationTests.swift */, + 84B527B728DD24BA00475E8D /* SentryDeviceTests.mm */, + 84B527BB28DD25E400475E8D /* SentryDevice.h */, + 84B527BC28DD25E400475E8D /* SentryDevice.mm */, D83A30C7279EFD6E00372D0A /* ClearTestState.swift */, 7B64386C26A6C544000D0F65 /* Info.plist */, ); @@ -804,8 +812,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 84B527B928DD24BA00475E8D /* SentryDeviceTests.mm in Sources */, D83A30E6279FE21F00372D0A /* SentryFileIOTrackingIntegrationTests.swift in Sources */, 7B64386B26A6C544000D0F65 /* LaunchUITests.swift in Sources */, + 84B527BD28DD25E400475E8D /* SentryDevice.mm in Sources */, D83A30C8279EFD6E00372D0A /* ClearTestState.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Samples/tvOS-Swift/tvOS-Swift.xcodeproj/project.pbxproj b/Samples/tvOS-Swift/tvOS-Swift.xcodeproj/project.pbxproj index 81a4e018119..051c92971b3 100644 --- a/Samples/tvOS-Swift/tvOS-Swift.xcodeproj/project.pbxproj +++ b/Samples/tvOS-Swift/tvOS-Swift.xcodeproj/project.pbxproj @@ -14,6 +14,8 @@ 7BA61D6A247FA32600C130A8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7BA61D69247FA32600C130A8 /* Assets.xcassets */; }; 7BA61D70247FA32600C130A8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7BA61D6E247FA32600C130A8 /* LaunchScreen.storyboard */; }; 7BA61D7A247FA35500C130A8 /* Sentry.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BA61D78247FA35500C130A8 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8466D4E328DE64F100932CE7 /* SentryDeviceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8466D4E228DE64F100932CE7 /* SentryDeviceTests.mm */; }; + 8466D4E428DE64F100932CE7 /* SentryDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8466D4E128DE64F000932CE7 /* SentryDevice.mm */; }; 84D4FEBF28ECD8A800EDAAFE /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D4FEBC28ECD8A100EDAAFE /* Sentry.framework */; }; 84D4FEC028ECD8AF00EDAAFE /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D4FEBC28ECD8A100EDAAFE /* Sentry.framework */; }; D822A4232760D15000E7B241 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D822A4222760D15000E7B241 /* AppDelegate.swift */; }; @@ -98,6 +100,9 @@ 7BA61D6F247FA32600C130A8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 7BA61D71247FA32600C130A8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7BA61D78247FA35500C130A8 /* Sentry.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Sentry.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8466D4DF28DE64F000932CE7 /* SentryDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryDevice.h; path = ../../../Sources/Sentry/include/SentryDevice.h; sourceTree = ""; }; + 8466D4E128DE64F000932CE7 /* SentryDevice.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SentryDevice.mm; path = ../../../Sources/Sentry/SentryDevice.mm; sourceTree = ""; }; + 8466D4E228DE64F100932CE7 /* SentryDeviceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SentryDeviceTests.mm; path = ../../../Tests/SentryTests/Helper/SentryDeviceTests.mm; sourceTree = ""; }; 84D4FEB628ECD8A100EDAAFE /* Sentry.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Sentry.xcodeproj; path = ../../Sentry.xcodeproj; sourceTree = ""; }; D822A4202760D15000E7B241 /* tvOS-SBSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "tvOS-SBSwift.app"; sourceTree = BUILT_PRODUCTS_DIR; }; D822A4222760D15000E7B241 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -152,6 +157,9 @@ 7B64388726A6C71A000D0F65 /* tvOS-SwiftUITests */ = { isa = PBXGroup; children = ( + 8466D4E228DE64F100932CE7 /* SentryDeviceTests.mm */, + 8466D4DF28DE64F000932CE7 /* SentryDevice.h */, + 8466D4E128DE64F000932CE7 /* SentryDevice.mm */, 7B64388826A6C71A000D0F65 /* LaunchUITests.swift */, 7B64388A26A6C71A000D0F65 /* Info.plist */, ); @@ -434,6 +442,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8466D4E328DE64F100932CE7 /* SentryDeviceTests.mm in Sources */, + 8466D4E428DE64F100932CE7 /* SentryDevice.mm in Sources */, 7B64388926A6C71A000D0F65 /* LaunchUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Samples/watchOS-Swift/watchOS-Swift.xcodeproj/xcshareddata/xcschemes/watchOS-Swift WatchKit App.xcscheme b/Samples/watchOS-Swift/watchOS-Swift.xcodeproj/xcshareddata/xcschemes/watchOS-Swift WatchKit App.xcscheme index 4979d444df6..7923fd3aea2 100644 --- a/Samples/watchOS-Swift/watchOS-Swift.xcodeproj/xcshareddata/xcschemes/watchOS-Swift WatchKit App.xcscheme +++ b/Samples/watchOS-Swift/watchOS-Swift.xcodeproj/xcshareddata/xcschemes/watchOS-Swift WatchKit App.xcscheme @@ -54,8 +54,10 @@ debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES"> - + - + - + - + + + + + diff --git a/Sentry.podspec b/Sentry.podspec index deba1824aec..47fff792370 100644 --- a/Sentry.podspec +++ b/Sentry.podspec @@ -20,7 +20,10 @@ Pod::Spec.new do |s| 'GCC_ENABLE_CPP_EXCEPTIONS' => 'YES', 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++14', 'CLANG_CXX_LIBRARY' => 'libc++' -} + } + s.watchos.pod_target_xcconfig = { + 'OTHER_LDFLAGS' => '$(inherited) -framework WatchKit' + } s.default_subspecs = ['Core'] diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index e74dfabcf1f..63b73d3b2f9 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -591,6 +591,9 @@ 7DC8310C2398283C0043DD9A /* SentryCrashIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DC831092398283C0043DD9A /* SentryCrashIntegration.m */; }; 8453421228BE855D00C22EEC /* SentrySampleDecision.m in Sources */ = {isa = PBXBuildFile; fileRef = 8453421128BE855D00C22EEC /* SentrySampleDecision.m */; }; 8453421628BE8A9500C22EEC /* SentrySpanStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 8453421528BE8A9500C22EEC /* SentrySpanStatus.m */; }; + 84A8891C28DBD28900C51DFD /* SentryDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A8891A28DBD28900C51DFD /* SentryDevice.h */; }; + 84A8891D28DBD28900C51DFD /* SentryDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A8891B28DBD28900C51DFD /* SentryDevice.mm */; }; + 84A8892128DBD8D600C51DFD /* SentryDeviceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A8892028DBD8D600C51DFD /* SentryDeviceTests.mm */; }; 861265F92404EC1500C4AFDE /* NSArray+SentrySanitize.h in Headers */ = {isa = PBXBuildFile; fileRef = 861265F72404EC1500C4AFDE /* NSArray+SentrySanitize.h */; }; 861265FA2404EC1500C4AFDE /* NSArray+SentrySanitize.m in Sources */ = {isa = PBXBuildFile; fileRef = 861265F82404EC1500C4AFDE /* NSArray+SentrySanitize.m */; }; 8E0551E026A7A63C00400526 /* TestProtocolClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E0551DF26A7A63C00400526 /* TestProtocolClient.swift */; }; @@ -1364,6 +1367,9 @@ 844DA81F28246DE300E6B62E /* scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = scripts; sourceTree = ""; }; 8453421128BE855D00C22EEC /* SentrySampleDecision.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySampleDecision.m; sourceTree = ""; }; 8453421528BE8A9500C22EEC /* SentrySpanStatus.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySpanStatus.m; sourceTree = ""; }; + 84A8891A28DBD28900C51DFD /* SentryDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDevice.h; path = include/SentryDevice.h; sourceTree = ""; }; + 84A8891B28DBD28900C51DFD /* SentryDevice.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryDevice.mm; sourceTree = ""; }; + 84A8892028DBD8D600C51DFD /* SentryDeviceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryDeviceTests.mm; sourceTree = ""; }; 861265F72404EC1500C4AFDE /* NSArray+SentrySanitize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSArray+SentrySanitize.h"; path = "include/NSArray+SentrySanitize.h"; sourceTree = ""; }; 861265F82404EC1500C4AFDE /* NSArray+SentrySanitize.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSArray+SentrySanitize.m"; sourceTree = ""; }; 8E0551DF26A7A63C00400526 /* TestProtocolClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProtocolClient.swift; sourceTree = ""; }; @@ -1828,6 +1834,8 @@ 7B2A70DC27D6083D008B0D15 /* SentryThreadWrapper.m */, 7B18DE3F28D9F748004845C6 /* SentryNSNotificationCenterWrapper.h */, 7B18DE4128D9F794004845C6 /* SentryNSNotificationCenterWrapper.m */, + 84A8891A28DBD28900C51DFD /* SentryDevice.h */, + 84A8891B28DBD28900C51DFD /* SentryDevice.mm */, 0A9E917028DC7E7000FB4182 /* SentryInternalDefines.h */, ); name = Helper; @@ -2423,6 +2431,7 @@ 7B2A70DE27D60904008B0D15 /* SentryTestThreadWrapper.swift */, 7B18DE4328D9F8F6004845C6 /* TestNSNotificationCenterWrapper.swift */, 7B18DE4928DA0C8B004845C6 /* SentryNSNotificationCenterWrapperTests.swift */, + 84A8892028DBD8D600C51DFD /* SentryDeviceTests.mm */, ); path = Helper; sourceTree = ""; @@ -3010,6 +3019,7 @@ 7BA235632600B61200E12865 /* SentryInternalNotificationNames.h in Headers */, 7BAF3DB9243C9777008A5414 /* SentryTransport.h in Headers */, 6383953623ABA42C000C1594 /* SentryHttpTransport.h in Headers */, + 84A8891C28DBD28900C51DFD /* SentryDevice.h in Headers */, 8E564AEF267AF24400FE117D /* SentryNetworkTracker.h in Headers */, 63FE715120DA4C1100CDBAE8 /* SentryCrashDebug.h in Headers */, 63FE70F520DA4C1000CDBAE8 /* SentryCrashMonitor_System.h in Headers */, @@ -3347,6 +3357,7 @@ 03F84D3627DD4191008FE43F /* SentryProfilingLogging.mm in Sources */, 8EC3AE7A25CA23B600E7591A /* SentrySpan.m in Sources */, 6360850E1ED2AFE100E8599E /* SentryBreadcrumb.m in Sources */, + 84A8891D28DBD28900C51DFD /* SentryDevice.mm in Sources */, 7B56D73324616D9500B842DA /* SentryConcurrentRateLimitsDictionary.m in Sources */, 8ECC674825C23A20000E2BF6 /* SentryTransaction.m in Sources */, 7BECF42826145CD900D9826E /* SentryMechanismMeta.m in Sources */, @@ -3517,6 +3528,7 @@ D8FFE50C2703DBB400607131 /* SwizzlingCallTests.swift in Sources */, D8B76B0828081461000A58C4 /* TestSentryScreenShot.swift in Sources */, 7BE2C7F8257000A4003B66C7 /* SentryTestIntegration.m in Sources */, + 84A8892128DBD8D600C51DFD /* SentryDeviceTests.mm in Sources */, 7BC6EBF4255C044A0059822A /* SentryEventTests.swift in Sources */, 63FE721920DA66EC00CDBAE8 /* SentryCrashReportStore_Tests.m in Sources */, 03F9D37C2819A65C00602916 /* SentryProfilerTests.mm in Sources */, @@ -3864,7 +3876,6 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry; PRODUCT_NAME = Sentry; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3903,7 +3914,6 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = NO; - OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry; PRODUCT_NAME = Sentry; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4070,7 +4080,6 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry; PRODUCT_NAME = Sentry; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4204,7 +4213,6 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry; PRODUCT_NAME = Sentry; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme b/Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme index e2e8db46043..a09c4a9edea 100644 --- a/Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme +++ b/Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme @@ -23,7 +23,7 @@ + +#import "SentryDevice.h" +#import +#if SENTRY_HAS_UIKIT +# import +#elif TARGET_OS_WATCH +# import +#endif + +namespace { +/** + * @brief Get an iOS hardware model name, or for mac devices, either the hardware model name or CPU + * architecture of the device, depending on the option provided. + * @note For an iOS CPU architecture name, `getArchitectureName` must be used. + * @discussion The values returned are different between iOS and macOS depending on which option is + * provided. Some examples of values returned on different devices: + * @code + * | device | machine | model | + * --------------------------------------------------------------- + * | m1 mbp | arm64 | MacBookPro18,3 | + * | iphone 13 mini | iPhone14,4 | D16AP | + * | intel imac | x86_64 | iMac20,1 | + * | iphone simulator on m1 mac | arm64 | MacBookPro18,3 | + * | iphone simulator on intel mac | x86_64 | iMac20,1 | + * @endcode + * @seealso See + * https://www.cocoawithlove.com/blog/2016/03/08/swift-wrapper-for-sysctl.html#looking-for-the-source + * for more info. + * @return @c sysctl value for the combination of @c CTL_HW and the provided other flag in the + * type parameter. + */ +NSString * +getHardwareDescription(int type) +{ +#if SENTRY_HAS_UIKIT && !TARGET_OS_SIMULATOR + NSCAssert( + type != HW_MODEL, @"Don't call this method with HW_MODEL for (non-simulator) iOS devices"); +#endif + int mib[2]; + char name[128]; + size_t len; + + mib[0] = CTL_HW; + mib[1] = type; + len = sizeof(name); + if (SENTRY_LOG_ERRNO(sysctl(mib, 2, &name, &len, NULL, 0)) != 0) { + return @""; + } + + const auto nameNSString = [NSString stringWithUTF8String:name]; + + NSString *argName; + switch (type) { + case HW_PRODUCT: + argName = @"HW_PRODUCT"; + break; + case HW_MACHINE: + argName = @"HW_MACHINE"; + break; + case HW_MODEL: + argName = @"HW_MODEL"; + break; + default: + NSCAssert(NO, @"Illegal argument"); + } + + SENTRY_LOG_DEBUG(@"Model name using %@: %@", argName, nameNSString); + return nameNSString; +} + +/** + * Provided as a fallback in case @c sysctlbyname fails in @c sentry_getCPUArchitecture using the + * @c hw.cpusubtype option. + * @note I've not observed a device that has needed this (armcknight 22 Sep 2022). Tested on: + * @code + * - 2015 MBP (x86_64h) + * - 2020 iMac (x86_64h) + * - 2021 MBP (M1 reported as arm64e) + * - iPhone simulators on all of those macs + * - iPhone 13 mini (arm64e) + * - iPod Touch (6th gen) (armv8) + * @endcode + */ +NSString * +getCPUType(NSNumber *_Nullable subtype) +{ + cpu_type_t type; + size_t typeSize = sizeof(type); + if (SENTRY_LOG_ERRNO(sysctlbyname("hw.cputype", &type, &typeSize, NULL, 0)) != 0) { + if (subtype != nil) { + return + [NSString stringWithFormat:@"no CPU type for unknown subtype %d", subtype.intValue]; + } + return @"no CPU type or subtype"; + } + switch (type) { + default: + if (subtype != nil) { + return [NSMutableString + stringWithFormat:@"unknown CPU type (%d) and subtype (%d)", type, subtype.intValue]; + } + return [NSMutableString stringWithFormat:@"unknown CPU type (%d)", type]; + case CPU_TYPE_X86_64: + // I haven't observed this branch being taken for 64-bit x86 architectures. Rather, the + // x86 branch is taken, and then the subtype is reported as the 64-bit + // subtype. Tested on a 2020 Intel-based iMac and 2015 MBP. (armcknight 21 Sep 2022) + return @"x86_64"; + case CPU_TYPE_X86: + return @"x86"; + case CPU_TYPE_ARM: + return @"arm"; + case CPU_TYPE_ARM64: + return @"arm64"; + case CPU_TYPE_ARM64_32: + return @"arm64_32"; + } +} +} // namespace + +NSString * +sentry_getCPUArchitecture(void) +{ + cpu_subtype_t subtype; + size_t subtypeSize = sizeof(subtype); + if (SENTRY_LOG_ERRNO(sysctlbyname("hw.cpusubtype", &subtype, &subtypeSize, NULL, 0)) != 0) { + return getCPUType(nil); + } + switch (subtype) { + default: + return getCPUType(@(subtype)); + case CPU_SUBTYPE_X86_64_H: + return @"x86_64h"; + case CPU_SUBTYPE_X86_64_ALL: + return @"x86_64"; + case CPU_SUBTYPE_ARM_V6: + return @"armv6"; + case CPU_SUBTYPE_ARM_V7: + return @"armv7"; + case CPU_SUBTYPE_ARM_V7S: + return @"armv7s"; + case CPU_SUBTYPE_ARM_V7K: + return @"armv7k"; + case CPU_SUBTYPE_ARM64_V8: + // this also catches CPU_SUBTYPE_ARM64_32_V8 since they are both defined as + // ((cpu_subtype_t) 1) + return @"armv8"; + case CPU_SUBTYPE_ARM64E: + return @"arm64e"; + } +} + +NSString * +sentry_getOSName(void) +{ +#if TARGET_OS_MACCATALYST + return @"Catalyst"; +#elif SENTRY_HAS_UIKIT + return UIDevice.currentDevice.systemName; +#else + return @"macOS"; +#endif // SENTRY_HAS_UIKIT +} + +NSString * +sentry_getOSVersion(void) +{ +#if TARGET_OS_WATCH + return WKInterfaceDevice.currentDevice.systemVersion; +#elif SENTRY_HAS_UIKIT + return UIDevice.currentDevice.systemVersion; +#else + // based off of + // https://github.com/lmirosevic/GBDeviceInfo/blob/98dd3c75bb0e1f87f3e0fd909e52dcf0da4aa47d/GBDeviceInfo/GBDeviceInfo_OSX.m#L107-L133 + if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { + const auto version = [[NSProcessInfo processInfo] operatingSystemVersion]; + return [NSString stringWithFormat:@"%ld.%ld.%ld", (long)version.majorVersion, + (long)version.minorVersion, (long)version.patchVersion]; + } else { + SInt32 major, minor, patch; + +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-declarations" + Gestalt(gestaltSystemVersionMajor, &major); + Gestalt(gestaltSystemVersionMinor, &minor); + Gestalt(gestaltSystemVersionBugFix, &patch); +# pragma clang diagnostic pop + + return [NSString stringWithFormat:@"%d.%d.%d", major, minor, patch]; + } +#endif // SENTRY_HAS_UIKIT +} + +NSString * +sentry_getDeviceModel(void) +{ +#if TARGET_OS_SIMULATOR + // iPhone/iPad, Watch and TV simulators + const auto simulatedDeviceModelName = sentry_getSimulatorDeviceModel(); + SENTRY_LOG_DEBUG(@"Got simulated device model name %@ (running on %@)", + simulatedDeviceModelName, getHardwareDescription(HW_MODEL)); + return simulatedDeviceModelName; +#else +# if defined(HW_PRODUCT) + if (@available(iOS 14, macOS 11, *)) { + const auto model = getHardwareDescription(HW_PRODUCT); + if (model.length > 0) { + SENTRY_LOG_DEBUG(@"Model name using HW_PRODUCT: %@", model); + return model; + } else { + SENTRY_LOG_DEBUG(@"Model name from HW_PRODUCT was empty."); + } + } +# endif // defined(HW_PRODUCT) + +# if SENTRY_HAS_UIKIT + // iPhone/iPad or TV devices + return getHardwareDescription(HW_MACHINE); +# else + // macs and watch devices TODO: test on watch devices, may need to separate TARGET_OS_WATCH + return getHardwareDescription(HW_MODEL); +# endif // SENTRY_HAS_UIKIT +#endif // TARGET_OS_SIMULATOR +} + +NSString * +sentry_getSimulatorDeviceModel(void) +{ + return NSProcessInfo.processInfo.environment[@"SIMULATOR_MODEL_IDENTIFIER"]; +} + +NSString * +sentry_getOSBuildNumber(void) +{ + char str[32]; + size_t size = sizeof(str); + int cmd[2] = { CTL_KERN, KERN_OSVERSION }; + if (SENTRY_LOG_ERRNO(sysctl(cmd, sizeof(cmd) / sizeof(*cmd), str, &size, NULL, 0)) == 0) { + return [NSString stringWithUTF8String:str]; + } + return @""; +} + +BOOL +sentry_isSimulatorBuild(void) +{ +#if TARGET_OS_SIMULATOR + return true; +#else + return false; +#endif +} diff --git a/Sources/Sentry/SentryProfiler.mm b/Sources/Sentry/SentryProfiler.mm index de58a0802f6..b7f030a5051 100644 --- a/Sources/Sentry/SentryProfiler.mm +++ b/Sources/Sentry/SentryProfiler.mm @@ -8,6 +8,7 @@ # import "SentryDebugMeta.h" # import "SentryDefines.h" # import "SentryDependencyContainer.h" +# import "SentryDevice.h" # import "SentryEnvelope.h" # import "SentryEnvelopeItemType.h" # import "SentryFramesTracker.h" @@ -15,7 +16,6 @@ # import "SentryHub.h" # import "SentryId.h" # import "SentryLog.h" -# import "SentryProfilingLogging.hpp" # import "SentrySamplingProfiler.hpp" # import "SentryScope+Private.h" # import "SentryScreenFrames.h" @@ -30,8 +30,6 @@ # import # import -# import -# import # if TARGET_OS_IOS # import @@ -60,40 +58,6 @@ return [symbolNSStr substringWithRange:[match rangeAtIndex:1]]; } -namespace { -NSString * -getDeviceModel() -{ - utsname info; - if (SENTRY_PROF_LOG_ERRNO(uname(&info)) == 0) { - return [NSString stringWithUTF8String:info.machine]; - } - return @""; -} - -NSString * -getOSBuildNumber() -{ - char str[32]; - size_t size = sizeof(str); - int cmd[2] = { CTL_KERN, KERN_OSVERSION }; - if (SENTRY_PROF_LOG_ERRNO(sysctl(cmd, sizeof(cmd) / sizeof(*cmd), str, &size, NULL, 0)) == 0) { - return [NSString stringWithUTF8String:str]; - } - return @""; -} - -bool -isSimulatorBuild() -{ -# if TARGET_OS_SIMULATOR - return true; -# else - return false; -# endif -} -} // namespace - @implementation SentryProfiler { NSMutableDictionary *_profile; uint64_t _startTimestamp; @@ -244,16 +208,16 @@ - (SentryEnvelopeItem *)buildEnvelopeItemForTransaction:(SentryTransaction *)tra profile[@"debug_meta"] = @{ @"images" : debugImages }; } + profile[@"device_architecture"] = sentry_getCPUArchitecture(); profile[@"device_locale"] = NSLocale.currentLocale.localeIdentifier; profile[@"device_manufacturer"] = @"Apple"; - const auto model = getDeviceModel(); - profile[@"device_model"] = model; - profile[@"device_os_build_number"] = getOSBuildNumber(); -# if TARGET_OS_IOS - profile[@"device_os_name"] = UIDevice.currentDevice.systemName; - profile[@"device_os_version"] = UIDevice.currentDevice.systemVersion; -# endif - profile[@"device_is_emulator"] = @(isSimulatorBuild()); + const auto isEmulated = sentry_isSimulatorBuild(); + profile[@"device_model"] + = isEmulated ? sentry_getSimulatorDeviceModel() : sentry_getDeviceModel(); + profile[@"device_os_build_number"] = sentry_getOSBuildNumber(); + profile[@"device_os_name"] = sentry_getOSName(); + profile[@"device_os_version"] = sentry_getOSVersion(); + profile[@"device_is_emulator"] = @(isEmulated); profile[@"device_physical_memory_bytes"] = [@(NSProcessInfo.processInfo.physicalMemory) stringValue]; profile[@"environment"] = hub.scope.environmentString ?: hub.getClient.options.environment ?: kSentryDefaultEnvironment; diff --git a/Sources/Sentry/include/SentryDevice.h b/Sources/Sentry/include/SentryDevice.h new file mode 100644 index 00000000000..59f1f4af961 --- /dev/null +++ b/Sources/Sentry/include/SentryDevice.h @@ -0,0 +1,48 @@ +#import +/** + * @seealso TargetConditionals.h has explanations and diagrams that show the relationships between + * different @c TARGET_OS_... and @c TARGET_CPU_... macros. + */ + +NS_ASSUME_NONNULL_BEGIN + +/** + * @return The CPU architecture name, such as @c armv7, @c arm64 or @c x86_64. + */ +NSString *sentry_getCPUArchitecture(void); + +/** + * @return The name of the operating system, such as @c iOS or @c macOS. + */ +NSString *sentry_getOSName(void); + +/** + * @return The OS version with up to three period-delimited numbers, like @c 14 , @c 14.0 or + * @c 14.0.1 . + */ +NSString *sentry_getOSVersion(void); + +/** + * @return The Apple hardware descriptor, such as @c iPhone14,4 or @c MacBookPro10,8 . + * @note If running on a simulator, this will be the model of the simulated device. + */ +NSString *sentry_getDeviceModel(void); + +/** + * @return The Apple hardware descriptor of the simulated device, such as @c iPhone14,4 or + * @c MacBookPro10,8 . + */ +NSString *_Nullable sentry_getSimulatorDeviceModel(void); + +/** + * @return A string describing the OS version's specific build, with alphanumeric characters, like + * @c 21G115 . + */ +NSString *sentry_getOSBuildNumber(void); + +/** + * @return @c YES if built and running in a simulator on a mac device, @c NO if running on a device. + */ +BOOL sentry_isSimulatorBuild(void); + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/include/SentryLog.h b/Sources/Sentry/include/SentryLog.h index 310301c07dc..520690ff83e 100644 --- a/Sources/Sentry/include/SentryLog.h +++ b/Sources/Sentry/include/SentryLog.h @@ -25,3 +25,20 @@ NS_ASSUME_NONNULL_END [SentryLog logWithMessage:[NSString stringWithFormat:__VA_ARGS__] andLevel:kSentryLevelError] #define SENTRY_LOG_CRITICAL(...) \ [SentryLog logWithMessage:[NSString stringWithFormat:__VA_ARGS__] andLevel:kSentryLevelCritical] + +/** + * If `errno` is set to a non-zero value after `statement` finishes executing, + * the error value is logged, and the original return value of `statement` is + * returned. + */ +#define SENTRY_LOG_ERRNO(statement) \ + ({ \ + errno = 0; \ + const auto __log_rv = (statement); \ + const int __log_errnum = errno; \ + if (__log_errnum != 0) { \ + SENTRY_LOG_ERROR(@"%s failed with code: %d, description: %s", #statement, \ + __log_errnum, strerror(__log_errnum)); \ + } \ + __log_rv; \ + }) diff --git a/Sources/Sentry/include/SentryProfilingLogging.hpp b/Sources/Sentry/include/SentryProfilingLogging.hpp index 3c3c67b2f20..d86a2949fbb 100644 --- a/Sources/Sentry/include/SentryProfilingLogging.hpp +++ b/Sources/Sentry/include/SentryProfilingLogging.hpp @@ -39,20 +39,3 @@ namespace profiling { } \ __log_errnum; \ }) - -/** - * If `errno` is set to a non-zero value after `statement` finishes executing, - * the error value is logged, and the original return value of `statement` is - * returned. - */ -#define SENTRY_PROF_LOG_ERRNO(statement) \ - ({ \ - errno = 0; \ - const auto __log_rv = (statement); \ - const int __log_errnum = errno; \ - if (__log_errnum != 0) { \ - SENTRY_PROF_LOG_ERROR("%s failed with code: %s, description: %s", #statement, \ - __log_errnum, std::strerror(__log_errnum)); \ - } \ - __log_rv; \ - }) diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m index d7953ab4eff..cf987b09857 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_System.m @@ -114,6 +114,8 @@ * @param name The sysctl name. * * @return The result of the sysctl call. + * + * @todo Combine into SentryDevice? */ static const char * stringSysctl(const char *name) @@ -401,7 +403,7 @@ sentrycrashsysctl_getMacAddress("en0", [data mutableBytes]); } - // Append some device-specific data. + // Append some device-specific data. TODO: use SentryDevice API here now? [data appendData:(NSData *_Nonnull)[nsstringSysctl(@"hw.machine") dataUsingEncoding:NSUTF8StringEncoding]]; [data appendData:(NSData *_Nonnull)[nsstringSysctl(@"hw.model") @@ -555,6 +557,7 @@ = cString([NSProcessInfo processInfo].environment[@"SIMULATOR_MODEL_IDENTIFIER"]); g_systemData.model = "simulator"; } else { + // TODO: combine this into SentryDevice? #if SentryCrashCRASH_HOST_MAC // MacOS has the machine in the model field, and no model g_systemData.machine = stringSysctl("hw.model"); diff --git a/Tests/SentryTests/Helper/SentryDeviceTests.mm b/Tests/SentryTests/Helper/SentryDeviceTests.mm new file mode 100644 index 00000000000..669acf36d6c --- /dev/null +++ b/Tests/SentryTests/Helper/SentryDeviceTests.mm @@ -0,0 +1,210 @@ +#import "SentryDevice.h" +#import + +#define SENTRY_ASSERT_EQUAL(actualString, expectedString) \ + XCTAssert([expectedString isEqualToString:actualString], @"Expected %@ but got %@", \ + expectedString, actualString) +#define SENTRY_ASSERT_CONTAINS(parentString, childString) \ + XCTAssert([parentString containsString:childString], @"Expected %@ to contain %@", \ + parentString, childString) +#define SENTRY_ASSERT_PREFIX(reportedVersion, ...) \ + const auto acceptableVersions = @[ __VA_ARGS__ ]; \ + auto foundPrefix = NO; \ + for (NSString * prefix in acceptableVersions) { \ + if ([osVersion hasPrefix:prefix]) { \ + foundPrefix = YES; \ + break; \ + } \ + } \ + XCTAssertTrue(foundPrefix, \ + @"Expected major version to be one of %@. Actual version reported was %@", \ + acceptableVersions, reportedVersion); + +/** + * @seealso TargetConditionals.h has explanations and diagrams that show the relationships between + * different @c TARGET_OS_... macros. + */ +@interface SentryDeviceTests : XCTestCase + +@end + +@implementation SentryDeviceTests + +- (void)testCPUArchitecture +{ + const auto arch = sentry_getCPUArchitecture(); +#if TARGET_OS_OSX +# if TARGET_CPU_X86_64 + // I observed this branch still being taken when running unit tests for macOS in Xcode 13.4.1 on + // an Apple Silicon MBP (armcknight 23 Sep 2022) + SENTRY_ASSERT_CONTAINS(arch, @"x86"); // Macs with Intel CPUs +# else + SENTRY_ASSERT_CONTAINS(arch, @"arm64"); // Macs with Apple Silicon +# endif +#elif TARGET_OS_MACCATALYST +# if TARGET_CPU_X86_64 + // I observed this branch still being taken when running unit tests for mac catalyst in + // Xcode 13.4.1 on an Apple Silicon MBP (armcknight 23 Sep 2022) + SENTRY_ASSERT_CONTAINS(arch, @"x86"); // Macs with Intel CPUs +# else + SENTRY_ASSERT_CONTAINS(arch, @"arm64"); // Macs with Apple Silicon +# endif +#elif TARGET_OS_IOS +# if TARGET_OS_SIMULATOR +# if TARGET_CPU_ARM64 + SENTRY_ASSERT_CONTAINS(arch, @"arm"); // iPhone simulator on M1 macs +# elif TARGET_CPU_X86_64 + SENTRY_ASSERT_CONTAINS(arch, @"x86"); // iPhone simulator on Intel macs +# else + XCTFail(@"Unexpected CPU type on test host."); +# endif // TARGET_CPU_ARM64 +# else + SENTRY_ASSERT_CONTAINS(arch, @"arm"); // Real iPads and iPhones +# endif +#elif TARGET_OS_TV + // We must test this branch in tvOS-SwiftUITests since it must run on device, which SentryTests + // cannot. +# if TARGET_OS_SIMULATOR +# if TARGET_CPU_ARM64 + SENTRY_ASSERT_CONTAINS(arch, @"arm"); // TV simulator on M1 macs +# elif TARGET_CPU_X86_64 + SENTRY_ASSERT_CONTAINS(arch, @"x86"); // TV simulator on Intel macs +# else + XCTFail(@"Unexpected CPU type on test host."); +# endif // TARGET_CPU_ARM64 +# else + SENTRY_ASSERT_CONTAINS(arch, @"arm"); // Real TVs +# endif +#elif TARGET_OS_WATCH + // TODO: create a watch UI test target to test this branch as it cannot run on the watch + // simulator + SENTRY_ASSERT_CONTAINS(arch, @"arm"); // Real Watches +#else + XCTFail(@"Unexpected device OS"); +#endif +} + +- (void)testOSVersion +{ + const auto osVersion = sentry_getOSVersion(); + XCTAssertNotEqual(osVersion.length, 0U); +#if TARGET_OS_OSX + SENTRY_ASSERT_PREFIX(osVersion, @"10.", @"11.", @"12.", @"13."); +#elif TARGET_OS_IOS || TARGET_OS_MACCATALYST || TARGET_OS_TV + SENTRY_ASSERT_PREFIX(osVersion, @"9.", @"10.", @"11.", @"12.", @"13.", @"14.", @"15.", @"16."); +#elif TARGET_OS_WATCH + SENTRY_ASSERT_PREFIX(osVersion, @"2.", @"3.", @"4.", @"5.", @"6.", @"7.", @"8.", @"9."); +#else + XCTFail(@"Unexpected OS."); +#endif +} + +- (void)testOSName +{ + const auto osName = sentry_getOSName(); +#if TARGET_OS_OSX + SENTRY_ASSERT_EQUAL(osName, @"macOS"); +#elif TARGET_OS_MACCATALYST + SENTRY_ASSERT_EQUAL(osName, @"Catalyst"); +#elif TARGET_OS_IOS + // We must test this branch in iOS-SwiftUITests since it must run on device, which SentryTests + // cannot. + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + SENTRY_ASSERT_EQUAL(osName, @"iPadOS"); + } else if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone) { + SENTRY_ASSERT_EQUAL(osName, @"iOS"); + } else { + XCTFail(@"Unsupported iOS UI idiom."); + } +#elif TARGET_OS_TV + // We must test this branch in tvOS-SwiftUITests since it must run on device, which SentryTests + // cannot. + SENTRY_ASSERT_EQUAL(osName, @"tvOS"); +#elif TARGET_OS_WATCH + // TODO: create a watch UI test target to test this branch as it cannot run on the watch + // simulator + SENTRY_ASSERT_EQUAL(osName, @"watchOS"); +#else + XCTFail(@"Unexpected device OS"); +#endif +} + +- (void)testDeviceModel +{ + const auto modelName = sentry_getDeviceModel(); + XCTAssertNotEqual(modelName.length, 0U); +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST +# if defined(TESTCI) || defined(TEST) + SENTRY_ASSERT_CONTAINS(modelName, @"VMware"); +# else + SENTRY_ASSERT_CONTAINS(modelName, @"Mac"); +# endif // defined(TESTCI) +#elif TARGET_OS_IOS + // We must test this branch in iOS-SwiftUITests since it must run on device, which SentryTests + // cannot. + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + SENTRY_ASSERT_CONTAINS(modelName, @"iPad"); + } else if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone) { + SENTRY_ASSERT_CONTAINS(modelName, @"iPhone"); + } else { + XCTFail(@"Unsupported iOS UI idiom."); + } +#elif TARGET_OS_TV + // We must test this branch in tvOS-SwiftUITests since it must run on device, which SentryTests + // cannot. + SENTRY_ASSERT_CONTAINS(modelName, @"TV"); +#elif TARGET_OS_WATCH + // TODO: create a watch UI test target to test this branch as it cannot run on the watch + // simulator + SENTRY_ASSERT_CONTAINS(modelName, @"Watch"); +#else + XCTFail(@"Unexpected target OS"); +#endif +} + +- (void)testOSBuildNumber +{ + XCTAssertNotEqual(sentry_getOSBuildNumber().length, 0U); +} + +- (void)testIsSimulator +{ +#if TARGET_OS_SIMULATOR + XCTAssertTrue(sentry_isSimulatorBuild()); +#else + XCTAssertFalse(sentry_isSimulatorBuild()); +#endif +} + +- (void)testSimulatedDeviceModel +{ +#if !TARGET_OS_SIMULATOR + XCTSkip(@"Should only run on simulators."); +#else + const auto modelName = sentry_getSimulatorDeviceModel(); + XCTAssertNotEqual(modelName.length, 0U); +# if TARGET_OS_IOS + // We must test this branch in iOS-SwiftUITests since it must run on device, which SentryTests + // cannot. + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + SENTRY_ASSERT_CONTAINS(modelName, @"iPad"); + } else if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone) { + SENTRY_ASSERT_CONTAINS(modelName, @"iPhone"); + } else { + XCTFail(@"Unsupported iOS UI idiom."); + } +# elif TARGET_OS_TV + // We must test this branch in tvOS-SwiftUITests since it must run on device, which SentryTests + // cannot. + SENTRY_ASSERT_CONTAINS(modelName, @"TV"); +# elif TARGET_OS_WATCH + // TODO: create a watch UI test target to test this branch as it cannot run on the watch + // simulator + SENTRY_ASSERT_CONTAINS(modelName, @"Watch"); +# else + XCTFail(@"Unexpected device OS"); +# endif +#endif +} + +@end diff --git a/scripts/add-sentry-to-homekit.patch b/scripts/add-sentry-to-homekit.patch index 8de5a08a625..4290874f931 100644 --- a/scripts/add-sentry-to-homekit.patch +++ b/scripts/add-sentry-to-homekit.patch @@ -1,3 +1,15 @@ +git diff HomeAssistant.xcconfig +diff --git a/Configuration/HomeAssistant.xcconfig b/Configuration/HomeAssistant.xcconfig +index 2b1cdd31..962ec867 100644 +--- a/Configuration/HomeAssistant.xcconfig ++++ b/Configuration/HomeAssistant.xcconfig +@@ -92,3 +92,5 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES + CLANG_ANALYZER_NONNULL = YES + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES + GCC_NO_COMMON_BLOCKS = YES ++ ++OTHER_LDFLAGS[sdk=watch*] = $(inherited) -framework WatchKit + diff --git a/Podfile b/Podfile index d2d83b14..6756f31b 100644 --- a/Podfile From 953d9c4893e48b65184d731ff64dedc404b061f3 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Fri, 14 Oct 2022 09:53:10 +0200 Subject: [PATCH 11/13] ci: Generate profile data only on schedule (#2289) Only run the profile data generator workflow on schedule. --- .github/workflows/profile-data-generator.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/profile-data-generator.yml b/.github/workflows/profile-data-generator.yml index 92e15eb2741..2dcdb0283e2 100644 --- a/.github/workflows/profile-data-generator.yml +++ b/.github/workflows/profile-data-generator.yml @@ -4,16 +4,6 @@ name: Generate Profiling Test Data on: schedule: - cron: '0 */6 * * *' # every 6 hours = 4x/day - push: - branches: - - master - pull_request: - paths: - - '.github/workflows/profile-data-generator.yml' - - 'fastlane/**' - - 'Samples/TrendingMovies/**' - - '.sauce/profile-data-generator-config.yml' - - 'scripts/ci-select-xcode.sh' jobs: build-profile-data-generator-targets: From 94b4f2bf3a91a8f9618f8f4b5893840963e5b106 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Fri, 14 Oct 2022 09:53:44 +0200 Subject: [PATCH 12/13] ci: Specify only iPhone Pro for high-end devices (#2292) Expand to any iPhone Pro and not only iPhone Pro Max 13 to speed up CI. --- .sauce/profile-data-generator-config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.sauce/profile-data-generator-config.yml b/.sauce/profile-data-generator-config.yml index 22e1a2efe03..6c6b200d36c 100644 --- a/.sauce/profile-data-generator-config.yml +++ b/.sauce/profile-data-generator-config.yml @@ -14,8 +14,7 @@ xcuitest: suites: - name: "High-end device" devices: - - name: "iPhone 13 Pro Max" - platformVersion: "15" + - name: "iPhone .* Pro .*" - name: "Mid-range device" devices: - name: "iPhone 8" From dc00a3673e3d313e41326bd53802f757defd0eee Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Fri, 14 Oct 2022 07:57:10 +0000 Subject: [PATCH 13/13] release: 7.28.0 --- CHANGELOG.md | 2 +- Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj | 8 ++++---- Sentry.podspec | 2 +- Sources/Configuration/Sentry.xcconfig | 2 +- Sources/Sentry/SentryMeta.m | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f78a7248079..9dc56941cb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 7.28.0 ### Features diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj index df7878a350c..77bfe030d56 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj @@ -1092,7 +1092,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 7.27.1; + MARKETING_VERSION = 7.28.0; PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match Development io.sentry.sample.iOS-Swift"; @@ -1121,7 +1121,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 7.27.1; + MARKETING_VERSION = 7.28.0; PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.sample.iOS-Swift"; @@ -1766,7 +1766,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 7.27.1; + MARKETING_VERSION = 7.28.0; PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift.Clip"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match Development io.sentry.sample.iOS-Swift.Clip"; @@ -1801,7 +1801,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 7.27.1; + MARKETING_VERSION = 7.28.0; PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift.Clip"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.sample.iOS-Swift.Clip"; diff --git a/Sentry.podspec b/Sentry.podspec index 47fff792370..b5209f82d02 100644 --- a/Sentry.podspec +++ b/Sentry.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Sentry" - s.version = "7.27.1" + s.version = "7.28.0" s.summary = "Sentry client for cocoa" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" diff --git a/Sources/Configuration/Sentry.xcconfig b/Sources/Configuration/Sentry.xcconfig index c5ae0439da0..bf796e37da5 100644 --- a/Sources/Configuration/Sentry.xcconfig +++ b/Sources/Configuration/Sentry.xcconfig @@ -29,7 +29,7 @@ MACH_O_TYPE = mh_dylib FRAMEWORK_VERSION = A PRODUCT_NAME = Sentry -CURRENT_PROJECT_VERSION = 7.27.1 +CURRENT_PROJECT_VERSION = 7.28.0 INFOPLIST_FILE = Sources/Sentry/Info.plist PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry ALWAYS_SEARCH_USER_PATHS = NO diff --git a/Sources/Sentry/SentryMeta.m b/Sources/Sentry/SentryMeta.m index a9aedc4605e..5687cf5e773 100644 --- a/Sources/Sentry/SentryMeta.m +++ b/Sources/Sentry/SentryMeta.m @@ -5,7 +5,7 @@ @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 *versionString = @"7.27.1"; +static NSString *versionString = @"7.28.0"; static NSString *sdkName = @"sentry.cocoa"; + (NSString *)versionString