LoginSignup
1
1

More than 3 years have passed since last update.

AppleWatchアプリをXcodeGenで構築した

Last updated at Posted at 2020-04-21

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"


あわせてどうぞ

1
1
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
1
1