diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c6b2e1d3f..ad7af3cc92b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Features +- Properly demangle Swift class name (#2162) + - From now on, Sentry SDK has a dependency on Swift framework - Offline caching improvements (#2263) - Report usage of stitchAsyncCode (#2281) diff --git a/Package.swift b/Package.swift index 1fde2484238..262fa2c4084 100644 --- a/Package.swift +++ b/Package.swift @@ -9,8 +9,15 @@ let package = Package( .library(name: "Sentry-Dynamic", type: .dynamic, targets: ["Sentry"]) ], targets: [ + .target( name: "SentrySwift", + path: "Sources", + sources: [ + "Swift" + ] + ), .target( name: "Sentry", + dependencies: ["SentrySwift"], path: "Sources", sources: [ "Sentry/", diff --git a/Samples/Carthage-Validation/Framework/input.xcfilelist b/Samples/Carthage-Validation/Framework/input.xcfilelist index 6c87cbf0d27..38c98e5185f 100644 --- a/Samples/Carthage-Validation/Framework/input.xcfilelist +++ b/Samples/Carthage-Validation/Framework/input.xcfilelist @@ -1 +1 @@ -$(SRCROOT)/Carthage/Build/iOS/Sentry.framework \ No newline at end of file +$(SRCROOT)/Carthage/Build/iOS/Sentry.framework diff --git a/Samples/Carthage-Validation/Framework/output.xcfilelist b/Samples/Carthage-Validation/Framework/output.xcfilelist index e2973ee20c3..d9ab7a67be9 100644 --- a/Samples/Carthage-Validation/Framework/output.xcfilelist +++ b/Samples/Carthage-Validation/Framework/output.xcfilelist @@ -1 +1 @@ -$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Sentry.framework \ No newline at end of file +$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Sentry.framework diff --git a/Sentry.podspec b/Sentry.podspec index b5209f82d02..5586c07ec74 100644 --- a/Sentry.podspec +++ b/Sentry.podspec @@ -16,6 +16,7 @@ Pod::Spec.new do |s| s.requires_arc = true s.frameworks = 'Foundation' s.libraries = 'z', 'c++' + s.swift_versions = "5.5" s.pod_target_xcconfig = { 'GCC_ENABLE_CPP_EXCEPTIONS' => 'YES', 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++14', @@ -29,10 +30,8 @@ Pod::Spec.new do |s| s.subspec 'Core' do |sp| sp.source_files = "Sources/Sentry/**/*.{h,hpp,m,mm,c,cpp}", - "Sources/SentryCrash/**/*.{h,hpp,m,mm,c,cpp}" - + "Sources/SentryCrash/**/*.{h,hpp,m,mm,c,cpp}", "Sources/Swift/**/*.{swift}" sp.public_header_files = "Sources/Sentry/Public/*.h" - end end diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 8820bc1c578..d907db31a99 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -661,6 +661,7 @@ A811D867248E2770008A41EA /* SentrySystemEventBreadcrumbsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A811D866248E2770008A41EA /* SentrySystemEventBreadcrumbsTest.swift */; }; A839D89824864B80003B7AFD /* SentrySystemEventBreadcrumbs.h in Headers */ = {isa = PBXBuildFile; fileRef = A839D89724864B80003B7AFD /* SentrySystemEventBreadcrumbs.h */; }; A839D89A24864BA8003B7AFD /* SentrySystemEventBreadcrumbs.m in Sources */ = {isa = PBXBuildFile; fileRef = A839D89924864BA8003B7AFD /* SentrySystemEventBreadcrumbs.m */; }; + D800942728F82F3A005D3943 /* SwiftDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D800942628F82F3A005D3943 /* SwiftDescriptor.swift */; }; D8019910286B089000C277F0 /* SentryCrashReportSinkTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D801990F286B089000C277F0 /* SentryCrashReportSinkTest.swift */; }; D808FB88281AB33C009A2A33 /* SentryUIEventTrackerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D808FB86281AB31D009A2A33 /* SentryUIEventTrackerTests.swift */; }; D808FB8B281BCE96009A2A33 /* TestSentrySwizzleWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D808FB89281BCE46009A2A33 /* TestSentrySwizzleWrapper.swift */; }; @@ -706,6 +707,7 @@ D8ACE3CF2762187D00F5A213 /* SentryFileIOTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8ACE3CC2762187D00F5A213 /* SentryFileIOTrackingIntegration.h */; }; D8B76B062808066D000A58C4 /* SentryScreenshotIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */; }; D8B76B0828081461000A58C4 /* TestSentryScreenShot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */; }; + D8BBD32728FD9FC00011F850 /* SentrySwift.h in Headers */ = {isa = PBXBuildFile; fileRef = D8BBD32628FD9FBF0011F850 /* SentrySwift.h */; }; D8C67E9B28000E24007E326E /* SentryUIApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = D8C67E9928000E23007E326E /* SentryUIApplication.h */; }; D8C67E9C28000E24007E326E /* SentryScreenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = D8C67E9A28000E23007E326E /* SentryScreenshot.h */; }; D8CE69BC277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */; }; @@ -1355,7 +1357,7 @@ 844DA7F6282435CD00E6B62E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 844DA80328246D5000E6B62E /* .oclint */ = {isa = PBXFileReference; lastKnownFileType = text; path = .oclint; sourceTree = ""; }; 844DA80428246D5000E6B62E /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; - 844DA80528246D5000E6B62E /* Sentry.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = Sentry.podspec; sourceTree = ""; }; + 844DA80528246D5000E6B62E /* Sentry.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = Sentry.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 844DA80628246D5000E6B62E /* .craft.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .craft.yml; sourceTree = ""; }; 844DA80728246D5000E6B62E /* Gemfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = Gemfile; sourceTree = ""; }; 844DA80828246D5000E6B62E /* .gitmodules */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitmodules; sourceTree = ""; }; @@ -1444,6 +1446,7 @@ A811D866248E2770008A41EA /* SentrySystemEventBreadcrumbsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySystemEventBreadcrumbsTest.swift; sourceTree = ""; }; A839D89724864B80003B7AFD /* SentrySystemEventBreadcrumbs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySystemEventBreadcrumbs.h; path = include/SentrySystemEventBreadcrumbs.h; sourceTree = ""; }; A839D89924864BA8003B7AFD /* SentrySystemEventBreadcrumbs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySystemEventBreadcrumbs.m; sourceTree = ""; }; + D800942628F82F3A005D3943 /* SwiftDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftDescriptor.swift; sourceTree = ""; }; D801990F286B089000C277F0 /* SentryCrashReportSinkTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCrashReportSinkTest.swift; sourceTree = ""; }; D808FB86281AB31D009A2A33 /* SentryUIEventTrackerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUIEventTrackerTests.swift; sourceTree = ""; }; D808FB89281BCE46009A2A33 /* TestSentrySwizzleWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentrySwizzleWrapper.swift; sourceTree = ""; }; @@ -1490,6 +1493,7 @@ D8ACE3CC2762187D00F5A213 /* SentryFileIOTrackingIntegration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryFileIOTrackingIntegration.h; path = include/SentryFileIOTrackingIntegration.h; sourceTree = ""; }; D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryScreenshotIntegrationTests.swift; sourceTree = ""; }; D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentryScreenShot.swift; sourceTree = ""; }; + D8BBD32628FD9FBF0011F850 /* SentrySwift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentrySwift.h; path = include/SentrySwift.h; sourceTree = ""; }; D8C67E9928000E23007E326E /* SentryUIApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryUIApplication.h; path = include/SentryUIApplication.h; sourceTree = ""; }; D8C67E9A28000E23007E326E /* SentryScreenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryScreenshot.h; path = include/SentryScreenshot.h; sourceTree = ""; }; D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryFileIOTrackingIntegrationObjCTests.m; sourceTree = ""; }; @@ -1854,6 +1858,7 @@ 63AA756E1EB8AEDB00D153DE /* Sources */ = { isa = PBXGroup; children = ( + D800942328F82E8D005D3943 /* Swift */, 63AA75A31EB8AFDF00D153DE /* Configuration */, 63FE6FB920DA4C1000CDBAE8 /* SentryCrash */, 63AA75C61EB8B06100D153DE /* Sentry */, @@ -1947,6 +1952,7 @@ 8ECC673625C23936000E2BF6 /* Transaction */, 8E25C94F25F836AB00DC215B /* Tools */, 63AA76931EB9C1C200D153DE /* Sentry.h */, + D8BBD32628FD9FBF0011F850 /* SentrySwift.h */, 7B6D125E265F778500C9BE4B /* PrivateSentrySDKOnly.h */, 7B6D1260265F784000C9BE4B /* PrivateSentrySDKOnly.m */, 63AA76941EB9C1C200D153DE /* SentryClient.h */, @@ -2813,6 +2819,14 @@ name = Transaction; sourceTree = ""; }; + D800942328F82E8D005D3943 /* Swift */ = { + isa = PBXGroup; + children = ( + D800942628F82F3A005D3943 /* SwiftDescriptor.swift */, + ); + path = Swift; + sourceTree = ""; + }; D808FB85281AB2EF009A2A33 /* UIEvents */ = { isa = PBXGroup; children = ( @@ -2909,6 +2923,7 @@ 0ADC33EE28D9BB890078D980 /* SentryUIDeviceWrapper.h in Headers */, 8E133FA625E72EB400ABD0BF /* SentrySamplingContext.h in Headers */, 0A9BF4E428A114B50068D266 /* SentryViewHierarchyIntegration.h in Headers */, + D8BBD32728FD9FC00011F850 /* SentrySwift.h in Headers */, 8E4E7C7425DAAB49006AB9E2 /* SentrySpanProtocol.h in Headers */, 8EC4CF4A25C38DAA0093DEE9 /* SentrySpanStatus.h in Headers */, 8ECC673D25C23996000E2BF6 /* SentrySpanId.h in Headers */, @@ -3176,9 +3191,9 @@ isa = PBXNativeTarget; buildConfigurationList = 63AA75A01EB8AEF500D153DE /* Build configuration list for PBXNativeTarget "Sentry" */; buildPhases = ( + 63AA75981EB8AEF500D153DE /* Headers */, 63AA75961EB8AEF500D153DE /* Sources */, 63AA75971EB8AEF500D153DE /* Frameworks */, - 63AA75981EB8AEF500D153DE /* Headers */, 63AA75991EB8AEF500D153DE /* Resources */, ); buildRules = ( @@ -3484,6 +3499,7 @@ 632F43521F581D5400A18A36 /* SentryCrashExceptionApplication.m in Sources */, 0AABE2ED2885924A0057ED69 /* SentryPermissionsObserver.m in Sources */, 7B77BE3727EC8460003C9020 /* SentryDiscardReasonMapper.m in Sources */, + D800942728F82F3A005D3943 /* SwiftDescriptor.swift in Sources */, 63FE712520DA4C1000CDBAE8 /* SentryCrashSignalInfo.c in Sources */, 63FE70F320DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.c in Sources */, D859696F27BECDA20036A46E /* SentryCoreDataTracker.m in Sources */, @@ -3942,6 +3958,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 63AA76AE1EB9D5CD00D153DE /* SentryTests.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ENABLE_MODULES = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -3970,6 +3987,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 63AA76AE1EB9D5CD00D153DE /* SentryTests.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ENABLE_MODULES = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -4109,6 +4127,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 63AA76AE1EB9D5CD00D153DE /* SentryTests.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ENABLE_MODULES = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -4242,6 +4261,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 63AA76AE1EB9D5CD00D153DE /* SentryTests.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ENABLE_MODULES = YES; CLANG_WARN_BOOL_CONVERSION = YES; diff --git a/Sources/Sentry/Public/SentryStacktrace.h b/Sources/Sentry/Public/SentryStacktrace.h index e8c67d83f41..f151c539527 100644 --- a/Sources/Sentry/Public/SentryStacktrace.h +++ b/Sources/Sentry/Public/SentryStacktrace.h @@ -7,7 +7,6 @@ NS_ASSUME_NONNULL_BEGIN @class SentryFrame; -NS_SWIFT_NAME(Stacktrace) @interface SentryStacktrace : NSObject SENTRY_NO_INIT diff --git a/Sources/Sentry/Public/SentryThread.h b/Sources/Sentry/Public/SentryThread.h index 7546e419ea0..ecca3e03e06 100644 --- a/Sources/Sentry/Public/SentryThread.h +++ b/Sources/Sentry/Public/SentryThread.h @@ -5,7 +5,6 @@ NS_ASSUME_NONNULL_BEGIN @class SentryStacktrace; -NS_SWIFT_NAME(Thread) @interface SentryThread : NSObject SENTRY_NO_INIT diff --git a/Sources/Sentry/SentryBreadcrumbTracker.m b/Sources/Sentry/SentryBreadcrumbTracker.m index 6022b4d18bb..81fcc5c7038 100644 --- a/Sources/Sentry/SentryBreadcrumbTracker.m +++ b/Sources/Sentry/SentryBreadcrumbTracker.m @@ -234,8 +234,7 @@ + (NSDictionary *)fetchInfoAboutViewController:(UIViewController *)controller { NSMutableDictionary *info = @{}.mutableCopy; - info[@"screen"] = [SentryUIViewControllerSanitizer - sanitizeViewControllerName:[NSString stringWithFormat:@"%@", controller]]; + info[@"screen"] = [SentryUIViewControllerSanitizer sanitizeViewControllerName:controller]; if ([controller.navigationItem.title length] != 0) { info[@"title"] = controller.navigationItem.title; diff --git a/Sources/Sentry/SentryUIViewControllerSanitizer.m b/Sources/Sentry/SentryUIViewControllerSanitizer.m index bbf608e93be..973e3f969d8 100644 --- a/Sources/Sentry/SentryUIViewControllerSanitizer.m +++ b/Sources/Sentry/SentryUIViewControllerSanitizer.m @@ -1,34 +1,11 @@ #import "SentryUIViewControllerSanitizer.h" +#import "SentrySwift.h" @implementation SentryUIViewControllerSanitizer -+ (NSRegularExpression *)viewControllerRegex -{ - static dispatch_once_t onceTokenRegex; - static NSRegularExpression *regex = nil; - dispatch_once(&onceTokenRegex, ^{ - NSString *pattern = @"[<.](\\w+)"; - regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil]; - }); - return regex; -} - + (NSString *)sanitizeViewControllerName:(id)controller { - NSString *description = [NSString stringWithFormat:@"%@", controller]; - - NSRange searchedRange = NSMakeRange(0, [description length]); - NSArray *matches = [[self.class viewControllerRegex] matchesInString:description - options:0 - range:searchedRange]; - NSMutableArray *strings = [NSMutableArray array]; - for (NSTextCheckingResult *match in matches) { - [strings addObject:[description substringWithRange:[match rangeAtIndex:1]]]; - } - if ([strings count] > 0) { - return [strings componentsJoinedByString:@"."]; - } - return description; + return [SwiftDescriptor getDescription:controller]; } @end diff --git a/Sources/Sentry/include/SentrySwift.h b/Sources/Sentry/include/SentrySwift.h new file mode 100644 index 00000000000..b70b3c5f035 --- /dev/null +++ b/Sources/Sentry/include/SentrySwift.h @@ -0,0 +1,27 @@ +#ifndef SentrySwift_h +#define SentrySwift_h + +/* + * This is a header to expose Swift code to Objective-c + * + * Because we use three different package managers + * we need to target the swift module in different ways. + * + * If the project is being used through SPM, Swift and Objective-c are compiled into separated + * targets, then we use "@import SentrySwift". + * + * Cocoapods combines everything into one target, if the user enable USE_FRAMEWORKS, + * Swift will be available through "#import " otherwise "#import + * "Sentry-Swift.h"". + */ + +#if SWIFT_PACKAGE // For SWIFT PACKAGE MANAGER +@import SentrySwift; +#else +# if __has_include() //COCOAPODS with USE_FRAMEWORKS +# import +# else +# import "Sentry-Swift.h" //Everything else +# endif +#endif +#endif diff --git a/Sources/Swift/SwiftDescriptor.swift b/Sources/Swift/SwiftDescriptor.swift new file mode 100644 index 00000000000..e0b8e85c306 --- /dev/null +++ b/Sources/Swift/SwiftDescriptor.swift @@ -0,0 +1,11 @@ +import Foundation + +@objc +public class SwiftDescriptor: NSObject { + + @objc + public static func getDescription(_ object: AnyObject) -> String { + return String(describing: type(of: object)) + } + +} diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift index 2dde33b2e80..15d81d40ba5 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift @@ -111,15 +111,15 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { let frame1 = Sentry.Frame() frame1.function = "Second_frame_function" - let thread1 = Sentry.Thread(threadId: 0) - thread1.stacktrace = Stacktrace(frames: [frame1], registers: [:]) + let thread1 = SentryThread(threadId: 0) + thread1.stacktrace = SentryStacktrace(frames: [frame1], registers: [:]) thread1.current = true let frame2 = Sentry.Frame() frame2.function = "main" - let thread2 = Sentry.Thread(threadId: 1) - thread2.stacktrace = Stacktrace(frames: [frame2], registers: [:]) + let thread2 = SentryThread(threadId: 1) + thread2.stacktrace = SentryStacktrace(frames: [frame2], registers: [:]) thread2.current = false threadInspector.allThreads = [ diff --git a/Tests/SentryTests/Protocol/SentryThreadEquality.swift b/Tests/SentryTests/Protocol/SentryThreadEquality.swift index 9731009056d..9e4414c22cd 100644 --- a/Tests/SentryTests/Protocol/SentryThreadEquality.swift +++ b/Tests/SentryTests/Protocol/SentryThreadEquality.swift @@ -1,8 +1,8 @@ import Foundation -extension Sentry.Thread { +extension SentryThread { open override func isEqual(_ object: Any?) -> Bool { - if let other = object as? Sentry.Thread { + if let other = object as? SentryThread { return threadId == other.threadId && name == other.name && stacktrace == other.stacktrace && @@ -17,9 +17,9 @@ extension Sentry.Thread { } } -extension Sentry.Stacktrace { +extension SentryStacktrace { open override func isEqual(_ object: Any?) -> Bool { - if let other = object as? Sentry.Stacktrace { + if let other = object as? SentryStacktrace { return frames == other.frames && registers == other.registers } else { diff --git a/Tests/SentryTests/Protocol/TestData.swift b/Tests/SentryTests/Protocol/TestData.swift index 68cc36a0648..2f64560ce16 100644 --- a/Tests/SentryTests/Protocol/TestData.swift +++ b/Tests/SentryTests/Protocol/TestData.swift @@ -119,8 +119,8 @@ class TestData { return mechanismMeta } - static var thread: Sentry.Thread { - let thread = Sentry.Thread(threadId: 10) + static var thread: SentryThread { + let thread = SentryThread(threadId: 10) thread.crashed = false thread.current = true thread.name = "main" @@ -129,8 +129,8 @@ class TestData { return thread } - static var stacktrace: Stacktrace { - let stacktrace = Stacktrace(frames: [frame], registers: ["register": "one"]) + static var stacktrace: SentryStacktrace { + let stacktrace = SentryStacktrace(frames: [frame], registers: ["register": "one"]) return stacktrace } diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift index c3e0f5359f2..73036e37aa5 100644 --- a/Tests/SentryTests/SentryClientTests.swift +++ b/Tests/SentryTests/SentryClientTests.swift @@ -1261,7 +1261,7 @@ class SentryClientTest: XCTestCase { private func givenEventWithThreads() -> Event { let event = Event(level: SentryLevel.fatal) - let thread = Sentry.Thread(threadId: 1) + let thread = SentryThread(threadId: 1) thread.crashed = true let threads = [thread] event.threads = threads @@ -1360,13 +1360,13 @@ class SentryClientTest: XCTestCase { } } - private func assertValidDebugMeta(actual: [DebugMeta]?, forThreads threads: [Sentry.Thread]?) { + private func assertValidDebugMeta(actual: [DebugMeta]?, forThreads threads: [SentryThread]?) { let debugMetas = fixture.debugImageBuilder.getDebugImages(for: threads ?? []) XCTAssertEqual(debugMetas, actual ?? []) } - private func assertValidThreads(actual: [Sentry.Thread]?) { + private func assertValidThreads(actual: [SentryThread]?) { let expected = fixture.threadInspector.getCurrentThreads() XCTAssertEqual(expected.count, actual?.count) XCTAssertEqual(expected, actual) diff --git a/Tests/SentryTests/SentryCrash/SentryDebugImageProviderTests.swift b/Tests/SentryTests/SentryCrash/SentryDebugImageProviderTests.swift index 9d0f45efe30..406d14e3fea 100644 --- a/Tests/SentryTests/SentryCrash/SentryDebugImageProviderTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryDebugImageProviderTests.swift @@ -122,10 +122,10 @@ class SentryDebugImageProviderTests: XCTestCase { func testImagesForThreads() { let sut = fixture.getSut(images: fixture.getTestImages()) - let thread = Sentry.Thread(threadId: NSNumber(value: 1)) + let thread = SentryThread(threadId: NSNumber(value: 1)) let frame = Sentry.Frame() frame.imageAddress = "0x0000000105705000" - thread.stacktrace = Stacktrace(frames: [frame], registers: [:]) + thread.stacktrace = SentryStacktrace(frames: [frame], registers: [:]) var actual = sut.getDebugImages(for: [thread]) @@ -137,7 +137,7 @@ class SentryDebugImageProviderTests: XCTestCase { frame2.imageAddress = "0x00000001410b1a00" let frame3 = Sentry.Frame() frame3.imageAddress = "0x000000017ca5e400" - thread.stacktrace = Stacktrace(frames: [frame2, frame3], registers: [:]) + thread.stacktrace = SentryStacktrace(frames: [frame2, frame3], registers: [:]) actual = sut.getDebugImages(for: [thread]) @@ -151,7 +151,7 @@ class SentryDebugImageProviderTests: XCTestCase { func test_NoImage_ForThread_WithoutStackTrace() { let sut = fixture.getSut(images: fixture.getTestImages()) - let thread = Sentry.Thread(threadId: NSNumber(value: 1)) + let thread = SentryThread(threadId: NSNumber(value: 1)) let actual = sut.getDebugImages(for: [thread]) XCTAssertEqual(actual.count, 0) diff --git a/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift b/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift index 4c3624266ce..fcf32564fc6 100644 --- a/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift @@ -173,9 +173,9 @@ import XCTest private class TestSentryStacktraceBuilder: SentryStacktraceBuilder { - var stackTraces = [SentryCrashThread: Stacktrace]() - override func buildStacktrace(forThread thread: SentryCrashThread, context: OpaquePointer) -> Stacktrace { - return stackTraces[thread] ?? Stacktrace(frames: [], registers: [:]) + var stackTraces = [SentryCrashThread: SentryStacktrace]() + override func buildStacktrace(forThread thread: SentryCrashThread, context: OpaquePointer) -> SentryStacktrace { + return stackTraces[thread] ?? SentryStacktrace(frames: [], registers: [:]) } } diff --git a/Tests/SentryTests/SentryCrash/TestThreadInspector.swift b/Tests/SentryTests/SentryCrash/TestThreadInspector.swift index 6dc623e7091..3996ed7b93a 100644 --- a/Tests/SentryTests/SentryCrash/TestThreadInspector.swift +++ b/Tests/SentryTests/SentryCrash/TestThreadInspector.swift @@ -2,7 +2,7 @@ import Foundation class TestThreadInspector: SentryThreadInspector { - var allThreads: [Sentry.Thread]? + var allThreads: [SentryThread]? static var instance: TestThreadInspector { // We need something to pass to the super initializer, because the empty initializer has been marked unavailable. @@ -12,11 +12,11 @@ class TestThreadInspector: SentryThreadInspector { return TestThreadInspector(stacktraceBuilder: stacktraceBuilder, andMachineContextWrapper: SentryCrashDefaultMachineContextWrapper()) } - override func getCurrentThreads() -> [Sentry.Thread] { + override func getCurrentThreads() -> [SentryThread] { return allThreads ?? [TestData.thread] } - override func getCurrentThreadsWithStackTrace() -> [Sentry.Thread] { + override func getCurrentThreadsWithStackTrace() -> [SentryThread] { return allThreads ?? [TestData.thread] } diff --git a/Tests/SentryTests/SentryUIViewControllerSanitizerTests.swift b/Tests/SentryTests/SentryUIViewControllerSanitizerTests.swift index abb3446b49d..c2d83b402e1 100644 --- a/Tests/SentryTests/SentryUIViewControllerSanitizerTests.swift +++ b/Tests/SentryTests/SentryUIViewControllerSanitizerTests.swift @@ -1,6 +1,10 @@ import XCTest class SentryUIViewControllerSanitizerTests: XCTestCase { + + private class InnerClass: NSObject { + + } func testSanitizeViewControllerNameWithBaseObject() { let object = NSObject() @@ -16,19 +20,12 @@ class SentryUIViewControllerSanitizerTests: XCTestCase { XCTAssertEqual(name, "SentryOptions") } - func testSanitizeViewControllerNameWithStrings() { - XCTAssertEqual( - "sentry_ios_cocoapods.ViewController", sanitize("") - ) - - XCTAssertEqual( - "sentry_ios_cocoapodsViewController: 0x7fd9201253c0", sanitize("sentry_ios_cocoapodsViewController: 0x7fd9201253c0") - ) - - XCTAssertEqual( - "sentry_ios_cocoapods.ViewController.miau", sanitize("") - ) + func testSanitizeViewControllerNameWithPrivateSwiftClass() { + let object = InnerClass() + let name = sanitize(object) + XCTAssertNotEqual(name, object.description) + XCTAssertEqual(name, "InnerClass") } private func sanitize(_ name: Any) -> String { diff --git a/develop-docs/README.md b/develop-docs/README.md index b20ae26b187..8f72034241e 100644 --- a/develop-docs/README.md +++ b/develop-docs/README.md @@ -128,3 +128,14 @@ iOS 12 opens a risk of introducing bugs, which has already happened in the past, the iOS 12 simulator a try. Related to [GH-2218](https://github.com/getsentry/sentry-cocoa/issues/2218) + +### Adding Swift code in the project + +Date: October 1st 2022 +Contributors: @brustolin + +A Sentry SDK started to be [written in Swift once,](https://github.com/getsentry/raven-swift) but due to ABI not being stable at that time, it got dropped. Since then Swift 5.1 landed and we got ABI stability. We’ve considered adding Swift to our sentry.cocoa SDK since then, but because of some of the trade offs, we’ve postponed that decision. +This changed with our goal to better support SwiftUI. It’s growing in popularity and we need to write code in Swift in order to support it. +SwiftUI support will be available through an adicional library, but in order to support it we need to be able to demangle Swift class names in Sentry SDK, which can be done by using Swift API. +Since we support SPM, and SPM don't support multi language projects, we need to create two different targets, one with Swift and another with Objective-c code, because of that our Swift code in SPM resides in a different module, which requires a different import in projects, and for now, this is the reason we should avoid writing public API in Swift. But, everything written in Swift will be public if users import Sentry via CocoaPods or Carthage. +