2022年7月11日に、今年のWWDCで公開された内容から、選りすぐりの内容をデザインとディベロップメント双方の視点から深掘り・振り返りするイベント「WWDC22 Recap in Goodpatch」をオンラインで開催しました。

Goodpatchエンジニア2名によるLightning Talk、コミュニティから3名のトークセッション、最後にQ&Aセッションの構成です。Q&Aセッションには、Apple JapanからTechnology Evangelistの豊田さんにもご登壇いただき、登壇者のトークの内容に限らず、今回のWWDCでのアップデートについてディスカッションしました。

全体で2時間50分、「Swift Charts」「Widget」「Room Plan」「Swift Regex」など多岐にわたる技術トピックだけでなく、「デザイナーやエンジニアはHIGをどのように活用すればよいのか」「ソフトウェアUIデザインの目当て」「グラフ表現で気をつけること」「Widgetをデザインする際のプラクティス」などUIデザインのトピックも登壇者の皆さんが熱く語っています。

日頃Apple platformのアプリを開発されている皆さんが対象のコンテンツになっており、エンジニア、デザイナーに限らず、プロダクトマネージャーや企画職のみなさんにも読んでいただき、皆さまのプロダクトへ反映いただけると幸いです。

イベント開始直前まで参加登録者が増え続け、なんと732名もご登録いただくという、弊社が主催するイベントとしては、最大級の参加規模になりました。

本記事では、各登壇者によるトークと、Q&Aセッションの様子をダイジェストでお届けします。

なお、本イベントではプレリリース版Appleソフトウェアの内容が話されています。Apple Developer Program使用許諾契約の「秘密保持」に抵触する恐れがある部分については、登壇者および本記事の筆者の判断により、当該箇所を本記事に含めていない点をあらかじめご了承ください。

本イベントのTwitterハッシュタグは #wwdc22gp です。

LT:RoomPlanのスキャン体験をお手軽実装

はじめに、弊社エンジニア2名による各10分間のLTです。トップバッターは、弊社エンジニアの田中が、新しく登場した RoomPlan frameworkについて、現在公開されているドキュメント、実際に手を動かして理解した内容をお話ししました。

RoomPlanとは

今年のWWDCですが、近年「Apple Glass」という名前を時々聞いており、今年こそ何か発表があるのではと言われている中で、何かヒントになる情報を待ち望んでいました。そんな中で発表されたものがRoomPlanというFrameworkでした。

RoomPlanというのは、日本語では間取りという意味を持っていて、その名のとおり、このように部屋の間取りをiPhoneとかiPadに搭載されたカメラやLiDARセンサーでスキャンして、学習済みの機械学習モデルを活かして、構造を理解します。

最終的にこのように3Dモデルとして、エクスポートまでしてくれる。そういう技術です。

RoomPlanについては、WWDCのセッション「Create Parametric 3D room scans with RoomPlan」で詳しく説明されています。

RoomPlanのサンプルプロジェクトも公式で用意されています。実際に動かしてみたところ、このようになっていました。

RoomCaptureView

RoomCaptureViewを使えば、スキャン結果がリアルタイムに見えて非常に便利ですが、先ほどのセッションビデオによると、RoomPlanの提供するData APIを活用することで、スキャン体験のビジュアライゼーションをイチから実装することもできると説明されていました。

まず、新規プロジェクトをAugmented Reality appとして作成します。これにより、RealityKitのARViewをベースにしたアプリを作成できます。次に、セッションビデオの説明の内容にしたがって、部屋のスキャンプロセスを管理する、RoomCaptureSessionをセットアップします。最後に、RoomCaptureSessionのイベントハンドリングするために、RoomCaptureSessionDelegateを実装します。

簡便に3ステップで説明していますが、この3ステップ目が全体の実装の9割を占めています。

スキャンプロセスで得られた、壁や物体の検出結果を伝達するデリゲートメソッドが4つあります。スキャン過程で新たに検出されたもの、あるいは、検出されているが、スキャンの過程で情報が変化したとか、あるいはスキャンの過程で消えてしまったなど、というものが随時通知されます。

CapturedRoom

最も大事なのが、スキャンプロセスで伝達される、CapturedRoomというオブジェクトです。これは、部屋の構造を表現するものです。

CapturedRoomは、CapturedRoomを基点として、壁やドア、窓といった部屋の表面を表すSurfaceと、家具や寝具などを扱うObjectが紐づいています。

SurafceやObjectは、カテゴリがそれぞれあり、Surfaceの場合は壁、開口部、窓、ドアです。あるいはObjectは、テーブル、ベッド、ソファー、など、それが一体何を表しているのかを、これを用いて判別できます。

サイズや位置以外にも、SurfaceやObjectは、いろいろな情報を持っています。画面左側に注目してほしいのですが、種類や確証度を使うことによって、検出したオブジェクトが何者なのか、今回はStorageのため棚や椅子、振り返るとベッドがあり、確証度が黄色から緑になり、中から高になったということです。

確証度を表す三つのアンテナは今年 SF Symbols に導入されたVariable Colorを使ってみました。

Happy RoomPlan Life!

最後におまけですが、これはRoomPlanの意図する使い方とは少し違うかもしれませんが、このように、AR空間上に間取りを構築してあるので、それに合わせて、時計を這わせて移動させる、ということもできます。

今回はRoomPlanの可視化を自前実装することで、その仕組みの詳細に迫るチャレンジをしてみました。

お見せしたように、間取りを3Dモデル化する以外にも、結構遊べるのではないかと思っていますので、みなさんもRoomPlanで遊んでみてください。

LT:WWDC22のアプデましましで、あるあるアプリを作ってみた

続いて、弊社エンジニアの藤井 @touyou_dev が、日本語を認識できるようになったVision frameworkや、Swift Regex、Swift Chartsを活用した「レシート読み取り型家計簿アプリ(簡易版)」を実装した際の工夫や注意点などをお話ししました。

WWDC22で印象に残っている新機能

早速ですが、WWDC22で印象に残っている新機能はありますか?

僕はこのあたりが気になりました。Swift Regex、Swift Charts、Visionのセッションはサムネイルを見た瞬間に気になりだしたり、SwiftUIは最近案件でも扱うことが多いのでそのアップデートは毎回楽しみです。

それで自分で挙げてみたラインナップを見て思ったのが、Visionで日本語が認識できて、Swift Regexで正規表現が簡単になって、Swift Chartsでグラフを簡単に作れる。これってもしかしてあのアプリが簡単にできちゃうのでは?ということをパッと思いつきました。

今回作ったものはレシート読み取り型家計簿アプリ(簡易版)です。レシート画像から情報が読み取れて、それを記録できて記録がいい感じに見れるというところを目指していて、外せない部分としてとにかく実装を簡単にすることを意識しました。そのため設計はあまり考慮していません。こちらのURLにコードも上げているのであわせて参考にしてみてください。

詰まったところや工夫したポイント

それでは実装順に、詰まったところや工夫したポイントを紹介していきます。

まず最初はSwiftUIの細かいアップデートです。PhotosPickerというフォトライブラリの選択をSwiftUIのみで使えるようになる機能を使いました。

結果を画像としてコードで扱える型に「隠れ制約」のような罠がありました。このloadTransferableという変換用メソッドに渡せる型はTransferableというプロトコルに適合していればいいのですが、SwiftUIのImage型が適合しているのに結果を一切返さないという罠がありました。正しい使い方としては、Data型に変換して、UIImageにし、Imageに渡すという手順を踏んでいく形になります。

続いて、取ってきた画像を使ってVisionで日本語認識をします。専用ViewはUIKit向けにしかないですが、認識して結果を得るだけならこのVNImageRequestHandlerを使えば扱えます。

日本語認識できるようになったというものの、そのままXcode14 betaとiOS16 betaで動かしたら日本語認識してくれるわけでなく、VNRecognizeTextRequestRevision3を明示的に指定する必要があります。

レシートの読み取りが終わったら、Swift Regexで値段を読み取ります。本来であれば商品ごとの値段も取りたかったのですが、値引きがあったり、レシートによってフォーマットがバラバラすぎてうまく認識できそうにないなと思ったので、今回は合計のみを取ることにしました。

また簡単とはいえ全く知らない文法を「正規表現ならこれできるだろう」でドキュメントから探すのは大変だったため、適宜、岸川さんが先日公開された swiftregex.com を活用しました。matchやgroupを見ることでどこに結果が入っているのかがすぐに分かり、とても便利でした。

最後に読み取った結果をAppStorageに保存して、それをSwift Chartsで可視化しました。AppStorageも構造体のまま保存できるようにしているのですが、Charts用の構造体を別で用意しています。こうすることで色のコントロールなどができ、いい感じです。

まとめ

まとめると、ざっくりですが、今回のアップデートもよかったよという話でした。

  • Swift Regexは文法さえわかればかなり直感的だった
  • Swift Chartsはすごかった(詳細はこの後のセッションにて)
  • オンリーSwiftUIでいい感じにアプリが作れるようになってきてる
  • 今年のWWDCはレシート読み取り家計簿のためにあった(個人の感想)
  • 今年のWWDCは非エンジニアが見ても楽しいと思う(個人の感想)

SwiftUIでできることが増えたことが印象的でしたが、SwiftUIは、非エンジニアに対してのApp開発の敷居を下げるというところも目指していると思い、そのようなことに繋がっていってるのがSwiftUIのいいところだと思っています。

 

ここからは、コミュニティの方々による各30分間のトークセッションになります。

The HIG & Software UI Design|WWDC22の発表内容とHIGの更新内容からUIデザインを考える

はじめに、弊社の丸 @usagimaruma が、Human Interface Guidelines(HIG)の歴史、HIGとは何か、デザイナーやエンジニアはHIGをどのように活用すればよいのか、今年6月にアップデートされたHIGの変更点やHIG統合のねらい、WWDC22の注目セッション、ソフトウェアUIデザインの目当てについてお話ししました。

このトークセッションでは、新しくなったHIG(発音:ヒグ)、Human Interface Guidelinesを眺め、HIGとの向き合い方やソフトウェアのUIデザインについてを考えてみたいと思います。今回はUIデザインとソフトウェア開発、双方の視点から迫っていきます。

HIGとは何なのか

まずHIGとは、私の解釈ではAppleプラットフォームにおけるデザインガイダンス、デザイン言語を記したものと捉えています。しかしながらその根底にあるものはプラットフォームに依存しない普遍的なデザインの考え方に基づくものです。

