From 0f06e1c7f0d7927372b993e7159a22686c161f9e Mon Sep 17 00:00:00 2001 From: Alireza Hajebrahimi <6937697+iarata@users.noreply.github.com> Date: Tue, 18 Aug 2026 00:03:31 +0200 Subject: [PATCH] v5.0.0 --- packages/audio_streamer/CHANGELOG.md | 11 ++ packages/audio_streamer/README.md | 14 ++- packages/audio_streamer/android/build.gradle | 60 --------- .../audio_streamer/android/build.gradle.kts | 52 ++++++++ .../audio_streamer/android/gradle.properties | 3 - .../audio_streamer/android/settings.gradle | 27 ---- .../android/settings.gradle.kts | 1 + .../example/android/app/build.gradle | 72 ----------- .../example/android/app/build.gradle.kts | 44 +++++++ .../android/app/src/debug/AndroidManifest.xml | 1 - .../android/app/src/main/AndroidManifest.xml | 1 + .../audio_streamer_example/MainActivity.kt | 9 +- .../example/android/build.gradle | 18 --- .../example/android/build.gradle.kts | 24 ++++ .../example/android/gradle.properties | 10 +- .../gradle/wrapper/gradle-wrapper.properties | 5 +- .../example/android/settings.gradle | 25 ---- .../example/android/settings.gradle.kts | 26 ++++ .../ios/Flutter/AppFrameworkInfo.plist | 2 - .../example/ios/Flutter/Debug.xcconfig | 1 - .../example/ios/Flutter/Release.xcconfig | 1 - packages/audio_streamer/example/ios/Podfile | 50 -------- .../ios/Runner.xcodeproj/project.pbxproj | 117 +++++------------- .../xcshareddata/xcschemes/Runner.xcscheme | 18 +++ .../contents.xcworkspacedata | 3 - .../example/ios/Runner/AppDelegate.swift | 9 +- .../example/ios/Runner/Info.plist | 29 ++++- packages/audio_streamer/example/pubspec.yaml | 3 +- packages/audio_streamer/ios/Assets/.gitkeep | 0 .../ios/Classes/AudioStreamerPlugin.h | 4 - .../ios/Classes/AudioStreamerPlugin.m | 15 --- .../audio_streamer/ios/audio_streamer.podspec | 15 +-- .../ios/audio_streamer/Package.swift | 28 +++++ .../audio_streamer/PrivacyInfo.xcprivacy | 14 +++ .../SwiftAudioStreamerPlugin.swift | 42 +++++-- packages/audio_streamer/pubspec.yaml | 9 +- packages/noise_meter/pubspec.yaml | 2 +- 37 files changed, 351 insertions(+), 414 deletions(-) delete mode 100644 packages/audio_streamer/android/build.gradle create mode 100644 packages/audio_streamer/android/build.gradle.kts delete mode 100644 packages/audio_streamer/android/gradle.properties delete mode 100644 packages/audio_streamer/android/settings.gradle create mode 100644 packages/audio_streamer/android/settings.gradle.kts delete mode 100644 packages/audio_streamer/example/android/app/build.gradle create mode 100644 packages/audio_streamer/example/android/app/build.gradle.kts delete mode 100644 packages/audio_streamer/example/android/build.gradle create mode 100644 packages/audio_streamer/example/android/build.gradle.kts delete mode 100644 packages/audio_streamer/example/android/settings.gradle create mode 100644 packages/audio_streamer/example/android/settings.gradle.kts delete mode 100644 packages/audio_streamer/example/ios/Podfile delete mode 100644 packages/audio_streamer/ios/Assets/.gitkeep delete mode 100644 packages/audio_streamer/ios/Classes/AudioStreamerPlugin.h delete mode 100644 packages/audio_streamer/ios/Classes/AudioStreamerPlugin.m create mode 100644 packages/audio_streamer/ios/audio_streamer/Package.swift create mode 100644 packages/audio_streamer/ios/audio_streamer/Sources/audio_streamer/PrivacyInfo.xcprivacy rename packages/audio_streamer/ios/{Classes => audio_streamer/Sources/audio_streamer}/SwiftAudioStreamerPlugin.swift (77%) diff --git a/packages/audio_streamer/CHANGELOG.md b/packages/audio_streamer/CHANGELOG.md index 3a7dd938a..e1fe7ef46 100644 --- a/packages/audio_streamer/CHANGELOG.md +++ b/packages/audio_streamer/CHANGELOG.md @@ -1,3 +1,14 @@ +## 5.0.0 + +* **Breaking:** requires Flutter `>=3.44.0` +* **Breaking:** raised the minimum iOS deployment target from 8.0 to 16.0 and the Android `minSdk` from 16 to 24 +* Added Swift Package Manager (SPM) support - Fixes [#1299](https://github.com/cph-cachet/flutter-plugins/issues/1299) +* Added `PrivacyInfo.xcprivacy` privacy manifest +* Updated Android `compileSdk 36` and Java 17 +* Updated `permission_handler: ^13.0.1` +* Updated the example app +* Fix [#975](https://github.com/cph-cachet/flutter-plugins/issues/975) + ## 4.3.0 * Fix issue where stream function made a new thread each time a recording starts - Fixes [#1242](https://github.com/cph-cachet/flutter-plugins/issues/1242) diff --git a/packages/audio_streamer/README.md b/packages/audio_streamer/README.md index 762507ad9..ccdc89511 100644 --- a/packages/audio_streamer/README.md +++ b/packages/audio_streamer/README.md @@ -28,7 +28,9 @@ If editing the `Info.plist` file manually, the entries needed are: ``` -Edit the `Podfile` to include the permission for the microphone: +If your app requests the permission with [`permission_handler`](https://pub.dev/packages/permission_handler) +**and still integrates iOS dependencies with CocoaPods**, edit the `Podfile` to enable the +microphone permission: ```ruby post_install do |installer| @@ -45,6 +47,16 @@ post_install do |installer| end ``` +This step is not needed with Swift Package Manager — `permission_handler_apple` enables the +microphone permission automatically when `NSMicrophoneUsageDescription` is present in +`Info.plist`. + +## Swift Package Manager + +This plugin supports both [Swift Package Manager](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers) +and CocoaPods on iOS. SPM is used automatically on Flutter 3.44 and later; no configuration is +needed. The example app is integrated with SPM only and has no `Podfile`. + ## Using the plugin The plugin works as a singleton and provide a simple `audioStream` to listen to. diff --git a/packages/audio_streamer/android/build.gradle b/packages/audio_streamer/android/build.gradle deleted file mode 100644 index b88355abf..000000000 --- a/packages/audio_streamer/android/build.gradle +++ /dev/null @@ -1,60 +0,0 @@ -group 'plugins.cachet.audio_streamer' -version '1.0-SNAPSHOT' - -buildscript { - ext.kotlin_version = '2.2.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:8.12.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -rootProject.allprojects { - repositories { - google() - mavenCentral() - } -} - -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' - -android { - compileSdkVersion flutter.compileSdkVersion - ndkVersion flutter.ndkVersion - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - minSdkVersion 16 - targetSdkVersion flutter.targetSdkVersion - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - if (project.android.hasProperty("namespace")) { - namespace 'plugins.cachet.audio_streamer' - } -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" -} diff --git a/packages/audio_streamer/android/build.gradle.kts b/packages/audio_streamer/android/build.gradle.kts new file mode 100644 index 000000000..20cf9678c --- /dev/null +++ b/packages/audio_streamer/android/build.gradle.kts @@ -0,0 +1,52 @@ +group = "plugins.cachet.audio_streamer" +version = "5.0.0" + +allprojects { + repositories { + google() + mavenCentral() + } +} + +plugins { + id("com.android.library") +} + +// AGP 9+ has built-in Kotlin support; on older AGP the Kotlin Gradle plugin +// must be applied explicitly. Version is supplied by the consuming app. +// See https://docs.flutter.dev/release/breaking-changes/migrate-to-built-in-kotlin/for-plugin-authors +val agpMajor = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.substringBefore('.').toInt() +if (agpMajor < 9) { + apply(plugin = "org.jetbrains.kotlin.android") +} + +android { + namespace = "plugins.cachet.audio_streamer" + + compileSdk = 36 + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + sourceSets { + getByName("main") { + java.srcDirs("src/main/kotlin") + } + } + + defaultConfig { + minSdk = 24 + } + + lint { + disable += "InvalidPackage" + } +} + +project.extensions.configure(org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension::class.java) { + compilerOptions { + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + } +} diff --git a/packages/audio_streamer/android/gradle.properties b/packages/audio_streamer/android/gradle.properties deleted file mode 100644 index 94adc3a3f..000000000 --- a/packages/audio_streamer/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.useAndroidX=true -android.enableJetifier=true diff --git a/packages/audio_streamer/android/settings.gradle b/packages/audio_streamer/android/settings.gradle deleted file mode 100644 index 4ea03db05..000000000 --- a/packages/audio_streamer/android/settings.gradle +++ /dev/null @@ -1,27 +0,0 @@ -rootProject.name = 'audio_streamer' - -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - }() - - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.2" - id "com.android.application" version "8.12.1" apply false - id "org.jetbrains.kotlin.android" version "2.2.10" apply false -} - -include ":app" \ No newline at end of file diff --git a/packages/audio_streamer/android/settings.gradle.kts b/packages/audio_streamer/android/settings.gradle.kts new file mode 100644 index 000000000..f321ea08c --- /dev/null +++ b/packages/audio_streamer/android/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "audio_streamer" diff --git a/packages/audio_streamer/example/android/app/build.gradle b/packages/audio_streamer/example/android/app/build.gradle deleted file mode 100644 index d58b5b6a4..000000000 --- a/packages/audio_streamer/example/android/app/build.gradle +++ /dev/null @@ -1,72 +0,0 @@ -plugins { - id "com.android.application" - id "kotlin-android" - id "dev.flutter.flutter-gradle-plugin" -} - -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -android { - namespace 'plugins.cachet.audio_streamer_example' - compileSdkVersion flutter.compileSdkVersion - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - - lint { - disable 'InvalidPackage' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "plugins.cachet.audio_streamer_example" - minSdkVersion 28 - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies { - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test:runner:1.5.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' -} diff --git a/packages/audio_streamer/example/android/app/build.gradle.kts b/packages/audio_streamer/example/android/app/build.gradle.kts new file mode 100644 index 000000000..51d1d9cb1 --- /dev/null +++ b/packages/audio_streamer/example/android/app/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.android.application") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "plugins.cachet.audio_streamer_example" + // permission_handler_android 14 requires compiling against API 37, which is + // ahead of Flutter's default (flutter.compileSdkVersion == 36). + compileSdk = 37 + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + defaultConfig { + applicationId = "plugins.cachet.audio_streamer_example" + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.getByName("debug") + } + } +} + +kotlin { + compilerOptions { + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + } +} + +flutter { + source = "../.." +} diff --git a/packages/audio_streamer/example/android/app/src/debug/AndroidManifest.xml b/packages/audio_streamer/example/android/app/src/debug/AndroidManifest.xml index d47484dbb..f880684a6 100644 --- a/packages/audio_streamer/example/android/app/src/debug/AndroidManifest.xml +++ b/packages/audio_streamer/example/android/app/src/debug/AndroidManifest.xml @@ -3,5 +3,4 @@ to allow setting breakpoints, to provide hot reload, etc. --> - diff --git a/packages/audio_streamer/example/android/app/src/main/AndroidManifest.xml b/packages/audio_streamer/example/android/app/src/main/AndroidManifest.xml index b3917be86..116e97d13 100644 --- a/packages/audio_streamer/example/android/app/src/main/AndroidManifest.xml +++ b/packages/audio_streamer/example/android/app/src/main/AndroidManifest.xml @@ -1,4 +1,5 @@ + ("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/packages/audio_streamer/example/android/gradle.properties b/packages/audio_streamer/example/android/gradle.properties index 94c2a5888..e96108cfe 100644 --- a/packages/audio_streamer/example/android/gradle.properties +++ b/packages/audio_streamer/example/android/gradle.properties @@ -1,6 +1,6 @@ -org.gradle.jvmargs=-Xmx1536M +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true -android.enableJetifier=true -android.nonTransitiveRClass=false -android.nonFinalResIds=false - +# This newDsl flag was added by the Flutter template +android.newDsl=false +# This builtInKotlin flag was added by the Flutter template +android.builtInKotlin=false diff --git a/packages/audio_streamer/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/audio_streamer/example/android/gradle/wrapper/gradle-wrapper.properties index ea7573a3d..2d428bfb1 100644 --- a/packages/audio_streamer/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/audio_streamer/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Sun Mar 12 17:19:03 CST 2023 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip distributionPath=wrapper/dists -zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-all.zip diff --git a/packages/audio_streamer/example/android/settings.gradle b/packages/audio_streamer/example/android/settings.gradle deleted file mode 100644 index becc9d1a5..000000000 --- a/packages/audio_streamer/example/android/settings.gradle +++ /dev/null @@ -1,25 +0,0 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - }() - - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.2" - id "com.android.application" version '8.12.1' apply false - id "org.jetbrains.kotlin.android" version "2.2.10" apply false -} - -include ":app" \ No newline at end of file diff --git a/packages/audio_streamer/example/android/settings.gradle.kts b/packages/audio_streamer/example/android/settings.gradle.kts new file mode 100644 index 000000000..c21f0c5b4 --- /dev/null +++ b/packages/audio_streamer/example/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "9.0.1" apply false + id("org.jetbrains.kotlin.android") version "2.3.20" apply false +} + +include(":app") diff --git a/packages/audio_streamer/example/ios/Flutter/AppFrameworkInfo.plist b/packages/audio_streamer/example/ios/Flutter/AppFrameworkInfo.plist index d57061dd6..ab8e063fe 100644 --- a/packages/audio_streamer/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/audio_streamer/example/ios/Flutter/AppFrameworkInfo.plist @@ -20,7 +20,5 @@ ???? CFBundleVersion 1.0 - MinimumOSVersion - 13.0 diff --git a/packages/audio_streamer/example/ios/Flutter/Debug.xcconfig b/packages/audio_streamer/example/ios/Flutter/Debug.xcconfig index e8efba114..592ceee85 100644 --- a/packages/audio_streamer/example/ios/Flutter/Debug.xcconfig +++ b/packages/audio_streamer/example/ios/Flutter/Debug.xcconfig @@ -1,2 +1 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/packages/audio_streamer/example/ios/Flutter/Release.xcconfig b/packages/audio_streamer/example/ios/Flutter/Release.xcconfig index 399e9340e..592ceee85 100644 --- a/packages/audio_streamer/example/ios/Flutter/Release.xcconfig +++ b/packages/audio_streamer/example/ios/Flutter/Release.xcconfig @@ -1,2 +1 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/packages/audio_streamer/example/ios/Podfile b/packages/audio_streamer/example/ios/Podfile deleted file mode 100644 index 4b4b27594..000000000 --- a/packages/audio_streamer/example/ios/Podfile +++ /dev/null @@ -1,50 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '13.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - - target.build_configurations.each do |config| - # You can remove unused permissions here - # for more infomation: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h - # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0' - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ - '$(inherited)', - 'PERMISSION_MICROPHONE=1',] - end - end -end diff --git a/packages/audio_streamer/example/ios/Runner.xcodeproj/project.pbxproj b/packages/audio_streamer/example/ios/Runner.xcodeproj/project.pbxproj index 67cac9f46..2d5057341 100644 --- a/packages/audio_streamer/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/audio_streamer/example/ios/Runner.xcodeproj/project.pbxproj @@ -7,10 +7,10 @@ objects = { /* Begin PBXBuildFile section */ - 008E9881A1762105DD913DBA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EEBE10A0C8DBDCC8DCDB725 /* Pods_Runner.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; 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 */; }; @@ -30,14 +30,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 09B0AB11DA5E0C6B1BCCDC71 /* 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 = ""; }; - 13175BDFE93A1FC3CDEAB105 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 4EEBE10A0C8DBDCC8DCDB725 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; }; + 78DABEA22ED26510000E7860 /* audio_streamer */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = audio_streamer; path = ../../ios/audio_streamer; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; @@ -46,7 +46,6 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - EB683AE4FEDF6FDAF8A5F300 /* 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -54,7 +53,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 008E9881A1762105DD913DBA /* Pods_Runner.framework in Frameworks */, + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -64,24 +63,16 @@ 168765EC234C0FBB14455618 /* Pods */ = { isa = PBXGroup; children = ( - 09B0AB11DA5E0C6B1BCCDC71 /* Pods-Runner.debug.xcconfig */, - 13175BDFE93A1FC3CDEAB105 /* Pods-Runner.release.xcconfig */, - EB683AE4FEDF6FDAF8A5F300 /* Pods-Runner.profile.xcconfig */, ); path = Pods; sourceTree = ""; }; - 2DE9FA3B2CFFEB5BF79D07B4 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 4EEBE10A0C8DBDCC8DCDB725 /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( + 78DABEA22ED26510000E7860 /* audio_streamer */, + 784666492D4C4C64000A1A5F /* FlutterFramework */, + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, @@ -97,7 +88,6 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 168765EC234C0FBB14455618 /* Pods */, - 2DE9FA3B2CFFEB5BF79D07B4 /* Frameworks */, ); sourceTree = ""; }; @@ -139,21 +129,21 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 6D17391BF62DFF7AB8D8C904 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - C8DCEBC0A311A81F291600C2 /* [CP] Embed Pods Frameworks */, - B027207B6AEA34DF4256343D /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( ); name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; @@ -182,6 +172,9 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */, + ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; @@ -222,28 +215,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 6D17391BF62DFF7AB8D8C904 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -259,40 +230,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - B027207B6AEA34DF4256343D /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - C8DCEBC0A311A81F291600C2 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -368,7 +305,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -391,7 +328,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -455,7 +392,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -504,7 +441,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -528,7 +465,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -560,7 +497,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -601,6 +538,20 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "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/packages/audio_streamer/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/audio_streamer/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fc5ae0316..0bd6d4227 100644 --- a/packages/audio_streamer/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/audio_streamer/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -5,6 +5,24 @@ + + + + + + + + + + - - diff --git a/packages/audio_streamer/example/ios/Runner/AppDelegate.swift b/packages/audio_streamer/example/ios/Runner/AppDelegate.swift index b63630348..c30b367ec 100644 --- a/packages/audio_streamer/example/ios/Runner/AppDelegate.swift +++ b/packages/audio_streamer/example/ios/Runner/AppDelegate.swift @@ -1,13 +1,16 @@ -import UIKit import Flutter +import UIKit @main -@objc class AppDelegate: FlutterAppDelegate { +@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/packages/audio_streamer/example/ios/Runner/Info.plist b/packages/audio_streamer/example/ios/Runner/Info.plist index fa415122b..02f27d58f 100644 --- a/packages/audio_streamer/example/ios/Runner/Info.plist +++ b/packages/audio_streamer/example/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable @@ -24,6 +26,29 @@ NSMicrophoneUsageDescription Records audio for cough detection + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + FlutterSceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + UIBackgroundModes audio @@ -47,9 +72,5 @@ UIViewControllerBasedStatusBarAppearance - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - diff --git a/packages/audio_streamer/example/pubspec.yaml b/packages/audio_streamer/example/pubspec.yaml index 723afa99a..7109bb0fc 100644 --- a/packages/audio_streamer/example/pubspec.yaml +++ b/packages/audio_streamer/example/pubspec.yaml @@ -1,6 +1,7 @@ name: audio_streamer_example description: Demonstrates how to use the audio_streamer plugin. publish_to: 'none' +version: 1.0.0 environment: sdk: ">=3.8.1 <4.0.0" @@ -10,7 +11,7 @@ dependencies: flutter: sdk: flutter - permission_handler: ^12.0.0 + permission_handler: ^13.0.1 cupertino_icons: ^1.0.4 dev_dependencies: diff --git a/packages/audio_streamer/ios/Assets/.gitkeep b/packages/audio_streamer/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/audio_streamer/ios/Classes/AudioStreamerPlugin.h b/packages/audio_streamer/ios/Classes/AudioStreamerPlugin.h deleted file mode 100644 index 06f1f2d52..000000000 --- a/packages/audio_streamer/ios/Classes/AudioStreamerPlugin.h +++ /dev/null @@ -1,4 +0,0 @@ -#import - -@interface AudioStreamerPlugin : NSObject -@end diff --git a/packages/audio_streamer/ios/Classes/AudioStreamerPlugin.m b/packages/audio_streamer/ios/Classes/AudioStreamerPlugin.m deleted file mode 100644 index 051e0912e..000000000 --- a/packages/audio_streamer/ios/Classes/AudioStreamerPlugin.m +++ /dev/null @@ -1,15 +0,0 @@ -#import "AudioStreamerPlugin.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 "audio_streamer-Swift.h" -#endif - -@implementation AudioStreamerPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - [SwiftAudioStreamerPlugin registerWithRegistrar:registrar]; -} -@end diff --git a/packages/audio_streamer/ios/audio_streamer.podspec b/packages/audio_streamer/ios/audio_streamer.podspec index 95f6888a0..edf57ac14 100644 --- a/packages/audio_streamer/ios/audio_streamer.podspec +++ b/packages/audio_streamer/ios/audio_streamer.podspec @@ -4,20 +4,21 @@ # Pod::Spec.new do |s| s.name = 'audio_streamer' - s.version = '4.3.0' + s.version = '5.0.0' s.summary = 'Streaming of PCM audio from Android and iOS' s.description = <<-DESC Streaming of PCM audio from Android and iOS DESC - s.homepage = 'http://example.com' s.license = { :file => '../LICENSE' } - s.author = { 'Your Company' => 'email@example.com' } + s.homepage = 'https://carp.dk' + s.author = { 'Copenhagen Research Platform' => 'support@carp.dk' } s.source = { :path => '.' } - s.source_files = 'Classes/**/*' + s.source_files = 'audio_streamer/Sources/audio_streamer/**/*.swift' s.dependency 'Flutter' - s.platform = :ios, '8.0' + s.platform = :ios, '16.0' - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } + # 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 = { 'audio_streamer_privacy' => ['audio_streamer/Sources/audio_streamer/PrivacyInfo.xcprivacy'] } end diff --git a/packages/audio_streamer/ios/audio_streamer/Package.swift b/packages/audio_streamer/ios/audio_streamer/Package.swift new file mode 100644 index 000000000..b3d5f4cc7 --- /dev/null +++ b/packages/audio_streamer/ios/audio_streamer/Package.swift @@ -0,0 +1,28 @@ +// 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: "audio_streamer", + platforms: [ + .iOS("16.0") + ], + products: [ + .library(name: "audio-streamer", targets: ["audio_streamer"]) + ], + dependencies: [ + .package(name: "FlutterFramework", path: "../FlutterFramework") + ], + targets: [ + .target( + name: "audio_streamer", + dependencies: [ + .product(name: "FlutterFramework", package: "FlutterFramework") + ], + resources: [ + .process("PrivacyInfo.xcprivacy") + ] + ) + ] +) diff --git a/packages/audio_streamer/ios/audio_streamer/Sources/audio_streamer/PrivacyInfo.xcprivacy b/packages/audio_streamer/ios/audio_streamer/Sources/audio_streamer/PrivacyInfo.xcprivacy new file mode 100644 index 000000000..a34b7e2e6 --- /dev/null +++ b/packages/audio_streamer/ios/audio_streamer/Sources/audio_streamer/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTrackingDomains + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/packages/audio_streamer/ios/Classes/SwiftAudioStreamerPlugin.swift b/packages/audio_streamer/ios/audio_streamer/Sources/audio_streamer/SwiftAudioStreamerPlugin.swift similarity index 77% rename from packages/audio_streamer/ios/Classes/SwiftAudioStreamerPlugin.swift rename to packages/audio_streamer/ios/audio_streamer/Sources/audio_streamer/SwiftAudioStreamerPlugin.swift index 4a24269f3..d4458ab0a 100644 --- a/packages/audio_streamer/ios/Classes/SwiftAudioStreamerPlugin.swift +++ b/packages/audio_streamer/ios/audio_streamer/Sources/audio_streamer/SwiftAudioStreamerPlugin.swift @@ -40,6 +40,12 @@ public class SwiftAudioStreamerPlugin: NSObject, FlutterPlugin, FlutterStreamHan } @objc func handleInterruption(notification: Notification) { + // AVAudioSession posts interruption notifications on an internal thread, so + // hop onto the platform thread before touching the event sink or the engine. + onPlatformThread { self.handleInterruptionOnPlatformThread(notification) } + } + + private func handleInterruptionOnPlatformThread(_ notification: Notification) { // If no eventSink to emit events to, do nothing (wait) if eventSink == nil { return @@ -66,22 +72,31 @@ public class SwiftAudioStreamerPlugin: NSObject, FlutterPlugin, FlutterStreamHan } default: - eventSink!( + eventSink?( FlutterError( code: "100", message: "Recording was interrupted", details: "Another process interrupted recording.")) } } + // Runs [block] on the platform (main) thread. + // + // Platform channel messages must be sent on the platform thread, but the + // audio tap and the interruption notification both fire on other threads. + // See https://docs.flutter.dev/platform-integration/platform-channels#channels-and-platform-threading + private func onPlatformThread(_ block: @escaping () -> Void) { + if Thread.isMainThread { + block() + } else { + DispatchQueue.main.async(execute: block) + } + } + // Handle stream emitting (Swift => Flutter) private func emitValues(values: [Float]) { - - // If no eventSink to emit events to, do nothing (wait) - if eventSink == nil { - return - } - // Emit values count event to Flutter - eventSink!(values) + // Emit values event to Flutter. The sink is only read on the platform + // thread, so a stream cancelled in the meantime simply drops the buffer. + onPlatformThread { self.eventSink?(values) } } // Event Channel: On Stream Listen @@ -133,10 +148,13 @@ public class SwiftAudioStreamerPlugin: NSObject, FlutterPlugin, FlutterStreamHan try engine.start() } catch { - eventSink!( - FlutterError( - code: "100", message: "Unable to start audio session", details: error.localizedDescription - )) + onPlatformThread { + self.eventSink?( + FlutterError( + code: "100", message: "Unable to start audio session", + details: error.localizedDescription + )) + } } } } diff --git a/packages/audio_streamer/pubspec.yaml b/packages/audio_streamer/pubspec.yaml index 5176cd763..cfb67aa22 100644 --- a/packages/audio_streamer/pubspec.yaml +++ b/packages/audio_streamer/pubspec.yaml @@ -1,14 +1,13 @@ name: audio_streamer description: Streaming of Pulse-code modulation (PCM) audio from Android and iOS -version: 4.3.0 -homepage: https://github.com/cph-cachet/flutter-plugins/tree/master/packages/ +version: 5.0.0 +homepage: https://github.com/carp-dk/flutter-plugins/tree/master/packages/audio_streamer environment: sdk: ">=3.8.1 <4.0.0" - flutter: ">=3.0.0" + flutter: ">=3.44.0" dependencies: - permission_handler: ^12.0.0 flutter: sdk: flutter @@ -18,6 +17,8 @@ dev_dependencies: flutter_lints: any flutter: + config: + enable-swift-package-manager: true plugin: platforms: android: diff --git a/packages/noise_meter/pubspec.yaml b/packages/noise_meter/pubspec.yaml index e24fd2b79..3b7f4cb6d 100644 --- a/packages/noise_meter/pubspec.yaml +++ b/packages/noise_meter/pubspec.yaml @@ -10,7 +10,7 @@ environment: dependencies: flutter: sdk: flutter - audio_streamer: ^4.3.0 + audio_streamer: ^5.0.0 dev_dependencies: flutter_test: