AppleWatchアプリをXcodeGenで構築した

AppleWatchアプリをXcodeGenで構築したので、project.ymlを大雑把に置いておきます

# 困ったこと
- AppleWatchでのXcodeGenの文献が少なかった

# 開発環境と構成
- Xcode11.X~
- 構成
  - iOSAppTarget
  - WatchKit App
  - WatchKit Extension
- iOS13.X
- WatchOS6.X
- ツール系
    - Mint: 0.13.0(Mintfile)
      - XcodeGen: 2.15.1(project.yml)
        - SwiftPM
            - SwiftPMに対応しているライブラリがあれば優先的に
      - SwiftLint: 0.39.2
      - Carthage: 0.34.0(Cartfile)
          - SwiftPMに対応してないが、Carthageに対応しているライブラリがあれば優先的に
    - Bundler: 2.1.3(Gemfile)
        - Cocoapods: 1.9.1(Podfile)
            - SwiftPMにもCarthageにも対応してないライブラリ(Firebaseとか)
        - Fastlane: 2.144.0(Fastfile)
            - いろいろ

## XcodeGenはMintで管理
- Mintを使って XcodeGen / SwiftLint / Carthage のバージョンを管理しました
- ライブラリはなるべくSwiftPMに対応していればそれを優先的に利用し、Carthage->CocoaPodsの順で優先度を割り振りました
  
# XcodeGenのproject.yml