HIGはこの6月に大きくアップデートされましたが、今回に限らず、これまでの長い歴史の中で幾度も改定を重ねてきました。

文献を漁ってみると、私の知る限りでは少なくとも1985年~1977年あたりまで遡ることができます。この『The Apple II Human Interface Guidelines』がおそらくHIGの起源の一つと考えられます。

画像中の真ん中に写っているのが1987年版のHIGです。そして右側に写っているのが87年版の日本語訳版です。これらはすでに絶版になっていて、今では手に入れづらいものになっています。

HIGのルーツ

この87年版HIGを開いてみると、あるページにSRIやXerox PARCについての言及があります。ダグラス・エンゲルバートやアラン・ケイらの功績を讃える内容になっており、Apple Desktop InterfaceはAppleよりも前の時代のヒューマンインターフェイス分野の研究成果や思想を受け継いでいることを示唆しています。このことは非常に面白く興味深い点に思います。

デザイン言語

冒頭で「HIGはデザイン言語を記したもの」と説明しました。私なりの解釈では、デザイン言語(Design Language)とは、ある仕組みやシステムの理解のために、統一見解や表現方法、ルール、設計思想を記したものです。

例えば開発現場ではこのようなやり取りや解釈がよく見られるかと思います。

  • 「デザインガイドラインはデザイナーが読むもの」
  • 「エンジニアにはデザインの云々は無関係である」
  • 「デザインガイドラインには見た目の事柄だけを記せば良い」

私は、このような捉え方や考え方は間違っているのかなと考えます。

先ほどのデザイン言語の説明に則るとしたら、開発に関わる全ての人々がそのプロダクトの「設計」すなわち「デザイン」についての理解を深める必要があるためです。

ソフトウェアの構造とデザイン

HIGの読み方を説明するために、このような概念図を導入して理解を促してみたいと思います。

これは、OSを含む開発環境とアプリケーションの関係を図にまとめたものです。まず根底部分にアーキテクチャのレイヤー(設計思想などを示すもの)があり、その上にはアーキテクチャを反映・実装したフレームワークがあり、さらに頂点にはアプリケーションのレイヤーがあります。ソフトウェアデザインの世界観を簡易的に表すとこのような様相になるのだと思います。

下二つのレイヤーでは、HIGなどのデザインガイドライン(デザイン言語)によって そのデザインの方向性を示します。

Appleプラットフォームでいうと、このあたりはAppleが時間をかけて世界観を作ってくれているため、アプリケーションを作る私たちとしては、Appleが示している世界観がどのようなものであるのかをデザイン言語(HIGなど)から理解を深めていかなければなりません。その上で、自分達の独自の表現をどこまで実装できるのかを考えていくのかなと思います。

したがって、開発現場の私たちはプラットフォームのデザイン言語を理解して、まずは同じ言葉で会話する。そういったアプローチが良いプロダクト作りには欠かせないのだと思います。

HIG(2022.6)の主な変更

今回はHIGのアップデートがあったため、その変更点を探ってみましょう。

2021年11月時点のスナップショットと比べてみると、2022年6月版は見た目やコンテンツの扱い方が大きく変わったことがわかります。

まず特徴的なのが、これまでのOS別ページ構成がひとつに統合され、トピックごとに分類されるようになりました。OSごとの個別的な話はそれらのトピック内で別途言及されるようになっています。そのほか、トピックに紐づくWWDCセッションビデオへのリンクが加わったり、検索機能が強化されたりしています。全体的には以前よりも見やすく、読みやすくなった印象です。

HIG統合のねらいとは

今回のHIG統合のねらいを考えてみましょう。

  • 可能な限りのアーキテクチャの統合
  • OS間のデザイン言語の統一と区別
  • macOSとiPadOSの接近
  • AppKit / UIKitからの脱却、SwiftUIへの移行

昨今のAppleプラットフォームの動向を見ていると、デバイスやOS間のアーキテクチャの統合が顕著に見られます。Apple SiliconによるCPUアーキテクチャの統合もそうですし、UIフレームワークの統合も進んでいます。OS間のデザイン言語やUXの統合が進む中で、今回のWWDC22で発表のあったStage Managerの導入は象徴的です。

先ほど紹介したApple Desktop Interfaceのルーツのくだりにも「PARCのデスクトップにはオーバーラップ型のウインドウシステム」と記載があります。Overlapping Windowsは70年代にアラン・ケイらが発明したものですが、巡り巡って2022年のiPadの新機能としてそれが再び脚光を浴びることは、なかなか感慨深いことだと思います。

注目セッション

Explore navigation design for iOS

https://developer.apple.com/videos/play/wwdc2022/10001/

これはiOSのナビゲーションの話で、とても興味深いです。簡単にまとめると、iOSのタブバーのナビゲーション設計について、こういう点に気をつけよう、ということが説明されています。

後半にモーダルビューの設計の話もあります。詳細は割愛しますが、モーダルビューは作業に割り込むむ自己完結型タスクの表現であるため基本的には多用は厳禁ですが、適切に使えば正しく機能すると説明されています。興味深い内容であるため、是非このセッションをチェックしてみてください。

Writing for interfaces 

https://developer.apple.com/videos/play/wwdc2022/10037/

