Created
May 13, 2025 03:56
-
-
Save kumeS/109c3f24847b4a67ad422a59367909be to your computer and use it in GitHub Desktop.
iOSアプリ開発をCLIで自動化するbashスクリプトです。プロジェクト構造の生成、SwiftUIエントリポイント&APIキー設定ファイル作成、XcodeGenによる.xcodeproj生成、ビルド→シミュレータ起動→インストール→起動、各種設定/ドキュメントファイルの雛形作成までを一括で行います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| #=================================================== | |
| # init_ios_project.sh | |
| # - プロジェクト名を引数に、 | |
| # 1. フォルダ&Sources/・Sources/Config・Resources・Tests 作成 | |
| # 2. APIKeys.swift, SwiftUI エントリポイント生成 | |
| # 3. project.yml + XcodeGen で .xcodeproj 生成 | |
| # 4. ビルド → インストール → 起動 | |
| # 5. .env.example, .gitignore, .swiftlint.yml, .swiftformat, | |
| # Tests/*Tests.swift, .cursor/rules, README.md, Makefile, AGENT_GUIDE.md の生成 | |
| #=================================================== | |
| if [ $# -lt 1 ]; then | |
| echo "Usage: $0 <ProjectName>" | |
| exit 1 | |
| fi | |
| PROJECT="$1" | |
| BUNDLE_ID="com.example.${PROJECT}" | |
| # ──────────────────────────────────────────────── | |
| # 1) シミュレータ自動検出 | |
| # ──────────────────────────────────────────────── | |
| SIM_NAME=$( | |
| xcrun simctl list devices available \ | |
| | grep -E "iPhone [0-9]+" \ | |
| | head -n1 \ | |
| | sed -E 's/.*(iPhone [0-9A-Za-z \-]+) \(.*/\1/' | |
| ) | |
| if [ -z "$SIM_NAME" ]; then | |
| echo "⚠️ 利用可能な iPhone シミュレータが見つからず、汎用指定にフォールバック" | |
| DEST="generic/platform=iOS Simulator" | |
| else | |
| echo "▶ 検出されたシミュレータ: ${SIM_NAME}" | |
| DEST="platform=iOS Simulator,name=${SIM_NAME}" | |
| fi | |
| echo "▶ Destination: ${DEST}" | |
| # ──────────────────────────────────────────────── | |
| # 2) ディレクトリ構造 & 必要ファイル生成 | |
| # ──────────────────────────────────────────────── | |
| mkdir -p "${PROJECT}"/{Sources,Resources,Tests,Sources/Config} | |
| cd "${PROJECT}" | |
| # 2.1) APIKeys.swift | |
| cat <<'EOF' > Sources/Config/APIKeys.swift | |
| /** | |
| * APIキー設定ファイル | |
| * | |
| * 使用方法: | |
| * 1. このファイルを `APIKeys.swift` としてコピー | |
| * 2. 以下の定数に実際のAPIキーを設定 | |
| * 3. .gitignore でリポジトリにコミットされないことを確認 | |
| */ | |
| enum APIKeys { | |
| /// OpenAI APIキー | |
| /// GPT-4 Vision モデルへのアクセス権が必要 | |
| /// https://platform.openai.com/ から取得できます | |
| static let openAI = "YOUR_OPENAI_API_KEY_HERE" | |
| } | |
| EOF | |
| # 2.2) SwiftUI エントリポイント | |
| cat <<EOF > Sources/${PROJECT}App.swift | |
| import SwiftUI | |
| @main | |
| struct ${PROJECT}App: App { | |
| var body: some Scene { | |
| WindowGroup { | |
| ContentView() | |
| } | |
| } | |
| } | |
| struct ContentView: View { | |
| var body: some View { | |
| Text("Hello, ${PROJECT}!") | |
| .padding() | |
| } | |
| } | |
| EOF | |
| # ──────────────────────────────────────────────── | |
| # 3) project.yml の生成 | |
| # ──────────────────────────────────────────────── | |
| cat <<EOF > project.yml | |
| name: ${PROJECT} | |
| options: | |
| bundleIdPrefix: com.example | |
| settings: | |
| SWIFT_VERSION: 5.9 | |
| configs: | |
| Debug: debug | |
| Release: release | |
| targets: | |
| ${PROJECT}: | |
| type: application | |
| platform: iOS | |
| deploymentTarget: "17.0" | |
| sources: [Sources] | |
| settings: | |
| PRODUCT_BUNDLE_IDENTIFIER: ${BUNDLE_ID} | |
| GENERATE_INFOPLIST_FILE: YES | |
| EOF | |
| # ──────────────────────────────────────────────── | |
| # 4) XcodeGen プロジェクト生成 | |
| # ──────────────────────────────────────────────── | |
| echo "▶ xcodegen generate..." | |
| xcodegen generate | |
| # ──────────────────────────────────────────────── | |
| # 5) ビルド → インストール → 起動 | |
| # ──────────────────────────────────────────────── | |
| DERIVED_DATA="build" | |
| echo "▶ Building..." | |
| xcodebuild \ | |
| -scheme "${PROJECT}" \ | |
| -destination "${DEST}" \ | |
| -derivedDataPath "${DERIVED_DATA}" \ | |
| build | |
| if [[ "${DEST}" != generic* ]]; then | |
| echo "▶ Simulator 起動..." | |
| xcrun simctl boot "${SIM_NAME}" || true | |
| APP_PATH="${DERIVED_DATA}/Build/Products/Debug-iphonesimulator/${PROJECT}.app" | |
| echo "▶ App インストール..." | |
| xcrun simctl install booted "${APP_PATH}" | |
| echo "▶ App 起動..." | |
| xcrun simctl launch booted "${BUNDLE_ID}" | |
| else | |
| echo "▶ 汎用シミュレータのため install/launch はスキップ" | |
| fi | |
| # ──────────────────────────────────────────────── | |
| # 6) 各種設定ファイル生成 | |
| # ──────────────────────────────────────────────── | |
| # .env.example | |
| cat <<EOF > .env.example | |
| # Environment variables example | |
| OPENAI_API_KEY=your_openai_api_key_here | |
| EOF | |
| # .gitignore | |
| cat <<EOF > .gitignore | |
| # APIキー設定ファイルを除外 | |
| Sources/Config/APIKeys.swift | |
| # 環境変数ファイル | |
| .env | |
| # Xcode ビルド成果物 | |
| build/ | |
| DerivedData/ | |
| # SwiftLintキャッシュ | |
| .swiftlint.yml | |
| EOF | |
| # SwiftLint config | |
| cat <<EOF > .swiftlint.yml | |
| disabled_rules: | |
| - trailing_whitespace | |
| - line_length | |
| EOF | |
| # SwiftFormat config | |
| cat <<EOF > .swiftformat | |
| --indent 4 | |
| --line-length 100 | |
| EOF | |
| # Basic unit test | |
| cat <<EOF > Tests/${PROJECT}Tests.swift | |
| import XCTest | |
| @testable import ${PROJECT} | |
| final class ${PROJECT}Tests: XCTestCase { | |
| func testExample() throws { | |
| XCTAssertTrue(true) | |
| } | |
| } | |
| EOF | |
| # .cursor/rules | |
| mkdir -p .cursor | |
| cat << 'EOF' > .cursor/rules | |
| style: | |
| - Use Swift 5.9, SwiftUI 3, async/await only | |
| folders: | |
| - Sources: src code | |
| - Sources/Config: config code | |
| - Resources: assets & plist | |
| - Tests: unit tests | |
| restrictions: | |
| - Do NOT import UIKit unless explicitly asked | |
| - Keep imports alphabetically sorted | |
| - Log with os_log only | |
| testing: | |
| - Always add failing unit test before bug-fix | |
| file_safety: | |
| protect: | |
| - "*.xcodeproj" | |
| - "*.xcworkspace" | |
| - "init_ios_project.sh" | |
| - "Makefile" | |
| - ".cursor/rules" | |
| - "README.md" | |
| - "AGENT_GUIDE.md" | |
| - "Sources/Config/APIKeys.swift" | |
| delete: | |
| allow_patterns: | |
| - "DerivedData/**" | |
| - "build/**" | |
| forbid_patterns: | |
| - "Sources/**" | |
| - "Resources/**" | |
| - "Tests/**" | |
| tests: | |
| enforce_location: "Tests/" | |
| naming_pattern: "*Tests.swift" | |
| max_per_feature: 3 | |
| EOF | |
| # README.md | |
| cat << EOF > README.md | |
| # ${PROJECT} | |
| ## Overview | |
| - **Description**: (アプリの概要) | |
| - **Target**: iOS 17 / Swift 5.9 | |
| - **Bundle ID**: ${BUNDLE_ID} | |
| ## Features | |
| 1. Feature A | |
| 2. Feature B | |
| 3. Feature C | |
| ## Usage | |
| \`\`\`bash | |
| make run | |
| \`\`\` | |
| EOF | |
| # Makefile | |
| cat << 'EOF' > Makefile | |
| SCHEME = ${PROJECT} | |
| DEST = ${DEST} | |
| build: | |
| xcodebuild -scheme $(SCHEME) -destination $(DEST) -derivedDataPath build build | |
| run: build | |
| @[ "\$(echo \$(DEST) | grep -q '^platform'; echo \$?)" -eq 0 ] && \ | |
| xcrun simctl boot "${SIM_NAME}" && \ | |
| xcrun simctl install booted build/Build/Products/Debug-iphonesimulator/\$(SCHEME).app && \ | |
| xcrun simctl launch booted com.example.\$(SCHEME) || \ | |
| echo "⚠️ generic simulator; skipping install+launch" | |
| test: | |
| xcodebuild test -scheme $(SCHEME) -destination $(DEST) -derivedDataPath build | |
| format: | |
| swift format . | |
| clean: | |
| rm -rf build | |
| xcodebuild clean -scheme $(SCHEME) | |
| EOF | |
| # AGENT_GUIDE.md | |
| cat << 'EOF' > AGENT_GUIDE.md | |
| # Agent Interaction Guide | |
| ## 開発開始 | |
| 1. Cursor Editor でフォルダを開く: \`cd ${PROJECT}\` | |
| 2. 右上歯車メニュー → **Index Workspace** を実行 | |
| ## Agent モードの開発フロー例 | |
| - 🛠 新しい SwiftUI 画面 "QuizListView" を Sources/QuizListView.swift に作成して。プレビュー付きで。 | |
| - 🐛 モジュールインポートエラーが出たから、Sources/OCRService.swift に import Vision と import OpenAI を追加してビルドを通して。 | |
| - 🎨 ContentView を「Hello, ${PROJECT}!」から「Welcome!」に変更して、プレビューとシミュレータで確認まで。 | |
| ## ビルド/実行のワンライナー | |
| \`\`\`bash | |
| make run | |
| \`\`\` | |
| ## トラブル対応テンプレート | |
| - 🚑 simctl のログを貼るので、原因と対処を教えて。 | |
| - 🔍 ビルドログ全文を貼るので、原因特定して修正して。 | |
| EOF | |
| echo "✅ Initialization complete! cd ${PROJECT} → open in Cursor Editor and index the workspace." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment