Kotlin Multiplatform 네이티브 앱으로 전환 (Android + iOS 공용 코드)

TWA 래퍼를 걷어내고 Compose Multiplatform 으로 다시 만들었다. 엔진·UI·모드
전부 commonMain 한 벌이라 Android 와 iOS 가 같은 코드를 쓴다.

- engine/: 웹 JS 엔진을 Kotlin 으로 이식 (SRS+180 킥, 7-bag, T-spin, B2B,
  콤보, All Clear, 점수·레벨). commonTest 28개 통과
- game/: 모드 규칙 + 중력/락딜레이/DAS/ARR 타이밍
- ui/: 네오브루탈 컴포넌트, 메인/솔로시트/인게임/결과/설정
- ui/Responsive.kt: 고정 해상도를 버리고 가용 크기에서 셀 크기·배율 계산.
  폰 세로, 플립 초세로, 플립 커버(소형), 폴드 펼침, 태블릿/아이패드 가로 대응
- androidMain: resizeableActivity + configChanges 로 접기/펴기·회전 시 재시작 없음
- iosMain + iosApp/: MainViewController + SwiftUI 껍데기 + XcodeGen 설정
  (실제 iOS 빌드는 macOS + Xcode 필요)
- scripts/release.sh: 버전 상승 → 테스트 → 서명 빌드 → 태그 → Gitea 릴리스 자동화
This commit is contained in:
2026-09-23 10:37:17 +09:00
parent 0839705b97
commit cbd0f62319
87 changed files with 2706 additions and 783 deletions

View File

@@ -0,0 +1,19 @@
import SwiftUI
import UIKit
import ComposeApp
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
// Kotlin 쪽 MainViewController() — commonMain 의 App() 을 그대로 띄운다.
MainViewControllerKt.MainViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
struct ContentView: View {
var body: some View {
ComposeView()
.ignoresSafeArea(.keyboard)
}
}

View File

@@ -0,0 +1,11 @@
import SwiftUI
@main
struct iOSApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.ignoresSafeArea(.all)
}
}
}

53
app/iosApp/project.yml Normal file
View File

@@ -0,0 +1,53 @@
# XcodeGen 설정 — macOS 에서 `xcodegen generate` 로 iosApp.xcodeproj 를 만든다.
# brew install xcodegen
# cd app/iosApp && xcodegen generate && open iosApp.xcodeproj
# Gradle 이 만든 ComposeApp.framework 를 링크한다.
name: iosApp
options:
bundleIdPrefix: kr.tkrmagid
deploymentTarget:
iOS: "15.0"
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: kr.tkrmagid.tetrig
MARKETING_VERSION: "2.0.0"
CURRENT_PROJECT_VERSION: "2"
SWIFT_VERSION: "5.0"
TARGETED_DEVICE_FAMILY: "1,2" # iPhone + iPad
ENABLE_USER_SCRIPT_SANDBOXING: NO
targets:
iosApp:
type: application
platform: iOS
sources:
- path: iosApp
info:
path: iosApp/Info.plist
properties:
CFBundleDisplayName: TETRIG
UILaunchScreen: {}
UISupportedInterfaceOrientations:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
UIRequiresFullScreen: false
settings:
base:
FRAMEWORK_SEARCH_PATHS:
- "$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)"
OTHER_LDFLAGS:
- "-framework"
- "ComposeApp"
preBuildScripts:
- name: Build Compose framework
script: |
cd "$SRCROOT/../"
./gradlew :composeApp:embedAndSignAppleFrameworkForXcode
basedOnDependencyAnalysis: false