もう一つの注目セッションとして「Writing for interfaces」を紹介します。いわゆるUXライティングのような分野の話です。UIにおける文言表現の勘所についてAppleからガイダンスが示されています。

ちょうど私も2017年に似たようなトピックの記事を書いたことがあります。ダイアログ設計であるあるの「キャンセルのキャンセル」問題を避けるための基本を紹介しています。

キャンセルのキャンセル問題から考えるダイアログデザイン|Goodpatch Blog グッドパッチブログ

ソフトウェアUIデザインの目当て

最後にソフトウェアUIデザインの目当てで締めようと思います。ソフトウェアに簡単に触れられるようにすることが、UIデザインの目当てだと考えています。

ソフトウェアはそもそも形がないため、その見えにくいものを、正しく、人が直接認識できるようにすることが大切だと思います。

概念的には、ソフトウェアの世界と私たちの世界には隔たりがあり、そこで対話を促すにはまず世界の間にUIを作ってあげなければなりません。しかしUIだけだとまだインタラクションがうまく機能しないため、ハードウェアまで認識を広げて、UIを介してユーザーがソフトウェアに直接触れられるような形にします。

デザイナーがこのような世界認識を持っておけば、きっとソフトウェアのUIデザインとうまく向き合えるようになると考えています。

おわりに

今回のセッションでは、前半にHIGの位置付けや読み方、HIGの歴史について解説しました。後半ではソフトウェアのデザインについてのお話をしました。私自身もそうですが、私が在籍しているグッドパッチでも、普段はこのような視点でソフトウェアというものを捉えています。

私は生まれた時からAppleのコンピュータに囲まれて育ちました。基本的にはAppleの話題に触れることが多いのですが、Appleプラットフォームに限らず、ソフトウェアをどのように作ったら社会を形作れるものなのかをこれからも追求していきたいですし、もちろんAppleプラットフォームのウォッチャーでもあり続けたいと考えています。

Swift Chartsのデザインを考える

続いて、松館 大輝さん @d_date が、そもそもチャートとは何か、グラフの表現で気をつけること、といった一般的な話から、具体的なSwift Chartsの使い方や、Swift Chartsでのグラフ表現の種類などをお話ししました。Swift Charts関連でチェックしておくべきWWDCのセッションも紹介されています。

今日は、Swift Chartsについて話します。触ったことがある方はわかると思いますが、Swift ChartsはとてもAPIが簡単です。APIの説明だけすると5分で終わってしまうため、そもそもチャートって何なのというところから、できるだけ一般的な話から、Swift Chartsに向かっていくようなお話をしてみたいなと思います

チャートをデザインすると、テキストだけでは伝わらないニュアンスのようなものを、視覚的に簡単に伝えることができ、アプリに個性を出したり、ビジュアル的におもしろい、そのようなものを加えられるのではないかと思います。

ですが、チャートは使ってみると、このように領域を食い潰すため、やみくもにチャートを使えばよいというわけではなく、どのようなデータをどのように伝えるか、ということを明確にしておく必要があると思います。

チャートの種類と解釈

チャートにどういう種類があるのかという話をしながら、こういう表現は間違っている、という話をしていきます。

今から話す「チャート」というのは、「グラフ」という言葉と混同してしています。今日話す「チャート」と「グラフ」は大枠では意味は一緒です。

これが棒グラフです。どういう時に使うかというと、データ間の量の違いを比較したい時に使います。このグラフをパッと見れば、アメリカがダントツで多くて、中国、オーストラリアが2位、3位と続いていることが、見ただけで分かりますし、例えば、中国、オーストラリアに注目すると、横線の目盛りがあるおかけで、中国が10万人を超えていて、オーストラリアは10万人を割っているということも解釈できると思います。

アメリカを除いて、アメリカがあまりにも多すぎるため、中国と他の国を比べたい時に、このように使えます。気をつけなければいけないことは、Y軸のスタートをいじれるのですが、世の中にありふれている誇張表現されているグラフはY軸の目盛りが疑わしかったりします。

これは左下が3万人というスタートで、このようなビジュアルをパッと見せられると、中国がすごく多くて、フランスはなにか少ないんだなと解釈をしてしまいがちなのですが、これはミスリードにつながる表現です。こういうのは、良くないというか、正しくない表現です。このような時はどうすればよいかというと、(Y軸が)0始まりなのですが、波線、破断を書いて省略を表現するという使い方をするとよいと思います。

さて、同じデータを今度は円グラフにしてみましょう。円グラフは、全体を1とした時、100%とした時の割合を表現するものです。これもよくある数字のマジックなのですが、このグラフには間違いがあります。何が間違っているのでしょうか?

全体を100とした時の割合なので、このグラフ(間違っている方)は、10カ国しか入れていないのですが、国別在留邦人数とうたっているからには、全体を100にするには「その他」を入れなければなりません。「その他」というのを入れた時に、アメリカが32%というのが正しい表現になります。

次に折れ線グラフを紹介します。パッと見た時にダメだと分からないといけません。なぜダメかというと、折れ線グラフというのは、データ間の推移を表します。これをパッと見た時に、アメリカの次に中国とオーストラリアが並んでいますが、アメリカ、中国、オーストラリアの間にはデータ上は何の関連性もないですね。

