LoginSignup
11
8

More than 1 year has passed since last update.

最低限困らない SwiftUI を指定した Xcode プロジェクトを XcodeGen で生成する

Last updated at Posted at 2021-12-16

この記事は、ゆめみ Advent Calendar 2021 の17日目の記事です。

はじめに

XcodeGen に入門しようと SwiftUI を指定した Xcode プロジェクトを題材にしたら、ビルドするためにちょっとした設定が必要でした。
この記事ではその原因と対応策を紹介します。

環境

  • macOS 12.0.1
  • Xcode 13.1
  • XcodeGen 2.25.0

成果物

gist にあげていますが、Qiita では展開されないので貼っておきます。

# 任意のProduct Nameに置き換える(Targetも同様)
name: FooProduct

options:
  bundleIdPrefix: com.example
  deploymentTarget: 
    iOS: 15.0
  xcodeVersion: "13.1"

settings:
  base:
    # 任意のTeam IDに置き換える
    DEVELOPMENT_TEAM: (YOUR_TEAM)
    # すべてのTargetで共通にするためにここで指定する
    MARKETING_VERSION: 1.0.0
    # すべてのTargetで共通にするためにここで指定する
    CURRENT_PROJECT_VERSION: 1
    # Xcode 13.1のテンプレートから作成したものと差分があったので、そろえている
    CLANG_CXX_LANGUAGE_STANDARD: gnu++17
    # 任意でManualに置き換える
    CODE_SIGN_STYLE: Automatic

targets:
  # アプリのTarget定義を記載する
  FooProduct:
    type: application
    platform: iOS
    sources: 
      - FooProduct
    settings:
      base:
        ENABLE_PREVIEWS: YES
        DEVELOPMENT_ASSET_PATHS: "\"FooProduct/Preview Content\""
        ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor
    # 生成するInfo.plistの設定を記載する
    info:
      # 生成先のPathを指定する
      path: FooProduct/Info.plist
      # 各種設定は基本的にXcode 13.1のテンプレートから作成したものとそろえている
      properties:
        # settingsで設定した環境変数を使用する
        CFBundleVersion: $(CURRENT_PROJECT_VERSION)
        # settingsで設定した環境変数を使用する
        CFBundleShortVersionString: $(MARKETING_VERSION)
        LSRequiresIPhoneOS: YES
        # UILaunchScreenをダミーでもいいので設定しないと、描画がおかしくなる
        UILaunchScreen: ""
        UIApplicationSupportsIndirectInputEvents: YES
        UIApplicationSceneManifest: 
          UIApplicationSupportsMultipleScenes: YES
        # Device OrientationはXcode 13.1のテンプレートとそろえている
        UISupportedInterfaceOrientations~iphone:
          [UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight]
        UISupportedInterfaceOrientations~ipad:
          [UIInterfaceOrientationPortrait, UIInterfaceOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight]

  FooProductTests:
    # UnitTestのTarget定義を指定する
    type: bundle.unit-test
    platform: iOS
    sources: 
      - FooProductTests
    dependencies:
      - target: FooProduct
    settings:
      base:
        ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: YES
    # 生成するInfo.plistの設定を記載する
    info:
      # 生成先のPathを指定する
      path: FooProductTests/Info.plist
      # 各種設定は基本的にXcode 13.1のテンプレートから作成したものとそろえている
      properties:
        CFBundleVersion: $(CURRENT_PROJECT_VERSION)
        CFBundleShortVersionString: $(MARKETING_VERSION)

  FooProductUITests:
    # UITestのTarget定義
    type: bundle.ui-testing
    platform: iOS
    sources: 
      - FooProductUITests
    dependencies:
      - target: FooProduct
    settings:
      base:
        ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: YES
    # 生成するInfo.plistの設定を記載する
    info:
      # 生成先のPathを指定する
      path: FooProductUITests/Info.plist
      # 各種設定は基本的にXcode 13.1のテンプレートから作成したものとそろえている
      properties:
        CFBundleVersion: $(CURRENT_PROJECT_VERSION)
        CFBundleShortVersionString: $(MARKETING_VERSION)

簡単にビルドしたい人向けにサンプルプロジェクトも用意しました。
DEVELOPMENT_TEAM だけご自身の環境にあわせて変えていただいたら試せると思います。

SwiftUISampleWithXcodeGen v0.0.1
(今後手を入れていく予定なので、記事執筆時点のタグを指定しています)

原因

Info.plist が生成されない

SwiftUI を指定した Xcode プロジェクトでは Info.plist が生成されないので、project.yml で既存のファイルを読み込むことができませんでした。
Info.plist の設定をなにもせずプロジェクトを生成すると、Targetの Info のタブに「Information from info.plist not available. File may not exist at specified path.」という、Info.plistの情報が読み込めない旨のメッセージが表示されます。

スクリーンショット 2021-12-15 11 21 40

SwiftUI を指定した Xcode プロジェクトでは Info.plist が生成されないことも、いままで Info.plist に記載されていた設定が Xcode 13.0 からプロジェクトファイルの中に書き込まれているということも初めて知ったので、かなり面食らいました。

Xcode の Release Notes に書いてあった

ちゃんとチェックしないとだめですね…。

Projects created from several templates no longer require configuration files such as entitlements and Info.plist files. Configure common fields in the target’s Info tab, and build settings in the project editor. These files are added to the project when additional fields are used. (68254857)

対応

方針

原因は Info.plist が生成されないことだとわかったので、Info.plist を作成して project.yml で読み込むようにすれば、ビルドできるようになりそうです。
XcodeGen のドキュメント を読むと、指定したパスに Info.plist を生成できるとあったので、 project.yml に必要な設定を記述すればうまくいきそうです。

やったこと

Xcode のテンプレートから SwiftUI を指定した Xcode プロジェクトを作成して、Info タブに記載されている内容を地道に転記しました。
この作業をするために、記述するべき key/value を調べようと Info.plist を開こうとして、「いや、それを作ろうとしてるんですよ…」ってなりました。
ずーっと不満なんですが、Xcode から見た Info.plist の key/value と実際に記述するべき key/value が統一されていないのは、なんでですかね。

そして、作業中にたまたま Info タブでコンテクストメニューを表示したら「Raw Keys & Values」という項目を見つけまして、この項目を選択すれば記述するべき key/value に切り替わることを知りました。
最初からそっちを表示してもいいんですよ。

項目選択前 項目選択後
スクリーンショット 2021-12-15 12 14 45 スクリーンショット 2021-12-15 12 14 54

また詳細は割愛しますが、UnitTestやUITestもビルドできなかったので、 Info.plist を作成するようにしました。

面白いなって思ったこと

Info.plistUILaunchScreen という設定があるのですが、これを設定しないと描画がおかしくなりました。

UILaunchScreen の設定がない UILaunchScreen の設定がある

ドキュメントによるとアプリの起動画面を指定するとありますが、いろいろ value を変えて試したところ、key が存在すれば描画はうまくいくみたいでした。

Xcode のテンプレートでは以下のようになっていたのですが、project.yml でどう指定したらいいかわからず、今回は String として指定しています。
スクリーンショット 2021-12-15 12 36 58

さいごに

今回作成したリポジトリは、今後ビルド時に SwiftLint を実行するための定義を追加したり、GitHub Actions と連携させたり、いろいろ手を入れていこうとおもいます。

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8