#yumemi_swift 【まとめ報告】YUMEMI.swift #8 ~みんなで振り返ろう、WWDC~に参加してきた!
はじめてのWidget
Widgetとは?
- ホーム画面にあるViewで、SwiftUI限定になる。
- 大きさは、small, medium, largeの3サイズがあり、pxのサイズはデバイスによって違う。
- 注意点として動的なコンテンツは含められない。システムコントロールやアニメーションなど含められない
水分補給リマインダーアプリを作ってみる
- プロジェクトを作成し、WidgetExtensionのTargetを追加する
- デフォルトのテンプレでWidgetsEntryViewがスタートポイントになる
- Widgetsの中をいじっていく
- 最初にPreviewProviderを継承したプレビューを準備すると開発しやすい
- 角丸のシェープを作る時はContainerRelativeShapeを使う
- 唯一動的なコンテンツはタイマーのみになる
- Dateとstyleを与えることによって表示方法を変えれる
- 中サイズ、大サイズWidgetは複数のリンクを入れることができ、タップすることでアプリ起動後の遷移先を操作できる
- @Environment(.widgetFamily)を使うと、なんのWidgetなのかを指定できる
DeepLinking
- 遷移方法はいままでのuniversal linkなどと一緒。
- WidgetのLinkのなかにURLを渡すことで遷移可能
- SwiftUI Appのmodifierで処理が可能
placeholder
- カスタマイズするには、StaticConfigurationに、placehollderにわたすとできる
Widgetでのデータ取得
- APIであれば通信できる。しかし通信時間が長いとキルされる。そこでAppGroupを用いて、DBなどをいれて本アプリと一緒に使うことができる。
- 処理時間がながくならないように処理した内容をいれておくといい
- 設定方法としてはCapabilityにAppGroupsを追加する
- UserDefaultsで共有する時はsuiteNameにグループネームを指定すると共有できる
- フォルダの場所を知りたい場合はFileManager.default.containerURL(forSecurityApplicationGroupIdentifier: グループ名)で取得できる
Timelines
- Widgetはこの時間にこのViewを表示してくれと予約ができる
- 手動でアップデートしたい時はWidgetCenter.shared.reloadすることで可能
Intents
- Widgets自体に接待を入れたいときに使う。仕組みはSiri IntentsとShortcutsと一緒
- 設定のカスタマイズが可能
FAQ
- ios13ターゲットでWidget使えるか?
- ios14からの機能になる。
- Widget自体は別ターゲットになるので、ios13ではwidgetがつかえないだけ
- widgetをインストールするとアプリと一緒にはいるのか?
- ホーム画面に追加するにはユーザ自身がwidgetギャラリーを開いてアプリを選択して追加する必要がある
はじめてのApp Clip
AppClipとは
- アプリがない場合に、Cardが表示されて、そこからアプリの単一の機能をすぐ使えるもの。
- NFC、位置情報、メッセージ、webpage、QRCode、AppClipCodeなどのトリガーをもとにAppClipExperienceカードが起動される
- AppClipは起動の度AppStoreからDLされる
- アプリがあればアプリ内の同じ機能が実行される
- 同一のAsset,ソースコードが利用できる
- たとえばアプリがない場合に駐禁上でNFCをタップして駐車したり、コーヒーショップで注文したり、電動スケーターですぐ使えるようになったりする
- しかし、AppClipCardは実際はダウンロードして使われるということで、すこし時間がかかる
- アプリの画面構造でアプリが持っている一部の機能がAppClipとして提供されるが、AppClipはそれぞれ独立したアプリケーションになる。しかし、基本的にはURL記述でユニバーサルリンクとおなじ技術を使う
- ライフサイクルはURLに従ってAppStoreConnectに登録された内容をカードで表示され、カードを使うとオンデマンドでバイナリがDLされて使える。しばらくすると削除される。
- 何度も使っていると削除の期間が長くなる
特徴
- 単一の機能を提供する
- 複数のAppClipを提供できる
- サイズは10MB以下
- 個人情報にはアクセス不可
- SwiftUI, UIKit使用可能
- ローカルストレージは短期間のキャッシュとして扱われるのでAppClipの削除とともになくなる
- AppClipからアプリをインストールした場合はキャッシュ情報は引き継げる
設計
- HIG的には重要な機能に焦点をあてて、役立つ機能として使ってくださいとのこと
- 従来はアプリ内を回遊して必要な機能にたどりつくが、AppClipによってアプリがなくても素早く大事な機能を利用できるようになった
- NFCタグが違う場所にあった場合、正しい位置にあるかどうかを判定することもできる
AppClipを追加する
- AppleDeveloperサイトからAppClipを登録する
- その場合cababilityにon demand instal capableにチェックが入る
- xcodeだと、Targetを選ぶ時にAppClipを追加する
- Parent Application Identifierが自動生成されるが、AppClipと親アプリのつながりを記述ルう
- BundleIdentifierも自動生成され、親のBundleIdentifierに.Clipが追加されたものが追加される
- AppClipを追加する場合にアセットやクラスファイルは共通化されるので、アプリの一部の機能を実現することができます
- ビルドしていくとappstoreに送る時にAppClip用のものが追加されてアップロードする
AppClipを登録する
- AppStoreConnect側で、アプリ以外にType: Clipという項目が増えていて、AppClipExperienceを設定することができる
- サブタイトルやアクションを設定できる
- ユーザ目線だとカードが表示されて機能がつかえる。技術者目線だと、外部のものをトリガーにして、ランチャーとして登録された情報を表示し、オンデマンドでDLして即座に利用できるアプリになる
FAQ
- AppClipが使えればsuica使えなくても改札で支払いができるか?
- 支払い元が何かになる。アカウント登録しないで登録しないようにできているとおもうが、カードだとApplePayで支払いできるが、suicaはわからない
初めて?のSource of Truth
- 実は去年から出てきたコンセプトだった
- Source of Truthは真実の情報源ということになる
- 1. 常に一つであるべき。誰がデータを所有しているか
- 2. 必要に応じて適切な共有を選ぶ
- list viewがあった時に、isOnというプロパティがあり、DetailViewに遷移してそこにもisOnがある場合、isOnはそれぞれ独立したsource of truthになる
- nameというプロパティになった場合、同じ情報が複数箇所に存在することになり、変更が共有されず、どれが正しいかわからなくなる
- nameのプロパティを参照するものを作ればListViewのnameがsource of truthになる
- DetailViewではReference of truthになる
- 他のやり方としてモデルがメインのデータをもつこともある
- 度のデータがsourceになるのを意識するのが大事
- 変わらないデータということで基本的にはletで宣言する
- 変わるデータに関してはデータが値型か、参照型かでやり方が変わる
- 値型は@State varオブジェクトをつかう。参照型は@StateObject varを使う
- 可変共有の場合は@Binding var、参照型は@ObservedObject varを使う
- 不可変共有でletでいいのは問題ない。UIKit.UIViewは参照型で、ビュー作成ときに生成され、ビューヒエラルキーからなくなった時に破棄され、生存期間が長い。しかし生成回数は少なく、本質はビューオブジェクトそのものになる
- swiftUIは必要になったとき都度生成されるためletでも正しくレンダリングされる
- @State varと@StateObject varの意義はデータが更新された時に参照を持つインスタンスに通知をだす。さらに、SwiftUIにおいて、view構造体とは別の場所で格納し、データの生存期間をViewのライフサイクルから開放する意義がある
- 例えばListView.isOnを、@Stateにすることで、SwiftUI.isOnに持たすことで、SwiftUIが管理することができる。
まとめ
- source of truthを常に心がける (SwiftUIに限らずどんな設計にも通用する)
- 適切なデータ宣言でSource of Truthを維持する
- SwiftUIのViewはただのレンダリング説明
SwiftUI_Tips
- LazyVStackとVStackの違い
- スクロールバーの違い、メモリ使用量が違う
- ScrollViewReader
- セルの数を自分で決めれる
- ViewModifier_navigationTitleのオンオフが今までは同じ画面でできなくて、一回OffにしちゃうとOnにできなかった(デフォルトメソッドでは)のができるようになった
- @Published変数が同じだとエラーが出ない事象があって、Bindingする時に@Publishedを使ってるが、Segmentation fault: 11というエラーがでるが、変数名が一緒だとどこがエラーなのかわかりづらかったりする。
- ObservableObjectの変数を疑うといい
- bindで無限ループになる
- ObservableObjectをつけているとお互い参照しあってループしてしまうので注意
- 一つのものをみるようにしましょう
- var body: some Viewの中でインターナルにしたいステートの中で変数を使いまわしたい時がある。例えば撮ってきた先でnil許容しないといけないときに、Stringを設定したものをオブジェクトの中で設定する時に便利
- returnを書いてやるとstackの中で使い回せる
- tableviewやlistviewで共通のデザインを使うが、というものを使って共通Viewを使うことで使い回せる
- frameの中で三項演算子とかやったりするとき、swiftuiが読み込まない時にstring型に変換すると読み込めるようになったりします
- プレビューがみれない事があるのでライブラリを導入する際はプレビューがみれるかどうかを検証しながら進めたほうがいい
FAQ
- SwiftUIでエラー見つけるのが大変
- extensionをつける時はxcodeのscheme依存をしっかりしないと復活できない
- iOSはSwiftUIを使いますが、AndroidはJetpack Compose使わない理由はSwiftUIの方がよくできているのでしょうか?
- 同じアプリを使ってる中で、swiftUIのほうが簡単で早い
- 差し支えなければリリースしているアプリをダウンロードしたいのですが。。
- NDAに抵触するので秘密です
コロナ自粛中にSwiftでビデオチャットアプリを作ったお話
connpass
connpass - エンジニアをつなぐIT勉強会支援プラットフォーム
connpassはイベントやIT勉強会の開催、さらに参加者の集客に便利です。コミュニティやグループの運営やイベントの検索、事前決済もできます。
- Nowyというサービスを2週間(!!)で作った。
- オンライン上で人や友達と交流できる・喋れる場所がない
- コロナ中は自分が友達と喋れる機会がなかったので作った
- コミュニティーは参加するだけで横のつながりがなかなかできない。
- コミュニティー向けのビデオチャットサービスにしたら喋れるのは?
- 相手の様子がわからないから話しかけられない。話題がないとしゃべれない
- シャッフル交流会がコミュニティーで大人気企画になった
- コミュニティにいる通しは喋りたいというニーズがあることがわかった
- Swift5 + Storyboard、Go signaling server, node.jsで作った
- アプリのイメージとしてはzoomで流してるのをyoutubeで流してる感じ
- プロフィールで待機するだけで喋れる。喋れるかどうかの確認のステップが不要にした
- コミュニティーのページが有ってユーザ同士がチャットできるようなもの
FAQ
- どうやってそんな爆速で作られたのでしょうか?
- サービス作りにはパターンがあって、swift開発してる時に、googleのエンジニアがクリーンアーキテクチャを使っているのを知った。reduxなどと組み合わせて、アーキテクチャをバックエンドも揃えていくとソースコードが簡素化して、役割がわけられるようになって作業ゲーで作れるようになった
- wwdc20で発表された技術はなにか使ったりしましたか?
- zoomの画面シェアは難しく、broadcast extensionというのがあり、appleが難しいといっていて結構難しい。swiftUIが使えてないので今年のはあまりいかせてなくない
- スピードすごい!テストコードがどうなっているのか気になります!
- テストコードは書いてない
- バックエンドの重要なところはしっかり書いてる
- nodeとgo のシグナリングのところはしっかり書いている
PHPickerViewControllerの紹介
PHPickerViewControllerとは
- 今まで写真選択はUIImagePickerControllerを使っていたが、それの大体。PhotoLibraryへの完全アクセスがなくても選択できる
- 写真のズームイン・ズームアウトなどができる(結構スムーズ)
- 画像の検索もできる(日付検索や画像を認知した検索、位置情報の検索など)
- 画像複数選択やプレビューもできる
権限とプライバシー
- Pickerを出すだけなら許諾アラートが必要ない
- アプリとは別プロセスで動く
- アプリからはピッカーのコンテンツにアクセスすることはできない
- アプリはピッカーから選択されたコンテンツだけ知ることができる
PHPickerの使い方
- PHPickerViewControllerDelegateを起動する時に渡し、写真などをdelegateメソッド経由で受け取る
- PHPickerConfiguration
- selectionLimitで何枚選択できるか
- 動画、live photoだけとかの選択もできる
- PhotoKitもサポートされている
まとめ
- PHPIckerは柔軟に写真を選択できる
- PHPickerはプライバシーに配慮しつつ写真動画を選択できる
- AppleはPHPickerを推奨している
- 今日のお話は大体こちらにかいてある→UIImagePickerControllerに代わるPHPickerViewControllerの紹介
FAQ
- 御社のサービスで写真選択周りのプライバシー取得周りでかなり影響出そうですがどのように対応する予定ですか?
- ios14にあげた棚m津でios13でビルドしたアプリ動かすと影響を受けていて、全て写真許可する、許可しない、選択した写真だけ許可するというものが出ている。3つ目はちょっと分かりづらいのでUX面で考えないと行けないと思っている
- 次回何を発表する予定か?
- autofillで住所の入力が楽になるのでそれを発表する予定
@mogmetの所感
SwiftUIを作るに当たりトラブルシューティングな情報を知れたのは良かったと思いました。個人的には今年から使えそうであれば採用して行こうかとは思いましたが、まだまだはまる部分が多くて難しそうな印象は受けました。また、爆速でサービスを作られた学生のお話は社会人も圧倒される内容で、是非爆速で作るコツを学びたいと思ったのと同時に、最近の学生はとてもレベルが高く改めて若者の力に負けずと頑張らないと思いました。