これは世界で超話題のトピックで、地球の温度が上がっているというものですが、こういう時系列データになっていて、緑が北半球、青が世界全体、グレーが南半球を表しますが、だいたい時系列データで並んでいるものを折れ線グラフで繋いでいくと、明らかに右肩上がりになっているということが分かり、温暖化が進んでいることが分かってきます。もちろん、株価みたいなものでも有効です。

このようにグラフというのは、データの解釈表現です。何を伝えたいのかを、見ただけで分かるようにしなければなりません。特にiPhoneのように小さなデバイスで表示する場合は、それだけで領域が占有されて、ユーザーの目もそっちに行ってしまうため、特に何を伝えたいのかは、明確かつシンプルにした方がよいと思います。

アプリにチャートを組み込む

アプリにチャートを組み込む場合は、アプリの体験に気をつける必要があります。チャートだけで完結するアプリはなく、必ずユーザーの行動に応じて、ユーザーにこういう情報を与えたいので、チャートを組み込むということを設計しなければなりません。

だんだんと情報を付け加えるというのは、セッションでも話されていた内容ですが、これは最初に見せるチャートです。チャートの上のところに、30日で12%、これはセッションの中でパンケーキの売上の話ですが、30日で前月比12%売れていますとか、合計で1234枚のパンケーキが売れています、という情報をテキストで補助的に表示します。このグラフをタップすると、さらにいろんな情報が出てきて、しかもアプリですから、出せる情報を選択的に切り替えられます。

Daily Averageをタップすれば、日時平均が出ますし、Weekday、Weekendをタップすれば、表示される値も変わります。このように、与えられる情報をユーザーの欲しいものに応じて選択的に提供できる、というところがアプリに組み込むメリットではないかと思います。

WWDCのセッション

「Hello Swift Charts」は入門的なセッションで、Swift Chartsをとりあえず触ってみたいと思った人が、Swift Chartsはどんなものだろうという説明を受けるセッションです。

「Swift Charts: Raise the bar」は、主にDeveloper向けで、実装しながらChartsを細かくカスタマイズしたいときに観ておくと、かなり学びが深いと思います。

「Design app experiences with charts」「Design an effective chart」は、まさにデザイナーの皆さん向けのセッションなのですが、ぜひDeveloperのみなさんにも観てほしいです。いま話したような、チャートをデザインしていく時に、どのようなことを考えてデザインすればよいのかという話を、たったこの二本のセッションで要約してくれています。

「Bring accessibility to charts in your app」は、Swift Chartsが出る前の2021年のアクセシビリティに関するセッションです。今回はデモを用意できなかったのですが、実はSwift Chartsはタップすると、値の増減を音で知らせてくれるという機能があります。ちゃんとしたアクセシビリティを簡単に提供できるというのは、Swift Chartsの強力なところだと思いますので、ぜひチェックしてみてください。

Swift Charts

Chart(data, id: \.name) {
    BarMark(
        x: .value("Sales", $0.sales),
        y: .value("Name", $0. name)
    )
}

実際にチャートを描画しているのは、たったこれだけのコードです。

Chart(data, id: \.name) {
    BarMark(
        x: .value("Sales", $0.sales),
        y: .value("Name", $0. name)
    )
    .foregroundStyle(.pink)
}

バーをピンクにしたいと思ったら、このようにします。

Chart(data, id: \.name) {
    BarMark(
        X: .value("Sales", $0.sales),
        y: .value("Name", $0. name)
    )
    .foregroundStyle(.pink)
    .accessibilityLabel($0.name)
    .accessibilityValue("\($0.sales) sold")
}

先ほど話した、アクセシビリティのラベルとバリューをタップした時に何としゃべるかは、これだけで設定できます。

まとめ

  • APIはあまりにも簡単
  • 簡単ゆえにチャートを含めたアプリデザインが重要
  • データの表現は簡単に誤読を導く

最初に話したとおり、APIはこのようにあまりにも簡単です。それゆえに、正しくデザインをして、ユーザー体験に組み込むということが重要だと思います。

前半で話しましたデータの表現は、簡単に誤解を招くため、提供する側も、受け取る側もデータの信憑性、表現の信憑性を精査するようにしましょう。

実践: ロック画面のウィジェットを作ろう

最後に、岸川 克己さん @k_katsumi が、ホーム画面のWidget、iOS 16から可能になったロック画面のWidget、WatchのComplicationとWidgetの関係、Widgetを実際に作ってみた所感や、Widgetを作成する流れと実装上の注意点などお話ししました。

今日は、新しくiOS16からできるようになったロック画面にWidgetがおける、ロック画面のカスタマイズとして、自分が作ったWidgetを提供できるようになった、ということについて実際に作ってみるとこんな感じだだとか、たぶん、こういうものを作ったら面白いんじゃないか、これは反則だけどすごく便利だよ、という話をみなさんと一緒に共感してもらったり、いやそれは…みたいな議論のタネになればいいなと思ってお話しします。

ロック画面のWidgetとは

ロック画面のWidgetがどのようなものかというと、ロック画面に自分のアプリのコンテンツを表示できるものになっています。

赤枠で囲まれているものがWidgetです。実はここ(Monday, June 6の箇所)もWidgetです。ここに、テキスト主体の1行のものを置けます。

余談ですが、Widgetが上にきたことによって、真ん中にあったPush通知が下に寄ってかなり目立たないところになってしまって、基本的にPush通知は、どんどん、これから目立たないところにまとめられていくことになると思います。

