2014年からのiOSアプリ開発のポイント

2014年は6月にSwiftはもとより、Widgetを含むiOS8の発表、大画面サイズの到来を告げるiPhone6、iPhone6 Plusの発表、 2015年のApple Watch発売に向けてWatch SDKが発表されたりとiOSも次の時代に突入していくことを肌で実感する年になりました。

UIViewControllerの刷新やiPhone6、iPhone6 Plusの登場によって大画面、`@3x`画像の追加などで悲鳴をあげた開発・デザインチームも多かったかと思います。

一方でExtensionの登場は開発者にとってはアイデアを刺激される素晴らしい進化だったと感じます。

こういった今年の変化を踏まえ、2015年以降、iOSアプリを開発する上で頭に入れるべきことをピックアップしました。

## Extensionを意識して設計を行う

アプリを新規で開発するのであれば、Extensionによって後々拡張されることを想定して設計をした方が良いと思います。

### 共有領域
App Groupの設定をして、CoreDataやUserDefaultを共有領域に保存するようにしておけば、将来的にExtensionやApple Watchに対応して機能を拡張をすることになった場合もアプリ内で作成したデータを利用できるので開発が楽になります。

![appgroup.png](https://qiita-image-store.s3.amazonaws.com/0/45525/544483df-d3ee-3781-d540-056ab7dc850d.png)


すでにアプリが出ていてCoreDataを使用している場合はマイグレーションする必要があります。[こちら](http://stackoverflow.com/questions/25699922/update-core-data-store-location-to-support-app-groups)が参考になりました。

Extensionの実装をしていないのに共有領域を使っていいのか若干の不安がありますが、将来的に使う可能性があれば問題ないのではないかと思います。使わないとは誰も言えないですし、あとからマイグレーションする手間を考えると最初から設定しておいた方が楽だと思います。

### Embedded Framework
またExtensionは、簡単にリリースしようとするとアプリの中にすでに存在している機能を切り出すだけの場合もあるかと思います。

このような場合、本体のアプリ側と共通のクラスを使うことになるため、Embedded Framework、埋め込みフレームワーク化しておくと便利です。

![emmbeddedframework.png](https://qiita-image-store.s3.amazonaws.com/0/45525/8aedd573-0a52-d764-2249-3f5a7dbe3389.png)

なお、この際Extensionでは利用できないAPIがあるので、その点には注意して設計する必要があります。`NS_EXTENSION_UNAVAILABLE`というマクロがヘッダに存在するAPIは使用できません。

個人的に困ったこととしては`sharedApplication`が利用できません。

```objc:UIApplication.h
+ (UIApplication *)sharedApplication NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.");
```

`UILocalNotification`などはローカル通知の登録をする際は`sharedApplication`を使用するためExtensionでは使用できないということになります。

```swift

UIApplication.sharedApplication().scheduleLocalNotification(localNotification)

```
この辺りを押さえて各クラスの設計を行えば、例えばApple Watchに人気が出て対応が迫られたとしても早めに手を打つことができます。

## アプリ本体外から入ってくることを想定してURLスキームの設計をする

iOSから他のアプリを起動するには`UIApplication`の`openURL:`を使用しますが、Extension側から起動する場合は`NSExtensionContex`クラスの`openURL:completionHandler:`を使用します。

つまり、どちらにせよURLスキームの設定は必要になります。

例えば、Today Extension=WidgetなどはWidget上に置いたボタンからアプリを起動するというシーンが結構多くなると思います。

その際、URLによって処理する内容をハンドリングできると便利なのでカスタムURL設計を考えておくと便利かもしれないです。


参考

* [Custom URL Schemeの処理をシンプルに書く](http://qiita.com/naonya3/items/c55e6151b4ff6ab5725f)


## Autolayout

必須技術になってしまいましたね。

つい1年くらい前は「Autolayoutなんかクソだ！」みたいな声を聞いたりしたのですが、iPhone6の登場によって使わざるを得なくなりました。

iOS8からはSize Classが導入されたことによって、デバイスのサイズというよりも抽象化された概念を知っておく必要が出てきました。

![sizeclass.png](https://qiita-image-store.s3.amazonaws.com/0/45525/76a0dfef-b202-f055-a59b-fe1f0a76939a.png)

TraitCollectionというものでViewControllerやViewの特徴を見ることができます。


|  iPhone6 Plus     | ポートレート | ランドスケープ  |
|:------------------|:-----------|:-------------|
|horizontalSizeClass| Compact    | Regular      |
|verticalSizeClass  | Regular    | Compact      |
|userInterfaceIdiom | UIUserInterfaceIdiomPhone | UIUserInterfaceIdiomPhone |
|displayScale       | 3.0        |3.0           |

ポートレートからランドスケープに変わると`horizontalSizeClass`と`verticalSizeClass`が変わるため`traitCollectionDidChange:`が呼ばれるので、そこで何か特殊な処理をすることもできます。

`userInterfaceIdiom`や`displayScale`は変わりません。

`Trait Collection`はデザインにも深く関わってくる部分です。`UISplitViewController`はiOS8からiPhoneでもiPadのような画面の分割表示をさせることが可能になりました。

各デバイスがどのように振る舞うのかをデザイナーに共有しておくとより良いデザインに仕上がると思います。

## デザイン環境の構築

`@3x`が追加されたことによって書き出しの作業がさらにバカにならなくなりました。はっきり言って画像の書き出しなんてかなりどうでもいい作業なので、ここをなるべく効率化させることがかなり重要になってきています。

以前は[Slicy](https://itunes.apple.com/jp/app/slicy/id512533449?mt=12)というアプリを使用して書き出しを行っていましたが、今は[スクリプトを使ってPhotoshopで@3x画像を作成](http://qiita.com/mo_to_44/items/f25c24063eac58659c88)しています。

ただ、この方法も`@4x`が出たらおしまいです。Xcode6からはベクター画像が使えるようになったので積極的に採用していくべきだと考えています。

[Makeappicon](http://makeappicon.com/)も各サイズごとのアプリアイコンを生成できてかなり便利です。

AppStoreのスクリーンショット画像を書き出すサービスも[Sketchが始めた](http://sketchtoappstore.com/)ので使っていきたいところです。

余談ですが、個人で作っているアプリをSwiftで書き上げて申請するタイミングになって用意すべきスクリーンショットの多さに愕然としたのは言うまでもありません（3.5inch,4inch,4.7inch,5.5inchのiPhoneに加えてiPadの5枚）。

こういったツールを利用して手間を減らしていくことも、これからの多種多様なデバイスに素早く対応していくために必要になってきます。

参考

* [[Xcode 6] Asset Catalog でベクターが扱えるようになりました！](http://dev.classmethod.jp/references/xcode-6-asset-catalog-vector/)


## まとめ

今年はSwiftの登場で（個人的にも）盛り上がりましたし、来年2月ごろに発売が噂されるApple Watchの登場に向けたWatch Kitの発表と、年末になってもiOS開発者は息つく暇もありませんでしたね。

もちろん、ここで取り上げたことが来年になったらコロッと変わっていることも大いに考えられますが、現時点でこれらのことを意識して設計・開発を進めればExtension対応はもちろん、新しいデバイスが出ても柔軟に対応できるのではないかと思います。