iOS 9の到来を祝うため、私たちは何人かの友人に、最新のiOSバージョンをサポートするためにアプリのアップデートをする際に学んだ、最も役立った事を共有してもらいました。ここでは、iOS 9での開発に最大限に活用し、かつスピードアップするための素晴らしいアドバイスをご紹介いたします。
Dave Verwer
@daveverwer — Curatedファウンダー、iOS Dev Weekly運営
iOS SDKの新しいAPIが、アプリの発見やマーケティングに実際に役立つことはめったにありません。なので、私にとってiOS 9の中で最もエキサイティングないくつかの機能は、新しいサーチAPIです。
これらの機能は、Handoff機能をサポートするためにiOS 8の中で紹介されNSUserActivity
の上で構築します。iOS 9のSpotlight検索に表示させるために、iOS 9用の追加メタデータとURLのディープリンクをアプリに追加することができ、ユーザーはアプリをローンチするためだけではなく、その内容を見ることができます。
これは既存ユーザーにとってはすぐに有益ですが、Appleはまた、これらの検索結果を中心にしてインデックスを行います。まだあなたのアプリをインストールしていないユーザーがSpotlightを使用する時に、あなたのアプリはおすすめとして表示されます。フリーマーケティング?まあ、そんなところですね。
ここで興味深いのは、あなたの既存ユーザーが定期的にアプリを使用して、あなたが提供する検索結果とインタラクションを行っている時にだけ、Appleが新しいユーザーにあなたのアプリをサジェストすることです。これはすぐにスパム的なアプリをカットし、真の価値を提供するものに焦点を当てます。そしてそれはApp Storeにとても良いことになります。
簡単なTipsを用意するよりももっと良いものがあります。これらのAPIの見識を深め、それらを実装するためには、WWDCでのSession 709 — Introducing Search APIsを見るのがいいでしょう。 iOSがあなたのアプリのリンクを正しく見ることができているかを確認するためにあなたのウェブサイトをバリデートする便利なツールもあります。
Tim Oliver
@TimOliverAU — iComicsクリエイター
iPhone 6sとiPhone 6s Plusに関するエキサイティングな発表によって、デベロッパーはついに自分のアプリを3Dタッチによるアドベンテージを得ることが可能になり、UIインタラクションへ(文字通り)完全に新しい次元を追加することができます!
Appleの予想通り、3Dタッチはシンプルに基礎的なレベルで、UITouch
の新しいプロパティとして、非常に簡単なAPIを介してデベロッパーに向け開放されました。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
guard let touch = touches.first else { return }
if traitCollection.forceTouchCapability == .Available {
println("Touch pressure is \(touch.force), maximum possible force is \(touch.maximumPossibleForce)")
}
}
この新しいAPIは、アプリの新しい機能への膨大な可能性を解き放ちます。それは例えば、ゲームへの追加コントロールオプションや、ドローイングアプリでのきめ細かいコントロール、もしくは私たちが初代のiOSデバイスの時から使っているタップ&ホールドパラダイムに代わる、より良いものです。
UIタッチAPIに加えて、Appleはまた、UIPreviewAction
とUIApplicationShortcutItem
という、アプリに3Dタッチの機能を追加するための二つの新しいクラスのセットを提供してきました。
ユーザーがUIエレメントを3Dタッチにした際に、UIPreviewAction
を使えば、デベロッパーはすぐに新しい「プレビュー」オーバーレイにコンテンツを表示することができます。これは、ビューコントローラの全体のトランジションを必要とせずに、Eメールや、写真、ウェブサイトなどを、素早く確認することを実現する素晴らしい方法です。
UIApplicationShortcutItem
オブジェクトは、iOSホームスクリーン上での素晴らしい新機能を可能にします。アプリのアイコンを3Dタッチアプリすると、選択肢が並んだシートが現れ、ユーザーはアプリの特定のセクションに素早く移動したり、アプリ内のアクションを実行できます。
全体的に言って、3Dタッチの発表はiOSデバイスインタラクションの全く新しいパラダイムを解き放ち、これから開発されるiOSアプリにおいて、新しい世代のイノベーションを可能にするでしょう。サンプルコードと3Dタッチ自体のより基本的な情報はApple Developerサイトの 3D Touch page で入手できます。Good luck!
iOS 9.0とOS X 10.11の新しい点は、UILayoutGuide
とNSLayoutGuide
クラスです。これらを使用することによって、本質的でないダミーのビューを生成することなく、Auto Layoutの制約に関連づいた「ビューのような」オブジェクトを生成することができます。例えば、空のビューを生成し、それらの大きさなどを制約する代わりに、これらの新しいクラスを使うことができます。
// Create the layout guides.
let layoutGuideA = UILayoutGuide()
let layoutGuideB = UILayoutGuide()
// Add them to the view.
let view: UIView = ...
view.addLayoutGuide(layoutGuideA)
view.addLayoutGuide(layoutGuideB)
// Add constraints using them.
layoutGuideA.heightAnchor.constraintEqualToAnchor(layoutGuideB.heightAnchor).active = true
// You can even set their identifiers...
layoutGuideA.identifier = "layoutGuideA"
layoutGuideB.identifier = "layoutGuideB"
// ...and get their calculated frames (valid once the owning view has been laid out)
print("layoutGuideA.layoutFrame -> \(layoutGuideA.layoutFrame)")
Indragie Karunaratne
@indragie — Mac and iOS ソフトウェアエンジニア、学生
iOS 9で導入されたNSLayoutAnchor
APIは、制約の記述をクリーンにするだけではなく、静的型チェックの力を通して、あなたの制約の正当性に関する追加の保証も行います。例えば、古いNSLayoutConstraint
APIを使用して作成されたこの制約を考えてみてください。
NSLayoutConstraint *constraint =
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:view2
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0];
Y軸(top)の属性に、X軸(leading)の属性を制約としているので、この制約は無効です。ただし、これはどんな警告なしにコンパイル、実行されて、 静かに 失敗します。そしてレイアウトをundefinedな状態にして、デバッグは非常に困難になります。数十の(または数百、数千…)の中の一つの制約が正しくないことはログに残りません。
NSLayoutAnchor
はSwiftとObject-Cの両方で、Genericsの力を活用することで、この問題を解決します。UIView
の anchor accessorsは、NSLayoutAnchor
から継承された型情報をメソッドに追加するNSLayoutAnchor
のサブクラスを具象化します。これらのアンカーの型はそれぞれ、同じ型の別のアンカーに制約されることが可能なので、
X軸、Y軸、及び大きさ(width/height)に別のNSLayoutAnchor
のサブクラスがあります。APIは有効な制約を作成するためのルール適用のために、型チェッカーを使用して、NSLayoutAnchor
のメソッドのアンカーパラメーターを、レシーバと同じジェネリックタイプに制約します。
先ほどの例に戻ってみましょう。ここでは、同等の制約がNSLayoutAnchor
APIを使用して宣言されています。
NSLayoutConstraint *constraint =
[view1.leadingAnchor constraintEqualToAnchor:view2.topAnchor];
古いAPIを使用するよりもはるかに読みやすいだけでなく、コンパイラはあなたが異なる型のアンカーを使用して制約を生成することができないのを知っているので、コンパイラの警告”Incompatible pointer type”を吐き出してくれます。
詳細については、NSLayoutAnchorのドキュメントをご覧ください。
SwiftとObjective-C Genericsに関してこれを書いている時点では、Xcode 7 beta 6とObjective-C genericsを使用してSwiftへ正確にブリッジすることはできません。もしこのAPIをSwiftで使用する場合に、このTips内で述べられている追加の型が適用されないということです。しかし、もしObjective-Cを使用する場合には、Joe Groffが証明しているように正確に動きます。
Ayaka Nonaka
@ayanonagon — Venmo iOS エンジニア
私の一番のiOS9のTipsは、iOS 7をドロップして、私が大好きなUIAlertController
(iOS 8+)を使い始めることです。それは、
ビューコントローラだけで、アラートとアクションシートと、レイアウトを考えるときの最良の方法であるUIStackView
(iOS 9+)の表示を実現します。あなたがまだ体験したことがなければ、ぜひトライしてみてください。とても素晴らしいですよ。これらを以前のiOSのバージョンに移植した、(PSTAlertController
とTZStackView
)というオープンソースライブラリもありますので、これらを使って置き換えることにはとても価値があり、その時点でiOS 7やiOS 8を切り捨てる準備が整います。
AppleはiOS 9で、App Transport Securityを発表しました。これは、全てのアプリがデフォルトでHTTPSを使用することを要求します。全てのアセットがHTTPS経由で提供されるわけではないので、AppleはATSを部分的、もしくは全体的に無効にする方法も提供します。
もしあなたのアプリが任意のURL(例 UIWebView)をロードできるようにする必要がある場合は、NSAllowsArbitraryLoads
キーをYES
に設定することで、おそらくATSを全体的に無効にするでしょう。これは問題ありませんが、ATSを全体的に無効にする場合は、重要なドメインのために、部分的にATSを有効にした方がいいでしょう。それはNSExceptionDomains
キーを設定することで実現できます。例えば、これはWorkflowのInfo.plistの一部です。
私たちがHTTPを経由して、ユーザーのファイルダウンロードをサポートしているのがわかると思います。しかし、workflow.is(それとWorkflowが使っている全てのAPIのドメイン)に接続する時には、HTTPSを必要とします。
また、特に注意すべき点は、ATSがそれぞれのバンドルに適用されていることです。あなたはATS辞書をメインのアプリのInfo.plistだけではなく、あなたのエクステンションの Info.plistのファイルにも追加する必要があります。
Jake Marsh
@jakemarsh — Little Bites of Cocoaクリエイター
あなたは新しい検索機能をたくさん実装できます。検索は、今後非常に重要になるでしょう、そしてiOS 9は単なる始まりです。私はできるだけ早く、アプリにNSUserActivity
のサポートを追加することをお勧めします。
これは信じられない程に単刀直入で、あなたが開発を完了したら、あなたのアプリはHandoffと新しいProactiveシステムの両方をサポートします。もしあなたのアプリが何か検索可能なコンテンツを持っている場合、あなたは間違いなく新しく素晴らしいCore Spotlightフレームワークを活用し、どのようにその全てをインデックスするかをシステムに伝えるべきです。また、あなたのアプリに関連付けられている全てのWebコンテンツがiOS 9の新しい検索結果ビュー用に最適化されているかを確認する必要があり、Appleは、いくつかのシンプルなメタタグがどのように役立つかを示す素晴らしいガイドを紹介しています。
ユーザーが何を行っているか、そしてどのようなコンテンツを彼らがつくりインタラクションしているかをシステムが知れば知るほど、よりインテリジェントな提案やオプションを提示します。
Sam Ritchie
@FakeSamRitchie — codespliceチーフcodesplicer
iOSの共有コードベースで作業している人は誰もが、Storyboardファイル上のコンフリクトが発生して、たびたびIBでの全ての変更を手動でやり直すことを経験しています。これはいくつかのチームにとって、共同でStoryboardの開発することを諦めて、いくつかの異なるsource control shingleを実装することになり、とても骨の折れる作業です。
もし、不運にも対応策がない場合に、マージのコンフリクトを最小化にするための最良の方法は、いくつかの小さなStoryboardに分割することでしょう。これまでは、Storyboardをまたがった画面遷移が必要な場合は、コードで実装する必要がありましたが、Xcode 7とiOS 9があれば、Storyboard Reference経由で通常のセグエを使用してこれを行うことができます。単一のStoryboardナビゲーションのすべての恩恵にあやかり、シンプルなマージのためにファイルを分割することになるでしょう。
単一のストーリーボードを分割する最も速くて簡単な方法は、ズームアウトです。関連す���シーンのグループをShift + 選択し、‘Editor’から’Refactor to Storyboard…’を選択します。(そうです、Storyboardリファクタリングが可能です。Swiftではまだできないのに。)。しかし、この方法は全てのシーンにStoryboard Referenceを残し、必要に応じて見た目の良くないStoryboard IDを自動生成するので、個人的には私は‘File‘から‘Duplicate…’を選び、複製してから、余分なシーンだけを削除します。
もしすでにいくつもStoryboardを持っている場合は、ガッツポーズをしましょう。あなたは何行かのコードを削除することができます!ObjectライブラリからStoryboard ReferenceにドラッグしてSegueを設定してから、あり余る勢いでデリートキーを叩き、自作のナビゲーションコードを取り除いてください。
Natasha Murashev
@NatashaTheRobot — Capital One iOSエンジニア, Natasha The Robot ブロガー
私はiOS 9をそこまで調べていませんが、watchOS 2に関連する開発に携わってきました。もしあなたがApple Watchアプリを開発しているなら、私は新しいWatch Connectivityフレームワークを使用して、最初からコードを書き換えることをお勧めします。watchOS 2は、全く異なっていて、以前のWatchKit extensionよりもはるかにパワフルです。これは未来です。なので、あなたのwatchをWatchKitエクステンションとして維持することは、ただ自分の技術的負債を増やすだけです。
また、ComplicationをあなたのWatchアプリに追加することを考えてみてください。Apple Watchの使われ方のヒエラルキーは、通知、グランス、そしてアプリです。未来のナンバー1(または少なくともナンバー1候補)はコンプリケーションです。想像してみてください、ユーザーが手首を挙げる毎回、あなたのアプリがここにあることを!
始めるにあたって、これらのリソースをチェックしてみてください。
Riley Testut
@rileytestut — GBA4iOSクリエイター、USC学生
もしあなたが私のようなら、あなたはコード内のバリデーションロジックを整理するためにEarly Exitを使うでしょう。Early Exitは最初からSwiftで可能でしたが、いくつか注意事項がありました。まず、それらはあなたが望む条件ではなく、望まない条件 (e.g. if variable is nil
)についてチェックする必要があります。しかし、さらに重要なことは、よくあるケースだと思いますが、もし変数がnil
の時には処理を終了し、そうではない時には継続するという場合、その値を使って処理を継続するためには、Early Exitの続きで、さらにその変数を強制アンラップする必要があります。
Swift 2では、SwiftチームはEarly Exitにおいて私たちを助けてくれる新しいキーワードguard
を与えてくれました。guard
は上記の問題の両方を解決します。ちょっと想像してみてください、あなたはゲームを作っています。そして、そのゲーム開発者はコールバックを分離することにとても怠け者だったので、全ての入力の変更は一つのコールバック関数を通して処理されます。
func gameController(gameController: GameControllerType, didActivateInput input: InputType?)
入力のアクティベート処理がうまくいった時のために2つめのコールバックを持つことは良いですが、これはguard
が役に立つことを明らかにしています。このオプショナルの引数input
がnil
でない時にボタンが押されたらゲームは反応すべきです。ボタンがすでに押されていないことを知らせるためには、引数input
はnil
になります。もし私たちがボタンが押されているかだけを気にする場合は、Swift 1の以下のEarly Exitを使って実現することができました。
func gameController(gameController: GameControllerType, didActivateInput input: InputType?)
{
if input == nil
{
return
}
self.performExampleMethodWithNonOptionalInput(input!)
}
私たちは、扱いたくないケースについて入力を比較していることに気がつきます。この場合は、それがnil
であるかどうかです。けれどさらに重要なことに、引数input
はオプショナルであり、私たちはそれはnil
ではないと知っているのにも関わらず、後の処理で、その値を強制アンラップしなければならないのです。Swift 2では、もっと良くなっています。
func gameController(gameController: GameControllerType, didActivateInput input: InputType?)
{
guard let unwrappedInput = input else { return }
// in development, I call the unwrapped variable the same name
// as the variable. However, unwrappedInput demonstrates this better.
self.performExampleMethodWithNonOptionalInput(unwrappedInput)
}
このように、引数input
がnil
ではないという条件を“guard”してunwrappedInput
に代入し、そうでなければreturn
します。さあ、unwrappedInput
はオプショナルではなくなり、そのまま使うことができ、みんながハッピーです!こうして、“guard”はiOS 9のコードをキレイに、エラーを起こしにくくすることができます。
Janie Clayton
@RedQueenCoder — iOS/Mac developer、Blogger at Red Queen Coder、NSBrief 主催者
私のプロジェクトは実際ほとんどの方々のものと少し異なっています。私はMac上でロボットの制御ソフトウェアを書いています。iOS 9 / Swift 2 / El Capitanのリリースに向けて私たちがした最も大きな準備は、Swift 2向けのエラーハンドリングのアップデートです。Swift 1がリリースされた時、私たちはNSErrorに関する問題がたくさんあったので、独自のエラーハンドリングメソッドを書き、組み込みました。
ハードウェア開発を始めてから、エラーハンドリングは私たちのソフトウェアの本当に重要なパートです。もし正しくエラーを予測することも、処理することもできない場合は、たくさん物理的ダメージを引き起こすからです。物理的ダメージは高くつきます!だから、私がiOS 9のTipsを紹介するならば、あなたがエラー処理に詳しくなるためにSwiftを使用している場合に、私はそれが、楽しくも華やかでもないけれど私たちが行うであろうユニットテストのようなものだとわかっていますと言いたいです。けれど、私たちは外の世界をコントロールしていないし、物事がうまくいかない時にどのようにあなたのアプリを反応させたいかを考えることが重要です。
Glen Low
@pixelglow — Instavizクリエイター、Apple Design Award Winner 2004
UIKitプログラミング道を発展させるために、システムとケンカするのをやめ、その代わりにフレームワークを正しく活用しなければなりません。さもなければ、Appleの新しいiOSのリリースの度にあなたは消されてしまうことでしょう。
代表例:UIKitは、表示されている画面上に表示されたあなたのビューコントローラを本当に維持したがります。たとえそれらを異なったスクリーンと向きに再表示し、ポップオーバーのフキダシを再配置するとしてもです。
システムの中で、ほとんどのアダプティブな表示のデフォルトを受け入れ、UIAdaptivePresentationControllerDelegate / UIPopoverPresentationControllerDelegateで新しいポップオーバーの位置を提供しましょう。サイズまたはSize Classの変更であなたのビューコントローラを片付けてしまわないでください。これらのデリゲートもまた、アダプト中だけに限られたカスタマイズ性を提供します。新しいビューコントローラに交換するのは簡単ですが、実際には既存のビューコントローラを変更するのは難しいです。例えば、あなたが戻るボタンを無効にしたい場合などです。
さもなければ、せいぜい良くても、デバイスを回転中、もしくは新しいiPadマルチタスキング中や、最新のAppleの魔法の技術を使用している時におかしな挙動を引き起こす危険性があり、最悪の場合は、新しいiOSリリースの前日の眠れない深夜にクラッシュして、デバッグの嵐になるでしょう。
お読みいただきありがとうございました!
さあ出発です、素晴らしいアプリをつくりましょう!!
翻訳: Sohei Kitada, Sayuri Takizawa
About the content
This content has been published here with the express permission of the author.