ComplicationはWidgetとしてWidgetKitに統合されました。

ClockKitは昔から文字盤を作るためのSDKとしてありますが、このClockKitは今回から非推奨になり、全てWidgetKitになりました。ホーム画面のWidgetもロック画面のWidgetもApple WatchのComplication、これもWidgetという呼び方が正しいかと思いますが、Apple WatchのComplicationとしてのWidgetも全てWidgetKitで作れるように統合されましたし、APIも整理されました。

Complication、ClockKitで作れるものがもっとあって、WidgetKitだけではカバーできないと、WatchのComplicationを作ったことのある人は感じるかと思いますが。Complicationのうちいくつかは廃止されました。

その結果、WidgetKitだけで、全てロック画面のWidgetも、これまでのホーム画面のWidgetも、WidgetKitで同じように作れますし、Apple WatchのWidgetも同じように作れるようになったということです。

WidgetKitは、SwiftUIでしか書けないという制約があり、その点うまく作用していますし、SwiftUIを普及させるための第一歩、第二歩としてうまく作用しているのではと思います。

Widgetのコード

ひとつ大事なことは、Widget本体のこのコードです。Viewを呼び出しているWidget部分のコード、ここに supportedFamilies を追加する必要があります。

@main
struct ExampleWidget: Widget {
    let kind: String = "ExampleWidget"

    var body: some WidgetConfiguration {
        IntentConfiguration(
            kind: kind, 
            intent: ConfigurationIntent.self, 
            provider: Provider()
        ) { entry in
            ExampleWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
    }
}

systemSmallからsystemLargeがホーム画面に置くWidgetの大中小で、accessoryCircularRectangularInlineがロック画面に置くWidgetになります。これに加え、iPad専用のExtraLargeなどありますが、これらも書く必要があります。

@main
struct ExampleWidget: Widget {
    let kind: String = "ExampleWidget"

    var body: some WidgetConfiguration {
        IntentConfiguration(
            kind: kind,
            intent: ConfigurationIntent.self,
            provider: Provider()
        ) { entry in
            ExampleWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
        .supportedFamilies([
            .systemSmall,
            .systemMedium,
            .systemLarge,
            .accessoryCircular,
            .accessoryRectangular,
            .accessoryInline
        ])
    }
}

これを書かないと、デフォルトはホーム画面に置く大中小だけになっているはずで、この3つだけ書いている状態になります。

.supportedFamilies([
    .systemSmall,
    .systemMedium,
    .systemLarge,
])

そうすると、ロック画面に置くWidgetをサポートしていないということになります。ビルドして再起動してもロック画面に置くWidgetに出てこない、という感じで少しハマったりするため、ここは注意です。

Widgetを作るのはとても簡単

Widgetを作るのは本当にとても簡単です。制限もありますが、どちらかというとこの制限が、SwiftUIのこれどうしたらよいのだろう、というところを気にしなくてもよく、これだけしか出来ないのだから、SwiftUIでこうすればよい、という感じになるため、そこにフィットしているところがあります。

ガイドラインにおけるWidget

アプリが起動しなくても役に立つ情報が見られるようにする、ということです。天気のWidget、カレンダーのWidget、ニュースのWidgetはわかりやすいです。いちいち見なくても、1時間後の予定などが分かっていれば、ホーム画面やロック画面を見ただけで、そうなんだと分かるという感じです。

アプリが提供する最も重要なコンテンツに絞って表示する。表示領域が小さいので何でもかんでも表示するわけにいかないので、一番重要なもの、もしくは、使っている人にとって重要なものを表示するのがよいと思います。

Widgetはランチャーではない。これは、装飾のWidgetがすごく流行っているので、なかなか難しいところではありますが。基本的には、Widgetはランチャーではないので、アプリを開くものではないので、それは当然というか、アプリのランチャーであれば、普通にホーム画面にアイコンを置いているのと変わらないということです。

1日のうちに適切な内容を更新する。変化がないと、やはり、わざわざホーム画面に置いている意味があまりない、ということです。適切にいくつか重要な情報が更新されるコンテンツを選んだ方がよいということです。

Widgetの制約

  • 表示領域や色の表現が制限されている
  • 画面に表示されるはいわゆるビューではなくスナップショット
  • アクション(タップやスクロールなど)は受け取れない
    • Link.widgetURL()を使って多少のインタラクションが作れる
  • 更新間隔は厳密でなく、OSによってコントール(制限)される
    • 毎秒更新など高すぎる更新頻度は制限される(カウントダウンなどは専用のコンポーネントがある)

基本的にボタンとか置いても、アクションとかは取ることはできません。なぜならば、事前に描画されたスナップショットが画面に表示されるからです。

ただし、例外があって、Link.widgetURLを使って多少のインタラクションが作れます。したがって、先ほどの施錠・解錠だと、施錠と解錠でそれぞれURLを変えて、ボタンにリンクを付けておくと、そうするとボタンをタップしたら、アプリが起動しますが、アプリでURLを受け取って、処理を分けるということができます。

更新間隔は厳密ではなくて、OSによってコントロールされます。毎秒更新みたいな高すぎる更新頻度は制限されるため注意してください。カウントダウンしたい時は、専用のコンポーネントがあります。

Tips

