iOS9から使える3DTouch・クイックアクションを実装する


iPhone 6s、iPhone6s Plusから使えるようになった3DTouch。
その中の**クイックアクション**の実装をしてみます。

3D Touchの機能のPeek and Popの実装についてはこちらで書きました。
あわせて読んでいただけると嬉しいです。

・[iOS9から使える3D Touch・Peek and Popを実装する](http://qiita.com/takashings/items/ead3e9d935c2108d55a7)

### クイックアクションの実装方法には2通りある
まず、クイックアクションについて。
アプリアイコンを強く押し込むと表示されるこのことですね。

![24a999aa-c89c-d9c6-07b3-f98605088ef8.jpeg](https://qiita-image-store.s3.amazonaws.com/0/40009/03136c73-387a-dfc9-08f9-8205a40a81e1.jpeg)

アプリのよく使う機能や、機能のショートカットを設定することができます。
クイックアクションは1個から4個までを登録することができます。

実装はiOS9から可能ですが、3D Touch対応機種でのみ使うことができる機能となっています。

そして、クイックアクションには2通り実装があります。
その実装方法を以下に書いていきたいと思います。

#### static quick actions
クイックアクションの機能が決まっている場合です。
例えば上記のカメラアプリやFacebookのアプリはこの実装がされています。

![c87cb1f8-9ad2-f711-6081-d7f15681aa03.jpeg](https://qiita-image-store.s3.amazonaws.com/0/40009/3cbc77cc-5d54-c189-657b-174b294fd775.jpeg)

メリット・デメリットを書いてみました。

**◆メリット**

+ （アプリ初回起動なしに）アプリを起動しなくてもクイックアクションが使える
+ 機能が決まっているため、処理が複雑になりにくい

**◆デメリット**

+ クイックアクションを変更する場合はアプリのアップデート以外では変更ができない

**static quick actions**はInfo.plistに"UIApplicationShortcutItems"の記述を追加することで実装ができます。

設定する項目は以下の通りです。

|項目|意味|
|:-:|:-:|
|UIApplicationShortcutItemTitle|ショートカットのタイトル(必須)|
|UIApplicationShortcutItemType|ショートカット処理の識別子(必須)| 
|UIApplicationShortcutItemSubtitle|ショートカットのサブタイトル|
|UIApplicationShortcutItemIconType|Appleが用意しているアイコンの画像タイプ|
|UIApplicationShortcutItemIconFile|ユーザー指定のアイコンの画像|
|UIApplicationShortcutItemUserInfo|ユーザー指定の辞書型データ|

XML上の設定例としては以下の通り。

```xml
<key>UIApplicationShortcutItems</key>
    <array>
        <dict>
            <key>UIApplicationShortcutItemIconFile</key>
            <string>open-favorites</string>
            <key>UIApplicationShortcutItemTitle</key>
            <string>Favorites</string>
            <key>UIApplicationShortcutItemType</key>
            <string>com.mycompany.myapp.openfavorites</string>
            <key>UIApplicationShortcutItemUserInfo</key>
            <dict>
                <key>key1</key>
                <string>value1</string>
            </dict>
        </dict>
        <dict>
            <key>UIApplicationShortcutItemIconType</key>
            <string>UIApplicationShortcutIconTypeCompose</string>
            <key>UIApplicationShortcutItemTitle</key>
            <string>New Message</string>
            <key>UIApplicationShortcutItemType</key>
            <string>com.mycompany.myapp.newmessage</string>
            <key>UIApplicationShortcutItemUserInfo</key>
            <dict>
                <key>key2</key>
                <string>value2</string>
            </dict>
        </dict>
    </array>
```

当然のごとく、iOS9以降でないと設定ができません。

#### dynamic quick actions
もう1つの方法はコードで記述する **dynamic quick actions**。
**UIApplicationShortcutItem**クラスを使って設定します。

この方法はユーザーがフレキシブルにクイックアクションを変更することができます。
この方法が使われているのは（厳密には違いますが）ミュージックアプリやFacebookメッセンジャーや電話アプリなどですね。

![ee16de81-b0fa-9280-1e87-b118941984b5.jpeg](https://qiita-image-store.s3.amazonaws.com/0/40009/0516049d-7cc3-e9d0-2c78-a22e1067cc21.jpeg)

こちらのメリット・デメリットをはこちら

**◆メリット**

+ ユーザーの操作によってクイックアクションの内容を変更できる
+ 処理によって(実質)4つ以上のクイックアクションを使うことができる

**◆デメリット**

+ 少なくとも1回はアプリの起動が必要
+ 実装コード部分の処理が行われないと登録されない
+ 登録予定のクイックアクションの数だけ実装を行う必要がある
+ フレキシブルに登録ができるため、処理が複雑になりやすい

実装は先述したとおり、コードで実装します。

```swift:swift
let shortcut1 = UIMutableApplicationShortcutItem(type: "com.mycompany.myapp.openfavorites", localizedTitle: Favorites, localizedSubtitle: "", icon: UIApplicationShortcutIconType.Compose, userInfo:["value1":"key1"])
    
let shortcut2 = UIMutableApplicationShortcutItem(type: "com.mycompany.myapp.newmessage", localizedTitle: New Message, localizedSubtitle: "send Friends", icon: UIApplicationShortcutIcon(templateImageName: "shortcut_icon_newmessage"), userInfo:["value2":"key2"])

// 登録
UIApplication.sharedApplication().shortcutItems = [shortcut1, shortcut2]
```

#### クイックアクションが押された時の処理
クイックアクションからアプリが起動された時の処理についてはAppDelegateに以下のデリゲートメソッドを追加する必要があります。
``UIApplicationDelegate``の追加も忘れずに。

```swift:swift
class AppDelegate: UIResponder, UIApplicationDelegate {

	func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
	}
}
```

この部分に処理を記載して、クイックアクションの処理分け等を行います。
記述例としては以下の通りです。

```swift:swift
class AppDelegate: UIResponder, UIApplicationDelegate {

	func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
		if let _ : UIApplicationShortcutItem = shortcutItem {
			if shortcutItem.type == com.mycompany.myapp.newmessage {
				let alert : UIAlertController = UIAlertController(title: "", message: "クイックアクションで起動されました", preferredStyle: UIAlertControllerStyle.Alert)
				alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))
				self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
			}
		}	
	}

}
```

クイックアクションでアプリ起動した場合はアプリの起動は必ずされます。
途中でキャンセルなどはできないので、どのような状況でもクイックアクションが実行されることを考えての設計が必要となります。

以上です。

いかがでしたでしょうか。
クイックアクションは便利ですが、アプリの内容によっては実装しづらいものもあると思います。
ですが、クイックアクションによってアプリがより使いやすくなる場合があるのは確実なので、検討してはいかがでしょうか。


参考ページ
- [Apple Developper Library | Information Property List Key Reference](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW36)