What's New in iOS11まとめ (Metal2以外)

[What's New in iOS 11.0](https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS_11_0.html)(β)を軽くまとめてみました。公開資料などが出次第更新していければと思います。認識が間違っている箇所がありましたら、修正リクエストよろしくお願いいたします🙏 ※ ARKitとかCoreMLについてはきっと詳しい記事があると思うので適当にしちゃいました🙇

[What's New in tvOS11 まとめ](http://qiita.com/hanawat/items/f7b67f73992d231bf536)も書いているので合わせてどうぞ📺

* 2017/06/14 MusicKitの項目を追記しました👏

# General

## バーコードの生成と読み取りをサポート

バーコードの検出や作成をサポートするAPIを下記のフレームワークに追加

* **CoreImage**
* **AVFoundation** (`AVMetadataMachineReadableCodeObject`)
* **SiriKit** (*Visual Codes Intent Domain*)

### CIBarcodeDescriptor

このクラスを継承した下記の子クラスを使用して特定の種類のバーコードを処理する

* `CIQRCodeDescriptor`: [QRコード](https://en.wikipedia.org/wiki/QR_code)
* `CIAztecCodeDescriptor`: [アステカコード](https://en.wikipedia.org/wiki/Aztec_Code)
* `CIPDF417CodeDescriptor`: [PDF417](https://en.wikipedia.org/wiki/PDF417)
* `CIDataMatrixCodeDescriptor`: [データマトリックス](https://en.wikipedia.org/wiki/Data_Matrix)

## MusicKit

別で記事を書いたのでどうぞ👏
[Qiita - iOS11で発表されたMusicKitについて](http://qiita.com/hanawat/items/c59c3365156a474821cc)

# App Frameworks

## ドラッグ&ドロップ

アイテムのドラッグ&ドロップ移動が可能になった。iPadでは異なるアプリ間のドラッグ&ドロップも可能だが、iPhoneの場合はシングルアプリケーションのみ対応している。

ある特定のビューにドラッグ&ドロップ処理をする場合は対象のビューに`addInteraction`してDelegate先で必要なメソッドを実装するだけです。

```swift
// for Dragging Image View
let dragInteraction = UIDragInteraction(delegate: self)
imageView.addInteraction(dragInteraction)

// for Dropping Super View
let dropInteraction = UIDropInteraction(delegate: self)
view.addInteraction(dropInteraction)
```

### UIDragInteractionDelegate

Requiredなメソッドはこれだけです。ドラッグ操作を無効にしたい場合は空の配列を返せばOKみたいです。
アイテムの受け渡しはExtensionで用いられる`NSItemProvider`で行えます。

```swift
func dragInteraction(
  _ interaction: UIDragInteraction,
  itemsForBeginning session: UIDragSession) -> [UIDragItem] {

  guard let image = imageView.image else { return [] }

  let provider = NSItemProvider(object: image)
  let item = UIDragItem(itemProvider: provider)
  item.localObject = image
  return [item]
}
```

その他のメソッドは持ち上げた時のプレビューやアニメーションの変更ができます。基本的にデフォルトで用意してくれます。

```swift
// for Lifting Preview
optional public func dragInteraction(_ interaction: UIDragInteraction, previewForLifting item: UIDragItem, session: UIDragSession) -> UITargetedDragPreview?

// for Lifting Animation
optional public func dragInteraction(_ interaction: UIDragInteraction, willAnimateLiftWith animator: UIDragAnimating, session: UIDragSession)
```

他にもドラッグ操作(セッション)の開始時やドラッグ中などライフサイクルメソッドが多数用意されているので目を通しておくといいと思います。

### UIDropInteractionDelegate

iPadの場合は他のアプリからのデータを受け取る場合があるので、下記のメソッドでセッションの中身を確認して受け取るかどうか決められます。

```swift
func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {

  // Accept when the item is an image and the count is 1.
  return session.hasItemsConforming(toTypeIdentifiers: [kUTTypeImage as String])
    && session.items.count == 1
}
```

下記のメソッドでアイテムをコピー/移動/キャンセル/禁止の指定をします。ただし移動自身のアプリ内のみ有効です。

```swift

func dropInteraction(
  _ interaction: UIDropInteraction,
  sessionDidUpdate session: UIDropSession) -> UIDropProposal {

  let dropLocation = session.location(in: view)
  let operation: UIDropOperation

  if imageView.frame.contains(dropLocation) {
    operation = session.localDragSession == nil ? .copy : .move
  } else {
    operation = .cancel
  }

  return UIDropProposal(operation: operation)
}
```

あとはデータの受け取りです。非同期なんですね。

```swift
func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {

  session.loadObjects(ofClass: UIImage.self) { imageItems in
    guard let images = imageItems as? [UIImage] else { return }

    self.imageView.image = images.first
  }
}
```

他にもこんな特徴があるみたいです。

* ドラッグ中はユーザーの他の操作を妨げない
* システムは複数のドラッグを同時に管理できる
* `UITextView`, `UITextField`はデフォルトでサポートされる
* `UITableView`, `UICollectionView`もビルドインだがある程度実装が必要になる
* アプリ間のドラッグ&ドロップはシステムがセキュリティ面の保証をしてくれる

## ドキュメントブラウザ

クラウドまたはローカルに保存されたドキュメントを表示するビューコントローラーが追加されました。

### UIDocumentBrowserViewController

ドキュメントファイルを一覧表示するViewControllerで、そのまま出すだけでも自身のiCloudとローカルのDocumentsディレクトリトリにアクセスできます。
ファイルタイプ(`allowedContentTypes`)は[Uniform Type Identifier](https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Introduction/Introduction.html)の文字列のみ指定可能です。

```swift
init(forOpeningFilesWithContentTypes allowedContentTypes: [String]?)
```

`UIDocumentBrowserViewControllerDelegate`というDelegateも用意されているので、ファイルの取得も簡単です。
また下記のような特徴もあります。

* `Info.plist`で許可をすれば他のアプリへDocumentsディレクトリを公開できる
* ドキュメントの編集内容は各々のDocumentsディレクトリのファイルに反映される
* `FileProvider`と`FileProviderUI`を実装すれば外部のクラウドストレージも提供できる
* TabBar/NavigationControllerではなく常にRootViewControllerで表示しなくてはならない
* 異なるヒエラルキーで出したい場合は`UIDocumentPickerViewController`を使う
* `UIDocumentBrowserTransitionController`でアニメーションも変更できる

## Dynamic Typeの改良
* `UIFontMetrics`を使うことでテキストサイズに合わせてフォントも変えられるようになった
* AutoLayoutで動的にテキストサイズを変更する場合に間隔を自動調整してくれる
* PDFのアセットデータによる画像のスムーズなサイズ調整が可能になった
* アクセシビリティテキストで指定したサイズに画像のサイズを調整するプロトコル`UIAccessibilityContentSizeCategoryImageAdjusting`の追加
* `UIStackView`でカスタマイズ可能な間隔の指定が可能になった

## パスワードの自動入力の改良
* `username`と`password`が入力内容保管の`UITextContentType`で使用可能になった

## Keyboard Extensionの改良
* `selectedText`で直近の選択されたテキストを取得できる
* `documentIdentifier`でユーザが新たなテキストウィジェットに移動しているか判定できる
* `hasFullAccess`でキーボードへのアクセス許可があるか確認できる
* `needsInputModeSwitchKey`で入力モード切り替えキーの表示を制御できる
* システム権限にKeyboard Extensionが追加

## 利用可能ストレージ空容量のAPIの改良
* keyにURLを指定できるようになった
* `volumeAvailableCapacityForImportantUsageKey`でアプリに必須のデータ容量を指定できる
* `volumeAvailableCapacityForOpportunisticUsageKey`でアプリに必須ではないデータ容量を指定できる

# Graphics and Games

## ARKit
* AR体験ができる機能を提供する

## 画像認識
* Vision framework: 顔、バーコード、テキスト、画像の水平線や長方形の領域を検出できる
* 機械学習用のCore MLを使用して任意の学習モデルを使用できる
* ビデオ内のオブジェクトを認識して追尾できる

## 画像のブレンド追加
* 2つのカーネルをブレンドできるCIBlendKernelの追加
* Metalを使用したカーネルの作成が可能になった

## ReplayKit frameworkの改良
* `RPScreenRecorder`がバックカメラとキャプチャに対応

## CoreImageフィルターの追加
* `CITextImageGenerator`
* `CIColorCurves`
* `CILabDeltaE`
* `CIBokehBlur`
* `CIMinMaxRed`
* `CIBicubicScaleTransform`

# App Services

## 機械学習モデル
* 簡単に機械学習モデルをアプリに組み込めるCore ML frameworkの追加

## SiriKitのIntent追加
* Visual Codes: QRコードを使用して支払いや連絡先の交換が可能になった
* Lists and Notes: メモの追加、予定やリマインダーの追加が可能になった
* Ride Bookingに乗車キャンセルとフィードバック機能が追加された
* Paymentsにアカウント検索と送金機能が追加された

## デバイスの向首角を検知
* `CMDeviceMotion`に向首角(Heading Angle)を検知するheadingが追加された

## マルチパスTCPに対応
* `URLSessionConfiguration`がWi-Fiと携帯通信のようにマルチパスTCPに対応した

## DNSプロキシに対応
* Network Extension frameworkにDNSプロキシタイプが追加された

## Apple Payの改良
* PassKitに支払い情報、認証エラーに当たるPKPaymentErrorが追加された
* 上記エラーをハンドリングする`PKPaymentAuthorizationControllerDelegate`が追加された
* `PKPaymentRequest`に取引する国を指定する`supportedCountries`が追加された
* ウォレットで支払い方法がサポートされていない場合でもApple Payでの支払いが可能になった

## In-App Purchasesの促進
* ストアで20件までのアプリ内課金アイテムを表示できるようになった
* 上記のリンクからアプリ内課金を行う場所まで連れて行かれる
* `paymentQueue:`の実装が必要

## ライブメッセージ
* 動的なメッセージ表示できるレイアウトの`MSMessageLiveLayout`が追加された
* 独自の`MSMessagesAppViewController`を持っているので複数のライブメッセージがアクティブに存在できる

## HomeKitのトリガー追加
* `HMSignificantTimeEvent`: 日の出と日没のオフセット時間を指定できる
* `HMCalendarEvent`: 特定の日時を指定できる
* `HMDurationEvent`: タイムインターバルで指定できる
* `HMCharacteristicThresholdRangeEvent`: アクセサリから取得できる温度などの状態を範囲指定できる
* `HMPresenceEvent`: ユーザーが居るか居ないかで指定できる

## MapKitの改良
* 地図の表示タイプに情報を削った状態にする`mutedStandard`が追加された
* アノテーションの表示優先順位を指定できる`displayPriority`が追加された
* 衝突判定を長方形か円形か指定できる`collisionMode`が追加された
* アノテーションをクラスタリングする識別子`clusteringIdentifier`が追加された

# Media and Web

## High Efficiency Video Coding(HEVC)対応
* とっても綺麗な動画エンコーディング

## High Efficiency Image Format(HEIF)
* とっても綺麗な画像エンコーディング

## Depth API
* Depth Data(デュアルカメラで撮影した時の背景の距離)がAV Foundationに追加された

## ストレージ管理
* `AVAssetDownloadTask`によるストリーミング時のストレージ管理を自動で行う機能が追加された

## AirPlay2
* Podcastなどの長い時間のオーディオのためにAirPlayがマルチスピーカーに対応

## Live Photoの編集
* Live Photoにループやバウンスなどのエフェクトが追加された
* Live Photoなどの特定の種類のメディアライブラリを提示できるようになった

# System

## Core Bluetooth frameworkの改良
* L2CAPチャンネルをサポート
* Bluetoothのリセットと再起動時にセッションの復元ができるようになった

## Core NFC
* NFCタグを検出/読み込みが行える