Communitygithub.com

byteratio/iphone-dev

原生 iPhone 應用程式開發的慣例 — 使用 SwiftUI + SwiftData 的本地優先應用程式、XcodeGen 專案生成、僅 CLI 的建置/測試/部署流程(預設模擬器,透過 devicectl 簽署部署至實體裝置)、具可見涵蓋率的 XCTest,以及免費個人團隊簽署的陷阱。在建立 iOS/iPhone 應用程式、為專案新增 iOS 目標或 Makefile 迴圈、除錯 Xcode 簽署/佈建/部署問題,或將現有應用程式的邏輯移植至原生 Swift 用戶端時使用。

iphone-dev 是什麼?

此技能(byteratio/iphone-dev)提供一系列針對小型、本地優先的原生 iPhone 應用程式開發的慣例與最佳實踐,特別適用於使用免費個人 Apple ID 的開發者。它圍繞 SwiftUI 和 SwiftData 建立,強調無伺服器依賴的資料模型、使用 XcodeGen 進行專案生成,以及完全基於命令列的開發迴圈(建置、測試、部署),預設目標為模擬器。此技能深入說明了 SwiftData 的建模技巧、XcodeGen 的配置,以及一個包含 `ios-sim`、`ios-test` 和 `ios-deploy` 等目標的 Makefile 驅動的工作流程,這些目標能自動處理簽署、啟動模擬器以及透過 `devicectl` 部署至實體裝置。 關鍵部分專門用於解決免費個人團隊簽署的常見陷阱,例如取得正確的團隊 ID、處理首次裝置設定,以及應對 7 天安裝到期限制。它也涵蓋了測試實務(使用記憶體內上下文的 XCTest)、偵錯便利功能(如範例資料播種器),以及為同時擁有伺服器端的應用程式提供清晰的同步分層架構(從單純的輕量級用戶端到完整的雙向同步)。這項技能支援任何命令列環境(包括 CI/頭部less 設定),並提供了從頭開始設定全新 Mac 的逐步引導,使其成為建置和維護自包含 iOS 應用程式的全面指南。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/byteratio/skills/tree/main/plugins/hechtch-skills/skills/iphone-dev

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

iPhone 應用程式開發

從將 SwiftUI 應用程式從空白儲存庫一路交付到在實體手機上執行的已簽署建置過程中,所提煉出的慣例。

假設情境:小型應用程式、免費的個人 Apple 帳戶、無 App Store 發行。付費的開發者團隊會改變以下幾項規則 — 簽署章節會標示出哪些規則會受影響。

架構預設值

  • SwiftUI + SwiftData,本地優先。 一個小型應用程式不應依賴可連線的伺服器。資料儲存在裝置上的 SwiftData 中;網路呼叫僅用於公開 API(https,無 ATS 例外)。如果應用程式一開始是現有後端的輕量級用戶端,可以預期「我們能拋棄伺服器嗎?」的轉折 — 將後端邏輯移植為針對 SwiftData 陣列的純 Swift 函式,而不是為了單一手機而維持伺服器運作。
  • SwiftData 建模:使用真實的物件關係,而非整數外鍵。使用 @Attribute(.unique) 作為自然鍵。SwiftData 的多對多陣列不保留順序 — 在需要順序時,新增一個 sortOrder 欄位和一個 sortedX 計算屬性。日期使用 Date,而非字串。列舉使用 String 原始值並遵循 Codable 協定。
  • 即時安裝上的結構描述變更:新增模型或可選屬性會在下次啟動時靜默地進行輕量級遷移;重新命名、刪除或型別變更(若沒有 SchemaMigrationPlan)會導致儲存空間無法開啟 — 已部署的應用程式會在啟動時崩潰,但使用者的資料仍完好無損卻無法存取。重新部署(相同 bundle ID)永遠不會清除資料容器;只有刪除應用程式才會。在使用者累積真實資料之前,請規劃一個匯出/備份路徑。
  • 檢視直接與 @Query + modelContext 溝通。 除非某些功能確實需要快取,否則不需要 Store / repository 層。純邏輯(比對、解析、匯入)放在列舉命名空間中(enum Foo { static func … })—— 可在沒有 UI 的情況下測試。
  • 部署目標:current-major-minus-one,除非所需 API 另有規定。單一目標,TARGETED_DEVICE_FAMILY: "1",除非應用程式需要橫向模式,否則使用直向。

專案生成 — XcodeGen,絕不提交 .xcodeproj

ios/project.yml 是真理來源;.xcodeproj 套件是生成的並被加入 gitignore(也要 gitignore ios/build/ 和生成的 Info.plist)。在新增或移除檔案後重新生成 — xcodegen 會 glob 原始碼目錄,因此編輯現有檔案不需要任何動作。

  • 從 GitHub 發行版的 zip 檔安裝 xcodegen(PREFIX=~/.local ./install.sh)— 無需 Homebrew,可在鎖定的 Mac 上運作。
  • 單元測試目標需要 GENERATE_INFOPLIST_FILE: YES,否則測試套件會簽署失敗。
  • 在 project.yml 中定義 scheme,並設定 gatherCoverageData: true 並附加測試目標,否則 xcodebuild test 將沒有東西可以執行。