  • アプリとのデータ共有はApp GroupとKeychain
  • Keychainはロック中は読めないので注意
  • WidgetのConfigurationは表示項目の調整などWidget自身の設定に使用する。データの入力にあまり適さない

アプリとのデータ共有は、先ほどの奇抜なのはおいておいて、普通にWidgetを作るとデータ共有すると思いますが、それはApp GroupsとKeychainを使うのがよいと思います。

Keychainはロック中は読めないので注意です。

App Groupsを使うと、そういうことは無いため、Watchは別として、センシティブでないデータは基本的にApp Groupsに入れておくと、Extensionとアプリは同じデバイスで生きているので、ただ保管場所が違うということだけのため、リアルタイムに同期されています。App GroupsとKeychainのアクセスグループで共有するのは、今のところ、最初予定がなくても、後から必要になってくることが多いので、初めからやっておくことをおすすめします。

まとめ

ロックスクリーンという、最後の一等地が解放されて、Push通知はさらに目立たなくなりました。基本的に、別にアプリのグロースをどんどんやれということを言いたいわけでは全然ないのですが、そのための手段として、ロックスクリーンのところに置いておく、デファクトスタンダードみたいものを取りに行くというは、きっと面白いのではないかと思います。

Widgetを作るのはとても簡単です。大変かもしれませんが、作って楽しいので、やってみるのはおすすめします。SwiftUIに慣れるというところでも、SwiftUIらしくものを作るということを本当によくできる所だと思いますので、一石二鳥、三鳥あるのではないかと思います。

先ほど話したような奇抜なアイデアは色々と出てくると思いますが、早い者勝ちだと思いますので、どんどん実装して、どんどん出して、フィードバックを得ていくのがよいのではないかと思っています。

Q&Aセッション

Q&Aセッションには、Apple JapanからTechnology Evangelistの豊田さんにもご登壇いただき、登壇者のトークの内容に限らず、今回のWWDCでのアップデートについてディスカッションしました。

モデレーター:

  • @d_date さん
  •  齋藤(Goodpatch Anywhere)

スピーカー:

  • Apple Japan Technology Evangelist 豊田さん
  • @k_kishikawa さん、Goodpatch 田中、Goodpatch 丸(50音順)

Q:ボタンが中心に付いているタブバーはよく見る気がしますが、HIG的にどうお考えでしょうか?

丸:

たぶん、HIGとしては具体的な定義は無くて、無いということは、別に肯定も否定もしないということです。すなわち、そういう解釈はどんどんやっていって良いのではないかという風に受け取ってよいと、個人的には思っています。したがって、禁止されているということはないと思います。

たしか、Dropboxは真ん中に+ボタンが付いていたような記憶があります。タブはもともとナビゲーションのためのコンポーネントであり、その真ん中にいきなり、性質の異なるアクションボタンがくっつくことで、どうしても性質の違うコントロールが並ぶことになるため、やはりビジュアル的にしっかり境界というか、違いを見せる工夫が求められるかなと思います。このあたりは、デザイナーの腕の見せ所というか、きちんと吟味する必要があると思います。

岸川:

デザイナーの腕の見せ所というのは、おっしゃるとおりで、疑問が出てくるというのは揺れがある所だと思いますので、迷う人はやめておけ、ということはあるかなと思います。やるのであれば、色々研究して、違和感が無いように作るのが大事なのかなという感じです。

松舘:

そうですね、昔からあるような話で、Developerとしては、タブバーのカスタマイズはできるだけしたくない、他の画面と重なってしまったりとか、すこし整合性が取れないため、あまりやりたくないかなと思っています。おっしゃるとおり、デザイナーの腕の見せ所、という感じがしました。

Q:実際の企業の開発現場で、SwiftUIの採用が進んでいる印象はありますか?

松舘:

私は全てSwiftUIで書いています。他の皆さんはいかがですか?

岸川:

私が思っているよりかは進んでいる印象がある感じです。私は去年まではブレーキをかけ、いやまだ早いやめておけ、と言っていました。SwiftUIで書いていますというチームに入って、それ本当にメリットになるのかと思いながら、途中まで書いているチームに入って、無理だなということなり、UIKitで書き直すということを2回くらいやりました。

ただ、まあ、もう行けるのではないかと、というところはあります。無理なところが、まだ多いところもあり、そのあたりをおさえるのが難しい感じもありますが。

松舘:

グッドパッチさんは、どのような感じでしょうか?

田中:

グッドパッチのiOSの案件では、SwitUIを採用しはじめています。ただ、フルにSwiftUIで実装することは今のところなくて、UIKitと組み合わせてという感じです。ViewはSwiftUIで作りながら、View Controllerでラップしていくような、そういう実装方針がメインかなと思っています。

松舘:

そうですね、そのへんに落とすのが賢いというか、無難というか、僕もiOS 14のころは、そのような書き方をしていました。iOS 15になってから、いろいろ機能が拡充されて、今回のiOS 16の発表はSwift Chartsもそうですが、SwiftUIでないと扱えないWidgetみたいなものとかも増えているため、できるだけSwiftUIに倒していくといいな、という気持ちになっています。

岸川:

やっていかないと分からないため、今は、どこまでSwiftUIで書けるのかというところを頑張ろうというフェーズかなと思います。2年前は、そこを頑張るのはリターンが割に合わないかなということがあったかと思いますが、そこは変わってきているのではと思います。コンサバに行くのであれば、まだ難しいと思います。というか、ハードルはまだあると思います。

UIKitの方にSwiftUIとの親和性を高める拡張も、今回、入っていますので、そういう意味だと、混ぜて使うところに安心感はあります。

松舘:

以前は、本当にViewだけSwiftUIで、TableViewやCollectionViewのCellだけSwiftUIで書くとかをやってたのですが、それもUIHostingControllerでラップするのはパフォーマンス的にどうなのかという話もありました。UIHostingConfigurationも出てきてUIKit、AppKitの連携周りが簡単になったというのもあり、セッションを見る限りでは、まだまだ、UIKit、AppKitは併用して使っていって大丈夫だよ、というメッセージなのかなという気がしました。

Q:HIGを読む会をチームで実施したのですが、とても多くて1回では読み切れず…おすすめの読み方や、もし実施したことがあればどのくらい時間掛かったかなど知見を教えてください…!

丸:

読み合わせ会はやったことはないので、なんとも言えないですが、全部を読むのは大変なため、何かテーマというか気になる部分に絞って、複数回、開催するのがよいのではないかと思います。

例えば、iOSのロック画面に関する部分を読んでみようとか、先ほど話しましたが、最近はプラットフォームでUI機能の統合されていますが、iOSの場合はこのような表現だが、では、macOSではどうなんだ、というふうにプラットフォームをふたつ並べて、それぞれどういう表現、どういう実装になっているのかを比べてみると、意外と面白い発見があるのかなと思います。

これはAppleのデザインが素晴らしいというのがあると思いますので、iOSだけやっている方だとしても、他のmacOS、tvOS、watchOS、他のプラットフォームを同時に見ることをおすすめしたいです。

Q: 今年のWWDCをカジュアルに振り返ると、どのような感想でしょうか?

岸川:

ここ2、3年は、WWDCの発表よかったよね、という状況が続いていると思います。今回は、Appleの新しいサービスとか、iPhoneとしての新しい機能が増えるという発表が、特にKeynoteでは多かった感じです。例えば、写真の文字を読むというのは、APIが提供されていて、それがかなり簡単に使えて応用範囲が広いという、ImageViewにLive InteractionみたいなものをAddするとできるようになります。Developer側で、これもできるんだ、これもできるんだ、ちょっと面白いじゃないの、ということが多かった感じがあります。

丸:

先ほどの登壇の際にお話ししましたが、iPadにOverlapping Windows、まさにFederighiさんがOverlapping Windowsをやりますと、その名前で言ってくれたのが個人的に上がりましたし、Stage ManagerもmacOS Venturaにもあるのだけど、iPadOSに搭載されるよみたいなところが、iPadとMacのUXの統合みたいなところが進んでいて、非常に魅力的だと思いました。(中略)コロナ禍という厳しい世の中ではありますが、逆にAppleのイベントがオンライン化したことにより、現地で参加せずとも、というと申し訳ないのですが、品質の高いコンテンツに触れられるというのは、ある意味で魅力的だなと思っています。今度どうなるかわかりませんけれど、来年も期待したいと思っています。

松舘:

今年は、現地に行くことができました(中略)何がよかったというと、現地のタイムゾーンに、リアルタイムで公開されているセッションに参加したりとか、限られた時間の中でしか質問ができない状況があるので、セッションをライブで観て、その後にすぐに質問をしなければならないという、かなりシビアな状況ではあるのですが、タイムゾーンが一緒だったので、割とそういうも参加しやすかったですし、なにより、世界中のDeveloperが毎年Appleに集まってきて、Appleのエンジニアと交流ができる場所がやっとオフラインで帰っきたという印象深い年だったので(中略)このようにして、新しい技術への感度を高めていただけると、よいのではないかと思いました。

おわりに

本イベントは、松館さんのツイートをきっかけに企画がスタートしました。松舘さんには、登壇に加え、Appleの豊田さんと岸川さんをご紹介いただいたりと、イベントを全面的にバックアップいただきました。Apple Japanの豊田さんには、Q&Aセッションで、多岐にわたりご回答、サポートいただきました。豊田さんが満面の笑みでお話しされていたのがとても印象に残っています。岸川さんには、非常に実践的なトークセッションに加え、Q&Aにも多く回答いただきました。

松館さん、豊田さん、岸川さんに、この場をかりてあらためて深くお礼申し上げます。

今後もこのようなかたちで、コミュニティもAppleも一緒に盛り上げていけたらと思います。2時間50分という長丁場になりましたが、ご参加いただいた皆様ありがとうございました!


グッドパッチで、デベロッパーとして、デザイナーとして働くことにご興味のある方は弊社の採用ページからご連絡をお待ちしております。フリーランスや副業での採用にご興味がある方は、Goodpatch Anywhereの採用ページをご覧ください。


Appleへフィードバックしましょう!

iOSやmacOSなどのバグレポートや改善要望などは、フィードバックアシスタントAppや、フィードバックアシスタントのWebサイトを使ってフィードバックをAppleに提出できます。気になる点がある方は、Appleへフィードバックしましょう!

フィードバックされる際は、次のページをご確認ください。
https://developer.apple.com/jp/bug-reporting/
https://feedbackassistant.apple.com/