create-cmp-cli 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +232 -0
- package/bin/create-cmp.mjs +91 -0
- package/options.schema.json +110 -0
- package/package.json +52 -0
- package/src/bootstrap/checks.mjs +283 -0
- package/src/bootstrap/exec.mjs +90 -0
- package/src/commands/clean.mjs +195 -0
- package/src/commands/create.mjs +223 -0
- package/src/commands/doctor.mjs +256 -0
- package/src/commands/upgrade.mjs +196 -0
- package/src/commands/verify.mjs +94 -0
- package/src/doctor.mjs +109 -0
- package/src/lib/args.mjs +38 -0
- package/src/lib/clean.mjs +72 -0
- package/src/lib/fsutil.mjs +90 -0
- package/src/lib/log.mjs +40 -0
- package/src/lib/project-doctor.mjs +329 -0
- package/src/lib/registry.mjs +102 -0
- package/src/lib/rename.mjs +116 -0
- package/src/lib/schema.mjs +123 -0
- package/src/lib/toggle.mjs +130 -0
- package/src/lib/tokens.mjs +96 -0
- package/src/lib/toml.mjs +137 -0
- package/src/lib/upgrade.mjs +159 -0
- package/src/lib/verify.mjs +97 -0
- package/src/scaffold.mjs +347 -0
- package/src/verify.mjs +4 -0
- package/src/versions/registry.json +42 -0
- package/template/.github/workflows/verify.yml +70 -0
- package/template/build.gradle.kts +17 -0
- package/template/composeApp/build.gradle.kts +257 -0
- package/template/composeApp/google-services.json +29 -0
- package/template/composeApp/proguard-rules.pro +34 -0
- package/template/composeApp/src/androidDebug/AndroidManifest.xml +13 -0
- package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/ComposeRootRegistry.kt +40 -0
- package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/InspectorCatalog.kt +80 -0
- package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/InspectorHttpServer.kt +322 -0
- package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/InspectorInit.kt +16 -0
- package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/LiveSemanticsJson.kt +102 -0
- package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/RemoteControlPage.kt +106 -0
- package/template/composeApp/src/androidDebug/res/xml/debug_network_security_config.xml +9 -0
- package/template/composeApp/src/androidMain/AndroidManifest.xml +28 -0
- package/template/composeApp/src/androidMain/kotlin/com/example/app/AppApplication.kt +72 -0
- package/template/composeApp/src/androidMain/kotlin/com/example/app/MainActivity.kt +24 -0
- package/template/composeApp/src/androidMain/kotlin/com/example/app/core/connectivity/NetworkMonitor.kt +42 -0
- package/template/composeApp/src/androidMain/kotlin/com/example/app/data/local/DatabaseBuilder.android.kt +13 -0
- package/template/composeApp/src/androidMain/kotlin/com/example/app/di/AndroidModule.kt +9 -0
- package/template/composeApp/src/androidMain/kotlin/com/example/app/presentation/components/TestTagAutomation.android.kt +11 -0
- package/template/composeApp/src/androidMain/res/drawable/ic_launcher_background.xml +9 -0
- package/template/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
- package/template/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
- package/template/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/template/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/template/composeApp/src/androidMain/res/values/colors.xml +6 -0
- package/template/composeApp/src/androidMain/res/values/themes.xml +9 -0
- package/template/composeApp/src/androidMain/res/values-v31/themes.xml +8 -0
- package/template/composeApp/src/androidRelease/kotlin/com/example/app/inspector/InspectorInit.kt +13 -0
- package/template/composeApp/src/commonMain/composeResources/font/DMSans_Bold.ttf +0 -0
- package/template/composeApp/src/commonMain/composeResources/font/DMSans_Medium.ttf +0 -0
- package/template/composeApp/src/commonMain/composeResources/font/DMSans_Regular.ttf +0 -0
- package/template/composeApp/src/commonMain/composeResources/font/DMSans_SemiBold.ttf +0 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/App.kt +7 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/core/connectivity/NetworkMonitor.kt +7 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/data/local/AppDatabase.kt +28 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/data/local/DatabaseBuilder.kt +14 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/data/local/ItemDao.kt +18 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/data/remote/FirebaseConfig.kt +5 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/data/remote/ItemRepositoryImpl.kt +22 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/di/AppModule.kt +23 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/domain/model/Item.kt +8 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/domain/repository/ItemRepository.kt +8 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/domain/usecase/GetItemsUseCase.kt +12 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/App.kt +13 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/components/BaseScreen.kt +69 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/components/TestTagAutomation.kt +18 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/home/DetailScreen.kt +39 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/home/HomeScreen.kt +87 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/home/HomeViewModel.kt +35 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/navigation/AppNavHost.kt +43 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/navigation/AppShell.kt +144 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/navigation/AppTab.kt +25 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/navigation/Screen.kt +15 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/profile/ProfileScreen.kt +43 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/DesignToken.kt +25 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/Shape.kt +12 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/Theme.kt +64 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/Tokens.kt +19 -0
- package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/Typography.kt +36 -0
- package/template/composeApp/src/desktopMain/kotlin/com/example/app/core/connectivity/NetworkMonitor.desktop.kt +9 -0
- package/template/composeApp/src/desktopMain/kotlin/com/example/app/data/local/DatabaseBuilder.desktop.kt +13 -0
- package/template/composeApp/src/desktopMain/kotlin/com/example/app/di/DesktopModule.kt +32 -0
- package/template/composeApp/src/desktopMain/kotlin/com/example/app/main.kt +29 -0
- package/template/composeApp/src/desktopMain/kotlin/com/example/app/presentation/components/TestTagAutomation.desktop.kt +6 -0
- package/template/composeApp/src/iosMain/kotlin/com/example/app/KoinHelper.kt +50 -0
- package/template/composeApp/src/iosMain/kotlin/com/example/app/MainViewController.kt +10 -0
- package/template/composeApp/src/iosMain/kotlin/com/example/app/core/connectivity/NetworkMonitor.kt +32 -0
- package/template/composeApp/src/iosMain/kotlin/com/example/app/data/local/DatabaseBuilder.ios.kt +10 -0
- package/template/composeApp/src/iosMain/kotlin/com/example/app/presentation/components/TestTagAutomation.ios.kt +11 -0
- package/template/docs/dev-client.md +52 -0
- package/template/gitignore +21 -0
- package/template/gradle/libs.versions.toml +100 -0
- package/template/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/template/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/template/gradle.properties +9 -0
- package/template/gradlew +152 -0
- package/template/gradlew.bat +94 -0
- package/template/iosApp/Podfile +27 -0
- package/template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png +0 -0
- package/template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json +14 -0
- package/template/iosApp/iosApp/Assets.xcassets/Contents.json +6 -0
- package/template/iosApp/iosApp/ContentView.swift +17 -0
- package/template/iosApp/iosApp/GoogleService-Info.plist +34 -0
- package/template/iosApp/iosApp/Info.plist +43 -0
- package/template/iosApp/iosApp/PrivacyInfo.xcprivacy +42 -0
- package/template/iosApp/iosApp/iOSApp.swift +33 -0
- package/template/iosApp/project.yml +56 -0
- package/template/local.properties.example +2 -0
- package/template/manifest.json +125 -0
- package/template/qa/appium/README.md +23 -0
- package/template/qa/appium/lib/appium-client.mjs +225 -0
- package/template/qa/appium/package.json +8 -0
- package/template/qa/appium/run-android-smoke.mjs +39 -0
- package/template/settings.gradle.kts +34 -0
- package/template/tests/appium/cmp/conftest.py +96 -0
- package/template/tests/appium/cmp/test_smoke.py +17 -0
package/template/composeApp/src/iosMain/kotlin/com/example/app/data/local/DatabaseBuilder.ios.kt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package __PACKAGE__.data.local
|
|
2
|
+
|
|
3
|
+
import androidx.room.Room
|
|
4
|
+
import androidx.room.RoomDatabase
|
|
5
|
+
import platform.Foundation.NSHomeDirectory
|
|
6
|
+
|
|
7
|
+
actual fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
|
|
8
|
+
val dbFilePath = NSHomeDirectory() + "/Documents/app.db"
|
|
9
|
+
return Room.databaseBuilder<AppDatabase>(name = dbFilePath)
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
package __PACKAGE__.presentation.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.ui.Modifier
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* iOS: no-op — `testTagsAsResourceId` is Android-only in the compose `ui` artifact at this
|
|
7
|
+
* version set. Compose Multiplatform on iOS already exposes `Modifier.testTag` through the
|
|
8
|
+
* accessibility tree (XCUITest/Appium can match it as the accessibility identifier), so no
|
|
9
|
+
* extra semantics flag is required here.
|
|
10
|
+
*/
|
|
11
|
+
actual fun Modifier.exposeTestTagsForAutomation(): Modifier = this
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Desktop dev-client — the daily dev loop
|
|
2
|
+
|
|
3
|
+
Your app ships with a pre-wired **JVM desktop run target**: the shared `commonMain` UI in a live,
|
|
4
|
+
clickable window on your workstation, with **Compose Hot Reload** attached. Edit a composable,
|
|
5
|
+
save, and watch the window update — no emulator, no reinstall, no restart.
|
|
6
|
+
|
|
7
|
+
## Run it
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Hot reload (recommended): auto-reloads on every save
|
|
11
|
+
./gradlew :composeApp:hotRunDesktop --auto
|
|
12
|
+
|
|
13
|
+
# Hot reload, explicit mode: reload only when you run the `reload` task
|
|
14
|
+
./gradlew :composeApp:hotRunDesktop
|
|
15
|
+
|
|
16
|
+
# Plain run (no hot reload — works on any JDK 17+)
|
|
17
|
+
./gradlew :composeApp:run
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The window is phone-sized (411×891 dp) and titled `__APP_NAME__ dev-client`.
|
|
21
|
+
|
|
22
|
+
### How reload triggers
|
|
23
|
+
|
|
24
|
+
- With `--auto` (or `--autoReload`), Gradle's continuous build watches your sources; **saving a
|
|
25
|
+
file** recompiles and hot-swaps the running UI in place.
|
|
26
|
+
- Without it, trigger reloads explicitly with the IDE's **Reload UI** button (IntelliJ /
|
|
27
|
+
Android Studio with the Kotlin Multiplatform plugin) or `./gradlew reload`.
|
|
28
|
+
- Hot reload runs on the **JetBrains Runtime**. The scaffold wires the
|
|
29
|
+
`foojay-resolver-convention` settings plugin so Gradle auto-downloads a JBR the first time you
|
|
30
|
+
run `hotRunDesktop` if none is installed (one-time download). `:composeApp:run` needs no JBR.
|
|
31
|
+
|
|
32
|
+
## What's real and what's faked on desktop
|
|
33
|
+
|
|
34
|
+
The desktop target reuses all of `commonMain` — screens, ViewModels, navigation, theme, DI. The
|
|
35
|
+
platform seams get JVM implementations in `composeApp/src/desktopMain`:
|
|
36
|
+
|
|
37
|
+
| Seam | Desktop implementation |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `NetworkMonitor` | Always-online stub (`NetworkMonitor.desktop.kt`) |
|
|
40
|
+
| Room database | Real Room via `BundledSQLiteDriver`, stored in the OS temp dir (`DatabaseBuilder.desktop.kt`) |
|
|
41
|
+
| Firebase | **Not wired at all** — the dev-client never initializes or contacts Firebase |
|
|
42
|
+
| `ItemRepository` (example feature) | The same in-memory `ItemRepositoryImpl` every platform binds |
|
|
43
|
+
|
|
44
|
+
When you add a real remote-backed repository, bind a desktop fake for it in
|
|
45
|
+
`desktopMain/.../di/DesktopModule.kt` so the dev-client keeps running without a backend.
|
|
46
|
+
|
|
47
|
+
## Limits
|
|
48
|
+
|
|
49
|
+
- Desktop is a **development client**, not a shipping target: platform-specific behavior
|
|
50
|
+
(permissions, push, deep links, insets) still needs the Android/iOS builds.
|
|
51
|
+
- Hot reload swaps UI and most code changes in place; structural changes (new `expect`/`actual`,
|
|
52
|
+
build-file edits) need a restart of the run task.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
*.iml
|
|
2
|
+
.gradle
|
|
3
|
+
/local.properties
|
|
4
|
+
.DS_Store
|
|
5
|
+
/build
|
|
6
|
+
/captures
|
|
7
|
+
.externalNativeBuild
|
|
8
|
+
.cxx
|
|
9
|
+
*.log
|
|
10
|
+
|
|
11
|
+
# Kotlin
|
|
12
|
+
.kotlin/
|
|
13
|
+
|
|
14
|
+
# iOS / CocoaPods / XcodeGen
|
|
15
|
+
iosApp/Pods/
|
|
16
|
+
iosApp/Podfile.lock
|
|
17
|
+
iosApp/*.xcodeproj/
|
|
18
|
+
iosApp/*.xcworkspace/
|
|
19
|
+
iosApp/build/
|
|
20
|
+
xcuserdata/
|
|
21
|
+
*.xcuserstate
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
[versions]
|
|
2
|
+
# ── Frozen, CI-verified version set (the reproducibility moat). Do not bump in
|
|
3
|
+
# ── isolation — Kotlin / KSP / Compose / Room / AGP move as ONE set or the build dies.
|
|
4
|
+
kotlin = "2.2.20"
|
|
5
|
+
agp = "8.7.3"
|
|
6
|
+
google-services = "4.4.2"
|
|
7
|
+
compose-multiplatform = "1.10.3"
|
|
8
|
+
koin = "4.1.1"
|
|
9
|
+
ktor = "3.1.0"
|
|
10
|
+
room = "2.8.4"
|
|
11
|
+
sqlite = "2.6.2"
|
|
12
|
+
# KSP MUST be <kotlin>-<ksp>. With ksp.useKSP2=true this is the combo that links Room on iOS native.
|
|
13
|
+
ksp = "2.2.20-2.0.4"
|
|
14
|
+
kotlinx-serialization = "1.7.3"
|
|
15
|
+
kotlinx-datetime = "0.7.0"
|
|
16
|
+
lifecycle = "2.10.0"
|
|
17
|
+
navigation = "2.9.2"
|
|
18
|
+
firebase-gitlive = "2.1.0"
|
|
19
|
+
# Desktop dev-client. CHR 1.1.1 (latest stable) needs Kotlin >= 2.1.20 + CMP >= 1.8.2 — satisfied
|
|
20
|
+
# by this set. The 1.2.x line (beta) additionally requires CMP 1.10+; safe to move to when stable.
|
|
21
|
+
compose-hot-reload = "1.1.1"
|
|
22
|
+
coil = "3.1.0"
|
|
23
|
+
androidx-core = "1.15.0"
|
|
24
|
+
androidx-activity = "1.10.1"
|
|
25
|
+
|
|
26
|
+
[libraries]
|
|
27
|
+
# Compose Multiplatform
|
|
28
|
+
compose-ui = { module = "org.jetbrains.compose.ui:ui" }
|
|
29
|
+
compose-foundation = { module = "org.jetbrains.compose.foundation:foundation" }
|
|
30
|
+
compose-material3 = { module = "org.jetbrains.compose.material3:material3" }
|
|
31
|
+
compose-material-icons-extended = { module = "org.jetbrains.compose.material:material-icons-extended" }
|
|
32
|
+
|
|
33
|
+
# Lifecycle / ViewModel (JetBrains KMP)
|
|
34
|
+
lifecycle-viewmodel = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel", version.ref = "lifecycle" }
|
|
35
|
+
lifecycle-viewmodel-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
|
|
36
|
+
lifecycle-runtime-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" }
|
|
37
|
+
|
|
38
|
+
# Navigation
|
|
39
|
+
navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigation" }
|
|
40
|
+
|
|
41
|
+
# Koin
|
|
42
|
+
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
|
|
43
|
+
koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" }
|
|
44
|
+
koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koin" }
|
|
45
|
+
koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" }
|
|
46
|
+
|
|
47
|
+
# Ktor
|
|
48
|
+
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
|
|
49
|
+
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
|
|
50
|
+
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
|
|
51
|
+
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
|
|
52
|
+
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
|
|
53
|
+
|
|
54
|
+
# Firebase GitLive KMP SDK
|
|
55
|
+
firebase-auth = { module = "dev.gitlive:firebase-auth", version.ref = "firebase-gitlive" }
|
|
56
|
+
firebase-firestore = { module = "dev.gitlive:firebase-firestore", version.ref = "firebase-gitlive" }
|
|
57
|
+
firebase-functions = { module = "dev.gitlive:firebase-functions", version.ref = "firebase-gitlive" }
|
|
58
|
+
firebase-storage = { module = "dev.gitlive:firebase-storage", version.ref = "firebase-gitlive" }
|
|
59
|
+
firebase-messaging = { module = "dev.gitlive:firebase-messaging", version.ref = "firebase-gitlive" }
|
|
60
|
+
firebase-config = { module = "dev.gitlive:firebase-config", version.ref = "firebase-gitlive" }
|
|
61
|
+
|
|
62
|
+
# Room KMP
|
|
63
|
+
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
|
|
64
|
+
room-runtime-android = { module = "androidx.room:room-runtime-android", version.ref = "room" }
|
|
65
|
+
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
|
|
66
|
+
sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" }
|
|
67
|
+
|
|
68
|
+
# Kotlinx
|
|
69
|
+
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
|
|
70
|
+
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
|
|
71
|
+
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.9.0" }
|
|
72
|
+
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version = "1.9.0" }
|
|
73
|
+
# Desktop dev-client: Dispatchers.Main for Compose on the JVM (Swing event loop).
|
|
74
|
+
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version = "1.9.0" }
|
|
75
|
+
|
|
76
|
+
# Coil (image loading KMP)
|
|
77
|
+
coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
|
|
78
|
+
coil-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" }
|
|
79
|
+
|
|
80
|
+
# Android
|
|
81
|
+
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
|
|
82
|
+
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
|
|
83
|
+
android-desugar-jdk = { module = "com.android.tools:desugar_jdk_libs", version = "2.1.3" }
|
|
84
|
+
|
|
85
|
+
# Test
|
|
86
|
+
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
|
87
|
+
koin-test = { module = "io.insert-koin:koin-test", version.ref = "koin" }
|
|
88
|
+
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version = "1.9.0" }
|
|
89
|
+
|
|
90
|
+
[plugins]
|
|
91
|
+
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
|
92
|
+
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
|
93
|
+
compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" }
|
|
94
|
+
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
|
95
|
+
android-application = { id = "com.android.application", version.ref = "agp" }
|
|
96
|
+
android-library = { id = "com.android.library", version.ref = "agp" }
|
|
97
|
+
google-services = { id = "com.google.gms.google-services", version.ref = "google-services" }
|
|
98
|
+
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
|
99
|
+
room = { id = "androidx.room", version.ref = "room" }
|
|
100
|
+
compose-hot-reload = { id = "org.jetbrains.compose.hot-reload", version.ref = "compose-hot-reload" }
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
kotlin.code.style=official
|
|
2
|
+
android.useAndroidX=true
|
|
3
|
+
org.gradle.jvmargs=-Xmx4g -XX:+UseG1GC
|
|
4
|
+
org.gradle.parallel=true
|
|
5
|
+
org.gradle.caching=true
|
|
6
|
+
kotlin.incremental=true
|
|
7
|
+
# KSP2 — fixes "ClassNotFoundException: org.jetbrains.kotlin.cli.utilities.MainKt"
|
|
8
|
+
# on Kotlin/Native (iOS) targets with Room's KSP processor (the KSP1 native catch-22).
|
|
9
|
+
ksp.useKSP2=true
|
package/template/gradlew
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
#
|
|
3
|
+
# Copyright © 2015-2021 the original authors.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
#
|
|
17
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
##############################################################################
|
|
21
|
+
#
|
|
22
|
+
# Gradle start up script for POSIX generated by "Gradle Wrapper".
|
|
23
|
+
#
|
|
24
|
+
# Important for running:
|
|
25
|
+
#
|
|
26
|
+
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
|
27
|
+
# noncompliant, but you have some other POSIX-compliant shell such as ksh or
|
|
28
|
+
# bash, then to run this script, type that shell name before the whole
|
|
29
|
+
# command line, like:
|
|
30
|
+
#
|
|
31
|
+
# ksh Gradle
|
|
32
|
+
#
|
|
33
|
+
# Busybox and similar reduced shells will NOT work, because this script
|
|
34
|
+
# requires all of these POSIX shell features:
|
|
35
|
+
# * functions;
|
|
36
|
+
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
|
37
|
+
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
|
38
|
+
# * compound commands having a testable exit status, especially «case»;
|
|
39
|
+
# * various built-in commands including «command», «set», and «ulimit».
|
|
40
|
+
#
|
|
41
|
+
# Important for security:
|
|
42
|
+
#
|
|
43
|
+
# (2) This script relies on the fact that it is not setuid. Security audit
|
|
44
|
+
# tools (e.g. Sonartype) will complain about world-writable files in the
|
|
45
|
+
# Gradle user home, but that is just by design.
|
|
46
|
+
#
|
|
47
|
+
##############################################################################
|
|
48
|
+
|
|
49
|
+
# Attempt to set APP_HOME
|
|
50
|
+
# Resolve links: $0 may be a link
|
|
51
|
+
app_path=$0
|
|
52
|
+
|
|
53
|
+
# Need this for daisy-chained symlinks.
|
|
54
|
+
while
|
|
55
|
+
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
|
56
|
+
[ -h "$app_path" ]
|
|
57
|
+
do
|
|
58
|
+
ls=$( ls -ld "$app_path" )
|
|
59
|
+
link=${ls#*' -> '}
|
|
60
|
+
case $link in #(
|
|
61
|
+
/*) app_path=$link ;; #( absolute
|
|
62
|
+
*) app_path=$APP_HOME$link ;; #( relative
|
|
63
|
+
esac
|
|
64
|
+
done
|
|
65
|
+
|
|
66
|
+
# This is reliable for both POSIX and GNU/Linux.
|
|
67
|
+
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
|
68
|
+
|
|
69
|
+
APP_NAME="Gradle"
|
|
70
|
+
APP_BASE_NAME=${0##*/}
|
|
71
|
+
|
|
72
|
+
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
73
|
+
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
74
|
+
|
|
75
|
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
76
|
+
MAX_FD=maximum
|
|
77
|
+
|
|
78
|
+
warn () {
|
|
79
|
+
echo "$*"
|
|
80
|
+
} >&2
|
|
81
|
+
|
|
82
|
+
die () {
|
|
83
|
+
echo
|
|
84
|
+
echo "$*"
|
|
85
|
+
echo
|
|
86
|
+
exit 1
|
|
87
|
+
} >&2
|
|
88
|
+
|
|
89
|
+
# OS specific support (must be 'true' or 'false').
|
|
90
|
+
cygwin=false
|
|
91
|
+
msys=false
|
|
92
|
+
darwin=false
|
|
93
|
+
nonstop=false
|
|
94
|
+
case "$( uname )" in #(
|
|
95
|
+
CYGWIN* ) cygwin=true ;; #(
|
|
96
|
+
Darwin* ) darwin=true ;; #(
|
|
97
|
+
MSYS* | MINGW* ) msys=true ;; #(
|
|
98
|
+
NONSTOP* ) nonstop=true ;;
|
|
99
|
+
esac
|
|
100
|
+
|
|
101
|
+
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# Determine the Java command to use to start the JVM.
|
|
105
|
+
if [ -n "$JAVA_HOME" ] ; then
|
|
106
|
+
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
107
|
+
# IBM's JDK on AIX uses strange locations for the executables
|
|
108
|
+
JAVACMD=$JAVA_HOME/jre/sh/java
|
|
109
|
+
else
|
|
110
|
+
JAVACMD=$JAVA_HOME/bin/java
|
|
111
|
+
fi
|
|
112
|
+
if [ ! -x "$JAVACMD" ] ; then
|
|
113
|
+
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
|
114
|
+
|
|
115
|
+
Please set the JAVA_HOME variable in your environment to match the
|
|
116
|
+
location of your Java installation."
|
|
117
|
+
fi
|
|
118
|
+
else
|
|
119
|
+
JAVACMD=java
|
|
120
|
+
if ! command -v java >/dev/null 2>&1
|
|
121
|
+
then
|
|
122
|
+
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
123
|
+
|
|
124
|
+
Please set the JAVA_HOME variable in your environment to match the
|
|
125
|
+
location of your Java installation."
|
|
126
|
+
fi
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# Increase the maximum file descriptors if we can.
|
|
130
|
+
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|
131
|
+
case $MAX_FD in #(
|
|
132
|
+
max*)
|
|
133
|
+
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
|
134
|
+
# shellcheck disable=SC2039,SC3045
|
|
135
|
+
MAX_FD=$( ulimit -H -n ) ||
|
|
136
|
+
warn "Could not query maximum file descriptor limit"
|
|
137
|
+
;;
|
|
138
|
+
esac
|
|
139
|
+
case $MAX_FD in #(
|
|
140
|
+
'' | soft) :;; #(
|
|
141
|
+
*)
|
|
142
|
+
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
|
143
|
+
# shellcheck disable=SC2039,SC3045
|
|
144
|
+
ulimit -n "$MAX_FD" ||
|
|
145
|
+
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
|
146
|
+
esac
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
|
150
|
+
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$@"
|
|
151
|
+
|
|
152
|
+
exec "$JAVACMD" "$@"
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
@rem
|
|
2
|
+
@rem Copyright 2015 the original author or authors.
|
|
3
|
+
@rem
|
|
4
|
+
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
@rem you may not use this file except in compliance with the License.
|
|
6
|
+
@rem You may obtain a copy of the License at
|
|
7
|
+
@rem
|
|
8
|
+
@rem https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
@rem
|
|
10
|
+
@rem Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
@rem See the License for the specific language governing permissions and
|
|
14
|
+
@rem limitations under the License.
|
|
15
|
+
@rem
|
|
16
|
+
@rem SPDX-License-Identifier: Apache-2.0
|
|
17
|
+
@rem
|
|
18
|
+
|
|
19
|
+
@if "%DEBUG%"=="" @echo off
|
|
20
|
+
@rem ##########################################################################
|
|
21
|
+
@rem
|
|
22
|
+
@rem Gradle startup script for Windows
|
|
23
|
+
@rem
|
|
24
|
+
@rem ##########################################################################
|
|
25
|
+
|
|
26
|
+
@rem Set local scope for the variables with windows NT shell
|
|
27
|
+
if "%OS%"=="Windows_NT" setlocal
|
|
28
|
+
|
|
29
|
+
set DIRNAME=%~dp0
|
|
30
|
+
if "%DIRNAME%"=="" set DIRNAME=.
|
|
31
|
+
@rem This is normally unused
|
|
32
|
+
set APP_BASE_NAME=%~n0
|
|
33
|
+
set APP_HOME=%DIRNAME%
|
|
34
|
+
|
|
35
|
+
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
|
36
|
+
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
|
37
|
+
|
|
38
|
+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
39
|
+
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
|
40
|
+
|
|
41
|
+
@rem Find java.exe
|
|
42
|
+
if defined JAVA_HOME goto findJavaFromJavaHome
|
|
43
|
+
|
|
44
|
+
set JAVA_EXE=java.exe
|
|
45
|
+
%JAVA_EXE% -version >NUL 2>&1
|
|
46
|
+
if %ERRORLEVEL% equ 0 goto execute
|
|
47
|
+
|
|
48
|
+
echo. 1>&2
|
|
49
|
+
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
|
50
|
+
echo. 1>&2
|
|
51
|
+
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
|
52
|
+
echo location of your Java installation. 1>&2
|
|
53
|
+
|
|
54
|
+
goto fail
|
|
55
|
+
|
|
56
|
+
:findJavaFromJavaHome
|
|
57
|
+
set JAVA_HOME=%JAVA_HOME:"=%
|
|
58
|
+
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|
59
|
+
|
|
60
|
+
if exist "%JAVA_EXE%" goto execute
|
|
61
|
+
|
|
62
|
+
echo. 1>&2
|
|
63
|
+
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
|
64
|
+
echo. 1>&2
|
|
65
|
+
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
|
66
|
+
echo location of your Java installation. 1>&2
|
|
67
|
+
|
|
68
|
+
goto fail
|
|
69
|
+
|
|
70
|
+
:execute
|
|
71
|
+
@rem Setup the command line
|
|
72
|
+
|
|
73
|
+
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@rem Execute Gradle
|
|
77
|
+
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
|
78
|
+
|
|
79
|
+
:end
|
|
80
|
+
@rem End local scope for the variables with windows NT shell
|
|
81
|
+
if %ERRORLEVEL% equ 0 goto mainEnd
|
|
82
|
+
|
|
83
|
+
:fail
|
|
84
|
+
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
85
|
+
rem the _cmd.exe /C_ return code!
|
|
86
|
+
set EXIT_CODE=%ERRORLEVEL%
|
|
87
|
+
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
|
88
|
+
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
|
89
|
+
exit /b %EXIT_CODE%
|
|
90
|
+
|
|
91
|
+
:mainEnd
|
|
92
|
+
if "%OS%"=="Windows_NT" endlocal
|
|
93
|
+
|
|
94
|
+
:omega
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# iOS native Firebase SDKs for the GitLive Firebase KMP bindings (v2.1.0 -> Firebase iOS 11.x).
|
|
2
|
+
# The ComposeApp KMP framework references these Obj-C symbols at link time; the app provides them.
|
|
3
|
+
platform :ios, '16.0'
|
|
4
|
+
|
|
5
|
+
# Static linkage pairs with the static ComposeApp.framework (isStatic = true).
|
|
6
|
+
use_frameworks! :linkage => :static
|
|
7
|
+
|
|
8
|
+
target 'iosApp' do
|
|
9
|
+
# >>> cmp:feature firebase
|
|
10
|
+
pod 'FirebaseCore', '~> 11.0'
|
|
11
|
+
pod 'FirebaseAuth', '~> 11.0'
|
|
12
|
+
pod 'FirebaseFirestore', '~> 11.0'
|
|
13
|
+
pod 'FirebaseFunctions', '~> 11.0'
|
|
14
|
+
pod 'FirebaseStorage', '~> 11.0'
|
|
15
|
+
pod 'FirebaseMessaging', '~> 11.0'
|
|
16
|
+
pod 'FirebaseRemoteConfig', '~> 11.0'
|
|
17
|
+
# <<< cmp:feature firebase
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
post_install do |installer|
|
|
21
|
+
installer.pods_project.targets.each do |target|
|
|
22
|
+
target.build_configurations.each do |config|
|
|
23
|
+
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
|
|
24
|
+
config.build_settings['ENABLE_USER_SCRIPT_SANDBOXING'] = 'NO'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
import ComposeApp
|
|
3
|
+
|
|
4
|
+
struct ContentView: View {
|
|
5
|
+
var body: some View {
|
|
6
|
+
ComposeView()
|
|
7
|
+
.ignoresSafeArea(.keyboard)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// UIViewControllerRepresentable that hosts the Compose Multiplatform entry point.
|
|
12
|
+
struct ComposeView: UIViewControllerRepresentable {
|
|
13
|
+
func makeUIViewController(context: Context) -> UIViewController {
|
|
14
|
+
MainViewControllerKt.MainViewController()
|
|
15
|
+
}
|
|
16
|
+
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
PLACEHOLDER — replace with the real GoogleService-Info.plist for your iOS app from the
|
|
4
|
+
Firebase console (Project settings → your iOS app → download). Not templated on purpose.
|
|
5
|
+
-->
|
|
6
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
7
|
+
<plist version="1.0">
|
|
8
|
+
<dict>
|
|
9
|
+
<key>API_KEY</key>
|
|
10
|
+
<string>REPLACE_ME_IOS_API_KEY</string>
|
|
11
|
+
<key>GCM_SENDER_ID</key>
|
|
12
|
+
<string>000000000000</string>
|
|
13
|
+
<key>PLIST_VERSION</key>
|
|
14
|
+
<string>1</string>
|
|
15
|
+
<key>BUNDLE_ID</key>
|
|
16
|
+
<string>__IOS_BUNDLE_ID__</string>
|
|
17
|
+
<key>PROJECT_ID</key>
|
|
18
|
+
<string>REPLACE_ME_PROJECT_ID</string>
|
|
19
|
+
<key>STORAGE_BUCKET</key>
|
|
20
|
+
<string>REPLACE_ME_PROJECT_ID.appspot.com</string>
|
|
21
|
+
<key>IS_ADS_ENABLED</key>
|
|
22
|
+
<false/>
|
|
23
|
+
<key>IS_ANALYTICS_ENABLED</key>
|
|
24
|
+
<false/>
|
|
25
|
+
<key>IS_APPINVITE_ENABLED</key>
|
|
26
|
+
<true/>
|
|
27
|
+
<key>IS_GCM_ENABLED</key>
|
|
28
|
+
<true/>
|
|
29
|
+
<key>IS_SIGNIN_ENABLED</key>
|
|
30
|
+
<true/>
|
|
31
|
+
<key>GOOGLE_APP_ID</key>
|
|
32
|
+
<string>1:000000000000:ios:0000000000000000000000</string>
|
|
33
|
+
</dict>
|
|
34
|
+
</plist>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CADisableMinimumFrameDurationOnPhone</key>
|
|
6
|
+
<true/>
|
|
7
|
+
<key>CFBundleDevelopmentRegion</key>
|
|
8
|
+
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
9
|
+
<key>CFBundleDisplayName</key>
|
|
10
|
+
<string>__APP_NAME__</string>
|
|
11
|
+
<key>CFBundleExecutable</key>
|
|
12
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
13
|
+
<key>CFBundleIdentifier</key>
|
|
14
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
15
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
16
|
+
<string>6.0</string>
|
|
17
|
+
<key>CFBundleName</key>
|
|
18
|
+
<string>$(PRODUCT_NAME)</string>
|
|
19
|
+
<key>CFBundlePackageType</key>
|
|
20
|
+
<string>APPL</string>
|
|
21
|
+
<key>CFBundleShortVersionString</key>
|
|
22
|
+
<string>1.0</string>
|
|
23
|
+
<key>CFBundleVersion</key>
|
|
24
|
+
<string>1</string>
|
|
25
|
+
<key>NSCameraUsageDescription</key>
|
|
26
|
+
<string>__APP_NAME__ uses the camera to capture photos.</string>
|
|
27
|
+
<key>NSLocationWhenInUseUsageDescription</key>
|
|
28
|
+
<string>__APP_NAME__ uses your location to show nearby content.</string>
|
|
29
|
+
<key>NSPhotoLibraryUsageDescription</key>
|
|
30
|
+
<string>__APP_NAME__ lets you attach photos to your profile.</string>
|
|
31
|
+
<key>UIApplicationSceneManifest</key>
|
|
32
|
+
<dict>
|
|
33
|
+
<key>UIApplicationSupportsMultipleScenes</key>
|
|
34
|
+
<false/>
|
|
35
|
+
</dict>
|
|
36
|
+
<key>UILaunchScreen</key>
|
|
37
|
+
<dict/>
|
|
38
|
+
<key>UISupportedInterfaceOrientations</key>
|
|
39
|
+
<array>
|
|
40
|
+
<string>UIInterfaceOrientationPortrait</string>
|
|
41
|
+
</array>
|
|
42
|
+
</dict>
|
|
43
|
+
</plist>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<!--
|
|
4
|
+
PrivacyInfo.xcprivacy — Apple Privacy Manifest (required from May 2024).
|
|
5
|
+
Declare privacy-sensitive API usages used by the app and its SDKs. Extend as you add data
|
|
6
|
+
collection (Firebase Auth email/phone, location, etc.).
|
|
7
|
+
https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
|
|
8
|
+
-->
|
|
9
|
+
<plist version="1.0">
|
|
10
|
+
<dict>
|
|
11
|
+
<key>NSPrivacyTracking</key>
|
|
12
|
+
<false/>
|
|
13
|
+
|
|
14
|
+
<key>NSPrivacyTrackingDomains</key>
|
|
15
|
+
<array/>
|
|
16
|
+
|
|
17
|
+
<key>NSPrivacyCollectedDataTypes</key>
|
|
18
|
+
<array/>
|
|
19
|
+
|
|
20
|
+
<key>NSPrivacyAccessedAPITypes</key>
|
|
21
|
+
<array>
|
|
22
|
+
<!-- UserDefaults: required by Firebase, Koin, and local cache -->
|
|
23
|
+
<dict>
|
|
24
|
+
<key>NSPrivacyAccessedAPIType</key>
|
|
25
|
+
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
|
26
|
+
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
27
|
+
<array>
|
|
28
|
+
<string>CA92.1</string>
|
|
29
|
+
</array>
|
|
30
|
+
</dict>
|
|
31
|
+
<!-- File timestamp APIs: SQLite (Room) -->
|
|
32
|
+
<dict>
|
|
33
|
+
<key>NSPrivacyAccessedAPIType</key>
|
|
34
|
+
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
|
35
|
+
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
36
|
+
<array>
|
|
37
|
+
<string>C617.1</string>
|
|
38
|
+
</array>
|
|
39
|
+
</dict>
|
|
40
|
+
</array>
|
|
41
|
+
</dict>
|
|
42
|
+
</plist>
|