diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2fbe84a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,65 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + +jobs: + analyze: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Install dependencies + run: flutter pub get + - name: Analyze + run: flutter analyze + + verify-ios: + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + package-manager: + - cocoapods + - spm + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Install CocoaPods + run: | + if ! command -v pod >/dev/null; then + sudo gem install cocoapods + fi + - name: Accept Xcode license + run: sudo xcodebuild -license accept + - name: Verify iOS integration + shell: bash + run: | + if [[ "${{ matrix.package-manager }}" == "spm" ]]; then + flutter config --enable-swift-package-manager + pushd example/ios + pod deintegrate + grep -v 'Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig' Flutter/Debug.xcconfig > Flutter/Debug.xcconfig.tmp + mv Flutter/Debug.xcconfig.tmp Flutter/Debug.xcconfig + grep -v 'Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig' Flutter/Release.xcconfig > Flutter/Release.xcconfig.tmp + mv Flutter/Release.xcconfig.tmp Flutter/Release.xcconfig + rm -f Podfile Podfile.lock + popd + else + flutter config --no-enable-swift-package-manager + fi + + flutter pub get + pushd example + rm -rf ios/Pods ios/.symlinks ios/Flutter/ephemeral ios/Flutter/Generated.xcconfig ios/Flutter/flutter_export_environment.sh + flutter clean + flutter pub get + flutter build ios --simulator --debug + popd diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e6f2e73..11db78b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,12 +6,58 @@ on: - 'v[0-9]+.[0-9]+.[0-9]+*' jobs: + verify-ios: + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + package-manager: + - cocoapods + - spm + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Install CocoaPods + run: | + if ! command -v pod >/dev/null; then + sudo gem install cocoapods + fi + - name: Accept Xcode license + run: sudo xcodebuild -license accept + - name: Verify iOS integration + shell: bash + run: | + if [[ "${{ matrix.package-manager }}" == "spm" ]]; then + flutter config --enable-swift-package-manager + pushd example/ios + pod deintegrate + grep -v 'Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig' Flutter/Debug.xcconfig > Flutter/Debug.xcconfig.tmp + mv Flutter/Debug.xcconfig.tmp Flutter/Debug.xcconfig + grep -v 'Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig' Flutter/Release.xcconfig > Flutter/Release.xcconfig.tmp + mv Flutter/Release.xcconfig.tmp Flutter/Release.xcconfig + rm -f Podfile Podfile.lock + popd + else + flutter config --no-enable-swift-package-manager + fi + + flutter pub get + pushd example + rm -rf ios/Pods ios/.symlinks ios/Flutter/ephemeral ios/Flutter/Generated.xcconfig ios/Flutter/flutter_export_environment.sh + flutter clean + flutter pub get + flutter build ios --simulator --debug + popd + publish: + needs: verify-ios runs-on: ubuntu-latest permissions: id-token: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 - uses: subosito/flutter-action@v2 with: diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 9367d48..391a902 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -20,7 +20,5 @@ ???? CFBundleVersion 1.0 - MinimumOSVersion - 8.0 diff --git a/example/ios/Podfile b/example/ios/Podfile index 1e8c3c9..10f3c9b 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '9.0' +platform :ios, '13.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 0b8a17e..81a4d41 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -14,6 +14,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -47,6 +48,7 @@ D6D00D6796C73FB99B2941C5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D9626CA190507183C43EE8AB /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; F93D2570A58097DD9176E480 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -54,6 +56,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, 0B713DF27D8670B28A99C7A9 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -82,6 +85,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, @@ -128,6 +132,9 @@ /* Begin PBXNativeTarget section */ 97C146ED1CF9000F007C117D /* Runner */ = { + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( @@ -153,9 +160,12 @@ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, + ); isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -221,10 +231,12 @@ }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -235,6 +247,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -339,7 +352,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -417,7 +430,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -466,7 +479,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -546,6 +559,18 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140c..0bd6d42 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,10 +1,28 @@ + + + + + + + + + + @@ -45,11 +64,13 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift index 70693e4..c30b367 100644 --- a/example/ios/Runner/AppDelegate.swift +++ b/example/ios/Runner/AppDelegate.swift @@ -1,13 +1,16 @@ -import UIKit import Flutter +import UIKit -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { +@main +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } } diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 642066e..ce44372 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable @@ -22,6 +24,29 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + FlutterSceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/ios/Classes/ThermalPlugin.h b/ios/Classes/ThermalPlugin.h deleted file mode 100644 index ee82b5d..0000000 --- a/ios/Classes/ThermalPlugin.h +++ /dev/null @@ -1,4 +0,0 @@ -#import - -@interface ThermalPlugin : NSObject -@end diff --git a/ios/Classes/ThermalPlugin.m b/ios/Classes/ThermalPlugin.m deleted file mode 100644 index 9a8f173..0000000 --- a/ios/Classes/ThermalPlugin.m +++ /dev/null @@ -1,15 +0,0 @@ -#import "ThermalPlugin.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 "thermal-Swift.h" -#endif - -@implementation ThermalPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - [SwiftThermalPlugin registerWithRegistrar:registrar]; -} -@end diff --git a/ios/thermal.podspec b/ios/thermal.podspec index 8d8b25e..fa8ab1f 100644 --- a/ios/thermal.podspec +++ b/ios/thermal.podspec @@ -13,12 +13,12 @@ A new flutter plugin project. s.license = { :file => '../LICENSE' } s.author = { 'Your Company' => 'email@example.com' } s.source = { :path => '.' } - s.source_files = 'Classes/**/*' + s.source_files = 'thermal/Sources/thermal/**/*.swift' s.dependency 'Flutter' - s.platform = :ios, '8.0' + s.platform = :ios, '13.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } s.swift_version = '5.0' - s.resource_bundles = {'thermal' => ['Resources/PrivacyInfo.xcprivacy']} + s.resource_bundles = {'thermal_privacy' => ['thermal/Sources/thermal/PrivacyInfo.xcprivacy']} end diff --git a/ios/thermal/Package.swift b/ios/thermal/Package.swift new file mode 100644 index 0000000..26c3921 --- /dev/null +++ b/ios/thermal/Package.swift @@ -0,0 +1,27 @@ +// swift-tools-version: 5.9 + +import PackageDescription + +let package = Package( + name: "thermal", + platforms: [ + .iOS("13.0") + ], + products: [ + .library(name: "thermal", targets: ["thermal"]) + ], + dependencies: [ + .package(name: "FlutterFramework", path: "../FlutterFramework") + ], + targets: [ + .target( + name: "thermal", + dependencies: [ + .product(name: "FlutterFramework", package: "FlutterFramework") + ], + resources: [ + .process("PrivacyInfo.xcprivacy") + ] + ) + ] +) diff --git a/ios/Resources/PrivacyInfo.xcprivacy b/ios/thermal/Sources/thermal/PrivacyInfo.xcprivacy similarity index 50% rename from ios/Resources/PrivacyInfo.xcprivacy rename to ios/thermal/Sources/thermal/PrivacyInfo.xcprivacy index a1f9119..dca66c0 100644 --- a/ios/Resources/PrivacyInfo.xcprivacy +++ b/ios/thermal/Sources/thermal/PrivacyInfo.xcprivacy @@ -2,13 +2,11 @@ - NSPrivacyAccessedAPITypes - - NSPrivacyCollectedDataTypes - - NSPrivacyTrackingDomains - - NSPrivacyTracking - + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + diff --git a/ios/Classes/SwiftThermalPlugin.swift b/ios/thermal/Sources/thermal/SwiftThermalPlugin.swift similarity index 98% rename from ios/Classes/SwiftThermalPlugin.swift rename to ios/thermal/Sources/thermal/SwiftThermalPlugin.swift index b4ce800..422dc3b 100644 --- a/ios/Classes/SwiftThermalPlugin.swift +++ b/ios/thermal/Sources/thermal/SwiftThermalPlugin.swift @@ -4,7 +4,7 @@ import UIKit @available(iOS 11.0, *) public class SwiftThermalPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { var sink: FlutterEventSink? - + public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { self.sink = events NotificationCenter.default.addObserver( @@ -14,22 +14,21 @@ public class SwiftThermalPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { object: nil) return nil } - + public func onCancel(withArguments arguments: Any?) -> FlutterError? { self.sink = nil return nil } - + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { switch (call.method) { case "getThermalStatus": result(SwiftThermalPlugin.toChannelValue(state: ProcessInfo.processInfo.thermalState)) - break default: result(FlutterMethodNotImplemented) } } - + private static func toChannelValue(state: ProcessInfo.ThermalState) -> Int { switch state { case ProcessInfo.ThermalState.nominal: @@ -44,13 +43,13 @@ public class SwiftThermalPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { return 0 } } - + @objc public func onThermalStateChanged(_ notification: Notification) { if let events = self.sink { events(SwiftThermalPlugin.toChannelValue(state: ProcessInfo.processInfo.thermalState)) } } - + public static func register(with registrar: FlutterPluginRegistrar) { let eventChannel = FlutterEventChannel(name: "thermal/events", binaryMessenger: registrar.messenger()) let methodChannel = FlutterMethodChannel(name: "thermal", binaryMessenger: registrar.messenger()) diff --git a/pubspec.yaml b/pubspec.yaml index 3e0d575..e3ebe92 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,4 +24,4 @@ flutter: package: com.muxable.flutter.thermal pluginClass: ThermalPlugin ios: - pluginClass: ThermalPlugin + pluginClass: SwiftThermalPlugin