From de4eb08ca6fa30890a0b5d667f9c24445d2d4f28 Mon Sep 17 00:00:00 2001 From: Yongwoo Marco Kim Date: Tue, 27 Oct 2026 14:00:54 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[#24]=20feat:=20Flutter=20Walking=20Skeleto?= =?UTF-8?q?n=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/flutter-ci.yml | 59 ++ .gitignore | 6 + .metadata | 33 + README.md | 23 + analysis_options.yaml | 35 + android/.gitignore | 14 + android/app/build.gradle.kts | 39 ++ android/app/src/debug/AndroidManifest.xml | 7 + android/app/src/main/AndroidManifest.xml | 45 ++ .../com/marcorable/maltto/MainActivity.kt | 5 + .../res/drawable-v21/launch_background.xml | 12 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values-night/styles.xml | 18 + android/app/src/main/res/values/styles.xml | 18 + android/app/src/profile/AndroidManifest.xml | 7 + android/build.gradle.kts | 24 + android/gradle.properties | 6 + .../gradle/wrapper/gradle-wrapper.properties | 5 + android/settings.gradle.kts | 26 + docs/deployment.md | 26 + docs/log/images/issue-24/android-default.png | Bin 0 -> 31642 bytes .../images/issue-24/android-large-text.png | Bin 0 -> 34794 bytes docs/log/images/issue-24/ios-default.png | Bin 0 -> 80398 bytes docs/log/images/issue-24/ios-large-text.png | Bin 0 -> 88538 bytes docs/log/issue-24-walking-skeleton.md | 46 ++ ios/.gitignore | 34 + ios/Flutter/AppFrameworkInfo.plist | 24 + ios/Flutter/Debug.xcconfig | 1 + ios/Flutter/Release.xcconfig | 1 + ios/Runner.xcodeproj/project.pbxproj | 650 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 119 ++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + ios/Runner/AppDelegate.swift | 16 + .../AppIcon.appiconset/Contents.json | 122 ++++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 10932 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 295 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 406 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 450 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 282 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 462 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 704 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 406 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 586 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 862 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 862 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 1674 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 762 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 1226 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 1418 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + ios/Runner/Base.lproj/LaunchScreen.storyboard | 37 + ios/Runner/Base.lproj/Main.storyboard | 26 + ios/Runner/Info.plist | 70 ++ ios/Runner/Runner-Bridging-Header.h | 1 + ios/Runner/SceneDelegate.swift | 6 + ios/RunnerTests/RunnerTests.swift | 12 + lib/main.dart | 7 + lib/src/app/app.dart | 22 + lib/src/app/dependencies.dart | 13 + .../scripts/data/local_script_repository.dart | 18 + .../scripts/data/script_repository.dart | 5 + lib/src/features/scripts/model/script.dart | 7 + .../presentation/script_list_view.dart | 61 ++ .../presentation/script_list_view_model.dart | 29 + .../database/in_memory_script_service.dart | 6 + .../database/script_service.dart | 15 + pubspec.lock | 501 ++++++++++++++ pubspec.yaml | 20 + scripts/build.sh | 2 +- scripts/check_public_repo.sh | 26 + scripts/lib.sh | 2 +- scripts/screenshot.sh | 17 +- scripts/test.sh | 1 + test/unit/local_script_repository_test.dart | 25 + test/widget/script_list_view_test.dart | 25 + 89 files changed, 2458 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/flutter-ci.yml create mode 100644 .metadata create mode 100644 README.md create mode 100644 analysis_options.yaml create mode 100644 android/.gitignore create mode 100644 android/app/build.gradle.kts create mode 100644 android/app/src/debug/AndroidManifest.xml create mode 100644 android/app/src/main/AndroidManifest.xml create mode 100644 android/app/src/main/kotlin/com/marcorable/maltto/MainActivity.kt create mode 100644 android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 android/app/src/main/res/drawable/launch_background.xml create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/values-night/styles.xml create mode 100644 android/app/src/main/res/values/styles.xml create mode 100644 android/app/src/profile/AndroidManifest.xml create mode 100644 android/build.gradle.kts create mode 100644 android/gradle.properties create mode 100644 android/gradle/wrapper/gradle-wrapper.properties create mode 100644 android/settings.gradle.kts create mode 100644 docs/deployment.md create mode 100644 docs/log/images/issue-24/android-default.png create mode 100644 docs/log/images/issue-24/android-large-text.png create mode 100644 docs/log/images/issue-24/ios-default.png create mode 100644 docs/log/images/issue-24/ios-large-text.png create mode 100644 docs/log/issue-24-walking-skeleton.md create mode 100644 ios/.gitignore create mode 100644 ios/Flutter/AppFrameworkInfo.plist create mode 100644 ios/Flutter/Debug.xcconfig create mode 100644 ios/Flutter/Release.xcconfig create mode 100644 ios/Runner.xcodeproj/project.pbxproj create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/Runner/AppDelegate.swift create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 ios/Runner/Base.lproj/Main.storyboard create mode 100644 ios/Runner/Info.plist create mode 100644 ios/Runner/Runner-Bridging-Header.h create mode 100644 ios/Runner/SceneDelegate.swift create mode 100644 ios/RunnerTests/RunnerTests.swift create mode 100644 lib/main.dart create mode 100644 lib/src/app/app.dart create mode 100644 lib/src/app/dependencies.dart create mode 100644 lib/src/features/scripts/data/local_script_repository.dart create mode 100644 lib/src/features/scripts/data/script_repository.dart create mode 100644 lib/src/features/scripts/model/script.dart create mode 100644 lib/src/features/scripts/presentation/script_list_view.dart create mode 100644 lib/src/features/scripts/presentation/script_list_view_model.dart create mode 100644 lib/src/infrastructure/database/in_memory_script_service.dart create mode 100644 lib/src/infrastructure/database/script_service.dart create mode 100644 pubspec.lock create mode 100644 pubspec.yaml create mode 100755 scripts/check_public_repo.sh create mode 100644 test/unit/local_script_repository_test.dart create mode 100644 test/widget/script_list_view_test.dart diff --git a/.github/workflows/flutter-ci.yml b/.github/workflows/flutter-ci.yml new file mode 100644 index 0000000..586dc5e --- /dev/null +++ b/.github/workflows/flutter-ci.yml @@ -0,0 +1,59 @@ +name: Flutter CI + +on: + pull_request: + push: + branches: + - develop + +permissions: + contents: read + +env: + FLUTTER_VERSION: 3.47.7 + +jobs: + policy-and-test: + name: Policy, analyze, and test + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + fetch-depth: 0 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2 + with: + channel: stable + flutter-version: ${{ env.FLUTTER_VERSION }} + cache: true + - run: flutter pub get + - run: ./scripts/check_public_repo.sh + - run: dart format --output=none --set-exit-if-changed . + - run: flutter analyze + - run: dart test test/unit + - run: flutter test + + android-debug: + name: Android Debug build + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2 + with: + channel: stable + flutter-version: ${{ env.FLUTTER_VERSION }} + cache: true + - run: flutter pub get + - run: flutter build apk --debug + + ios-debug: + name: iOS Simulator Debug build + runs-on: macos-26 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2 + with: + channel: stable + flutter-version: ${{ env.FLUTTER_VERSION }} + cache: true + - run: flutter pub get + - run: flutter build ios --simulator --debug --no-codesign diff --git a/.gitignore b/.gitignore index 45a4751..e62873b 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,12 @@ Tuist/.build/ .bundle/ vendor/bundle/ Pods/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +*.iml # ── 에이전트 로컬 설정 (개인 설정은 커밋하지 않음) ───────────────── .claude/settings.local.json diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..ed4693f --- /dev/null +++ b/.metadata @@ -0,0 +1,33 @@ +# 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 and should not be manually edited. + +version: + revision: "abaf9c523780a608bd46686fd5e53740a07077f8" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: abaf9c523780a608bd46686fd5e53740a07077f8 + base_revision: abaf9c523780a608bd46686fd5e53740a07077f8 + - platform: android + create_revision: abaf9c523780a608bd46686fd5e53740a07077f8 + base_revision: abaf9c523780a608bd46686fd5e53740a07077f8 + - platform: ios + create_revision: abaf9c523780a608bd46686fd5e53740a07077f8 + base_revision: abaf9c523780a608bd46686fd5e53740a07077f8 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/README.md b/README.md new file mode 100644 index 0000000..0fad5d5 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# 말또 + +사용자가 직접 입력한 대본을 반복해서 낭독하도록 돕는 Flutter 앱이다. 사용자 텍스트와 음성은 기기 밖으로 보내지 않는다. + +## 로컬 검증 + +Flutter 3.47.7과 Dart 3.13.5를 기준으로 한다. + +```bash +flutter pub get +./scripts/check_public_repo.sh +./scripts/test.sh +./scripts/build.sh +``` + +실행 중인 Android Emulator와 iOS Simulator에서 화면을 확인하고 스크린샷을 저장한다. + +```bash +./scripts/screenshot.sh android +./scripts/screenshot.sh ios +``` + +서명 없는 검증과 실제 배포 절차는 [`docs/deployment.md`](docs/deployment.md)에 분리해 두었다. diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..e32dcfd --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,35 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +analyzer: + exclude: + - build/** + - android/** + - ios/** + - spikes/** + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..be3943c --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,14 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/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/android/app/build.gradle.kts b/android/app/build.gradle.kts new file mode 100644 index 0000000..cfbd2fc --- /dev/null +++ b/android/app/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + id("com.android.application") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.marcorable.maltto" + compileSdk = 36 + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + defaultConfig { + applicationId = "com.marcorable.maltto" + minSdk = 33 + targetSdk = 36 + // Uses the version code from pubspec.yaml. When using split APKs, 1000 * ABI_VERSION + // is added automatically by Flutter. (https://developer.android.com/studio/build/configure-apk-splits#configure-APK-versions) + // You can force using the value of versionCode by specifying the `-P force-version-code-ignoring-abi=true` + // flag during build. + versionCode = flutter.versionCode + versionName = flutter.versionName + } + +} + +kotlin { + compilerOptions { + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + } +} + +flutter { + source = "../.." +} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8585b7f --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/marcorable/maltto/MainActivity.kt b/android/app/src/main/kotlin/com/marcorable/maltto/MainActivity.kt new file mode 100644 index 0000000..6dec967 --- /dev/null +++ b/android/app/src/main/kotlin/com/marcorable/maltto/MainActivity.kt @@ -0,0 +1,5 @@ +package com.marcorable.maltto + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle.kts b/android/build.gradle.kts new file mode 100644 index 0000000..dbee657 --- /dev/null +++ b/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/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..e96108c --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,6 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +# This newDsl flag was added by the Flutter template +android.newDsl=false +# This builtInKotlin flag was added by the Flutter template +android.builtInKotlin=false diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a20f2c4 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts new file mode 100644 index 0000000..b28021a --- /dev/null +++ b/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "9.1.0" apply false + id("org.jetbrains.kotlin.android") version "2.4.0" apply false +} + +include(":app") diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..d258375 --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,26 @@ +# 빌드 검증과 배포 서명 + +## 시크릿 없는 검증 + +Pull Request와 `develop` CI는 배포 자격 증명을 사용하지 않는다. + +- `flutter analyze`, 순수 Dart 테스트, Flutter 테스트 +- Android Debug APK 빌드 +- iOS Simulator Debug 앱 빌드(`--no-codesign`) +- 커밋 금지 파일, 대표적인 시크릿 패턴, 제품 경로의 제3자 콘텐츠 표지 검사 + +이 단계는 같은 커밋이 양 플랫폼에서 컴파일되고 테스트되는지 확인한다. 시뮬레이터 앱은 서명이 필요 없고 실제 기기에 배포하지 않는다. + +## 실제 배포 + +TestFlight와 스토어 배포는 별도의 출시 Issue와 보호된 배포 workflow에서만 수행한다. 저장소에는 인증서, provisioning profile, App Store Connect API 키, Android keystore를 넣지 않는다. 필요한 값은 GitHub Actions Secrets 또는 배포 머신의 레포 밖 keychain/credential store에서 주입하며 로그에 출력하지 않는다. + +배포 단계는 다음 조건을 모두 확인한 뒤 추가한다. + +1. Marco가 배포 실행과 대상 버전을 승인한다. +2. 보호된 environment와 최소 권한을 설정한다. +3. iOS 배포 서명과 Android release signing을 실행 시점에만 구성한다. +4. 서명 전과 동일한 소스 커밋에서 release artifact를 만든다. +5. 업로드 결과와 artifact 식별자만 기록하고 자격 증명은 즉시 정리한다. + +현재 Walking Skeleton에는 실제 배포 workflow를 포함하지 않는다. diff --git a/docs/log/images/issue-24/android-default.png b/docs/log/images/issue-24/android-default.png new file mode 100644 index 0000000000000000000000000000000000000000..9e2ed8bea21eae53a7209d7e9e62507a1123ef91 GIT binary patch literal 31642 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 literal 0 HcmV?d00001 diff --git a/docs/log/images/issue-24/ios-large-text.png b/docs/log/images/issue-24/ios-large-text.png new file mode 100644 index 0000000000000000000000000000000000000000..b3bde12a1b2dbfc1d46cb3a86f4b7bc0a92cfecd GIT binary patch literal 88538 zcmeFaS6EY97dEQc5EWDelxo?CbW!P5QQ1mUkQxXGA|g#nD4|4bND)-3QWcRJ0!Rog zfYPL+kWfNVkQyMg&_c*R;}&#(`+v^Gxj7dn7d|X0Yt1$0DDV4@2_xv5j>bL~Zk8=u zw(Ps|_eH%eTecT&*}|g2yc2xpWl6Ii_^{PYPvgRtoEF}3@Slq|##e4@Yi|(&*UVeC z2HI`ePX8A0j~o2kvSnNH)-Bt>$F20wB{OY&b$em*wvB5R75X=}hnh}p*`l`P%Ej|H zytYpE?TO@r`R$rPTsX*dg_%j7nTcsmo~=yVnfD)6yT4`gB4Cw8 z3+3Fo5c>O58(&j%-ultdnTPc6AE1A=!`Sk2uYZ@5&vdb^&lk`C+;l4wnlrX=q}!0l zKf$|kyWbB8VA+Z}ZkTL*>5p~%^Ig{v;E~k2zu9*G=b<9ow?jBi86No8>VGcALM_*T zCiPYQKg$5m`DnN!*x-NPc`Fl{Yrg{y5xVgF_o99+Gx-9zTYweEe^#wV-LV})7C52& z*PrJ5`EBX@_d6IcUWc(e3}<7+4kHyX67~Q0btm8mne>+b;Qtg$Yr&ancHKxp&FIKL zet5bVq%d1)fTvUFxE0Q%v$M{UsE+3(Vb8TrzEs& zQPf{FpQurAsSl| z>+^G!+t?zReUJYzDfjj6wtTqH^w^c{Cm@b!gYKJwd<}b`GY|49)1@)gMFPqpzy4$j zv3mO?->4sD3KLUGD)(UuQ;`bn^`}fVLVc!ipJ!hm&Kuz~$iUQt*_u4h znm;|>)5ujm^SDEQ_kbssXr57bEq)VDs7VGCv5eR9IE&HNT4`o<47N_Gp!wV|`m4s^ zLg{pg{mPK)`q12JXGQsB1#KOf^#sm`c-vXGG5{wchjU7&UytQzbBIDkWp;WJF>v~cYy|Aw89pjp<*jBhcM;EuDNj9a(G6c%2KbJCa=bcO=NRAk;z52 zc2s4l*mXQLW^v`H(u0gIy=5H;ns{N?+p^hb&SE44jRNuX2_2PZ^~hdU9G}QSO}nk< z>6$&}M07e7cHc&dwhum}6j|F~$$0y|ey&mDC49M!D|rHkB%B&D8wxJf5b!I2W!acL z?(7@%9g>J&rd*FxVtRnAKN}q}r!_c{jj5nc4L{*=Iy|#>`Jlt4*t4&5ZGaCVb$w5Y z^m2>xe8k_U6_j1saHBT0fFcEA_JqOLh7D3VpBff=H@jf$MOCYxMz*f|CiM z^?wDn4+fo>J@j(9I+?2OkxTvHxKpuw={ErHxPH`0RS~2K2!^kg)ICdqQDo4wlg^aI zTDkQKDxo5Z9<9!OiC(MYX&9#^p4Rf}i?e-hcd?T;lA@CEFCnY$$Fj?T&lETrga$2; zfVdV^%mep21 zYpCcAF4jWD8%F|F*S^OpaR{F5M~o^Cm~>NP-_3tM5uWYadi6KcNI9^KqOGFl@R)Km z`PRHgvh-`Xb+L1)>g+pm5z#8iZ}CXu+%|m4$ZLE2dSb=Y2aG^%lxCm!1x!(h%^8(r zQi+ca&##qF7@#IphVeW0Oc4%R#}y@?w=chMnYCgqXV>!0T7Y6KPwvq7@fX>T5u7e) z*FmbK)2^^dcdd@dR+vDSN;=5{ShB)ML&;=*qsTx=)T~{tz}iQF$mQ@4h!9%tVE

Ie1h0GEaDY|oT6OVqSH+Uf#z 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 literal 0 HcmV?d00001 diff --git a/docs/log/issue-24-walking-skeleton.md b/docs/log/issue-24-walking-skeleton.md new file mode 100644 index 0000000..9d38404 --- /dev/null +++ b/docs/log/issue-24-walking-skeleton.md @@ -0,0 +1,46 @@ +# Issue #24 Walking Skeleton 검증 + +## 구현 결과 + +- Flutter 3.47.7 / Dart 3.13.5 기준의 `maltto` 앱을 루트에 생성했다. +- `ScriptListView → ScriptListViewModel → ScriptRepository → ScriptService` 경계를 연결하고 구체 구현 조립은 `app/dependencies.dart`에 한정했다. +- iOS deployment target 26.0, Android minSdk 33 / compileSdk 36 / targetSdk 36, 양 플랫폼 식별자 `com.marcorable.maltto`를 적용했다. +- PR과 `develop`에서 분석·Dart/Flutter 테스트·Android Debug·서명 없는 iOS Simulator Debug 빌드를 실행하는 CI를 추가했다. +- 실제 배포 서명은 별도 보호 단계로 분리하고 인증 자료를 저장소에 넣지 않는 기준을 `docs/deployment.md`에 기록했다. + +## 로컬 검증 환경 + +- macOS, Apple silicon +- Flutter 3.47.7 stable / Dart 3.13.5 +- Xcode 26.2 +- Android Emulator API 36 (`Medium_Phone_API_36`) +- iOS 26.3 Simulator (`iPhone 17 Pro`) + +## 실행 결과 + +| 검증 | 명령 | 결과 | +|---|---|---| +| Public 저장소 정책 | `./scripts/check_public_repo.sh` | 통과 | +| 포맷 | `dart format --output=none --set-exit-if-changed .` | 변경 0건 | +| 정적 분석 | `flutter analyze` | 문제 0건 | +| 순수 Dart 테스트 | `dart test test/unit` | 1건 통과 | +| Flutter 테스트 | `flutter test` | 2건 통과 | +| Android Debug | `flutter build apk --debug` | 성공 | +| iOS Simulator Debug | `flutter build ios --simulator --debug --no-codesign` | 성공 | +| Android 실행 | API 36 Emulator에 APK 설치·실행 | 성공 | +| iOS 실행 | iOS 26.3 Simulator에 앱 설치·실행 | 성공 | + +Android Emulator 최초 부팅 중 System UI 응답 지연 안내가 한 번 나타났다. 부팅 완료 상태를 확인하고 안내를 닫은 뒤 앱을 재실행해 정상 화면을 다시 캡처했다. 재발 방지를 위해 캡처 스크립트가 Android 부팅 완료와 boot animation 종료를 확인하도록 보강했다. + +## 화면 확인 + +| 플랫폼 | 기본 글씨 | 큰 글씨 | +|---|---|---| +| Android | ![Android 기본 글씨](images/issue-24/android-default.png) | ![Android 큰 글씨](images/issue-24/android-large-text.png) | +| iOS | ![iOS 기본 글씨](images/issue-24/ios-default.png) | ![iOS 큰 글씨](images/issue-24/ios-large-text.png) | + +양 플랫폼에서 Cupertino 기반 빈 대본 화면이 표시됐고, 큰 글씨에서도 제목과 빈 상태 문구가 잘리거나 겹치지 않았다. 화면에는 기본 탑재 대본이나 제3자 텍스트가 없다. + +## CI와 배포 경계 + +CI workflow 파일은 로컬에서 구성과 명령을 검증했지만, 이 작업에서는 push를 하지 않았으므로 GitHub-hosted runner의 실제 실행 결과는 아직 없다. PR을 열기 전에 사용자 확인을 받고 push한 뒤 세 job의 통과를 확인해야 한다. TestFlight와 스토어 업로드는 이 Issue 범위가 아니며 배포 시크릿도 만들거나 읽지 않았다. diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..391a902 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..89576b6 --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,650 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 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 */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 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 = ""; }; + 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 = ""; }; + 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 = ""; }; + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, + ); + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + 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++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + 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; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.marcorable.maltto; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + 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.marcorable.maltto.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + 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.marcorable.maltto.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + 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.marcorable.maltto.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + 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++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + 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; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + 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++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + 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; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.marcorable.maltto; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.marcorable.maltto; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..c3fedb2 --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..c30b367 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,16 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9ada4725e9b0ddb1deab583e5b5102493aa332 GIT binary patch literal 10932 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..797d452e458972bab9d994556c8305db4c827017 GIT binary patch literal 406 zcmV;H0crk;P))>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed2d933e1120817fe9182483a228007b18ab6ae GIT binary patch literal 450 zcmV;z0X_bSP)iGWQ_5NJQ_~rNh*z)}eT%KUb z`7gNk0#AwF^#0T0?hIa^`~Ck;!}#m+_uT050aTR(J!bU#|IzRL%^UsMS#KsYnTF*!YeDOytlP4VhV?b} z%rz_<=#CPc)tU1MZTq~*2=8~iZ!lSa<{9b@2Jl;?IEV8)=fG217*|@)CCYgFze-x? zIFODUIA>nWKpE+bn~n7;-89sa>#DR>TSlqWk*!2hSN6D~Qb#VqbP~4Fk&m`@1$JGr zXPIdeRE&b2Thd#{MtDK$px*d3-Wx``>!oimf%|A-&-q*6KAH)e$3|6JV%HX{Hig)k suLT-RhftRq8b9;(V=235Wa|I=027H2wCDra;{X5v07*qoM6N<$f;9x^2LJ#7 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..4cd7b0099ca80c806f8fe495613e8d6c69460d76 GIT binary patch literal 282 zcmV+#0p(^bcu7P-R4C8Q z&e;xxFbF_Vrezo%_kH*OKhshZ6BFpG-Y1e10`QXJKbND7AMQ&cMj60B5TNObaZxYybcN07*qoM6N<$g3m;S%K!iX literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fe730945a01f64a61e2235dbe3f45b08f7729182 GIT binary patch literal 462 zcmV;<0WtoGP)-}iV`2<;=$?g5M=KQbZ{F&YRNy7Nn@%_*5{gvDM0aKI4?ESmw z{NnZg)A0R`+4?NF_RZexyVB&^^ZvN!{I28tr{Vje;QNTz`dG&Jz0~Ek&f2;*Z7>B|cg}xYpxEFY+0YrKLF;^Q+-HreN0P{&i zK~zY`?b7ECf-n?@;d<&orQ*Q7KoR%4|C>{W^h6@&01>0SKS`dn{Q}GT%Qj_{PLZ_& zs`MFI#j-(>?bvdZ!8^xTwlY{qA)T4QLbY@j(!YJ7aXJervHy6HaG_2SB`6CC{He}f zHVw(fJWApwPq!6VY7r1w-Fs)@ox~N+q|w~e;JI~C4Vf^@d>Wvj=fl`^u9x9wd9 zR%3*Q+)t%S!MU_`id^@&Y{y7-r98lZX0?YrHlfmwb?#}^1b{8g&KzmkE(L>Z&)179 zp<)v6Y}pRl100G2FL_t(o!|l{-Q-VMg#&MKg7c{O0 z2wJImOS3Gy*Z2Qifdv~JYOp;v+U)a|nLoc7hNH;I$;lzDt$}rkaFw1mYK5_0Q(Sut zvbEloxON7$+HSOgC9Z8ltuC&0OSF!-mXv5caV>#bc3@hBPX@I$58-z}(ZZE!t-aOG zpjNkbau@>yEzH(5Yj4kZiMH32XI!4~gVXNnjAvRx;Sdg^`>2DpUEwoMhTs_st8pKG z(%SHyHdU&v%f36~uERh!bd`!T2dw;z6PrOTQ7Vt*#9F2uHlUVnb#ev_o^fh}Dzmq} zWtlk35}k=?xj28uO|5>>$yXadTUE@@IPpgH`gJ~Ro4>jd1IF|(+IX>8M4Ps{PNvmI zNj4D+XgN83gPt_Gm}`Ybv{;+&yu-C(Grdiahmo~BjG-l&mWM+{e5M1sm&=xduwgM9 z`8OEh`=F3r`^E{n_;%9weN{cf2%7=VzC@cYj+lg>+3|D|_1C@{hcU(DyQG_BvBWe? zvTv``=%b1zrol#=R`JB)>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..502f463a9bc882b461c96aadf492d1729e49e725 GIT binary patch literal 586 zcmV-Q0=4~#P)+}#`wDE{8-2Mebf5<{{PqV{TgVcv*r8?UZ3{-|G?_}T*&y;@cqf{ z{Q*~+qr%%p!1pS*_Uicl#q9lc(D`!D`LN62sNwq{oYw(Wmhk)k<@f$!$@ng~_5)Ru z0Z)trIA5^j{DIW^c+vT2%lW+2<(RtE2wR;4O@)Tm`Xr*?A(qYoM}7i5Yxw>D(&6ou zxz!_Xr~yNF+waPe00049Nkl*;a!v6h%{rlvIH#gW3s8p;bFr=l}mRqpW2h zw=OA%hdyL~z+UHOzl0eKhEr$YYOL-c-%Y<)=j?(bzDweB7{b+%_ypvm_cG{SvM=DK zhv{K@m>#Bw>2W$eUI#iU)Wdgs8Y3U+A$Gd&{+j)d)BmGKx+43U_!tik_YlN)>$7G! zhkE!s;%oku3;IwG3U^2kw?z+HM)jB{@zFhK8P#KMSytSthr+4!c(5c%+^UBn`0X*2 zy3(k600_CSZj?O$Qu%&$;|TGUJrptR(HzyIx>5E(2r{eA(<6t3e3I0B)7d6s7?Z5J zZ!rtKvA{MiEBm&KFtoifx>5P^Z=vl)95XJn()aS5%ad(s?4-=Tkis9IGu{`Fy8r+H07*qoM6N<$f20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0ec303439225b78712f49115768196d8d76f6790 GIT binary patch literal 862 zcmV-k1EKthP)20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e9f5fea27c705180eb716271f41b582e76dcbd90 GIT binary patch literal 1674 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0467bf12aa4d28f374bb26596605a46dcbb3e7c8 GIT binary patch literal 1418 zcmV;51$Fv~P)q zKfU)WzW*n(@|xWGCA9ScMt*e9`2kdxPQ&&>|-UCa7_51w+ zLUsW@ZzZSW0y$)Hp~e9%PvP|a03ks1`~K?q{u;6NC8*{AOqIUq{CL&;p56Lf$oQGq z^={4hPQv)y=I|4n+?>7Fim=dxt1 z2H+Dm+1+fh+IF>G0SjJMkQQre1x4|G*Z==(Ot&kCnUrL4I(rf(ucITwmuHf^hXiJT zkdTm&kdTm&kdTm&kdP`esgWG0BcWCVkVZ&2dUwN`cgM8QJb`Z7Z~e<&Yj2(}>Tmf` zm1{eLgw!b{bXkjWbF%dTkTZEJWyWOb##Lfw4EK2}<0d6%>AGS{po>WCOy&f$Tay_> z?NBlkpo@s-O;0V%Y_Xa-G#_O08q5LR*~F%&)}{}r&L%Sbs8AS4t7Y0NEx*{soY=0MZExqA5XHQkqi#4gW3 zqODM^iyZl;dvf)-bOXtOru(s)Uc7~BFx{w-FK;2{`VA?(g&@3z&bfLFyctOH!cVsF z7IL=fo-qBndRUm;kAdXR4e6>k-z|21AaN%ubeVrHl*<|s&Ax@W-t?LR(P-24A5=>a z*R9#QvjzF8n%@1Nw@?CG@6(%>+-0ASK~jEmCV|&a*7-GKT72W<(TbSjf)&Eme6nGE z>Gkj4Sq&2e+-G%|+NM8OOm5zVl9{Z8Dd8A5z3y8mZ=4Bv4%>as_{9cN#bm~;h>62( zdqY93Zy}v&c4n($Vv!UybR8ocs7#zbfX1IY-*w~)p}XyZ-SFC~4w>BvMVr`dFbelV{lLL0bx7@*ZZdebr3`sP;? zVImji)kG)(6Juv0lz@q`F!k1FE;CQ(D0iG$wchPbKZQELlsZ#~rt8#90Y_Xh&3U-< z{s<&cCV_1`^TD^ia9!*mQDq& zn2{r`j};V|uV%_wsP!zB?m%;FeaRe+X47K0e+KE!8C{gAWF8)lCd1u1%~|M!XNRvw zvtqy3iz0WSpWdhn6$hP8PaRBmp)q`#PCA`Vd#Tc$@f1tAcM>f_I@bC)hkI9|o(Iqv zo}Piadq!j76}004RBio<`)70k^`K1NK)q>w?p^C6J2ZC!+UppiK6&y3Kmbv&O!oYF z34$0Z;QO!JOY#!`qyGH<3Pd}Pt@q*A0V=3SVtWKRR8d8Z&@)3qLPA19LPA19LPEUC YUoZo%k(ykuW&i*H07*qoM6N<$f+CH{y8r+H literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..f2a5205 --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,70 @@ + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + 말또 + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + maltto + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/ios/Runner/SceneDelegate.swift b/ios/Runner/SceneDelegate.swift new file mode 100644 index 0000000..b9ce8ea --- /dev/null +++ b/ios/Runner/SceneDelegate.swift @@ -0,0 +1,6 @@ +import Flutter +import UIKit + +class SceneDelegate: FlutterSceneDelegate { + +} diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..fa1ad27 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,7 @@ +import 'package:flutter/widgets.dart'; +import 'package:maltto/src/app/dependencies.dart'; + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + runApp(createApp()); +} diff --git a/lib/src/app/app.dart b/lib/src/app/app.dart new file mode 100644 index 0000000..700aaf3 --- /dev/null +++ b/lib/src/app/app.dart @@ -0,0 +1,22 @@ +import 'package:flutter/cupertino.dart'; +import 'package:maltto/src/features/scripts/presentation/script_list_view.dart'; +import 'package:maltto/src/features/scripts/presentation/script_list_view_model.dart'; + +final class MalttoApp extends StatelessWidget { + const MalttoApp({required this.scriptListViewModel, super.key}); + + final ScriptListViewModel scriptListViewModel; + + @override + Widget build(BuildContext context) { + return CupertinoApp( + debugShowCheckedModeBanner: false, + title: '말또', + theme: const CupertinoThemeData( + primaryColor: CupertinoColors.systemBlue, + scaffoldBackgroundColor: CupertinoColors.systemBackground, + ), + home: ScriptListView(viewModel: scriptListViewModel), + ); + } +} diff --git a/lib/src/app/dependencies.dart b/lib/src/app/dependencies.dart new file mode 100644 index 0000000..c349286 --- /dev/null +++ b/lib/src/app/dependencies.dart @@ -0,0 +1,13 @@ +import 'package:flutter/widgets.dart'; +import 'package:maltto/src/app/app.dart'; +import 'package:maltto/src/features/scripts/data/local_script_repository.dart'; +import 'package:maltto/src/features/scripts/presentation/script_list_view_model.dart'; +import 'package:maltto/src/infrastructure/database/in_memory_script_service.dart'; + +Widget createApp() { + final scriptService = InMemoryScriptService(); + final scriptRepository = LocalScriptRepository(scriptService); + final scriptListViewModel = ScriptListViewModel(scriptRepository); + + return MalttoApp(scriptListViewModel: scriptListViewModel); +} diff --git a/lib/src/features/scripts/data/local_script_repository.dart b/lib/src/features/scripts/data/local_script_repository.dart new file mode 100644 index 0000000..8e50a19 --- /dev/null +++ b/lib/src/features/scripts/data/local_script_repository.dart @@ -0,0 +1,18 @@ +import 'package:maltto/src/features/scripts/data/script_repository.dart'; +import 'package:maltto/src/features/scripts/model/script.dart'; +import 'package:maltto/src/infrastructure/database/script_service.dart'; + +final class LocalScriptRepository implements ScriptRepository { + const LocalScriptRepository(this._service); + + final ScriptService _service; + + @override + Stream> watchAll() { + return _service.watchAll().map( + (rows) => List.unmodifiable( + rows.map((row) => Script(id: row.id, title: row.title, body: row.body)), + ), + ); + } +} diff --git a/lib/src/features/scripts/data/script_repository.dart b/lib/src/features/scripts/data/script_repository.dart new file mode 100644 index 0000000..4c694fb --- /dev/null +++ b/lib/src/features/scripts/data/script_repository.dart @@ -0,0 +1,5 @@ +import 'package:maltto/src/features/scripts/model/script.dart'; + +abstract interface class ScriptRepository { + Stream> watchAll(); +} diff --git a/lib/src/features/scripts/model/script.dart b/lib/src/features/scripts/model/script.dart new file mode 100644 index 0000000..6ff54f9 --- /dev/null +++ b/lib/src/features/scripts/model/script.dart @@ -0,0 +1,7 @@ +final class Script { + const Script({required this.id, required this.title, required this.body}); + + final int id; + final String title; + final String body; +} diff --git a/lib/src/features/scripts/presentation/script_list_view.dart b/lib/src/features/scripts/presentation/script_list_view.dart new file mode 100644 index 0000000..29a1db1 --- /dev/null +++ b/lib/src/features/scripts/presentation/script_list_view.dart @@ -0,0 +1,61 @@ +import 'package:flutter/cupertino.dart'; +import 'package:maltto/src/features/scripts/presentation/script_list_view_model.dart'; + +final class ScriptListView extends StatefulWidget { + const ScriptListView({required this.viewModel, super.key}); + + final ScriptListViewModel viewModel; + + @override + State createState() => _ScriptListViewState(); +} + +final class _ScriptListViewState extends State { + @override + void initState() { + super.initState(); + widget.viewModel.load(); + } + + @override + Widget build(BuildContext context) { + return CupertinoPageScaffold( + navigationBar: const CupertinoNavigationBar(middle: Text('대본')), + child: SafeArea( + child: AnimatedBuilder( + animation: widget.viewModel, + builder: (context, child) { + if (widget.viewModel.scripts.isEmpty) { + return Center( + child: Padding( + padding: const EdgeInsets.all(24), + child: Semantics( + label: '저장된 대본 없음', + child: const Text( + '저장된 대본이 없습니다.', + textAlign: TextAlign.center, + ), + ), + ), + ); + } + + return ListView.builder( + itemCount: widget.viewModel.scripts.length, + itemBuilder: (context, index) { + final script = widget.viewModel.scripts[index]; + return Semantics( + label: '${script.title}, 낭독 설정 열기', + child: Padding( + padding: const EdgeInsets.all(16), + child: Text(script.title), + ), + ); + }, + ); + }, + ), + ), + ); + } +} diff --git a/lib/src/features/scripts/presentation/script_list_view_model.dart b/lib/src/features/scripts/presentation/script_list_view_model.dart new file mode 100644 index 0000000..e6ecdf3 --- /dev/null +++ b/lib/src/features/scripts/presentation/script_list_view_model.dart @@ -0,0 +1,29 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:maltto/src/features/scripts/data/script_repository.dart'; +import 'package:maltto/src/features/scripts/model/script.dart'; + +final class ScriptListViewModel extends ChangeNotifier { + ScriptListViewModel(this._repository); + + final ScriptRepository _repository; + StreamSubscription>? _subscription; + List