From 818df146e2a6e0578a368a6ec309caf3e22f0ab2 Mon Sep 17 00:00:00 2001 From: Norbel AMBANUMBEN Date: Wed, 31 Jul 2024 15:54:23 +0100 Subject: [PATCH] chore: update ios flavor and build (#29) * chore: update documentation * chore: update configuration for news media scan --- .github/workflows/validate.yml | 11 +- README.md | 50 ++++ composeApp/build.gradle.kts | 35 ++- composeApp/composeApp.podspec | 2 +- .../composeResources/drawable/.gitignore | 2 + .../composeResources/values/.gitignore | 2 + .../values/{common.xml => strings-common.xml} | 0 .../probe/ui/dashboard/DashboardScreen.kt | 4 +- composeApp/src/dwMain/kotlin/Config.kt | 10 +- .../src/dwMain/resources/drawable/.gitignore | 2 - .../src/dwMain/resources/values/.gitignore | 2 - .../{strings.xml => strings-organization.xml} | 0 .../ooniMain/resources/drawable/.gitignore | 2 - .../src/ooniMain/resources/values/.gitignore | 2 - .../{strings.xml => strings-organization.xml} | 0 gradle/libs.versions.toml | 2 +- iosApp/Podfile | 29 +- iosApp/Podfile.lock | 4 +- iosApp/iosApp.xcodeproj/project.pbxproj | 282 ++++++++++++++++-- iosApp/iosApp/Info.plist | 4 +- iosApp/iosApp/NewsMediaScan-Info.plist | 50 ++++ 21 files changed, 430 insertions(+), 65 deletions(-) create mode 100644 composeApp/src/commonMain/composeResources/drawable/.gitignore create mode 100644 composeApp/src/commonMain/composeResources/values/.gitignore rename composeApp/src/commonMain/composeResources/values/{common.xml => strings-common.xml} (100%) delete mode 100644 composeApp/src/dwMain/resources/drawable/.gitignore delete mode 100644 composeApp/src/dwMain/resources/values/.gitignore rename composeApp/src/dwMain/resources/values/{strings.xml => strings-organization.xml} (100%) delete mode 100644 composeApp/src/ooniMain/resources/drawable/.gitignore delete mode 100644 composeApp/src/ooniMain/resources/values/.gitignore rename composeApp/src/ooniMain/resources/values/{strings.xml => strings-organization.xml} (100%) create mode 100644 iosApp/iosApp/NewsMediaScan-Info.plist diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index b78504bc..7c363b41 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -13,6 +13,7 @@ jobs: strategy: matrix: type: [Debug, Release] + organization: [ooni, dw] steps: - uses: actions/checkout@v4 @@ -21,10 +22,10 @@ jobs: uses: ./.github/actions/setup - name: Build Android - run: ./gradlew assemble${{ matrix.type }} + run: ./gradlew copyBrandingToCommonResources assemble${{ matrix.type }} -Porganization=${{ matrix.organization }} - - name: Build iOS - run: ./gradlew link${{ matrix.type }}FrameworkIosSimulatorArm64 + - name: Build iOS Framework + run: ./gradlew link${{ matrix.type }}FrameworkIosSimulatorArm64 -Porganization=${{ matrix.organization }} android-lint: name: Android Lint @@ -38,7 +39,7 @@ jobs: uses: ./.github/actions/setup - name: Run lint - run: ./gradlew lint + run: ./gradlew copyBrandingToCommonResources lint - name: Uploads test reports uses: actions/upload-artifact@v4 @@ -59,7 +60,7 @@ jobs: uses: ./.github/actions/setup - name: Run lint - run: ./gradlew ktlintCheck + run: ./gradlew copyBrandingToCommonResources ktlintCheck - name: Uploads test reports uses: actions/upload-artifact@v4 diff --git a/README.md b/README.md index 9462564d..f37c9728 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Multiplatform (Android and iOS currently) version of the Probe app. - `commonMain` is for code that’s common for all targets. - `androidMain` Android-specific code - `iosMain` iOS-specific code written in Kotlin + - `dwMain` News Media Scan specific Branding and customization + - `ooniMain` OONI Probe specific Branding and customization * `iosApp` contains the iOS application configuration and the engine integration written in Swift @@ -40,3 +42,51 @@ besides platform-specific code that we can’t avoid, such as the loading our pr * `shared` classes and methods shared across the whole app * `data` data layer code (database, preferences, network...) * `ui` UI layer code, organized into features/screens + + + +### Build, Install, and Run + +To build, install, and run your application, use the following commands: + +- For OONI Probe: + ``` + ./gradlew runDebug -Porganization=ooni + ``` + +- For News Media Scan: + ``` + ./gradlew runDebug -Porganization=dw + ``` + +There is a custom gradle task(`copyBrandingToCommonResources`) that is used to copy brand specific resources to the common resources folder. This task is called before the `preBuild` task. + +### Creating Run Configurations in Android Studio + +Configure run configurations for easy execution within Android Studio: + +#### OONI Probe Android Configuration + +1. Click the **Plus (+)** sign in the top left corner of the "Run/Debug Configurations" dialog. +2. Choose 'Gradle'. +3. Configure with the following: +- **Name:** OONI_Probe +- **Run:** :composeApp:runDebug -Porganization=ooni + +#### News Media Scan Android Configuration + +1. Repeat the steps for creating a new configuration. +2. Configure with the following: +- **Name:** News_Media_Scan +- **Run:** :composeApp:runDebug -Porganization=dw + +#### OONI Probe iOS Configuration + +The "Run/Debug Configurations" already has the proper configuration and you just need to select the XCode Project Scheme `OONIProbe` and run it. + +#### News Media Scan iOS Configuration +The "Run/Debug Configurations" already has the proper configuration and you just need to select the XCode Project Scheme `NewsMediaScan` and run it. + +#### Switching between OONI Probe and News Media Scan +- Ensure you can run clean and build the project successfully. +- Run `pod install` in the `iosApp` directory. diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 731c2388..09cba321 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -48,7 +48,7 @@ kotlin { iosSimulatorArm64() cocoapods { - ios.deploymentTarget = "9.0" + ios.deploymentTarget = "12.0" version = "1.0" summary = "Compose App" @@ -98,13 +98,6 @@ kotlin { } } -compose.resources { - customDirectory( - sourceSetName = "commonMain", - directoryProvider = provider { layout.projectDirectory.dir(config.resRoot) }, - ) -} - android { namespace = "org.ooni.probe" compileSdk = libs.versions.android.compileSdk.get().toInt() @@ -157,13 +150,13 @@ ktlint { additionalEditorconfig.put("ktlint_function_naming_ignore_when_annotated_with", "Composable") } -tasks.register("copyCommonResourcesToFlavor") { +tasks.register("copyBrandingToCommonResources") { doLast { val projectDir = project.projectDir.absolutePath - val sourceFile = File(projectDir, "src/commonMain/composeResources") + val destinationFile = File(projectDir, "src/commonMain/composeResources") - val destinationFile = File(projectDir, config.resRoot) + val sourceFile = File(projectDir, config.resRoot) copyRecursive(sourceFile, destinationFile) } @@ -173,7 +166,7 @@ tasks.register("cleanCopiedCommonResourcesToFlavor") { doLast { val projectDir = project.projectDir.absolutePath - val destinationFile = File(projectDir, config.resRoot) + val destinationFile = File(projectDir, "src/commonMain/composeResources") destinationFile.listFiles()?.forEach { folder -> folder.listFiles()?.forEach { file -> if (file.name == ".gitignore") { @@ -192,17 +185,17 @@ tasks.register("cleanCopiedCommonResourcesToFlavor") { } /** - * Configure the prepareComposeResourcesTaskForCommonMain task to depend on the copyCommonResourcesToFlavor task. + * Configure the prepareComposeResourcesTaskForCommonMain task to depend on the copyBrandingToCommonResources task. * This will ensure that the common resources are copied to the correct location before the task is executed. * * NOTE: Current limitation is that multiple resources directories are not supported. */ tasks.named("preBuild").configure { - dependsOn("copyCommonResourcesToFlavor") + dependsOn("copyBrandingToCommonResources") } tasks.named("clean").configure { - dependsOn("copyCommonResourcesToFlavor") + dependsOn("copyBrandingToCommonResources") } tasks.named("clean").configure { @@ -279,3 +272,15 @@ fun copyRecursive( } } } + +tasks.register("runDebug", Exec::class) { + dependsOn("clean", "uninstallDebug", "installDebug") + commandLine( + "adb", + "shell", + "am", + "start", + "-n", + "${config.appId}.debug/org.ooni.probe.MainActivity", + ) +} diff --git a/composeApp/composeApp.podspec b/composeApp/composeApp.podspec index 73870841..ff72dc21 100644 --- a/composeApp/composeApp.podspec +++ b/composeApp/composeApp.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |spec| spec.summary = 'Compose App' spec.vendored_frameworks = 'build/cocoapods/framework/composeApp.framework' spec.libraries = 'c++' - spec.ios.deployment_target = '9.0' + spec.ios.deployment_target = '12.0' if !Dir.exist?('build/cocoapods/framework/composeApp.framework') || Dir.empty?('build/cocoapods/framework/composeApp.framework') diff --git a/composeApp/src/commonMain/composeResources/drawable/.gitignore b/composeApp/src/commonMain/composeResources/drawable/.gitignore new file mode 100644 index 00000000..4d576f73 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/.gitignore @@ -0,0 +1,2 @@ + +logo.xml \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/values/.gitignore b/composeApp/src/commonMain/composeResources/values/.gitignore new file mode 100644 index 00000000..217d1b4c --- /dev/null +++ b/composeApp/src/commonMain/composeResources/values/.gitignore @@ -0,0 +1,2 @@ + +strings-organization.xml \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/values/common.xml b/composeApp/src/commonMain/composeResources/values/strings-common.xml similarity index 100% rename from composeApp/src/commonMain/composeResources/values/common.xml rename to composeApp/src/commonMain/composeResources/values/strings-common.xml diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardScreen.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardScreen.kt index a66857db..c19d58a6 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardScreen.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardScreen.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier import ooniprobe.composeapp.generated.resources.Res import ooniprobe.composeapp.generated.resources.app_name import ooniprobe.composeapp.generated.resources.logo +import ooniprobe.composeapp.generated.resources.run_tests import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.ui.tooling.preview.Preview @@ -47,8 +48,7 @@ fun DashboardScreen( onClick = { onEvent(DashboardViewModel.Event.StartClick) }, enabled = !state.isRunning, ) { - // Text(stringResource(Res.string.run_tests)) - Text("Run Tests") + Text(stringResource(Res.string.run_tests)) } Image( diff --git a/composeApp/src/dwMain/kotlin/Config.kt b/composeApp/src/dwMain/kotlin/Config.kt index a6e0da90..673054da 100644 --- a/composeApp/src/dwMain/kotlin/Config.kt +++ b/composeApp/src/dwMain/kotlin/Config.kt @@ -1,7 +1,7 @@ +package org.ooni.probe.config + object Config { - object Config { - const val OONI_API_BASE_URL: String = "https://api.prod.ooni.io" - const val OONI_RUN_DASHBOARD_URL: String = "https://run-v2.ooni.org" - const val BASE_SOFTWARE_NAME: String = "news-media-scan" - } + const val OONI_API_BASE_URL: String = "https://api.prod.ooni.io" + const val OONI_RUN_DASHBOARD_URL: String = "https://run-v2.ooni.org" + const val BASE_SOFTWARE_NAME: String = "news-media-scan" } diff --git a/composeApp/src/dwMain/resources/drawable/.gitignore b/composeApp/src/dwMain/resources/drawable/.gitignore deleted file mode 100644 index 35f3f1a5..00000000 --- a/composeApp/src/dwMain/resources/drawable/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -compose-multiplatform.xml \ No newline at end of file diff --git a/composeApp/src/dwMain/resources/values/.gitignore b/composeApp/src/dwMain/resources/values/.gitignore deleted file mode 100644 index 5bdcc5ad..00000000 --- a/composeApp/src/dwMain/resources/values/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -common.xml \ No newline at end of file diff --git a/composeApp/src/dwMain/resources/values/strings.xml b/composeApp/src/dwMain/resources/values/strings-organization.xml similarity index 100% rename from composeApp/src/dwMain/resources/values/strings.xml rename to composeApp/src/dwMain/resources/values/strings-organization.xml diff --git a/composeApp/src/ooniMain/resources/drawable/.gitignore b/composeApp/src/ooniMain/resources/drawable/.gitignore deleted file mode 100644 index 35f3f1a5..00000000 --- a/composeApp/src/ooniMain/resources/drawable/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -compose-multiplatform.xml \ No newline at end of file diff --git a/composeApp/src/ooniMain/resources/values/.gitignore b/composeApp/src/ooniMain/resources/values/.gitignore deleted file mode 100644 index 5bdcc5ad..00000000 --- a/composeApp/src/ooniMain/resources/values/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -common.xml \ No newline at end of file diff --git a/composeApp/src/ooniMain/resources/values/strings.xml b/composeApp/src/ooniMain/resources/values/strings-organization.xml similarity index 100% rename from composeApp/src/ooniMain/resources/values/strings.xml rename to composeApp/src/ooniMain/resources/values/strings-organization.xml diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0942cdba..5cfad43e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ android-compileSdk = "34" android-minSdk = "24" android-targetSdk = "34" -compose-plugin = "1.7.0-alpha02" +compose-plugin = "1.6.11" kotlin = "2.0.0" [plugins] diff --git a/iosApp/Podfile b/iosApp/Podfile index c38ddd2b..cf494a9c 100644 --- a/iosApp/Podfile +++ b/iosApp/Podfile @@ -1,11 +1,23 @@ platform :ios, '12.0' use_frameworks! -target 'iosApp' do + +ooni_version = "v3.22.0" +ooni_pods_location = "https://github.com/ooni/probe-cli/releases/download/#{ooni_version}" + +target 'OONIProbe' do pod 'composeApp', :path => '../composeApp' - ooni_version = "v3.22.0" - ooni_pods_location = "https://github.com/ooni/probe-cli/releases/download/#{ooni_version}" + pod "libcrypto", :podspec => "#{ooni_pods_location}/libcrypto.podspec" + pod "libevent", :podspec => "#{ooni_pods_location}/libevent.podspec" + pod "libssl", :podspec => "#{ooni_pods_location}/libssl.podspec" + pod "libtor", :podspec => "#{ooni_pods_location}/libtor.podspec" + pod "libz", :podspec => "#{ooni_pods_location}/libz.podspec" + pod "oonimkall", :podspec => "#{ooni_pods_location}/oonimkall.podspec" +end + +target 'NewsMediaScan' do + pod 'composeApp', :path => '../composeApp' pod "libcrypto", :podspec => "#{ooni_pods_location}/libcrypto.podspec" pod "libevent", :podspec => "#{ooni_pods_location}/libevent.podspec" @@ -13,4 +25,13 @@ target 'iosApp' do pod "libtor", :podspec => "#{ooni_pods_location}/libtor.podspec" pod "libz", :podspec => "#{ooni_pods_location}/libz.podspec" pod "oonimkall", :podspec => "#{ooni_pods_location}/oonimkall.podspec" -end \ No newline at end of file +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' + end + end +end diff --git a/iosApp/Podfile.lock b/iosApp/Podfile.lock index b16758ea..3339c30d 100644 --- a/iosApp/Podfile.lock +++ b/iosApp/Podfile.lock @@ -33,7 +33,7 @@ EXTERNAL SOURCES: :podspec: https://github.com/ooni/probe-cli/releases/download/v3.22.0/oonimkall.podspec SPEC CHECKSUMS: - composeApp: 3f1f4ca4e070c2c0aa528bb1eb838ffc3860f5c0 + composeApp: be6187105a7697f3cb0799a21bbbfddc5e65b077 libcrypto: 1bb58600c586e28688f5578f4675f5ffa46c8eaf libevent: 5c8502ca5cc38be31bb510ddade0f238bcc5f0dc libssl: 170bebcaf567a0285e91a8850b9686137d07c3e1 @@ -41,6 +41,6 @@ SPEC CHECKSUMS: libz: 83658eb2a0db785623ffdf9ce13407e6b8b5c8f9 oonimkall: 9768ce9dad18265d45d2ea972c84fb0bd5237cc3 -PODFILE CHECKSUM: 04b498ba1984c25e9816234b0551222184c25492 +PODFILE CHECKSUM: 5bcb6ea084168cab14bd0cd0f6e4775194adbc48 COCOAPODS: 1.15.2 diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj index 123f806b..bad33e7c 100644 --- a/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/iosApp/iosApp.xcodeproj/project.pbxproj @@ -11,30 +11,51 @@ 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; - 90C537899E1A531A92327A33 /* Pods_iosApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3690801A53F73052EF6710A7 /* Pods_iosApp.framework */; }; + 79FBD00D2C5A70AF004E041C /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; + 79FBD00E2C5A70AF004E041C /* IosOonimkallBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E977702C4FCCE3009CCABC /* IosOonimkallBridge.swift */; }; + 79FBD00F2C5A70AF004E041C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; + 79FBD0132C5A70AF004E041C /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; + 79FBD0142C5A70AF004E041C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; 93E977712C4FCCE3009CCABC /* IosOonimkallBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E977702C4FCCE3009CCABC /* IosOonimkallBridge.swift */; }; + 94DC92639D2411CA34B45C81 /* Pods_NewsMediaScan.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96B0AC35C421922A1ED7D422 /* Pods_NewsMediaScan.framework */; }; + A26A8A38C066256520CE779E /* Pods_OONIProbe.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B59AB52BA10477541BE9D121 /* Pods_OONIProbe.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 1831699651CB16A290CA40C6 /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.release.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig"; sourceTree = ""; }; + 205238D88AD064C8AF508845 /* Pods-OONIProbe.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OONIProbe.debug.xcconfig"; path = "Target Support Files/Pods-OONIProbe/Pods-OONIProbe.debug.xcconfig"; sourceTree = ""; }; 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; }; - 3690801A53F73052EF6710A7 /* Pods_iosApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_iosApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4C317D1F5DE6C99A874555F9 /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.release.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig"; sourceTree = ""; }; + 4D603BCB2B32219C5CCC41B3 /* Pods-NewsMediaScan.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewsMediaScan.release.xcconfig"; path = "Target Support Files/Pods-NewsMediaScan/Pods-NewsMediaScan.release.xcconfig"; sourceTree = ""; }; + 506A0735B8488E63307B34DA /* Pods-NewsMediaScan.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewsMediaScan.debug.xcconfig"; path = "Target Support Files/Pods-NewsMediaScan/Pods-NewsMediaScan.debug.xcconfig"; sourceTree = ""; }; 7555FF7B242A565900829871 /* OONI Probe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "OONI Probe.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 79FBD01A2C5A70AF004E041C /* NewsMediaScan.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NewsMediaScan.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 79FBD01B2C5A70AF004E041C /* iosApp copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "iosApp copy-Info.plist"; path = "/Users/aanorbel/Code/ooni/new/probe-multiplatform/iosApp/iosApp copy-Info.plist"; sourceTree = ""; }; + 8918F4B39DEEFE89FDF20821 /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.debug.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig"; sourceTree = ""; }; 93E977702C4FCCE3009CCABC /* IosOonimkallBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosOonimkallBridge.swift; sourceTree = ""; }; + 96B0AC35C421922A1ED7D422 /* Pods_NewsMediaScan.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NewsMediaScan.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; - B24B7C9C049ADDADBB7C8DCE /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.debug.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig"; sourceTree = ""; }; + B2A30B3FAFDB1355D98FFF9E /* Pods-OONIProbe.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OONIProbe.release.xcconfig"; path = "Target Support Files/Pods-OONIProbe/Pods-OONIProbe.release.xcconfig"; sourceTree = ""; }; + B59AB52BA10477541BE9D121 /* Pods_OONIProbe.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OONIProbe.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 79FBD0102C5A70AF004E041C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 94DC92639D2411CA34B45C81 /* Pods_NewsMediaScan.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; B92378962B6B1156000C7307 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 90C537899E1A531A92327A33 /* Pods_iosApp.framework in Frameworks */, + A26A8A38C066256520CE779E /* Pods_OONIProbe.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -52,8 +73,12 @@ 20AA0919DAC14F9E057F989A /* Pods */ = { isa = PBXGroup; children = ( - B24B7C9C049ADDADBB7C8DCE /* Pods-iosApp.debug.xcconfig */, - 4C317D1F5DE6C99A874555F9 /* Pods-iosApp.release.xcconfig */, + 8918F4B39DEEFE89FDF20821 /* Pods-iosApp.debug.xcconfig */, + 1831699651CB16A290CA40C6 /* Pods-iosApp.release.xcconfig */, + 506A0735B8488E63307B34DA /* Pods-NewsMediaScan.debug.xcconfig */, + 4D603BCB2B32219C5CCC41B3 /* Pods-NewsMediaScan.release.xcconfig */, + 205238D88AD064C8AF508845 /* Pods-OONIProbe.debug.xcconfig */, + B2A30B3FAFDB1355D98FFF9E /* Pods-OONIProbe.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -61,7 +86,8 @@ 42799AB246E5F90AF97AA0EF /* Frameworks */ = { isa = PBXGroup; children = ( - 3690801A53F73052EF6710A7 /* Pods_iosApp.framework */, + 96B0AC35C421922A1ED7D422 /* Pods_NewsMediaScan.framework */, + B59AB52BA10477541BE9D121 /* Pods_OONIProbe.framework */, ); name = Frameworks; sourceTree = ""; @@ -74,6 +100,7 @@ 7555FF7C242A565900829871 /* Products */, 42799AB246E5F90AF97AA0EF /* Frameworks */, 20AA0919DAC14F9E057F989A /* Pods */, + 79FBD01B2C5A70AF004E041C /* iosApp copy-Info.plist */, ); sourceTree = ""; }; @@ -81,6 +108,7 @@ isa = PBXGroup; children = ( 7555FF7B242A565900829871 /* OONI Probe.app */, + 79FBD01A2C5A70AF004E041C /* NewsMediaScan.app */, ); name = Products; sourceTree = ""; @@ -117,9 +145,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 7555FF7A242A565900829871 /* iosApp */ = { + 7555FF7A242A565900829871 /* OONIProbe */ = { isa = PBXNativeTarget; - buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */; + buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "OONIProbe" */; buildPhases = ( 2221CAC0E44786DF6A5501B8 /* [CP] Check Pods Manifest.lock */, F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */, @@ -127,16 +155,38 @@ B92378962B6B1156000C7307 /* Frameworks */, 7555FF79242A565900829871 /* Resources */, 93E977732C4FE022009CCABC /* ShellScript */, + C15EB4D3556522B7CE6B1638 /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( ); - name = iosApp; + name = OONIProbe; productName = iosApp; productReference = 7555FF7B242A565900829871 /* OONI Probe.app */; productType = "com.apple.product-type.application"; }; + 79FBD0092C5A70AF004E041C /* NewsMediaScan */ = { + isa = PBXNativeTarget; + buildConfigurationList = 79FBD0172C5A70AF004E041C /* Build configuration list for PBXNativeTarget "NewsMediaScan" */; + buildPhases = ( + 320D500964B2C4AE97004E19 /* [CP] Check Pods Manifest.lock */, + 79FBD00B2C5A70AF004E041C /* Compile Kotlin Framework */, + 79FBD00C2C5A70AF004E041C /* Sources */, + 79FBD0102C5A70AF004E041C /* Frameworks */, + 79FBD0122C5A70AF004E041C /* Resources */, + 79FBD0152C5A70AF004E041C /* ShellScript */, + E83A3E9E7BCDBBDBB4891740 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NewsMediaScan; + productName = iosApp; + productReference = 79FBD01A2C5A70AF004E041C /* NewsMediaScan.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -165,7 +215,8 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 7555FF7A242A565900829871 /* iosApp */, + 7555FF7A242A565900829871 /* OONIProbe */, + 79FBD0092C5A70AF004E041C /* NewsMediaScan */, ); }; /* End PBXProject section */ @@ -180,6 +231,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 79FBD0122C5A70AF004E041C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 79FBD0132C5A70AF004E041C /* Preview Assets.xcassets in Resources */, + 79FBD0142C5A70AF004E041C /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -198,13 +258,70 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosApp-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-OONIProbe-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 320D500964B2C4AE97004E19 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-NewsMediaScan-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 79FBD00B2C5A70AF004E041C /* Compile Kotlin Framework */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Compile Kotlin Framework"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew copyBrandingToCommonResources :composeApp:embedAndSignAppleFrameworkForXcode -Porganization=dw\n"; + }; + 79FBD0152C5A70AF004E041C /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$SRCROOT/..\"\n./gradlew copyBrandingToCommonResources embedAndSignAppleFrameworkForXcode -Porganization=dw\n"; + }; 93E977732C4FE022009CCABC /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -220,7 +337,41 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "cd \"$SRCROOT/..\"\n./gradlew embedAndSignAppleFrameworkForXcode\n"; + shellScript = "cd \"$SRCROOT/..\"\n./gradlew copyBrandingToCommonResources embedAndSignAppleFrameworkForXcode -Porganization=ooni\n"; + }; + C15EB4D3556522B7CE6B1638 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-OONIProbe/Pods-OONIProbe-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-OONIProbe/Pods-OONIProbe-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OONIProbe/Pods-OONIProbe-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + E83A3E9E7BCDBBDBB4891740 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-NewsMediaScan/Pods-NewsMediaScan-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-NewsMediaScan/Pods-NewsMediaScan-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NewsMediaScan/Pods-NewsMediaScan-resources.sh\"\n"; + showEnvVarsInLog = 0; }; F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */ = { isa = PBXShellScriptBuildPhase; @@ -238,7 +389,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n"; + shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew copyBrandingToCommonResources :composeApp:embedAndSignAppleFrameworkForXcode -Porganization=ooni\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -253,6 +404,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 79FBD00C2C5A70AF004E041C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 79FBD00D2C5A70AF004E041C /* iOSApp.swift in Sources */, + 79FBD00E2C5A70AF004E041C /* IosOonimkallBridge.swift in Sources */, + 79FBD00F2C5A70AF004E041C /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ @@ -376,7 +537,7 @@ }; 7555FFA6242A565B00829871 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B24B7C9C049ADDADBB7C8DCE /* Pods-iosApp.debug.xcconfig */; + baseConfigurationReference = 205238D88AD064C8AF508845 /* Pods-OONIProbe.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "Apple Development"; @@ -400,7 +561,8 @@ "-framework", composeApp, ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; + PRODUCT_BUNDLE_IDENTIFIER = org.ooni.probe.debug; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.ooni.probe.debug; PRODUCT_NAME = "${APP_NAME}"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; @@ -410,7 +572,7 @@ }; 7555FFA7242A565B00829871 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4C317D1F5DE6C99A874555F9 /* Pods-iosApp.release.xcconfig */; + baseConfigurationReference = B2A30B3FAFDB1355D98FFF9E /* Pods-OONIProbe.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "Apple Development"; @@ -434,7 +596,8 @@ "-framework", composeApp, ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; + PRODUCT_BUNDLE_IDENTIFIER = org.ooni.probe; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.ooni.probe; PRODUCT_NAME = "${APP_NAME}"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; @@ -442,6 +605,76 @@ }; name = Release; }; + 79FBD0182C5A70AF004E041C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 506A0735B8488E63307B34DA /* Pods-NewsMediaScan.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; + DEVELOPMENT_TEAM = "${TEAM_ID}"; + ENABLE_PREVIEWS = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", + "$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", + "$(inherited)", + ); + INFOPLIST_FILE = "iosApp/NewsMediaScan-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 15.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + composeApp, + ); + PRODUCT_BUNDLE_IDENTIFIER = org.dw.probe.debug; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.dw.probe.debug; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 79FBD0192C5A70AF004E041C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4D603BCB2B32219C5CCC41B3 /* Pods-NewsMediaScan.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; + DEVELOPMENT_TEAM = "${TEAM_ID}"; + ENABLE_PREVIEWS = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", + "$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", + "$(inherited)", + ); + INFOPLIST_FILE = "iosApp/NewsMediaScan-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 15.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + composeApp, + ); + PRODUCT_BUNDLE_IDENTIFIER = org.dw.probe; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.dw.probe; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -454,7 +687,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = { + 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "OONIProbe" */ = { isa = XCConfigurationList; buildConfigurations = ( 7555FFA6242A565B00829871 /* Debug */, @@ -463,6 +696,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 79FBD0172C5A70AF004E041C /* Build configuration list for PBXNativeTarget "NewsMediaScan" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 79FBD0182C5A70AF004E041C /* Debug */, + 79FBD0192C5A70AF004E041C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 7555FF73242A565900829871 /* Project object */; diff --git a/iosApp/iosApp/Info.plist b/iosApp/iosApp/Info.plist index 412e3781..aaf5e182 100644 --- a/iosApp/iosApp/Info.plist +++ b/iosApp/iosApp/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable @@ -20,8 +22,6 @@ 1 LSRequiresIPhoneOS - CADisableMinimumFrameDurationOnPhone - UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/iosApp/iosApp/NewsMediaScan-Info.plist b/iosApp/iosApp/NewsMediaScan-Info.plist new file mode 100644 index 00000000..aaf5e182 --- /dev/null +++ b/iosApp/iosApp/NewsMediaScan-Info.plist @@ -0,0 +1,50 @@ + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + UILaunchScreen + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + +