diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml new file mode 100644 index 0000000..4f09eeb --- /dev/null +++ b/.github/workflows/update-readme.yml @@ -0,0 +1,41 @@ +name: Update README + +on: + push: + branches: + - main + paths: + - 'packages/**' + - '.gitmodules' + - 'scripts/update_readme.dart' + workflow_dispatch: + +permissions: + contents: write + +jobs: + update-readme: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: true + + - name: Setup Dart + uses: dart-lang/setup-dart@v1 + + - name: Run update script + run: dart scripts/update_readme.dart + + - name: Commit and Push + run: | + if [ -n "$(git status --porcelain README.md)" ]; then + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add README.md + git commit -m "docs: update README [skip ci]" + git push + else + echo "No changes to README.md" + fi diff --git a/.github/workflows/update-submodules.yml b/.github/workflows/update-submodules.yml new file mode 100644 index 0000000..4529e92 --- /dev/null +++ b/.github/workflows/update-submodules.yml @@ -0,0 +1,45 @@ +name: Update Submodules + +on: + schedule: + - cron: '0 0 * * *' # Runs daily at midnight + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + update-submodules: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - name: Update submodules + run: | + git submodule update --remote --recursive + + - name: Check for changes + id: diff + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "changes=true" >> $GITHUB_OUTPUT + else + echo "changes=false" >> $GITHUB_OUTPUT + fi + + - name: Create Pull Request + if: steps.diff.outputs.changes == 'true' + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore: update submodules" + title: "chore: update submodules" + body: "Automated update of submodules to their latest commits." + branch: update-submodules + base: main + delete-branch: true diff --git a/README.md b/README.md index 74b5e18..ab1843b 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,14 @@ A collection of Flutter packages maintained by @rodydavis. | Package | Description | Version | | :--- | :--- | :--- | +| [app_review](./packages/app_review) | Request and Write Reviews and Open Store Listing for Android and iOS in Flutter. | [![Pub](https://img.shields.io/pub/v/app_review.svg?style=popout)](https://pub.dartlang.org/packages/app_review) | | [breakpoint](./packages/breakpoint) | A Flutter plugin to calculate the material design breakpoints. | [![Pub](https://img.shields.io/pub/v/breakpoint.svg?style=popout)](https://pub.dartlang.org/packages/breakpoint) | | [flutter_sms](./packages/flutter_sms) | A Flutter plugin to send SMS and MMS on iOS and Android. | [![Pub](https://img.shields.io/pub/v/flutter_sms.svg?style=popout)](https://pub.dartlang.org/packages/flutter_sms) | | [flutter_vibrate](./packages/flutter_vibrate) | A Haptic Feedback and Vibration plugin. | [![Pub](https://img.shields.io/pub/v/flutter_vibrate.svg?style=popout)](https://pub.dartlang.org/packages/flutter_vibrate) | | [flutter_whatsnew](./packages/flutter_whatsnew) | A new Flutter package to show updates to users. | [![Pub](https://img.shields.io/pub/v/flutter_whatsnew.svg?style=popout)](https://pub.dartlang.org/packages/flutter_whatsnew) | -| [preact_signals](./packages/signals/packages/preact_signals) | Dart port of Preact.js Signals | [![Pub](https://img.shields.io/pub/v/preact_signals.svg?style=popout)](https://pub.dartlang.org/packages/preact_signals) | -| [signals](./packages/signals/packages/signals) | Reactivity made simple. Do more by doing less. Supports Flutter and any Dart project including HTML/JS, CLI, Shelf Server, VM and more. | [![Pub](https://img.shields.io/pub/v/signals.svg?style=popout)](https://pub.dartlang.org/packages/signals) | -| [signals_core](./packages/signals/packages/signals_core) | The signals library exposes four core functions which are the building blocks to model any business logic you can think of. | [![Pub](https://img.shields.io/pub/v/signals_core.svg?style=popout)](https://pub.dartlang.org/packages/signals_core) | -| [signals_flutter](./packages/signals/packages/signals_flutter) | The signals library exposes four core functions which are the building blocks to model any business logic you can think of. | [![Pub](https://img.shields.io/pub/v/signals_flutter.svg?style=popout)](https://pub.dartlang.org/packages/signals_flutter) | -| [signals_hooks](./packages/signals/packages/signals_hooks) | flutter_hooks bindings for signals | [![Pub](https://img.shields.io/pub/v/signals_hooks.svg?style=popout)](https://pub.dartlang.org/packages/signals_hooks) | -| [signals_lint](./packages/signals/packages/signals_lint) | linter and developer tool for signals | [![Pub](https://img.shields.io/pub/v/signals_lint.svg?style=popout)](https://pub.dartlang.org/packages/signals_lint) | +| [preact_signals](https://github.com/rodydavis/signals.dart/tree/main/packages/preact_signals) | Dart port of Preact.js Signals | [![Pub](https://img.shields.io/pub/v/preact_signals.svg?style=popout)](https://pub.dartlang.org/packages/preact_signals) | +| [signals](https://github.com/rodydavis/signals.dart/tree/main/packages/signals) | Reactivity made simple. Do more by doing less. Supports Flutter and any Dart project including HTML/JS, CLI, Shelf Server, VM and more. | [![Pub](https://img.shields.io/pub/v/signals.svg?style=popout)](https://pub.dartlang.org/packages/signals) | +| [signals_core](https://github.com/rodydavis/signals.dart/tree/main/packages/signals_core) | The signals library exposes four core functions which are the building blocks to model any business logic you can think of. | [![Pub](https://img.shields.io/pub/v/signals_core.svg?style=popout)](https://pub.dartlang.org/packages/signals_core) | +| [signals_flutter](https://github.com/rodydavis/signals.dart/tree/main/packages/signals_flutter) | The signals library exposes four core functions which are the building blocks to model any business logic you can think of. | [![Pub](https://img.shields.io/pub/v/signals_flutter.svg?style=popout)](https://pub.dartlang.org/packages/signals_flutter) | +| [signals_hooks](https://github.com/rodydavis/signals.dart/tree/main/packages/signals_hooks) | flutter_hooks bindings for signals | [![Pub](https://img.shields.io/pub/v/signals_hooks.svg?style=popout)](https://pub.dartlang.org/packages/signals_hooks) | +| [signals_lint](https://github.com/rodydavis/signals.dart/tree/main/packages/signals_lint) | linter and developer tool for signals | [![Pub](https://img.shields.io/pub/v/signals_lint.svg?style=popout)](https://pub.dartlang.org/packages/signals_lint) | diff --git a/packages/app_review/CHANGELOG.md b/packages/app_review/CHANGELOG.md index 4d20b48..570f1ae 100644 --- a/packages/app_review/CHANGELOG.md +++ b/packages/app_review/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.2.0 +* Update SDK constraints (Dart ^3.0.0, Flutter >=3.10.0) +* Update dependencies (package_info_plus ^9.0.0, url_launcher ^6.3.0, http ^1.2.0) +* Fix example app lint errors +* Fix iOS Store Page and Write Review URLs (use apps.apple.com) + ## 2.1.2 * Upgrading dependencies diff --git a/packages/app_review/example/.metadata b/packages/app_review/example/.metadata index de745e4..83b34eb 100644 --- a/packages/app_review/example/.metadata +++ b/packages/app_review/example/.metadata @@ -1,11 +1,11 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled. +# This file should be version controlled and should not be manually edited. version: - revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - channel: stable + revision: "f6ff1529fd6d8af5f706051d9251ac9231c83407" + channel: "stable" project_type: app @@ -13,26 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 + base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 - platform: android - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 + base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 - platform: ios - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 + base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 - platform: linux - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 + base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 - platform: macos - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 + base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 - platform: web - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 + base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 - platform: windows - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 + base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407 # User provided section diff --git a/packages/app_review/example/android/.gitignore b/packages/app_review/example/android/.gitignore index bc2100d..be3943c 100644 --- a/packages/app_review/example/android/.gitignore +++ b/packages/app_review/example/android/.gitignore @@ -5,3 +5,10 @@ gradle-wrapper.jar /gradlew.bat /local.properties GeneratedPluginRegistrant.java +.cxx/ + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/packages/app_review/example/android/app/build.gradle b/packages/app_review/example/android/app/build.gradle deleted file mode 100644 index 9bd9ba0..0000000 --- a/packages/app_review/example/android/app/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 33 - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.example" - minSdkVersion 19 - targetSdkVersion 33 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - 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 { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' -} diff --git a/packages/app_review/example/android/app/build.gradle.kts b/packages/app_review/example/android/app/build.gradle.kts new file mode 100644 index 0000000..859db0b --- /dev/null +++ b/packages/app_review/example/android/app/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.android.application") + id("kotlin-android") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.example.app_review_example" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.app_review_example" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + 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") + } + } +} + +flutter { + source = "../.." +} diff --git a/packages/app_review/example/android/app/src/debug/AndroidManifest.xml b/packages/app_review/example/android/app/src/debug/AndroidManifest.xml index c208884..399f698 100644 --- a/packages/app_review/example/android/app/src/debug/AndroidManifest.xml +++ b/packages/app_review/example/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/packages/app_review/example/android/app/src/main/AndroidManifest.xml b/packages/app_review/example/android/app/src/main/AndroidManifest.xml index 1e4a566..f928ba6 100644 --- a/packages/app_review/example/android/app/src/main/AndroidManifest.xml +++ b/packages/app_review/example/android/app/src/main/AndroidManifest.xml @@ -1,21 +1,16 @@ - - + - @@ -45,4 +31,15 @@ android:name="flutterEmbedding" android:value="2" /> + + + + + + + diff --git a/packages/app_review/example/android/app/src/main/kotlin/com/example/app_review_example/MainActivity.kt b/packages/app_review/example/android/app/src/main/kotlin/com/example/app_review_example/MainActivity.kt new file mode 100644 index 0000000..5381411 --- /dev/null +++ b/packages/app_review/example/android/app/src/main/kotlin/com/example/app_review_example/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.app_review_example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/packages/app_review/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/packages/app_review/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt deleted file mode 100644 index 1656503..0000000 --- a/packages/app_review/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.example - -import androidx.annotation.NonNull; -import io.flutter.embedding.android.FlutterActivity -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugins.GeneratedPluginRegistrant - -class MainActivity: FlutterActivity() { - override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { - GeneratedPluginRegistrant.registerWith(flutterEngine); - } -} diff --git a/packages/app_review/example/android/app/src/main/res/values/styles.xml b/packages/app_review/example/android/app/src/main/res/values/styles.xml index 1f83a33..cb1ef88 100644 --- a/packages/app_review/example/android/app/src/main/res/values/styles.xml +++ b/packages/app_review/example/android/app/src/main/res/values/styles.xml @@ -1,18 +1,18 @@ - - - diff --git a/packages/app_review/example/android/app/src/profile/AndroidManifest.xml b/packages/app_review/example/android/app/src/profile/AndroidManifest.xml index c208884..399f698 100644 --- a/packages/app_review/example/android/app/src/profile/AndroidManifest.xml +++ b/packages/app_review/example/android/app/src/profile/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/packages/app_review/example/android/build.gradle b/packages/app_review/example/android/build.gradle deleted file mode 100644 index 4256f91..0000000 --- a/packages/app_review/example/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - ext.kotlin_version = '1.6.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/packages/app_review/example/android/build.gradle.kts b/packages/app_review/example/android/build.gradle.kts new file mode 100644 index 0000000..dbee657 --- /dev/null +++ b/packages/app_review/example/android/build.gradle.kts @@ -0,0 +1,24 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = + rootProject.layout.buildDirectory + .dir("../../build") + .get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/packages/app_review/example/android/gradle.properties b/packages/app_review/example/android/gradle.properties index 38c8d45..fbee1d8 100644 --- a/packages/app_review/example/android/gradle.properties +++ b/packages/app_review/example/android/gradle.properties @@ -1,4 +1,2 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true -android.enableJetifier=true diff --git a/packages/app_review/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/app_review/example/android/gradle/wrapper/gradle-wrapper.properties index bc6a58a..e4ef43f 100644 --- a/packages/app_review/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/app_review/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip diff --git a/packages/app_review/example/android/settings.gradle b/packages/app_review/example/android/settings.gradle deleted file mode 100644 index 5a2f14f..0000000 --- a/packages/app_review/example/android/settings.gradle +++ /dev/null @@ -1,15 +0,0 @@ -include ':app' - -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() - -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} diff --git a/packages/app_review/example/android/settings.gradle.kts b/packages/app_review/example/android/settings.gradle.kts new file mode 100644 index 0000000..ca7fe06 --- /dev/null +++ b/packages/app_review/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 "8.11.1" apply false + id("org.jetbrains.kotlin.android") version "2.2.20" apply false +} + +include(":app") diff --git a/packages/app_review/example/ios/Flutter/AppFrameworkInfo.plist b/packages/app_review/example/ios/Flutter/AppFrameworkInfo.plist index 9625e10..1dc6cf7 100644 --- a/packages/app_review/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/app_review/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 13.0 diff --git a/packages/app_review/example/ios/Podfile b/packages/app_review/example/ios/Podfile index fdcc671..620e46e 100644 --- a/packages/app_review/example/ios/Podfile +++ b/packages/app_review/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '11.0' +# platform :ios, '13.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -29,7 +29,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do diff --git a/packages/app_review/example/ios/Podfile.lock b/packages/app_review/example/ios/Podfile.lock new file mode 100644 index 0000000..7a5c6a5 --- /dev/null +++ b/packages/app_review/example/ios/Podfile.lock @@ -0,0 +1,34 @@ +PODS: + - app_review (1.0.1): + - Flutter + - Flutter (1.0.0) + - package_info_plus (0.4.5): + - Flutter + - url_launcher_ios (0.0.1): + - Flutter + +DEPENDENCIES: + - app_review (from `.symlinks/plugins/app_review/ios`) + - Flutter (from `Flutter`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + +EXTERNAL SOURCES: + app_review: + :path: ".symlinks/plugins/app_review/ios" + Flutter: + :path: Flutter + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + +SPEC CHECKSUMS: + app_review: e2799b306b6460ca7e5f4df53f4f1a1473456ef0 + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 + url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b + +PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e + +COCOAPODS: 1.16.2 diff --git a/packages/app_review/example/ios/Runner.xcodeproj/project.pbxproj b/packages/app_review/example/ios/Runner.xcodeproj/project.pbxproj index 1973328..308d17d 100644 --- a/packages/app_review/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/app_review/example/ios/Runner.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 092B79500C28C00B3450B94C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 488DAEED41FE4CCC38DB05DA /* Pods_Runner.framework */; }; + 0C6E4A6F6EC71772E333471D /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28698D6A016CFD6813E41936 /* Pods_RunnerTests.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; @@ -14,8 +16,6 @@ 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 */; }; - B961EB3EB081A5305AC00866 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E01AECBBC70188617CD92D21 /* Pods_RunnerTests.framework */; }; - FEC50D01DC6AF22D567C979E /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15ED1195D8732D2C48135E81 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -42,17 +42,21 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0EEBA57C33962CA96C36FCF4 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 125121F4DD0B3FB4A20215BA /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.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 = ""; }; - 15ED1195D8732D2C48135E81 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 28698D6A016CFD6813E41936 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 411440D2CD22237725EC54A7 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 488DAEED41FE4CCC38DB05DA /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 505FA7E1DD243F1E7CAA3B75 /* 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 = ""; }; 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 = ""; }; - 75513F7E03C2A94857CF0035 /* 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 = ""; }; + 779668BF5DEAAD286540FC29 /* 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 = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 9133CC747618CF9D88DFDE97 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.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 = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -60,27 +64,23 @@ 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 = ""; }; - 9F62DFC38AED5F22E0EADDBC /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; - A1F6A258E7BFEFD6B2D4599B /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - B65E080503664380E7D789C4 /* 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 = ""; }; - CF043C693FD91482A91E8E8D /* 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 = ""; }; - E01AECBBC70188617CD92D21 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E20044C05259DFE0D694EC38 /* 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 2F47AEFBEA98D5F0BA3239D4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B961EB3EB081A5305AC00866 /* Pods_RunnerTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FEC50D01DC6AF22D567C979E /* Pods_Runner.framework in Frameworks */, + 092B79500C28C00B3450B94C /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D6A37C58D92C5BBDBDD6F3AC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C6E4A6F6EC71772E333471D /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -95,25 +95,11 @@ path = RunnerTests; sourceTree = ""; }; - 3389700BA5BC1CF220463F55 /* Pods */ = { + 966C8C6DF90DF64AB93EB815 /* Frameworks */ = { isa = PBXGroup; children = ( - CF043C693FD91482A91E8E8D /* Pods-Runner.debug.xcconfig */, - 75513F7E03C2A94857CF0035 /* Pods-Runner.release.xcconfig */, - B65E080503664380E7D789C4 /* Pods-Runner.profile.xcconfig */, - A1F6A258E7BFEFD6B2D4599B /* Pods-RunnerTests.debug.xcconfig */, - 9133CC747618CF9D88DFDE97 /* Pods-RunnerTests.release.xcconfig */, - 9F62DFC38AED5F22E0EADDBC /* Pods-RunnerTests.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; - 53B082F1202DF6A4E25FAAB4 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 15ED1195D8732D2C48135E81 /* Pods_Runner.framework */, - E01AECBBC70188617CD92D21 /* Pods_RunnerTests.framework */, + 488DAEED41FE4CCC38DB05DA /* Pods_Runner.framework */, + 28698D6A016CFD6813E41936 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -136,8 +122,8 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, - 3389700BA5BC1CF220463F55 /* Pods */, - 53B082F1202DF6A4E25FAAB4 /* Frameworks */, + A4D7451AA37BE95C67632FBC /* Pods */, + 966C8C6DF90DF64AB93EB815 /* Frameworks */, ); sourceTree = ""; }; @@ -165,6 +151,20 @@ path = Runner; sourceTree = ""; }; + A4D7451AA37BE95C67632FBC /* Pods */ = { + isa = PBXGroup; + children = ( + E20044C05259DFE0D694EC38 /* Pods-Runner.debug.xcconfig */, + 505FA7E1DD243F1E7CAA3B75 /* Pods-Runner.release.xcconfig */, + 779668BF5DEAAD286540FC29 /* Pods-Runner.profile.xcconfig */, + 411440D2CD22237725EC54A7 /* Pods-RunnerTests.debug.xcconfig */, + 125121F4DD0B3FB4A20215BA /* Pods-RunnerTests.release.xcconfig */, + 0EEBA57C33962CA96C36FCF4 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -172,10 +172,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( - 785BCB1B2DF5B7FA35BB1EE6 /* [CP] Check Pods Manifest.lock */, + D5D6181A66E041D698C0FE7B /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, - 2F47AEFBEA98D5F0BA3239D4 /* Frameworks */, + D6A37C58D92C5BBDBDD6F3AC /* Frameworks */, ); buildRules = ( ); @@ -191,14 +191,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 9F3CB46B46F9C6848AAB662F /* [CP] Check Pods Manifest.lock */, + FC42A54FAB8F06C3CA3A3F07 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 0F5F1F3B9EDDA3D95CCC6036 /* [CP] Embed Pods Frameworks */, + 2950327A593159085DC7408B /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -215,7 +215,8 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 331C8080294A63A400263BE5 = { @@ -269,7 +270,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 0F5F1F3B9EDDA3D95CCC6036 /* [CP] Embed Pods Frameworks */ = { + 2950327A593159085DC7408B /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -302,7 +303,22 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 785BCB1B2DF5B7FA35BB1EE6 /* [CP] Check Pods Manifest.lock */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + D5D6181A66E041D698C0FE7B /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -324,22 +340,7 @@ 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; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - 9F3CB46B46F9C6848AAB662F /* [CP] Check Pods Manifest.lock */ = { + FC42A54FAB8F06C3CA3A3F07 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -415,6 +416,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -444,6 +446,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -452,7 +455,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -468,14 +471,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = RVK2U9W9MX; + DEVELOPMENT_TEAM = 9FK3425VTA; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -485,14 +488,14 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A1F6A258E7BFEFD6B2D4599B /* Pods-RunnerTests.debug.xcconfig */; + baseConfigurationReference = 411440D2CD22237725EC54A7 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -503,14 +506,14 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9133CC747618CF9D88DFDE97 /* Pods-RunnerTests.release.xcconfig */; + baseConfigurationReference = 125121F4DD0B3FB4A20215BA /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -519,14 +522,14 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9F62DFC38AED5F22E0EADDBC /* Pods-RunnerTests.profile.xcconfig */; + baseConfigurationReference = 0EEBA57C33962CA96C36FCF4 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -537,6 +540,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -566,6 +570,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -580,7 +585,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -592,6 +597,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -621,6 +627,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -629,7 +636,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -647,14 +654,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = RVK2U9W9MX; + DEVELOPMENT_TEAM = 9FK3425VTA; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -670,14 +677,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = RVK2U9W9MX; + DEVELOPMENT_TEAM = 9FK3425VTA; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/packages/app_review/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/app_review/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index e42adcb..e3773d4 100644 --- a/packages/app_review/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/app_review/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ diff --git a/packages/app_review/example/ios/Runner/AppDelegate.swift b/packages/app_review/example/ios/Runner/AppDelegate.swift index 70693e4..6266644 100644 --- a/packages/app_review/example/ios/Runner/AppDelegate.swift +++ b/packages/app_review/example/ios/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ -import UIKit import Flutter +import UIKit -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/packages/app_review/example/ios/Runner/Info.plist b/packages/app_review/example/ios/Runner/Info.plist index 7f55346..1bdb2a8 100644 --- a/packages/app_review/example/ios/Runner/Info.plist +++ b/packages/app_review/example/ios/Runner/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Example + App Review Example CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - example + app_review_example CFBundlePackageType APPL CFBundleShortVersionString @@ -41,8 +41,6 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIViewControllerBasedStatusBarAppearance - CADisableMinimumFrameDurationOnPhone UIApplicationSupportsIndirectInputEvents diff --git a/packages/app_review/example/lib/main.dart b/packages/app_review/example/lib/main.dart index a3c30f6..d5e93f0 100644 --- a/packages/app_review/example/lib/main.dart +++ b/packages/app_review/example/lib/main.dart @@ -1,100 +1,277 @@ import 'package:app_review/app_review.dart'; import 'package:flutter/material.dart'; -import 'dart:io' show Platform; -import 'package:flutter/foundation.dart'; - -// The existing imports -// !! Keep your existing impots here !! - -/// main is entry point of Flutter application void main() { - // Desktop platforms aren't a valid platform. - if (!kIsWeb) _setTargetPlatformForDesktop(); - return runApp(MyApp()); + runApp(const MyApp()); } -/// If the current platform is desktop, override the default platform to -/// a supported platform (iOS for macOS, Android for Linux and Windows). -/// Otherwise, do nothing. -void _setTargetPlatformForDesktop() { - TargetPlatform? targetPlatform; - if (Platform.isMacOS) { - targetPlatform = TargetPlatform.iOS; - } else if (Platform.isLinux || Platform.isWindows) { - targetPlatform = TargetPlatform.android; - } - if (targetPlatform != null) { - debugDefaultTargetPlatformOverride = targetPlatform; - } -} - -class MyApp extends StatefulWidget { - @override - _MyAppState createState() => new _MyAppState(); -} - -class _MyAppState extends State { - @override - void initState() { - super.initState(); - AppReview.getAppID.then(log); - } - - String appID = ""; - String output = ""; +class MyApp extends StatelessWidget { + const MyApp({super.key}); @override Widget build(BuildContext context) { - return new MaterialApp( - home: new Scaffold( - appBar: new AppBar(title: const Text('App Review')), - body: new SingleChildScrollView( - child: new ListBody( - children: [ - new Container( - height: 40.0, + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + useMaterial3: true, + colorSchemeSeed: Colors.blueAccent, + brightness: Brightness.light, + ), + darkTheme: ThemeData( + useMaterial3: true, + colorSchemeSeed: Colors.blueAccent, + brightness: Brightness.dark, + ), + home: const HomePage(), + ); + } +} + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + @override + void initState() { + super.initState(); + AppReview.getAppID.then((onValue) { + setState(() { + appID = onValue ?? ''; + }); + log(onValue); + }); + } + + String appID = ""; + final List _logs = []; + + void log(String? message) { + if (message != null) { + setState(() { + _logs.insert(0, message); + }); + debugPrint(message); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: CustomScrollView( + slivers: [ + SliverAppBar.large( + title: const Text('App Review'), + centerTitle: true, + ), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildInfoCard( + context, + title: 'App ID', + subtitle: appID.isEmpty ? 'Loading...' : appID, + icon: Icons.info_outline, + onTap: () { + AppReview.getAppID.then(log); + }, + ), + const SizedBox(height: 16), + Text( + 'Actions', + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8), + _buildActionCard( + context, + title: 'View Store Page', + subtitle: 'Open the app store listing for this app', + icon: Icons.storefront, + color: Colors.orange, + onTap: () async { + final id = await AppReview.getIosAppId(); + if (id == null || id.isEmpty) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'App not found in store. Using Apple Developer App for testing.'), + ), + ); + } + // Use Apple Developer App ID for testing + // https://apps.apple.com/us/app/apple-developer/id640199958 + AppReview.openAppStore( + fallbackUrl: + 'https://apps.apple.com/us/app/apple-developer/id640199958', + ).then(log); + } else { + AppReview.storeListing.then(log); + } + }, + ), + const SizedBox(height: 12), + _buildActionCard( + context, + title: 'Request Review', + subtitle: 'Ask the user to rate the app', + icon: Icons.star_rate_rounded, + color: Colors.amber, + onTap: () { + AppReview.requestReview.then(log); + }, + ), + const SizedBox(height: 12), + _buildActionCard( + context, + title: 'Write a New Review', + subtitle: 'Navigate to the review page', + icon: Icons.rate_review_outlined, + color: Colors.green, + onTap: () async { + final id = await AppReview.getIosAppId(); + if (id == null || id.isEmpty) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'App not found in store. Using Apple Developer App for testing.'), + ), + ); + } + // Use Apple Developer App ID for testing + AppReview.openIosReview( + appId: '640199958', + compose: true, + ).then(log); + } else { + AppReview.writeReview.then(log); + } + }, + ), + const SizedBox(height: 24), + Text( + 'Log Output', + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8), + Container( + height: 200, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: Theme.of(context).colorScheme.outlineVariant, + ), + ), + child: _logs.isEmpty + ? Center( + child: Text( + 'No logs yet', + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + ), + ), + ) + : ListView.separated( + padding: const EdgeInsets.all(8), + itemCount: _logs.length, + separatorBuilder: (context, index) => + const Divider(height: 1), + itemBuilder: (context, index) { + return ListTile( + dense: true, + title: Text( + _logs[index], + style: TextStyle( + fontFamily: 'monospace', + fontSize: 12, + color: + Theme.of(context).colorScheme.onSurface, + ), + ), + leading: const Icon(Icons.code, size: 16), + ); + }, + ), + ), + ], ), - new ListTile( - leading: const Icon(Icons.info), - title: const Text('App ID'), - subtitle: new Text(appID), - onTap: () { - AppReview.getAppID.then(log); - }, + ), + ), + ], + ), + ); + } + + Widget _buildInfoCard( + BuildContext context, { + required String title, + required String subtitle, + required IconData icon, + required VoidCallback onTap, + }) { + return Card( + elevation: 0, + color: Theme.of(context).colorScheme.secondaryContainer, + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(12), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + children: [ + Icon( + icon, + color: Theme.of(context).colorScheme.onSecondaryContainer, + size: 28, ), - const Divider(height: 20.0), - new ListTile( - leading: const Icon( - Icons.shop, + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.labelLarge?.copyWith( + color: Theme.of(context) + .colorScheme + .onSecondaryContainer + .withValues(alpha: 0.8), + ), + ), + const SizedBox(height: 4), + Text( + subtitle, + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: Theme.of(context) + .colorScheme + .onSecondaryContainer, + fontWeight: FontWeight.bold, + ), + ), + ], ), - title: const Text('View Store Page'), - onTap: () { - AppReview.storeListing.then(log); - }, ), - const Divider(height: 20.0), - new ListTile( - leading: const Icon( - Icons.star, - ), - title: const Text('Request Review'), - onTap: () { - AppReview.requestReview.then(log); - }, + Icon( + Icons.copy, + size: 18, + color: Theme.of(context) + .colorScheme + .onSecondaryContainer + .withValues(alpha: 0.5), ), - const Divider(height: 20.0), - new ListTile( - leading: const Icon( - Icons.note_add, - ), - title: const Text('Write a New Review'), - onTap: () { - AppReview.writeReview.then(log); - }, - ), - const Divider(height: 20.0), - new ListTile(title: new Text(output)), ], ), ), @@ -102,12 +279,72 @@ class _MyAppState extends State { ); } - void log(String? message) { - if (message != null) { - setState(() { - output = message; - }); - print(message); - } + Widget _buildActionCard( + BuildContext context, { + required String title, + required String subtitle, + required IconData icon, + required Color color, + required VoidCallback onTap, + }) { + return Card( + elevation: 2, + shadowColor: Colors.transparent, + shape: RoundedRectangleBorder( + side: BorderSide( + color: Theme.of(context).colorScheme.outlineVariant, + ), + borderRadius: BorderRadius.circular(12), + ), + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(12), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + children: [ + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: color.withValues(alpha: 0.1), + shape: BoxShape.circle, + ), + child: Icon( + icon, + color: color, + size: 24, + ), + ), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + color: Theme.of(context).colorScheme.outline, + ), + ), + const SizedBox(height: 2), + Text( + subtitle, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.outline, + ), + ), + ], + ), + ), + Icon( + Icons.chevron_right, + color: Theme.of(context).colorScheme.outline, + ), + ], + ), + ), + ), + ); } } diff --git a/packages/app_review/example/linux/CMakeLists.txt b/packages/app_review/example/linux/CMakeLists.txt index d67bd4e..53d5a23 100644 --- a/packages/app_review/example/linux/CMakeLists.txt +++ b/packages/app_review/example/linux/CMakeLists.txt @@ -1,13 +1,13 @@ # Project-level configuration. -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. -set(BINARY_NAME "example") +set(BINARY_NAME "app_review_example") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID -set(APPLICATION_ID "com.example.example") +set(APPLICATION_ID "com.example.app_review_example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. @@ -54,25 +54,8 @@ add_subdirectory(${FLUTTER_MANAGED_DIR}) find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) -add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") - -# Define the application target. To change its name, change BINARY_NAME above, -# not the value here, or `flutter run` will no longer work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} - "main.cc" - "my_application.cc" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add dependency libraries. Add any application-specific dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter) -target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) @@ -123,6 +106,12 @@ foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) COMPONENT Runtime) endforeach(bundled_library) +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") diff --git a/packages/app_review/example/linux/runner/CMakeLists.txt b/packages/app_review/example/linux/runner/CMakeLists.txt new file mode 100644 index 0000000..e97dabc --- /dev/null +++ b/packages/app_review/example/linux/runner/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.13) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the application ID. +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") diff --git a/packages/app_review/example/linux/main.cc b/packages/app_review/example/linux/runner/main.cc similarity index 100% rename from packages/app_review/example/linux/main.cc rename to packages/app_review/example/linux/runner/main.cc diff --git a/packages/app_review/example/linux/my_application.cc b/packages/app_review/example/linux/runner/my_application.cc similarity index 56% rename from packages/app_review/example/linux/my_application.cc rename to packages/app_review/example/linux/runner/my_application.cc index 0ba8f43..53cbc6e 100644 --- a/packages/app_review/example/linux/my_application.cc +++ b/packages/app_review/example/linux/runner/my_application.cc @@ -14,6 +14,11 @@ struct _MyApplication { G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) +// Called when first Flutter frame received. +static void first_frame_cb(MyApplication* self, FlView* view) { + gtk_widget_show(gtk_widget_get_toplevel(GTK_WIDGET(view))); +} + // Implements GApplication::activate. static void my_application_activate(GApplication* application) { MyApplication* self = MY_APPLICATION(application); @@ -40,39 +45,52 @@ static void my_application_activate(GApplication* application) { if (use_header_bar) { GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "example"); + gtk_header_bar_set_title(header_bar, "app_review_example"); gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); } else { - gtk_window_set_title(window, "example"); + gtk_window_set_title(window, "app_review_example"); } gtk_window_set_default_size(window, 1280, 720); - gtk_widget_show(GTK_WIDGET(window)); g_autoptr(FlDartProject) project = fl_dart_project_new(); - fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + fl_dart_project_set_dart_entrypoint_arguments( + project, self->dart_entrypoint_arguments); FlView* view = fl_view_new(project); + GdkRGBA background_color; + // Background defaults to black, override it here if necessary, e.g. #00000000 + // for transparent. + gdk_rgba_parse(&background_color, "#000000"); + fl_view_set_background_color(view, &background_color); gtk_widget_show(GTK_WIDGET(view)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + // Show the window when Flutter renders. + // Requires the view to be realized so we can start rendering. + g_signal_connect_swapped(view, "first-frame", G_CALLBACK(first_frame_cb), + self); + gtk_widget_realize(GTK_WIDGET(view)); + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); gtk_widget_grab_focus(GTK_WIDGET(view)); } // Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { +static gboolean my_application_local_command_line(GApplication* application, + gchar*** arguments, + int* exit_status) { MyApplication* self = MY_APPLICATION(application); // Strip out the first argument as it is the binary name. self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); g_autoptr(GError) error = nullptr; if (!g_application_register(application, nullptr, &error)) { - g_warning("Failed to register: %s", error->message); - *exit_status = 1; - return TRUE; + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; } g_application_activate(application); @@ -81,6 +99,24 @@ static gboolean my_application_local_command_line(GApplication* application, gch return TRUE; } +// Implements GApplication::startup. +static void my_application_startup(GApplication* application) { + // MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application startup. + + G_APPLICATION_CLASS(my_application_parent_class)->startup(application); +} + +// Implements GApplication::shutdown. +static void my_application_shutdown(GApplication* application) { + // MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application shutdown. + + G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application); +} + // Implements GObject::dispose. static void my_application_dispose(GObject* object) { MyApplication* self = MY_APPLICATION(object); @@ -90,15 +126,23 @@ static void my_application_dispose(GObject* object) { static void my_application_class_init(MyApplicationClass* klass) { G_APPLICATION_CLASS(klass)->activate = my_application_activate; - G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_APPLICATION_CLASS(klass)->local_command_line = + my_application_local_command_line; + G_APPLICATION_CLASS(klass)->startup = my_application_startup; + G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown; G_OBJECT_CLASS(klass)->dispose = my_application_dispose; } static void my_application_init(MyApplication* self) {} MyApplication* my_application_new() { + // Set the program name to the application ID, which helps various systems + // like GTK and desktop environments map this running application to its + // corresponding .desktop file. This ensures better integration by allowing + // the application to be recognized beyond its binary name. + g_set_prgname(APPLICATION_ID); + return MY_APPLICATION(g_object_new(my_application_get_type(), - "application-id", APPLICATION_ID, - "flags", G_APPLICATION_NON_UNIQUE, - nullptr)); + "application-id", APPLICATION_ID, "flags", + G_APPLICATION_NON_UNIQUE, nullptr)); } diff --git a/packages/app_review/example/linux/my_application.h b/packages/app_review/example/linux/runner/my_application.h similarity index 70% rename from packages/app_review/example/linux/my_application.h rename to packages/app_review/example/linux/runner/my_application.h index 72271d5..db16367 100644 --- a/packages/app_review/example/linux/my_application.h +++ b/packages/app_review/example/linux/runner/my_application.h @@ -3,7 +3,10 @@ #include -G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, +G_DECLARE_FINAL_TYPE(MyApplication, + my_application, + MY, + APPLICATION, GtkApplication) /** diff --git a/packages/app_review/example/macos/.gitignore b/packages/app_review/example/macos/.gitignore index d2fd377..746adbb 100644 --- a/packages/app_review/example/macos/.gitignore +++ b/packages/app_review/example/macos/.gitignore @@ -3,4 +3,5 @@ **/Pods/ # Xcode-related +**/dgph **/xcuserdata/ diff --git a/packages/app_review/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/app_review/example/macos/Flutter/Flutter-Debug.xcconfig index 785633d..4b81f9b 100644 --- a/packages/app_review/example/macos/Flutter/Flutter-Debug.xcconfig +++ b/packages/app_review/example/macos/Flutter/Flutter-Debug.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/app_review/example/macos/Flutter/Flutter-Release.xcconfig b/packages/app_review/example/macos/Flutter/Flutter-Release.xcconfig index 5fba960..5caa9d1 100644 --- a/packages/app_review/example/macos/Flutter/Flutter-Release.xcconfig +++ b/packages/app_review/example/macos/Flutter/Flutter-Release.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/app_review/example/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/app_review/example/macos/Flutter/GeneratedPluginRegistrant.swift index 744bfe9..220cc08 100644 --- a/packages/app_review/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/packages/app_review/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,6 @@ import package_info_plus import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/packages/app_review/example/macos/Podfile b/packages/app_review/example/macos/Podfile index d60ec71..ff5ddb3 100644 --- a/packages/app_review/example/macos/Podfile +++ b/packages/app_review/example/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.15' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -9,74 +9,34 @@ project 'Runner', { 'Release' => :release, } -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', '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 - pods_ary = [] - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) { |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - pods_ary.push({:name => podname, :path => podpath}); - else - puts "Invalid plugin specification: #{line}" - end - } - return pods_ary + + 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 Flutter-Generated.xcconfig, then run \"flutter pub get\"" end -def pubspec_supports_macos(file) - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return false; - end - File.foreach(file_abs_path) { |line| - return true if line =~ /^\s*macos:/ - } - return false -end +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup target 'Runner' do use_frameworks! - use_modular_headers! - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - ephemeral_dir = File.join('Flutter', 'ephemeral') - symlink_dir = File.join(ephemeral_dir, '.symlinks') - symlink_plugins_dir = File.join(symlink_dir, 'plugins') - system("rm -rf #{symlink_dir}") - system("mkdir -p #{symlink_plugins_dir}") - - # Flutter Pods - generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig')) - if generated_xcconfig.empty? - puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths end - generated_xcconfig.map { |p| - if p[:name] == 'FLUTTER_FRAMEWORK_DIR' - symlink = File.join(symlink_dir, 'flutter') - File.symlink(File.dirname(p[:path]), symlink) - pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path])) - end - } - - # Plugin Pods - plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.map { |p| - symlink = File.join(symlink_plugins_dir, p[:name]) - File.symlink(p[:path], symlink) - if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml')) - pod p[:name], :path => File.join(symlink, 'macos') - end - } end -# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. -install! 'cocoapods', :disable_input_output_paths => true +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/packages/app_review/example/macos/Runner.xcodeproj/project.pbxproj b/packages/app_review/example/macos/Runner.xcodeproj/project.pbxproj index 331479d..d868a79 100644 --- a/packages/app_review/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/app_review/example/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -21,18 +21,22 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 33CC10E52044A3C60003C045 /* Project object */; @@ -49,8 +53,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -58,9 +60,11 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* app_review_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "app_review_example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -69,28 +73,39 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10EA2044A3C60003C045 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; 33BA886A226E78AF003329D5 /* Configs */ = { isa = PBXGroup; children = ( @@ -107,6 +122,7 @@ children = ( 33FAB671232836740065AC1E /* Runner */, 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, ); @@ -115,7 +131,8 @@ 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* example.app */, + 33CC10ED2044A3C60003C045 /* app_review_example.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, ); name = Products; sourceTree = ""; @@ -138,8 +155,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, ); path = Flutter; sourceTree = ""; @@ -167,6 +182,24 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 33CC10EC2044A3C60003C045 /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; @@ -184,7 +217,7 @@ ); name = Runner; productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productReference = 33CC10ED2044A3C60003C045 /* app_review_example.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -193,10 +226,15 @@ 33CC10E52044A3C60003C045 /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "The Flutter Authors"; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; 33CC10EC2044A3C60003C045 = { CreatedOnToolsVersion = 9.2; LastSwiftMigration = 1100; @@ -214,7 +252,7 @@ }; }; buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 8.0"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -227,12 +265,20 @@ projectRoot = ""; targets = ( 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, 33CC111A2044C6BA0003C045 /* Flutter Assemble */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10EB2044A3C60003C045 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -247,6 +293,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -260,7 +307,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -280,11 +327,19 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10E92044A3C60003C045 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -298,6 +353,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; @@ -318,11 +378,54 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/app_review_example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/app_review_example"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/app_review_example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/app_review_example"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/app_review_example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/app_review_example"; + }; + name = Profile; + }; 338D0CE9231458BD00FA5F75 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -346,9 +449,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -356,7 +461,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -373,10 +478,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -400,6 +501,7 @@ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -423,9 +525,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -439,7 +543,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -453,6 +557,7 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -476,9 +581,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -486,7 +593,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -503,10 +610,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -527,10 +630,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -560,6 +659,16 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/packages/app_review/example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/app_review/example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 764c74b..0000000 --- a/packages/app_review/example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/app_review/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/app_review/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index df12c33..4914365 100644 --- a/packages/app_review/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/app_review/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ @@ -27,29 +27,28 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - - - - - + + + + + + - - diff --git a/packages/app_review/example/macos/Runner/AppDelegate.swift b/packages/app_review/example/macos/Runner/AppDelegate.swift index d53ef64..b3c1761 100644 --- a/packages/app_review/example/macos/Runner/AppDelegate.swift +++ b/packages/app_review/example/macos/Runner/AppDelegate.swift @@ -1,9 +1,13 @@ import Cocoa import FlutterMacOS -@NSApplicationMain +@main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } } diff --git a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index 3c4935a..82b6f9d 100644 Binary files a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index ed4cc16..13b35eb 100644 Binary files a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index 483be61..0a3f5fa 100644 Binary files a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index bcbf36d..bdb5722 100644 Binary files a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png index 9c0a652..f083318 100644 Binary files a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index e71a726..326c0e7 100644 Binary files a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png index 8a31fe2..2f1632c 100644 Binary files a/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and b/packages/app_review/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/packages/app_review/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/app_review/example/macos/Runner/Base.lproj/MainMenu.xib index 537341a..80e867a 100644 --- a/packages/app_review/example/macos/Runner/Base.lproj/MainMenu.xib +++ b/packages/app_review/example/macos/Runner/Base.lproj/MainMenu.xib @@ -323,6 +323,10 @@ + + + + diff --git a/packages/app_review/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/app_review/example/macos/Runner/Configs/AppInfo.xcconfig index 1c34a70..80ddeab 100644 --- a/packages/app_review/example/macos/Runner/Configs/AppInfo.xcconfig +++ b/packages/app_review/example/macos/Runner/Configs/AppInfo.xcconfig @@ -5,10 +5,10 @@ // 'flutter create' template. // The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = example +PRODUCT_NAME = app_review_example // The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.example +PRODUCT_BUNDLE_IDENTIFIER = com.example.appReviewExample // The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2020 com.example. All rights reserved. +PRODUCT_COPYRIGHT = Copyright © 2026 com.example. All rights reserved. diff --git a/packages/app_review/example/macos/Runner/MainFlutterWindow.swift b/packages/app_review/example/macos/Runner/MainFlutterWindow.swift index 2722837..3cc05eb 100644 --- a/packages/app_review/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/app_review/example/macos/Runner/MainFlutterWindow.swift @@ -3,7 +3,7 @@ import FlutterMacOS class MainFlutterWindow: NSWindow { override func awakeFromNib() { - let flutterViewController = FlutterViewController.init() + let flutterViewController = FlutterViewController() let windowFrame = self.frame self.contentViewController = flutterViewController self.setFrame(windowFrame, display: true) diff --git a/packages/app_review/example/macos/RunnerTests/RunnerTests.swift b/packages/app_review/example/macos/RunnerTests/RunnerTests.swift index 5418c9f..61f3bd1 100644 --- a/packages/app_review/example/macos/RunnerTests/RunnerTests.swift +++ b/packages/app_review/example/macos/RunnerTests/RunnerTests.swift @@ -1,5 +1,5 @@ -import FlutterMacOS import Cocoa +import FlutterMacOS import XCTest class RunnerTests: XCTestCase { diff --git a/packages/app_review/example/pubspec.yaml b/packages/app_review/example/pubspec.yaml index bd78171..afa71f9 100644 --- a/packages/app_review/example/pubspec.yaml +++ b/packages/app_review/example/pubspec.yaml @@ -3,25 +3,26 @@ description: Demonstrates how to use the app_review plugin. version: 1.0.0+1 +publish_to: none environment: - - sdk: '>=3.0.0 <4.0.0' + sdk: ^3.0.0 dependencies: flutter: sdk: flutter - cupertino_icons: ^1.0.6 + cupertino_icons: ^1.0.8 -dev_dependencies: - flutter_test: - sdk: flutter - app_review: path: ../ +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + flutter: uses-material-design: true diff --git a/packages/app_review/example/test/widget_test.dart b/packages/app_review/example/test/widget_test.dart index 3969b8a..fe7b626 100644 --- a/packages/app_review/example/test/widget_test.dart +++ b/packages/app_review/example/test/widget_test.dart @@ -1,23 +1,30 @@ -// // This is a basic Flutter widget test. -// // To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter -// // provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to -// // find child widgets in the widget tree, read text, and verify that the values of widget properties -// // are correct. +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. -// import 'package:flutter/material.dart'; -// import 'package:flutter_test/flutter_test.dart'; -// import 'package:app_review_example/main.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; -// void main() { -// testWidgets('Verify App ID', (WidgetTester tester) async { -// // Build our app and trigger a frame. -// await tester.pumpWidget(new MyApp()); +import 'package:app_review_example/main.dart'; -// // Verify that platform version is retrieved. -// expect( -// find.byWidgetPredicate( -// (Widget widget) => widget is Text && widget.data.startsWith('App ID'), -// ), -// findsOneWidget); -// }); -// } +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/packages/app_review/example/windows/CMakeLists.txt b/packages/app_review/example/windows/CMakeLists.txt index 1378672..4507fcf 100644 --- a/packages/app_review/example/windows/CMakeLists.txt +++ b/packages/app_review/example/windows/CMakeLists.txt @@ -1,14 +1,14 @@ # Project-level configuration. cmake_minimum_required(VERSION 3.14) -project(example LANGUAGES CXX) +project(app_review_example LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. -set(BINARY_NAME "example") +set(BINARY_NAME "app_review_example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. -cmake_policy(SET CMP0063 NEW) +cmake_policy(VERSION 3.14...3.25) # Define build configuration option. get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) @@ -87,6 +87,12 @@ if(PLUGIN_BUNDLED_LIBRARIES) COMPONENT Runtime) endif() +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") diff --git a/packages/app_review/example/windows/flutter/CMakeLists.txt b/packages/app_review/example/windows/flutter/CMakeLists.txt index 930d207..903f489 100644 --- a/packages/app_review/example/windows/flutter/CMakeLists.txt +++ b/packages/app_review/example/windows/flutter/CMakeLists.txt @@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake) # https://github.com/flutter/flutter/issues/57146. set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + # === Flutter Library === set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") @@ -92,7 +97,7 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - windows-x64 $ + ${FLUTTER_TARGET_PLATFORM} $ VERBATIM ) add_custom_target(flutter_assemble DEPENDS diff --git a/packages/app_review/example/windows/runner/Runner.rc b/packages/app_review/example/windows/runner/Runner.rc index aecaa2b..ef0e28c 100644 --- a/packages/app_review/example/windows/runner/Runner.rc +++ b/packages/app_review/example/windows/runner/Runner.rc @@ -90,12 +90,12 @@ BEGIN BLOCK "040904e4" BEGIN VALUE "CompanyName", "com.example" "\0" - VALUE "FileDescription", "example" "\0" + VALUE "FileDescription", "app_review_example" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "example" "\0" - VALUE "LegalCopyright", "Copyright (C) 2023 com.example. All rights reserved." "\0" - VALUE "OriginalFilename", "example.exe" "\0" - VALUE "ProductName", "example" "\0" + VALUE "InternalName", "app_review_example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2026 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "app_review_example.exe" "\0" + VALUE "ProductName", "app_review_example" "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0" END END diff --git a/packages/app_review/example/windows/runner/flutter_window.cpp b/packages/app_review/example/windows/runner/flutter_window.cpp index b25e363..955ee30 100644 --- a/packages/app_review/example/windows/runner/flutter_window.cpp +++ b/packages/app_review/example/windows/runner/flutter_window.cpp @@ -31,6 +31,11 @@ bool FlutterWindow::OnCreate() { this->Show(); }); + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + return true; } diff --git a/packages/app_review/example/windows/runner/main.cpp b/packages/app_review/example/windows/runner/main.cpp index a61bf80..17343f6 100644 --- a/packages/app_review/example/windows/runner/main.cpp +++ b/packages/app_review/example/windows/runner/main.cpp @@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); - if (!window.Create(L"example", origin, size)) { + if (!window.Create(L"app_review_example", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true); diff --git a/packages/app_review/example/windows/runner/runner.exe.manifest b/packages/app_review/example/windows/runner/runner.exe.manifest index a42ea76..153653e 100644 --- a/packages/app_review/example/windows/runner/runner.exe.manifest +++ b/packages/app_review/example/windows/runner/runner.exe.manifest @@ -9,12 +9,6 @@ - - - - - - diff --git a/packages/app_review/example/windows/runner/utils.cpp b/packages/app_review/example/windows/runner/utils.cpp index b2b0873..3a0b465 100644 --- a/packages/app_review/example/windows/runner/utils.cpp +++ b/packages/app_review/example/windows/runner/utils.cpp @@ -45,13 +45,13 @@ std::string Utf8FromUtf16(const wchar_t* utf16_string) { if (utf16_string == nullptr) { return std::string(); } - int target_length = ::WideCharToMultiByte( + unsigned int target_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, -1, nullptr, 0, nullptr, nullptr) -1; // remove the trailing null character int input_length = (int)wcslen(utf16_string); std::string utf8_string; - if (target_length <= 0 || target_length > utf8_string.max_size()) { + if (target_length == 0 || target_length > utf8_string.max_size()) { return utf8_string; } utf8_string.resize(target_length); diff --git a/packages/app_review/lib/app_review.dart b/packages/app_review/lib/app_review.dart index a75aab2..270e133 100644 --- a/packages/app_review/lib/app_review.dart +++ b/packages/app_review/lib/app_review.dart @@ -115,15 +115,17 @@ class AppReview { }) async { if (compose) { final id = appId ?? (await getIosAppId()) ?? ''; - final reviewUrl = 'itunes.apple.com/app/id$id?mt=8&action=write-review'; - final uri = Uri.parse('itms-apps://$reviewUrl'); + // New format: https://apps.apple.com/app/idYOURAPPSTOREID?action=write-review + final reviewUrl = 'apps.apple.com/app/id$id'; + final uri = Uri.parse('https://$reviewUrl?action=write-review'); + if (await canLaunchUrl(uri)) { debugPrint('launching store page'); - await launchUrl(uri); + await launchUrl(uri, mode: LaunchMode.externalApplication); return 'Launched App Store Directly: $reviewUrl'; } - await launchUrl(Uri.parse('https://$reviewUrl')); + await launchUrl(uri, mode: LaunchMode.externalApplication); return 'Launched App Store: $reviewUrl'; } @@ -146,7 +148,7 @@ class AppReview { final appId = await getIosAppId() ?? ''; if (appId.isNotEmpty) { - launchUrl(Uri.parse('https://itunes.apple.com/app/id$appId'), + launchUrl(Uri.parse('https://apps.apple.com/app/id$appId'), mode: LaunchMode.externalApplication); return 'Launched App Store'; } @@ -226,7 +228,12 @@ class AppReview { 'https://itunes.apple.com/$country/lookup?bundleId=$id')) .timeout(const Duration(seconds: 5)); final Map json = jsonDecode(result.body); - appId = json['results'][0]['trackId']?.toString(); + final List results = json['results'] as List; + if (results.isNotEmpty) { + appId = results[0]['trackId']?.toString(); + } + } catch (e) { + debugPrint('Error fetching app ID: $e'); } finally { if (appId?.isNotEmpty == true) { debugPrint('Track ID: $appId'); diff --git a/packages/app_review/pubspec.yaml b/packages/app_review/pubspec.yaml index e3cccae..d89ad64 100644 --- a/packages/app_review/pubspec.yaml +++ b/packages/app_review/pubspec.yaml @@ -1,19 +1,20 @@ name: app_review description: Request and Write Reviews and Open Store Listing for Android and iOS in Flutter. -version: 2.1.2+1 -maintainer: Rody Davis (@rodydavis) -homepage: https://github.com/rodydavis/plugins -repository: https://github.com/fluttercommunity/app_review - +version: 2.2.0 environment: - sdk: '>=3.0.0 <4.0.0' - flutter: ^1.10.0 + sdk: ^3.5.0 + flutter: ^3.38.5 +resolution: workspace +maintainer: Rody Davis (@rodydavis) +homepage: https://github.com/rodydavis/packages.dart +repository: https://github.com/rodydavis/packages.dart + dependencies: - http: ^1.1.0 + http: ^1.2.0 - url_launcher: ^6.1.7 - package_info_plus: ^5.0.0 + url_launcher: ^6.3.0 + package_info_plus: ^9.0.0 flutter: sdk: flutter diff --git a/packages/flutter_vibrate/pubspec.yaml b/packages/flutter_vibrate/pubspec.yaml index 80ac508..de11e12 100644 --- a/packages/flutter_vibrate/pubspec.yaml +++ b/packages/flutter_vibrate/pubspec.yaml @@ -4,10 +4,10 @@ version: 1.4.0 environment: sdk: ^3.5.0 flutter: ^3.38.5 +resolution: workspace maintainer: Rody Davis (@rodydavis) homepage: https://github.com/rodydavis/packages.dart repository: https://github.com/rodydavis/packages.dart -resolution: workspace dependencies: flutter: diff --git a/pubspec.lock b/pubspec.lock index c9420ac..53766a4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -192,6 +192,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" + http: + dependency: transitive + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" leak_tracker: dependency: transitive description: @@ -264,6 +280,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + package_info_plus: + dependency: transitive + description: + name: package_info_plus + sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d + url: "https://pub.dev" + source: hosted + version: "9.0.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + url: "https://pub.dev" + source: hosted + version: "3.2.1" path: dependency: transitive description: @@ -541,6 +573,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + win32: + dependency: transitive + description: + name: win32 + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e + url: "https://pub.dev" + source: hosted + version: "5.15.0" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 36282e5..66fe264 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,4 +8,5 @@ workspace: - packages/flutter_vibrate - packages/flutter_sms - packages/flutter_whatsnew - - packages/breakpoint \ No newline at end of file + - packages/breakpoint + - packages/app_review \ No newline at end of file diff --git a/scripts/update_readme.dart b/scripts/update_readme.dart index dee4921..acfda23 100644 --- a/scripts/update_readme.dart +++ b/scripts/update_readme.dart @@ -5,6 +5,29 @@ void main() async { final packagesDir = Directory('${rootDir.path}/packages'); final readmeFile = File('${rootDir.path}/README.md'); + final gitmodulesFile = File('${rootDir.path}/.gitmodules'); + final submodules = {}; + + if (gitmodulesFile.existsSync()) { + final lines = await gitmodulesFile.readAsLines(); + String? currentPath; + String? currentUrl; + for (final line in lines) { + final trimmed = line.trim(); + if (trimmed.startsWith('path = ')) { + currentPath = trimmed.substring(7).trim(); + } else if (trimmed.startsWith('url = ')) { + currentUrl = trimmed.substring(6).trim(); + } + + if (currentPath != null && currentUrl != null) { + submodules[currentPath] = currentUrl; + currentPath = null; + currentUrl = null; + } + } + } + if (!packagesDir.existsSync()) { print('Error: packages directory not found at ${packagesDir.path}'); return; @@ -27,12 +50,49 @@ void main() async { if (name != null && version != null && publishTo != 'none') { // Calculate relative path from root - final relativePath = entity.parent.path.replaceFirst(rootDir.path, '.'); + var relativePath = entity.parent.path.replaceFirst(rootDir.path, '.'); + if (relativePath.startsWith('./')) { + relativePath = relativePath.substring(2); + } + + // Check for submodule match + String? linkPath; + for (final entry in submodules.entries) { + final subPath = entry.key; + final subUrl = entry.value; + if (relativePath.startsWith(subPath)) { + // It is inside this submodule + // Verify if it is exact match or subdir + if (relativePath == subPath || + relativePath.startsWith('$subPath/')) { + final remainder = relativePath.substring(subPath.length); + // Remove leading slash if present + final cleanRemainder = remainder.startsWith('/') + ? remainder.substring(1) + : remainder; + + // Construct URL + // Assuming standard GitHub structure: url/tree/main/path + // If cleanRemainder is empty, we link to root + if (cleanRemainder.isEmpty) { + linkPath = subUrl; + } else { + linkPath = '$subUrl/tree/main/$cleanRemainder'; + } + break; + } + } + } + + // Fallback to local relative path if not in submodule (add ./ back for consistency if desired, or keep as relative path string) + if (linkPath == null) { + linkPath = './$relativePath'; + } packages.add(_Package( name: name, description: description ?? '', - path: relativePath, + path: linkPath, )); } }