PakePlus-iOS

PakePlus エコシステムの iOS 向けテンプレート — URL または静的 HTML を WKWebView で包み、GitHub Actions 上で IPA を生成する。

1 — 概要

PakePlus-iOS(Sjj1024/PakePlus-iOS)は、PakePlus がフォークする iOS ビルド用テンプレートリポジトリ。デスクトップ版が Tauri を使う一方、iOS 版は SwiftUI + WKWebView の薄いネイティブシェルで Web コンテンツを表示する。ユーザーは PakePlus クライアントまたは Web UI で ppconfig.json を書き、GitHub Actions が ppworker で Xcode プロジェクトへ設定を流し込み、署名なしの .ipa を Release に公開する。

WKWebView表示コア
ppworker設定注入
IPA配布形式
GH Actionsクラウドビルド

親プロジェクト PakePlus は Mac / Windows / Linux / Android / iOS を横断する「Web をアプリ化」ツール群。iOS テンプレート単体では GUI は持たず、設定ファイル + ビルドスクリプト + 最小 Swift アプリ が本体になる。

Pake との関係: tw93/Pake が CLI 一本でデスクトップ化するのに対し、PakePlus は GitHub Token とクラウド Actions でテンプレートをフォーク・カスタマイズする運用モデル。iOS 版はその中のネイティブ(非 Tauri)経路。
2 — アーキテクチャ
flowchart TD
  subgraph native["SwiftUI シェル"]
    App["PakePlusApp"]
    CV["ContentView"]
    WV["WebView UIViewRepresentable"]
  end
  subgraph config["Info.plist キー"]
    WEBURL["WEBURL"]
    DEBUG["DEBUG"]
    FULL["FULLSCREEN / LAUNCHIMAGE"]
  end
  subgraph web["表示対象"]
    Remote["リモート URL"]
    Local["Bundle 内 index.html"]
    Pwd["pppwd.html パスワードゲート"]
  end
  App --> CV
  CV --> WV
  config --> CV
  config --> WV
  WV --> Remote
  WV --> Local
  WV --> Pwd
主要ディレクトリ
PakePlus/           # SwiftUI アプリ本体
  PakePlusApp.swift   # @main エントリ
  ContentView.swift   # WebView + 起動画像 ZStack
  WebView.swift       # WKWebView ラッパー・Coordinator
  custom.js           # ページ注入用(ビルド時コピー)
scripts/
  ppconfig.json       # PakePlus が書き込む設定
  ppworker.cjs        # plist / pbxproj / Swift へ反映
  www/                # 静的 HTML パック用
.github/workflows/
  build.yml           # IPA ビルド・Release 公開

ContentView は Info.plist の WEBURL・DEBUG・FULLSCREEN・LAUNCHIMAGE・SCREENON を読み、WebView のロード完了まで起動画像を重ねる。WebView は UIViewRepresentable で WKWebView を生成し、Coordinator がナビゲーション・ダウンロード・権限・JS ブリッジを担当する。

3 — ビルドパイプライン
flowchart LR
  A["checkout"] --> B["pnpm install"]
  B --> C["pnpm pp:worker"]
  C --> D["appicon 生成"]
  D --> E["xcodebuild Release"]
  E --> F["Payload + zip → IPA"]
  F --> G["softprops/action-gh-release"]
  1. Init: pnpm install のあと pnpm pp:worker(node scripts/ppworker.cjs)が ppconfig.json を読み、Bundle ID・表示名・URL・デバッグフラグなどをプロジェクトへ書き込む。
  2. アイコン: ルートの app-icon.png から brew install appicon で AppIcon.appiconset を生成。
  3. ビルド: xcodebuild を CODE_SIGNING_ALLOWED=NO で実行(署名なし)。DerivedData から PakePlus.app を拾う。
  4. パッケージ: Payload/PakePlus.app を zip し {NAME}-{VERSION}.ipa に。静的 HTML モード時は Scripts/www/* を app バンドルへ追加。
  5. 公開: ppworker が GITHUB_ENV に書いた NAME / VERSION / PUBBODY で GitHub Release を作成。
ローカル向け npm scripts(package.json)
pnpm pp:worker    # 設定反映のみ
pnpm run icon     # appicon でアイコン生成
pnpm run build:ipa# make package(Theos / 別経路)
署名について: ワークフローは意図的にコード署名を無効化している。実機インストールや App Store 配布には別途 Apple Developer 署名・プロビジョニングが必要。PakePlus 本体の FAQ と同様、個人利用では AltStore 等のサイドロードや企業配布を想定した運用が多い。
4 — 設定注入(ppworker)

scripts/ppconfig.json は PakePlus クライアントが生成する巨大な設定 JSON。ppworker.cjs がビルド前に以下を更新する。

設定領域反映先内容
showName / appidInfo.plist, project.pbxproj表示名・Bundle Identifier・画面向き
url / isHtmlInfo.plist の WEBURLリモート URL またはダミー pakeplus.com(ローカル HTML 用)
startMethodWEBURL + www/ コピーpassword 時は password.com + pppwd.html
devbugDEBUG, vConsole.jsデバッグ時のみ vConsole 注入・ファイル残置
phone.safeAreaContentView.swiftignoresSafeArea の edges を文字列置換
phone.launchImageLAUNCHIMAGE, Assetslaunch.jpg → LaunchScreen.imageset
webview.userAgentUSERAGENT, WebView.swiftカスタム UA
メタGITHUB_ENVNAME, VERSION, PUBBODY, ISHTML

表示モードの分岐

  • リモート URL: WEBURL に実 URL を設定し、余分な index.html は削除。
  • 静的 HTML: scripts/www/ を PakePlus/ へコピーし、WEBURL を https://www.pakeplus.com/ に。WebView はホスト名で Bundle 内 index.html を loadFileURL する。
  • パスワード起動: pppwd.html を経由し、検証後に本番 URL またはローカル HTML へ遷移。
5 — WebView 機能
機能実装の要点
ズーム無効viewport meta 注入 + viewForZooming で nil
スワイプ戻る/進む左右スワイプで goBack / goForward
ファイルダウンロードリンククリック時に拡張子判定 → URLSession または blob JS ブリッジ
外部スキームtel / mailto / sms 等は UIApplication.open
メディア権限iOS 15+ requestMediaCapturePermissionFor でシステム許可と連動
位置情報CLLocationManager で事前認可(Web 内 Geolocation 用)
カスタム JSBundle の custom.js を documentStart で注入
デバッグDEBUG 時 vConsole + isInspectable(iOS 16.4+)

Blob ダウンロードは blobDownload メッセージハンドラでチャンク受信 → 一時ファイル保存 → UIActivityViewController(共有シート)でユーザーに保存先を選ばせる。