開發迴圈 — 僅 CLI,預設使用模擬器

每個 iOS 專案都會獲得這些 Makefile 目標。將模擬器名稱、裝置 ID 和團隊 ID 參數化為 ?= 變數,這樣就不會硬編碼任何機器特定的資訊:

目標說明
ios-projectxcodegen 生成 + 在 Xcode 中開啟
ios-sim為模擬器建置未簽署版本,啟動模擬器,安裝,啟動 — 預設迴圈;零簽署,零密碼提示
ios-sim-seedios-sim,然後使用 --seed-demo 重新啟動
ios-test在模擬器中執行 xcodebuild test + 使用 xccov 的每個目標涵蓋率報告
ios-deploy為已連接的手機建立已簽署的建置 + 使用 devicectl 安裝 + 啟動

ios-test 會在每次執行時列印涵蓋率 — 內部規則是 make test 總是顯示數字,但沒有附加硬性門檻。

模擬器建置:對於 generic/platform=iOS 的編譯檢查,CODE_SIGNING_ALLOWED=NO 是可行的;模擬器目標不需要任何簽署。請記住,模擬器和手機有獨立的資料庫。

總是值得的偵錯便利功能

  • 範例資料播種器(DemoData.swift,#if DEBUG):精選的資料集,其中到期/日期欄位相對於 .now 計算,具有冪等性(重新執行不會新增任何內容),透過三種方式公開 — 設定中的「開發者」區段按鈕、透過 ProcessInfo.processInfo.arguments 檢查的 --seed-demo 啟動參數,以及 ios-sim-seed 目標。新增一個測試來斷言播種器能涵蓋應用程式的主要狀態,這樣它就不會默默地腐化。
  • 可搜尋的選取器:一旦列表可能超過幾十個項目(匯入的資料集保證會如此),就使用可搜尋的選取器,而非滾輪選取器。
  • 相機/掃描器功能:檢查 DataScannerViewController.isSupported && .isAvailable 並提供手動輸入的備援方案 — 這在模擬器中也能優雅地降級。

測試

  • 在模擬器中使用 XCTest;在從其他堆疊移植邏輯時,同時移植參考測試套件,以便跨語言鎖定語義。
  • 共享輔助函式:makeInMemoryContext(),建立一個 isStoredInMemoryOnly: true 的 ModelContainer;使用 @MainActor 的測試類別搭配 setUp() async throws。
  • 從結果套件中讀取通過/失敗狀態:xcrun xcresulttool get test-results summary --path build/test.xcresult。

簽署與部署 — 陷阱(每一個都花費了實際時間)

  • 團隊 ID 不是 security find-identity 中括號內的內容 — 那是憑證本身的 ID。從佈建設定檔中獲取真實的團隊 ID(security cms -D -i <profile> → application-identifier 前綴)或 Xcode 的帳號面板。錯誤的 ID 會產生誤導的「No Account for Team」錯誤。
  • -allowProvisioningUpdates 無法從一般終端機看到 Apple ID 工作階段。 在 Xcode GUI 中建立一次佈建設定檔(Signing & Capabilities → 設定 Team → Try Again);之後,純 CLI 的建置就能透過 DEVELOPMENT_TEAM=<id> CODE_SIGN_STYLE=Automatic 運作。
  • 首次裝置設定步驟:在手機上啟用開發者模式(設定 → 隱私權與安全性;只有在 Xcode 與裝置溝通後才會出現該切換開關;重新啟動)→ 信任電腦 → 首次安裝後,信任開發者憑證(設定 → 一般 → VPN 與裝置管理)。Xcode 的「your team has no devices」錯誤通常意味著註冊嘗試發生在手機重新啟動或鎖定時 — 選擇手機作為執行目標並重試。
  • 每次建置都出現鑰匙圈提示:在 codesign 鑰匙圈對話框上按一下永遠允許;每次建置的密碼提示就會停止。
  • 免費個人團隊限制:安裝在 7 天後過期(重新部署以重新簽署),最多 3 個側載應用程式,無推播通知,無 App Groups。付費團隊可以解除所有四項限制 — 如果應用程式需要推播或 App Groups,那就是取得付費團隊的觸發點。
  • 部署/啟動 CLI:xcrun devicectl list devices、xcrun devicectl device install app --device <id> <path>.app、… device process launch --device <id> <bundle-id>。

全新 Mac 引導程序(適合無頭模式)

  1. 從 App Store 安裝 Xcode(開啟 macappstore://apps.apple.com/app/id497799835)。
  2. sudo xcode-select -s /Applications/Xcode.app && sudo xcodebuild -license accept && sudo xcodebuild -runFirstLaunch — 需要管理者權限;在標準帳戶上,先修正管理者成員資格(su admin -c 'sudo dseditgroup -o edit -a <user> -t user admin')。
  3. xcodebuild -downloadPlatform iOS — 自 Xcode 15 起,iOS SDK + 模擬器執行環境是獨立的多 GB 下載;沒有它,建置會失敗並顯示「iOS X.Y 未安裝」的錯誤。
  4. 在修正 xcode-select 之前,DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer 可以作為每個指令的覆蓋變數使用。
  5. 從發行版 zip 檔將 xcodegen 安裝到 ~/.local(見上文)。

現有伺服器應用程式的伴隨用戶端 — 同步分層

當 iPhone 應用程式加入一個已有伺服器 + Web 應用程式的應用程式時(伺服器仍然是唯一的真理來源),請選擇手機使用案例允許的最便宜分層。先問「手機是否需要在不連線伺服器網路的情況下運作?」以及「是僅擷取還是完整編輯?」:

  1. 輕量級用戶端 — 無本地儲存;手機呼叫現有 API。在連線能力有保證的情況下直接使用。
  2. 快照鏡像 — 從完整的 JSON 拉取中整體重建 SwiftData 快取(單一使用者資料庫很小)。無需合併 → 無需墓碑、無需每行時間戳、無需衝突引擎;伺服器端的刪除/編輯會免費傳達。照片透過 URL 快取進行延遲載入。
  3. 限定範圍的寄件匣 — 離線建立功能僅限於已存在記錄的子記錄(針對已知父記錄的日誌、筆記、照片)。父記錄帶有真實的伺服器 ID,因此重播只是純 API 呼叫 — 整數主鍵的結構描述不需要 UUID 遷移。同步事件 = 推送寄件匣,然後拉取快照(自己的擷取會以已確認狀態返回)。顯示 404 孤兒記錄(「N 無法同步」),絕不默默丟棄。顯示待處理標記 + 上次同步時間戳。僅在使用者固定的伺服器位址有回應時才自動同步 — 絕不探查外部網路。
  4. 完整雙向同步(UUID、墓碑、增量端點、LWW/CRDT)— 僅在有證據顯示分層 1–3 不足時才使用;重構從伺服器端開始(用戶端可生成的 UUID、冪等 upsert、changes?since= + 墓碑),然後才撰寫任何 Swift 程式碼。

分層 2 和 3 可以很好地組合:用於讀取的快照鏡像加上用於擷取的限定範圍寄件匣,可以在不需要任何分層 4 的機制下,涵蓋「在家工作,隨處擷取」的需求。

專案衛生

  • 機器與裝置特定的事實(團隊 ID、裝置 UDID、模擬器名稱)放在 Makefile 的 ?= 變數或專案自己的筆記中 — 絕不硬編碼在腳本中,也絕不寫入此技能。
  • 為每個進行中的工作片段保留一份 plans/<topic>.md 文件,以及一份頂層的 CHANGELOG.md 來說明已發佈的內容;在某個計畫完成後,將其移至 plans/done/<topic>.md,並在頂部加上「Delivered in <版本> — <日期>」的標頭。
  • 將每個計畫片段的大小切割成最終能在手機或模擬器上執行的內容。一個無法啟動的 iOS 片段是無法被審查的。

Individual skills in this repo

This repo contains 5 individual skills — each has its own dedicated page.

byteratio/example-skill

Template skill for this marketplace. Use as a starting point when adding a new skill — copy this plugin directory, rename it, and replace this description with the specific trigger conditions for your skill (what the user says or does that should invoke it).

byteratio/kanban-plans

Track multi-session plans on a locally-running kanban board (github.com/hechtch/kanban) via its agent REST API. Claim a plan, move it through todo/doing/blocked/awaiting_merge/done, leave notes, and set the git branch. Use at the start of any non-trivial multi-session plan, when resuming such a plan, or when the user asks what's on the board or where a plan stands.

byteratio/password-generator

Generates secure, memorable passwords using 3 random dictionary words with leet-speak substitutions. Use when the user asks to generate a password, create a new password, or needs a secure passphrase.

byteratio/security-sweep

Investigate whether a project (or every repo on the machine) is exposed to known and actively-exploited dependency vulnerabilities. Combines a deterministic per-ecosystem audit (npm audit, govulncheck, pip-audit, osv-scanner) with live web research into recent/active supply-chain incidents, then checks each project's lockfiles directly — the leading-indicator check that `npm audit` misses. Use when the user asks to "investigate security", "check for vulnerable dependencies", "are we affected by <a named CVE / package compromise>", "scan the projects for supply-chain issues", or wants a recurring security sweep.

byteratio/ux-agents

Scaffold persona-based UX testing agents for a web app — project-scoped .claude/agents/<persona>-ux.md files that drive a real browser via Playwright, walk user journeys as a specific persona, and report tagged friction findings. Use when setting up UX review automation, when the user asks what a specific user segment would think of the app, or after the user accepts an offer to add persona testing.

相關技能