diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 2f46d6bc36..1521336a85 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -143,6 +143,33 @@ jobs: ;; esac + spm: + name: "SPM" + runs-on: macos-15 + timeout-minutes: 30 + defaults: + run: + shell: bash + working-directory: flutter/example + strategy: + fail-fast: false + matrix: + target: [ios, macos] + + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 # pin@v2.16.0 + with: + channel: main + - run: flutter upgrade + - run: flutter config --enable-swift-package-manager + - name: Run on iOS + if: matrix.target == 'ios' + run: flutter run -d "iPhone 16 Pro" + - name: Run on macOS + if: matrix.target == 'macos' + run: flutter run -d "macOS" + analyze: uses: ./.github/workflows/analyze.yml with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 2997308558..570cc3ca92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -163,6 +163,8 @@ ); ``` +- SPM Support ([#2280](https://github.com/getsentry/sentry-dart/pull/2280)) + ### Enhancements - Avoid sending too many empty client reports when Http Transport is used ([#2380](https://github.com/getsentry/sentry-dart/pull/2380)) diff --git a/flutter/.gitignore b/flutter/.gitignore index 30db743ffc..8ac84f58d5 100644 --- a/flutter/.gitignore +++ b/flutter/.gitignore @@ -10,4 +10,8 @@ build/ .cxx/ .vscode/launch.json +cocoa_bindings_temp + +ios/sentry_flutter/Package.resolved + temp diff --git a/flutter/ios/.gitignore b/flutter/ios/.gitignore index aa479fd3ce..d10a0d4773 100644 --- a/flutter/ios/.gitignore +++ b/flutter/ios/.gitignore @@ -34,4 +34,8 @@ Icon? .tags* /Flutter/Generated.xcconfig -/Flutter/flutter_export_environment.sh \ No newline at end of file +/Flutter/flutter_export_environment.sh + +.build +.swiftpm +Package.resolved diff --git a/flutter/ios/Assets/.gitkeep b/flutter/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/flutter/ios/Classes/SentryFlutterPlugin.h b/flutter/ios/Classes/SentryFlutterPlugin.h deleted file mode 100644 index 962c158028..0000000000 --- a/flutter/ios/Classes/SentryFlutterPlugin.h +++ /dev/null @@ -1,10 +0,0 @@ -#if TARGET_OS_IPHONE - #import -#else - #import -#endif - -#import - -@interface SentryFlutterPlugin : NSObject -@end diff --git a/flutter/ios/Classes/SentryFlutterPlugin.m b/flutter/ios/Classes/SentryFlutterPlugin.m deleted file mode 100644 index f541e31c0e..0000000000 --- a/flutter/ios/Classes/SentryFlutterPlugin.m +++ /dev/null @@ -1,15 +0,0 @@ -#import "SentryFlutterPlugin.h" -#if __has_include() -#import -#else -// Support project import fallback if the generated compatibility header -// is not copied when this plugin is created as a library. -// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 -#import "sentry_flutter-Swift.h" -#endif - -@implementation SentryFlutterPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - [SentryFlutterPluginApple registerWithRegistrar:registrar]; -} -@end diff --git a/flutter/ios/sentry_flutter/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/flutter/ios/sentry_flutter/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..919434a625 --- /dev/null +++ b/flutter/ios/sentry_flutter/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/flutter/ios/sentry_flutter/Package.swift b/flutter/ios/sentry_flutter/Package.swift new file mode 100644 index 0000000000..f7d76a8e31 --- /dev/null +++ b/flutter/ios/sentry_flutter/Package.swift @@ -0,0 +1,34 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "sentry_flutter", + platforms: [ + .iOS("12.0"), + .macOS("10.13") + ], + products: [ + .library(name: "sentry-flutter", targets: ["sentry_flutter", "sentry_flutter_objc"]) + ], + dependencies: [ + .package(url: "https://github.com/getsentry/sentry-cocoa", from: "8.40.1") + ], + targets: [ + .target( + name: "sentry_flutter", + dependencies: [ + "sentry_flutter_objc", + .product(name: "Sentry", package: "sentry-cocoa") + ] + ), + // SPM does not support mixed-language targets, so we need to move the ObjC files into a separate one + .target( + name: "sentry_flutter_objc", + dependencies: [ + .product(name: "Sentry", package: "sentry-cocoa") + ] + ) + ] +) diff --git a/flutter/ios/Classes/SentryFlutter.swift b/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutter.swift similarity index 100% rename from flutter/ios/Classes/SentryFlutter.swift rename to flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutter.swift diff --git a/flutter/ios/Classes/SentryFlutterPluginApple.swift b/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift similarity index 97% rename from flutter/ios/Classes/SentryFlutterPluginApple.swift rename to flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift index 727928f913..6af936e3ed 100644 --- a/flutter/ios/Classes/SentryFlutterPluginApple.swift +++ b/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift @@ -1,4 +1,10 @@ import Sentry + +#if SWIFT_PACKAGE +import Sentry._Hybrid +import sentry_flutter_objc +#endif + #if os(iOS) import Flutter import UIKit @@ -11,7 +17,7 @@ import CoreVideo // swiftlint:disable file_length function_body_length // swiftlint:disable:next type_body_length -public class SentryFlutterPluginApple: NSObject, FlutterPlugin { +public class SentryFlutterPlugin: NSObject, FlutterPlugin { private let channel: FlutterMethodChannel private static let nativeClientName = "sentry.cocoa.flutter" @@ -39,7 +45,7 @@ public class SentryFlutterPluginApple: NSObject, FlutterPlugin { let channel = FlutterMethodChannel(name: "sentry_flutter", binaryMessenger: registrar.messenger) #endif - let instance = SentryFlutterPluginApple(channel: channel) + let instance = SentryFlutterPlugin(channel: channel) instance.registerObserver() registrar.addMethodCallDelegate(instance, channel: channel) } @@ -323,7 +329,7 @@ public class SentryFlutterPluginApple: NSObject, FlutterPlugin { } let version = PrivateSentrySDKOnly.getSdkVersionString() - PrivateSentrySDKOnly.setSdkName(SentryFlutterPluginApple.nativeClientName, andVersionString: version) + PrivateSentrySDKOnly.setSdkName(SentryFlutterPlugin.nativeClientName, andVersionString: version) // note : for now, in sentry-cocoa, beforeSend is not called before captureEnvelope options.beforeSend = { event in @@ -364,9 +370,9 @@ public class SentryFlutterPluginApple: NSObject, FlutterPlugin { #if canImport(UIKit) && !SENTRY_NO_UIKIT #if os(iOS) || os(tvOS) - let breadcrumbConverter = SentryFlutterReplayBreadcrumbConverter() - let screenshotProvider = SentryFlutterReplayScreenshotProvider(channel: self.channel) - PrivateSentrySDKOnly.configureSessionReplay(with: breadcrumbConverter, screenshotProvider: screenshotProvider) + let breadcrumbConverter = SentryFlutterReplayBreadcrumbConverter() + let screenshotProvider = SentryFlutterReplayScreenshotProvider(channel: self.channel) + PrivateSentrySDKOnly.configureSessionReplay(with: breadcrumbConverter, screenshotProvider: screenshotProvider) #endif #endif @@ -385,7 +391,7 @@ public class SentryFlutterPluginApple: NSObject, FlutterPlugin { if isValidSdk(sdk: sdk) { switch sdk["name"] as? String { - case SentryFlutterPluginApple.nativeClientName: + case SentryFlutterPlugin.nativeClientName: #if os(OSX) let origin = "mac" #elseif os(watchOS) @@ -500,7 +506,7 @@ public class SentryFlutterPluginApple: NSObject, FlutterPlugin { let isColdStart = appStartMeasurement.type == .cold let item: [String: Any] = [ - "pluginRegistrationTime": SentryFlutterPluginApple.pluginRegistrationTime, + "pluginRegistrationTime": SentryFlutterPlugin.pluginRegistrationTime, "appStartTime": appStartTime, "isColdStart": isColdStart, "nativeSpanTimes": nativeSpanTimes diff --git a/flutter/ios/Classes/SentryFlutterReplayBreadcrumbConverter.m b/flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayBreadcrumbConverter.m similarity index 97% rename from flutter/ios/Classes/SentryFlutterReplayBreadcrumbConverter.m rename to flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayBreadcrumbConverter.m index bde889b6bf..060bbbd80a 100644 --- a/flutter/ios/Classes/SentryFlutterReplayBreadcrumbConverter.m +++ b/flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayBreadcrumbConverter.m @@ -1,7 +1,11 @@ -#import "SentryFlutterReplayBreadcrumbConverter.h" +#import "include/SentryFlutterReplayBreadcrumbConverter.h" @import Sentry; +#if SWIFT_PACKAGE +@import Sentry._Hybrid; +#endif + #if SENTRY_TARGET_REPLAY_SUPPORTED @implementation SentryFlutterReplayBreadcrumbConverter { diff --git a/flutter/ios/Classes/SentryFlutterReplayScreenshotProvider.m b/flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayScreenshotProvider.m similarity index 97% rename from flutter/ios/Classes/SentryFlutterReplayScreenshotProvider.m rename to flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayScreenshotProvider.m index b363cf5342..864744c539 100644 --- a/flutter/ios/Classes/SentryFlutterReplayScreenshotProvider.m +++ b/flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayScreenshotProvider.m @@ -1,5 +1,9 @@ @import Sentry; +#if SWIFT_PACKAGE +@import Sentry._Hybrid; +#endif + #if SENTRY_TARGET_REPLAY_SUPPORTED #import "SentryFlutterReplayScreenshotProvider.h" #import diff --git a/flutter/ios/Classes/SentryFlutterReplayBreadcrumbConverter.h b/flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayBreadcrumbConverter.h similarity index 100% rename from flutter/ios/Classes/SentryFlutterReplayBreadcrumbConverter.h rename to flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayBreadcrumbConverter.h diff --git a/flutter/ios/Classes/SentryFlutterReplayScreenshotProvider.h b/flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayScreenshotProvider.h similarity index 100% rename from flutter/ios/Classes/SentryFlutterReplayScreenshotProvider.h rename to flutter/ios/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayScreenshotProvider.h diff --git a/flutter/macos/Classes/SentryFlutter.swift b/flutter/macos/Classes/SentryFlutter.swift deleted file mode 120000 index ea42d8c01c..0000000000 --- a/flutter/macos/Classes/SentryFlutter.swift +++ /dev/null @@ -1 +0,0 @@ -../../ios/Classes/SentryFlutter.swift \ No newline at end of file diff --git a/flutter/macos/Classes/SentryFlutterPlugin.h b/flutter/macos/Classes/SentryFlutterPlugin.h deleted file mode 120000 index 4e043862d2..0000000000 --- a/flutter/macos/Classes/SentryFlutterPlugin.h +++ /dev/null @@ -1 +0,0 @@ -../../ios/Classes/SentryFlutterPlugin.h \ No newline at end of file diff --git a/flutter/macos/Classes/SentryFlutterPlugin.m b/flutter/macos/Classes/SentryFlutterPlugin.m deleted file mode 120000 index 99905179b3..0000000000 --- a/flutter/macos/Classes/SentryFlutterPlugin.m +++ /dev/null @@ -1 +0,0 @@ -../../ios/Classes/SentryFlutterPlugin.m \ No newline at end of file diff --git a/flutter/macos/Classes/SentryFlutterPluginApple.swift b/flutter/macos/Classes/SentryFlutterPluginApple.swift deleted file mode 120000 index 1ac6c4f5be..0000000000 --- a/flutter/macos/Classes/SentryFlutterPluginApple.swift +++ /dev/null @@ -1 +0,0 @@ -../../ios/Classes/SentryFlutterPluginApple.swift \ No newline at end of file diff --git a/flutter/macos/sentry_flutter/Package.swift b/flutter/macos/sentry_flutter/Package.swift new file mode 120000 index 0000000000..fe0be63eb8 --- /dev/null +++ b/flutter/macos/sentry_flutter/Package.swift @@ -0,0 +1 @@ +../../ios/sentry_flutter/Package.swift \ No newline at end of file diff --git a/flutter/macos/sentry_flutter/Sources/sentry_flutter/SentryFlutter.swift b/flutter/macos/sentry_flutter/Sources/sentry_flutter/SentryFlutter.swift new file mode 120000 index 0000000000..9fbb9bb436 --- /dev/null +++ b/flutter/macos/sentry_flutter/Sources/sentry_flutter/SentryFlutter.swift @@ -0,0 +1 @@ +../../../../ios/sentry_flutter/Sources/sentry_flutter/SentryFlutter.swift \ No newline at end of file diff --git a/flutter/macos/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift b/flutter/macos/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift new file mode 120000 index 0000000000..30044f0967 --- /dev/null +++ b/flutter/macos/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift @@ -0,0 +1 @@ +../../../../ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift \ No newline at end of file diff --git a/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayBreadcrumbConverter.m b/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayBreadcrumbConverter.m new file mode 120000 index 0000000000..a015af93e4 --- /dev/null +++ b/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayBreadcrumbConverter.m @@ -0,0 +1 @@ +../../../../ios/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayBreadcrumbConverter.m \ No newline at end of file diff --git a/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayScreenshotProvider.m b/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayScreenshotProvider.m new file mode 120000 index 0000000000..e0b12e88bb --- /dev/null +++ b/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayScreenshotProvider.m @@ -0,0 +1 @@ +../../../../ios/sentry_flutter/Sources/sentry_flutter_objc/SentryFlutterReplayScreenshotProvider.m \ No newline at end of file diff --git a/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayBreadcrumbConverter.h b/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayBreadcrumbConverter.h new file mode 120000 index 0000000000..a1f59a3999 --- /dev/null +++ b/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayBreadcrumbConverter.h @@ -0,0 +1 @@ +../../../../../ios/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayBreadcrumbConverter.h \ No newline at end of file diff --git a/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayScreenshotProvider.h b/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayScreenshotProvider.h new file mode 120000 index 0000000000..1c8b3852ca --- /dev/null +++ b/flutter/macos/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayScreenshotProvider.h @@ -0,0 +1 @@ +../../../../../ios/sentry_flutter/Sources/sentry_flutter_objc/include/SentryFlutterReplayScreenshotProvider.h \ No newline at end of file