[WWDC19] Xcode11新機能まとめ

# はじめに

[WWDC19 報告会 at Yahoo! JAPAN](https://yj-meetup.connpass.com/event/137133/)で発表したXcode11の新機能について文章でまとめた記事です。
NDAや著作権に配慮してスクリーンショットなどは載せておりません。

# エディタ

## エディタUIの刷新
  - コミット履歴が一番右のインスペクタに統合
    - 真ん中の時計アイコン（Source Control History表示）
  - AssistantとAuthorsエディタをStandardエディタに統合
    - Editor Optionから表示モードが選択できるように
      - Editor Only（エディタのみ）
      - Editor and Canvas（SwiftUIのプレビュー用）
      - Editor and Assistant（従来のアシスタントエディタ）
  - Authorの表示
    - Editor Option > Show Authors
  - エディタを縦横に追加可能
    - 縦に追加する場合はoptionを押しながら
  - 個々のエディタで個別の表示設定が可能

- エディタを縦横に分割可能
  - 縦に追加する場合はoptionを押しながら
  - フォーカスモードで一つのエディタを一時的に拡大

## SwiftUIのサポート
 - プロジェクト作成時にUse SwiftUIにチェック
 - プレビュー表示
   - Editor Option > Editor and Canvas

## Mini Map | ミニマップ
  - ミニマップの表示
    - Editor Option > Show Minimap
  - すばやく任意のセクションにジャンプ
  - ホバーで関数名などを表示
  - find箇所のハイライト

## inline code diffs | インラインコード差分
  - change barをクリックしてShow Changeをクリック
  - マウスホバーで差分を強調表示

## ドキュメンテーション機能の強化
  - パラメータを追加した時に差分だけのコメントを追加
    - command + クリック > Add Documentation
 
  - typoの修正もドキュメンテーションと同期
    - command + クリック > Edit All in Scope

## Spell Checking | スペルチェック

 - スペルチェック機能がサポートされた
 - 現在開いているファイルのチェック
    - Edit > Format > Spelling and Grammar > Check Document Now
    - command + ;
 - タイピング時に自動でチェック
    - Edit > Format > Spelling and Grammar > Check Spelling While Typing
 - 赤線部分を右クリック
    - スペル候補が表示される
    - Ignore Spelling（スペルを無視）
    - Learn Spelling（スペルを学習）

## cherry-pick

  - git cherry-pickコマンドがGUIで操作可能に
  - 別ブランチでのコミットを反映できる機能

## stash
  - git stashコマンドがGUIで操作可能に
  - commitしていない変更を一時退避できる機能
  - メッセージも任意で追加可能

## source control file inspector

 - インスペクタから現在のブランチでの履歴を見られる
 - StoryboardやXIBも含め、全ての種類のファイルで閲覧できる

# パッケージ管理

## Swift Package Manager

 - Swift Package Managerの機能がXcodeに統合
 - GitHub、Bitbucket、GitLab、または自分のホストで公開されているSwiftパッケージを利用できる
 - 依存関係分析に基づいてパッケージを自動的に取得
 - Swiftパッケージの作成方法（参考：[Creating Swift Packages](https://developer.apple.com/videos/play/wwdc2019/410)）
 - Swiftパッケージの導入方法（参考：[Adopting Swift Packages in Xcode](https://developer.apple.com/videos/play/wwdc2019/408)）

## XCFramework
 - ライブラリ、フレームワークの新しいバイナリ配布形式（.xcframework）
 - SwiftとC-basedコードをサポート
 - 1つのフレームワークで複数のプラットフォームで動かせる
    - 複数のフレームワークがアーキテクチャ毎のディレクトリに含まれる構成
 - xcframeworkを作成
    - ビルド設定のBuild Options > Build Libraries for Distribution をYesにする

```bash
xcodebuild archive -scheme XXX -destination "xxx" -destination "xxx" SKIP_INSTALL=NO
xcodebuild -create-xcframework -framework [path] -framework [path] -output XXX.xcframework
```

# デバッグ・テスト

## Device Conditions

  - デバイスの発熱状態、 通信状態をシミュレートできる機能
  - Window > Device and Simulators > DEVICE CONDITIONS
  - Thermal State （発熱状態のシミュレート）
    - 選択候補 
      - Fair
      - Serious
      - Critical
    - 本当に熱くなるわけではない
  - Network Link（通信状態）
    - 選択候補
       - 100% packet loss
       - Very poor network
       - Edge Network - poor
       - Edge Network - average
       - Edge Network - good
       - Edge Network - best
       - 2G Network - poor
       - 2G Network - better
       - 3G Network - average
       - 3G Network - good
       - 3G Network - best
       - LTE Network
       - WiFi Network
       - WiFi Network（802.11ac）
       - DSL Network
       - High Latency DNS

## Environment Overrides

  - デバイスの表示設定を実行時にリアルタイムで変更できる機能
  - Interface Style（ダークモードかどうか）
  - Dynamic Type（ダイナミックタイプ）
  - Accessibility Options（アクセシビリティでの設定）
    - Increase Contrast（コントラストを上げる）
    - Bold Text（文字を太くする）
    - Reduce Transparency（透明度を下げる）
    - Reduce Motion（示唆効果を減らす）
    - On/Off Labels（オン/オフラベル）
    - Button Shapes（ボタンの形）
    - Grayscale（グレイスケール）
    - Smart Invert（色を反転）
    - Differentiate Without Color（色なしで区別）

## XCTest frameworkの新しいAPI

### XCTUnwrap

 - nilが入ったらassert（＝XCTAssertNotNil）
 - nilでない場合はUnwrapして値が取り出せる
 - nilの場合throwされるので、テストケースの関数をthrowsにする

```swift
func testFirstNameNotEmpty() throws {
    let forenames: [String] = customer.forenames

    let firstName =  try XCTUnwrap(forenames.first)
    XCTAssertFalse(firstName.isEmpty)
}
```

### measure(metrics:options:block:)
  - measure関数でメトリクス計測できる項目が増えてCPUやメモリの使用率なども計測できる
  - https://developer.apple.com/documentation/xctest/xctestcase/3194265-measure
  - XCTMetricの継承クラス
    - XCTClockMetric
    - XCTOSSignpostMetric
    - XCTCPUMetric
    - XCTMemoryMetric
    - XCTStorageMetric

```swift
func testExample() {
    // Measures the CPU and memory impact of sorting the input list.
    measure(metrics: [XCTCPUMetric(), XCTMemoryMetric()]) {
        sortedList = qsort(list: self.fiftyNumbersFrom0to100)
    }
}
```

## Test Plan

  - 異なる設定毎にでテストを複数回実行できる機能
    - ローカリゼーション（言語、地域、位置情報）
    - アルファベット順、ランダム順
    - サニタイザー（Address、Thread、Undefined Behavior）
    - メインスレッドチェッカー
    - 引数もしくは環境変数
    - Memory diagnostics（MallocStackLogging、NSZombies）
    - スクリーンショットの撮影
  - 一箇所にテスト変数を定義し、複数のスキーム間でシェア可能
    - Test Planファイル（拡張子は.xctestplan）を作成（中身はJSON形式）
      - Testsタブ
         - テストケースの有効/無効のチェック
         - 並列実行するか
         - 新しいテストケースを自動で追加するか
      - Configurationsタブ
         - Shared Settings（すべてのテストで共通するデフォルト設定、個々のConfigurationで上書きも可能）
         - Configuration（Configurationを作成した分だけテストが実行される）
      - Option + クリックで選択したConfigurationのテストを1回だけ実行することも可能
         - テストナビゲーターではcontrol + クリックで同様のことが可能
    - 既存のTestスキームをTest Planをコンバートすることも可能

```bash
# -testPlanオプションを複数つけることで、Configurationを複数指定
xcodebuild test -project ... -scheme ... -testPlan 'Configuration1' -testPlan 'Configuration2'
```

## Result Bundle
  - ビルドとテストの結果を含む新しいファイル形式（拡張子は.xcresult）
    - ビルドログ
    - テストレポート
    - コードカバレッジレポート
    - テストアタッチメント
  - 特徴
    - 従来のフォーマットに比べて容量が小さい(4倍小さい)
    - Xcodeで内容を閲覧可能
    - プログラムでアクセス可能なコンテンツ  
    - xcresulttoolでアクセスする

```bash
# Result Bundleの書き出しパス指定
xcodebuild test ... -resultBundlePath /path/ResultBundle.xcresult

# 結果をJSONで取得
xcrun xcresulttool get --path ResultBundle.xcresult --format json

# マークダウン形式
xcrun xcresulttool formatDescription get

# コードカバレッジ
xcrun xccov view --report ResultBundle.xcresult

# コードカバレッジレポートの比較
xcrun xccov diff --json Before.xcresult After.xcresult
```

# その他の改善

## Signing and Distribution | 署名と配布

 - Signing & Capabilitiesタブにまとめられた
 - Configuration毎の設定が可能
 - 新しい証明書タイプ
    - Apple Development、Apple Distribution
    - すべてのプラットフォームをサポートする
    - Xcode11以降で利用可能
    - 既存の証明書も利用可能だが、旧バージョンのXcodeでは新しい証明書を利用できない

## Asset Catalogの新機能
  - ローカライズのサポート
  - ダークモードのサポート
    - Darkアピアランスの設定（Any、Light、Dark）
  - SF Symbols
    - Symbol Configurationからサイズと太さのバリエーションを設定
  - 切り取り、コピー、貼り付けが可能に

## Metrics Organizer
  - Window > Organizer > Metrics 
  - リリース済みアプリのメトリクスデータを収集する機能
    - Battery（バッテリー消費）
    - Launch Time（起動時間）
    - Hang Rate（ハング率｜レスポンス）
    - Memory（メモリ消費）
    - Disk Writes（ディスク書き込み）
  - ユーザーの許可設定が必要（設定 > プライバシー > 解析 > Appデベロッパと共有）

## シミュレータ
 - Metalサポート
 - 60FPSで滑らかに描画
 - CPUの利用は90%減
 - Warm bootが二倍早く
 - シミュレータでもWatch単体で起動できるように

# 参考資料
- [Xcode Release Notes](https://developer.apple.com/documentation/xcode_release_notes/)
- [WWDC19 Video - What's New in Xcode 11](https://developer.apple.com/videos/play/wwdc2019/401/)
- [WWDC19 Video - Getting Started with Xcode](https://developer.apple.com/wwdc19/404)
- [WWDC19 Video - Creating Swift Packages](https://developer.apple.com/videos/play/wwdc2019/410)
- [WWDC19 Video - Adopting Swift Packages in Xcode](https://developer.apple.com/videos/play/wwdc2019/408)
- [WWDC19 Video - Binary Frameworks in Swift](https://developer.apple.com/videos/play/wwdc2019/416/)
- [WWDC19 Video - Debugging in Xcode 11](https://developer.apple.com/videos/play/wwdc2019/412/)
- [WWDC19 Video - Creating Great Localized Experiences with Xcode 11](https://developer.apple.com/videos/play/wwdc2019/403)
- [WWDC19 Video - Testing in Xcode](https://developer.apple.com/videos/play/wwdc2019/413/)
- [Xcode Help - About Metrics organizer](https://help.apple.com/xcode/mac/current/#/devb642b28ac)
- [Xcode Help - Share crash, energy, and metrics data with developers](https://help.apple.com/xcode/mac/current/#/deve2819c518)