```project.yml
attributes:
  LastSwiftUpdateCheck: 1130
  LastUpgradeCheck: 1130
  ORGANIZATIONNAME: inc.noplan
settings:
  base:
    CURRENT_PROJECT_VERSION: 1
    MARKETING_VERSION: "0.0.26"
configs:
  Debug: debug
  Release: release
name: [アプリ名]
packages:
  Nuke:
    url: https://github.com/kean/Nuke.git
    from: 8.4.1
  [SwiftPMで使用するライブラリたち]
options:
  groupSortPosition: bottom
  transitivelyLinkDependencies: false
settingGroups:
  Debug:
    ALWAYS_SEARCH_USER_PATHS: NO
    CLANG_ANALYZER_NONNULL: YES
    CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: YES_AGGRESSIVE
    CLANG_CXX_LANGUAGE_STANDARD: gnu++14
    CLANG_CXX_LIBRARY: libc++
    CLANG_ENABLE_MODULES: YES
    CLANG_ENABLE_OBJC_ARC: YES
    CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING: YES
    CLANG_WARN_BOOL_CONVERSION: YES
    CLANG_WARN_COMMA: YES
    CLANG_WARN_CONSTANT_CONVERSION: YES
    CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS: YES
    CLANG_WARN_DIRECT_OBJC_ISA_USAGE: YES_ERROR
    CLANG_WARN_DOCUMENTATION_COMMENTS: YES
    CLANG_WARN_EMPTY_BODY: YES
    CLANG_WARN_ENUM_CONVERSION: YES
    CLANG_WARN_INFINITE_RECURSION: YES
    CLANG_WARN_INT_CONVERSION: YES
    CLANG_WARN_NON_LITERAL_NULL_CONVERSION: YES
    CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF: YES
    CLANG_WARN_OBJC_LITERAL_CONVERSION: YES
    CLANG_WARN_OBJC_ROOT_CLASS: YES_ERROR
    CLANG_WARN_RANGE_LOOP_ANALYSIS: YES
    CLANG_WARN_STRICT_PROTOTYPES: YES
    CLANG_WARN_SUSPICIOUS_MOVE: YES
    CLANG_WARN_UNGUARDED_AVAILABILITY: YES_AGGRESSIVE
    CLANG_WARN_UNREACHABLE_CODE: YES
    CLANG_WARN__DUPLICATE_METHOD_MATCH: YES
    COPY_PHASE_STRIP: NO
    DEBUG_INFORMATION_FORMAT: dwarf
    ENABLE_STRICT_OBJC_MSGSEND: YES
    ENABLE_TESTABILITY: YES
    GCC_C_LANGUAGE_STANDARD: gnu11
    GCC_DYNAMIC_NO_PIC: NO
    GCC_NO_COMMON_BLOCKS: YES
    GCC_OPTIMIZATION_LEVEL: 0
    GCC_PREPROCESSOR_DEFINITIONS:
    - $(inherited)
    - DEBUG=1
    GCC_WARN_64_TO_32_BIT_CONVERSION: YES
    GCC_WARN_ABOUT_RETURN_TYPE: YES_ERROR
    GCC_WARN_UNDECLARED_SELECTOR: YES
    GCC_WARN_UNINITIALIZED_AUTOS: YES_AGGRESSIVE
    GCC_WARN_UNUSED_FUNCTION: YES
    GCC_WARN_UNUSED_VARIABLE: YES
    MTL_ENABLE_DEBUG_INFO: YES
    ONLY_ACTIVE_ARCH: YES
    PRODUCT_NAME: $(TARGET_NAME)
    SDKROOT: iphoneos
    SWIFT_ACTIVE_COMPILATION_CONDITIONS: DEBUG
    SWIFT_OPTIMIZATION_LEVEL: -Onone
    SWIFT_VERSION: 5.0
  Staging:
    [割愛]
  Release:
    [割愛]

schemes:
  \[scheme名]:
    build:
      targets:
          [iOSのターゲット名]: all
    run:
      config: Debug
    test:
      config: Debug
    profile: 
      config: Debug 
    analyze:
      config: Debug
    archive: 
      config: Release
  \[いろいろiOSのscheme]:
  \[WatchOSのscheme名 WatchKit App]:
    build:
      targets:
        [WatchOSのターゲット名 WatchKit App]: all
    run:
      config: Debug
    test:
      config: Debug
    profile:
      config: Debug
    analyze:
      config: Debug
    archive:
      config: Release
  \[WatchOSのscheme名 WatchKit Extension]:
    build:
      targets:
        [WatchOSのターゲット名 WatchKit Extension]: all
    run:
      config: Debug
    test:
      config: Debug
    profile:
      config: Debug
    analyze:
      config: Debug
    archive:
      config: Release
targets:
  \[iOSのターゲット名]:
    dependencies:
      - target: [WatchOSのターゲット WatchKit App]
      - {embed: false, framework: Pods_[iOSのターゲット].framework}
      - {embed: false, framework: StoreKit.framework}
      - package: SDWebImageSwiftUI
      - package: SwiftUIX
      - carthage: SwiftyStoreKit
      - carthage: SwiftDate 
      - carthage: ObjectMapper
    platform: iOS
    postbuildScripts:
    - inputFiles:
      - ${PODS_PODFILE_DIR_PATH}/Podfile.lock
      - ${PODS_ROOT}/Manifest.lock
      name: '[CP] Check Pods Manifest.lock'
      outputFiles:
      - $(DERIVED_FILE_DIR)/Pods-[プロジェクト]-checkManifestLockResult.txt
      runOnlyWhenInstalling: false
      script: "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\"
        > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo
        \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install'
        or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output
        is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\"
        > \"${SCRIPT_OUTPUT_FILE_0}\"\n"
      shell: /bin/sh
      showEnvVars: false
    - inputFileLists:
      - ${PODS_ROOT}/Target Support Files/Pods-{iOSのターゲット}/Pods-{iOSのターゲット}-frameworks-${CONFIGURATION}-input-files.xcfilelist
      name: '[CP] Embed Pods Frameworks'
      outputFileLists:
      - ${PODS_ROOT}/Target Support Files/Pods-{iOSのターゲット}/Pods-{iOSのターゲット}-frameworks-${CONFIGURATION}-output-files.xcfilelist
      runOnlyWhenInstalling: false
      script: '"${PODS_ROOT}/Target Support Files/Pods-{iOSのターゲット}/Pods-{iOSのターゲット}-frameworks.sh"'
      shell: /bin/sh
      showEnvVars: false
    prebuildScripts:
      - name: run swiftlint
        script: | 
                if mint which swiftlint >/dev/null; then
                  mint run swiftlint autocorrect --format
                  mint run swiftlint
                else
                  echo "warning: mint install swiftlint"
                fi
      - name: linence plist
        script: | 
                ${PODS_ROOT}/LicensePlist/license-plist --output-path $PRODUCT_NAME/Settings.bundle --config-path $PRODUCT_NAME/license_plist.yml

                /usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:2:DefaultValue ${MARKETING_VERSION}" "$PRODUCT_NAME/Settings.bundle/Root.plist"
                /usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:3:DefaultValue ${CURRENT_PROJECT_VERSION}" "$PRODUCT_NAME/Settings.bundle/Root.plist"
    settings:
      configs:
        Debug:
          ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
          CLANG_ENABLE_MODULES: YES
          CODE_SIGN_ENTITLEMENTS: [ENTITLEMENTSのpath].entitlements
          CODE_SIGN_IDENTITY: iPhone Developer
          CODE_SIGN_STYLE: Automatic
          DEVELOPMENT_ASSET_PATHS: '"[DEVELOPMENT_ASSETのpath]/Preview Content"'
          DEVELOPMENT_TEAM: [TEAMをどうぞ]
          ENABLE_PREVIEWS: YES
          FRAMEWORK_SEARCH_PATHS:
          - $(inherited)
          - '"."'
          INFOPLIST_FILE: [plistのpath]/Info.plist
          LD_RUNPATH_SEARCH_PATHS:
          - $(inherited)
          - '@executable_path/Frameworks'
          PRODUCT_BUNDLE_IDENTIFIER: [PRODUCTのBUNDLE_IDENTIFIER]
          PRODUCT_NAME: $(TARGET_NAME)
          SDKROOT: iphoneos
          SWIFT_OBJC_BRIDGING_HEADER: [Bridging-Headerのpath/Bridging-Header.h]
          SWIFT_OPTIMIZATION_LEVEL: -Onone
          SWIFT_VERSION: 5.0
          TARGETED_DEVICE_FAMILY: 1,2
        Staging:
          [割愛]
        Release:
          [割愛]
    sources:
      - [デフォルトだとtarget名がフォルダ名と同じになってる]
      - name: GoogleService-Info.plist
        path: GoogleService-Info.plist
        group: [ファイルはrootにあるけどまとめたいのでフォルダを指定する]
    type: application
    deploymentTarget: "13.0"
    attributes:
      SystemCapabilities:
        com.apple.Push:
          enabled: 1
        com.apple.InAppPurchase:
          enabled: 1
  \[WatchOSのプロジェクト WatchKit App]:
    dependencies:
    - target: [WatchOSのtarget名 WatchKit Extension]
    - {embed: false, framework: Pods_[プロジェクト]_WatchKit_App.framework}
    platform: watchOS
    postbuildScripts:
    - inputFiles:
      - ${PODS_PODFILE_DIR_PATH}/Podfile.lock
      - ${PODS_ROOT}/Manifest.lock
      name: '[CP] Check Pods Manifest.lock'
      outputFiles:
      - $(DERIVED_FILE_DIR)/Pods-[プロジェクト] WatchKit App-checkManifestLockResult.txt
      runOnlyWhenInstalling: false
      script: "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\"
        > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo
        \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install'
        or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output
        is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\"
        > \"${SCRIPT_OUTPUT_FILE_0}\"\n"
      shell: /bin/sh
      showEnvVars: false
    settings:
      configs:
        Debug:
          ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: YES
          ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
          CODE_SIGN_STYLE: Automatic
          DEVELOPMENT_TEAM: [チーム]
          FRAMEWORK_SEARCH_PATHS:
          - $(inherited)
          - '"."'
          IBSC_MODULE: [IBSC_MODULE]_WatchKit_Extension
          INFOPLIST_FILE: [プロジェクト] WatchKit App/Info.plist
          LD_RUNPATH_SEARCH_PATHS:
          - $(inherited)
          - '@executable_path/Frameworks'
          PRODUCT_BUNDLE_IDENTIFIER: [アプリのBUNDLE_IDENTIFIER].watchkitapp
          PRODUCT_NAME: $(TARGET_NAME)
          SDKROOT: watchos
          SKIP_INSTALL: YES
          SWIFT_VERSION: 5.0
          TARGETED_DEVICE_FAMILY: 4
          WATCHOS_DEPLOYMENT_TARGET: 6.1
        Stating:
          [割愛]
        Release:
          [割愛]
    sources:
    - name: [デフォルトだとtarget名がフォルダ名と同じになってるやつ] WatchKit App
    type: application.watchapp2
    deploymentTarget: "6.0"
  \[WatchOSのプロジェクト] WatchKit Extension:
    dependencies:
    - {embed: false, framework: Pods_[プロジェクト]_WatchKit_Extension.framework}
    - carthage: ObjectMapper
    - package: Nuke
    platform: watchOS
    postbuildScripts:
    - inputFiles:
      - ${PODS_PODFILE_DIR_PATH}/Podfile.lock
      - ${PODS_ROOT}/Manifest.lock
      name: '[CP] Check Pods Manifest.lock'
      outputFiles:
      - $(DERIVED_FILE_DIR)/Pods-[プロジェクト] WatchKit Extension-checkManifestLockResult.txt
      runOnlyWhenInstalling: false
      script: "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\"
        > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo
        \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install'
        or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output
        is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\"
        > \"${SCRIPT_OUTPUT_FILE_0}\"\n"
      shell: /bin/sh
      showEnvVars: false
    settings:
      configs:
        Debug:
          ASSETCATALOG_COMPILER_COMPLICATION_NAME: Complication
          CODE_SIGN_STYLE: Automatic
          DEVELOPMENT_ASSET_PATHS: '"[プロジェクト] WatchKit Extension/Preview Content"'
          DEVELOPMENT_TEAM: 83GH78U9V5
          ENABLE_PREVIEWS: YES
          FRAMEWORK_SEARCH_PATHS:
          - $(inherited)
          - '"."'
          INFOPLIST_FILE: [プロジェクト] WatchKit Extension/Info.plist
          LD_RUNPATH_SEARCH_PATHS:
          - $(inherited)
          - '@executable_path/Frameworks'
          - '@executable_path/../../Frameworks'
          PRODUCT_BUNDLE_IDENTIFIER: [アプリのBUNDLE_IDENTIFIER].watchkitapp.watchkitextension
          PRODUCT_NAME: ${TARGET_NAME}
          SDKROOT: watchos
          SKIP_INSTALL: YES
          SWIFT_VERSION: 5.0
          TARGETED_DEVICE_FAMILY: 4
          WATCHOS_DEPLOYMENT_TARGET: 6.1
        Staging:
          [割愛]
        Release:
          [割愛]
    sources:
      - [デフォルトだとtarget名がフォルダ名と同じになってるやつ] WatchKit Extension
      - name: [iOSでもWatchOSでも使いたいファイル].swift
        path: [path/to/ファイルの所在地].swift
        group: [置いておきたいpath/to/DataModel]

    type: watchkit2-extension
    deploymentTarget: "6.0"


```

# あわせてどうぞ
- [AppleWatchアプリが更新されないかもしれない](https://qiita.com/okamu_/items/452f1f8b73094ce8731e)
- [AppleWatchでログが出ないことがあるので、iPhoneに投げつけて無理やり表示](https://qiita.com/okamu_/items/790828edb5ca079458f6)