kumamotone’s blog

iOS/Android アプリエンジニアです https://twitter.com/kumamo_tone

(翻訳) Announcing Flutter 2.8

medium.com

by Tim Sneath 12月9日 読むのに7分

このアップデートは、モバイルやウェブの開発者の皆様の使い勝手を向上させ、デスクトップの安定したサポートに近づけるための新機能や改善点を多数含んでいます。

Flutterは、アプリケーションの作り方を変えることを目的としています。Flutterは、モバイル、ウェブ、デスクトップ、組み込み機器の開発を単一のツールキットに統合します。開発者は、どのプラットフォームをターゲットにするかではなく、まず何を作りたいかに集中し、高性能で生産性の高いフレームワークを提供することで、開発者のインナーループを短縮し、1つのコードベースで複数のプラットフォームやフォームファクタをターゲットにすることができます。

新機能と改良:より速く、より生産的に

今回のリリースでは、モバイルパフォーマンスに重点を置いています。優れたパフォーマンスは無償で提供されるのが理想ですが、実際には、複雑なアプリケーションであっても、基盤となるハードウェアやライブラリをうまく利用するための最適化が必要です。これには、ネットワークの帯域幅やその他の初期化コストによって制約を受ける起動時のパフォーマンス、特にメモリに制約のあるデバイスでのメモリ使用量、グラフィックスレンダリングなどが含まれます。私たちは、Google Payなどの大規模なGoogleアプリでの経験を活かして、Flutter自体のパフォーマンスを向上させるとともに、お客様のアプリのプロファイリングや最適化を支援するツールを充実させています。Flutter 2.8にアップグレードするだけで、アプリの起動が速くなり、メモリ使用量も少なくなります。

最新のアップデートでは、FirebaseやGoogle Cloudなどのバックエンドサービスにアプリを接続することがこれまで以上に容易になりました。また、Google Adsの本番環境への対応や、カメラおよび埋め込みWebプラグインの大幅なアップグレードも行われています。また、Dart 2.15も含まれており、並行処理の大幅な改善、コンストラクタのティアオフや列挙の強化などの言語機能の追加、メモリ使用量を10%削減する最適化などが行われています。

今回のリリースのもう一つの大きなテーマは、開発者の生産性をさらに向上させることです。ステートフルホットリロードなどの機能により、私たちは常に開発者のためにタイトなインナーループを作ることに注力してきました。今回のリリースでは、開発者がより迅速に作業を進めることができるよう、より高度な抽象化を目指しています。例えば、今回のリリースでは、Firebaseを使って認証を処理するサインイン・ウィジェットを追加しています。このウィジェットがあれば、二要素認証やパスワードリセットなどのサインインのエッジケースや、認証プロバイダとしてのGoogleAppleTwitterFacebookのサポートの複雑さを気にする必要はありません。このような機能は、Flutterの中核的な基盤の上に構築されており、ローコードソリューションの開発スピードと完全なUIフレームワークの柔軟性とパワーを組み合わせることで、開発者のアプリケーション構築方法を変える可能性を秘めています。

Dart 2.15は現在公開されており、新しい機能強化についての詳細を記したテクニカル・ブログ・ポストを用意しておりますので、ぜひご覧ください。Flutter 2.8の公開プロセスを開始したところですが、2時間以内には公開され、詳細なブログ記事が掲載される予定です。公開され次第、ここにあるリンクを更新します。

Flameによるカジュアルゲーム開発

ほとんどの開発者にとって、Flutterはアプリのフレームワークです。しかし、Flutterが提供するハードウェアアクセラレーションによるグラフィックスサポートを利用した、カジュアルゲーム開発のエコシステムも成長しています。

本日、Flutterの上に構築されたモジュール式の2DゲームエンジンであるFlameの1.0リリースを記念して、私たちは興奮しています。Flameは、ゲームループだけでなく、コンポーネントシステム、アニメーション化されたスプライトやイメージ、衝突検知、ワールドカメラ、エフェクトシステム、ジェスチャーや入力のサポートなど、ゲームを素早く構築するために必要なものを備えています。

例えば、Rive(アニメーション)、audioplayers(音楽とサウンドエフェクト)、Forge2D(Box2Dスタイルの物理エンジン)、Tiled(タイルマップエディタ)、Fire Atlas(スプライトシートとアニメーションエディタ)などがあり、Flameはモジュール式で、他のライブラリとの統合を提供するパッケージで拡張できます。Flameと幅広いエコシステムは、カジュアルゲームや2Dゲームの開発者に強力なサービスを提供しています。

Flameは、FlutterやDartオープンソースパッケージやプラグインの作成に注力しているコントリビューターのグループ、Blue Fireによって作成されています。ゲーム開発に興味のある方は、ぜひFlameをチェックしてみてください。

勢いのあるFlutter

Flutterは、コアフレームワークの上に構築されたアプリケーションやツールのエコシステムを繁栄させながら、急速に成長し続けていることに驚かされています。今年のGoogle I/Oイベントでは、Flutterで構築されたアプリがPlay Storeですでに20万本以上提供されていることを紹介しました。そのイベントからわずか半年余りで、Flutterアプリの数はほぼ倍増し、現在Playストアには375,000本以上のFlutterアプリが登録されています。

(Flutterは、AndroidiOS、iPadOS、Web、WindowsmacOSLinuxをサポートしているので、異なるデバイスフォームファクタをターゲットにするためにアプリを書き直す必要はありません。)

もちろん、Flutterが使われているのはAndroidだけではありません。独立系モバイルアナリスト企業のAppAnnieによると、iOSでFlutterを使用しているアプリには、BMW、eBay、WeChat、SHEIN、Philips Hue、Norton、trip.com、Greggsなどのトップブランドやアプリが含まれています。ウェブ上では、Flutterはアプリのエクスペリエンスに適しており、FlutterFlowやRiveなどのデザインツールの恩恵を受けています。デスクトップでは、Ubuntuのエンジニアリングチームが、新しいインストーラーやファームウェアアップデータなど、Flutterを使ったさまざまな新しい体験を構築し続けています。PUBGのようなゲームでも、FlutterがUI画面に最適であることがわかってきました。

エコシステムの構築には長い時間がかかりますが、Statista、JetBrains、SlashData、Stack Overflowが独自に測定した結果、Flutterは今や最も人気のあるマルチプラットフォームのツールキットとなっています。私たちはそれを当然のことだとは思っていませんが、Flutterの人気の高まりは、それをサポートするパッケージやツールのエコシステムがますます広がっていくことにつながります。

2021年を振り返って、2022年に向けて

この困難な昨年の間に、私たちのエンジニアリングチームは多忙を極めました。Flutter 2.8の機能だけでなく、開発者向けツールの書き換え、null safetyとWebサポートのリリース、ネイティブコード統合のためのFFIの完成、Material Youの初期サポートの追加、そしてパフォーマンスと品質の向上のために懸命に取り組んできました。合計で約2万件の問題を解決しました。Flutterをよりよく紹介するために、スマートな新しいウェブサイトを作成しました。また、エンジニアの生産性を向上させ、テストを拡大するために、この数ヶ月間、エンジニアリングインフラの見直しにかなりの労力を費やしてきました。

2022年に向けて、私たちは何人かの方と直接お会いできることを願っています。私たちは、言語の強化、ドキュメントの更新、Flutterで洗練されたアプリケーションを簡単に構築するための高レベルの抽象化など、開発者の体験の中核となる部分にさらなる投資を行う予定です。安定したデスクトップのサポートを完成させ、ウェブでの作業をさらに拡大する予定です。また、他のプラットフォームとの相互運用性や、新しいターゲットへの移植性を高めることも計画しています。私たちはまだ始まったばかりなのです!

このFlutter 2.8のリリースを、ちょうど一週間前に亡くなったVery Good Venturesの開発者、Kevin Grayに捧げたいと思います。Kevinは初期の頃からFlutterの成功に重要な貢献をしてきました。彼は初期のFlutterのデモの多くの開発者であり、その中には注目を集めた最初のお客様の獲得、デスクトップでの初めてのFlutterのデモ、そしてGoogle I/Oの基調講演で取り上げられた最初のFlutterのデモなどが含まれます。彼は、才能があり、思いやりがあり、面白くて、親切な人でした。彼を知る人は、彼がぽっかりと穴を開けてしまったことにすぐに同意するでしょう。悲しみに暮れながらも、彼の人生を祝福し、彼の影響力をすべての人に知ってもらうために、公に彼を偲びます。彼がいなければ、今のFlutterはありません。

ケビン、あなたがいなくて寂しいです。Flutterのためにしてくれたこと、そして友情に感謝します。ケビンの家族と友人には、私たちの愛を送ります。

また、Flutterの開発者と支援者の幅広いコミュニティにも、私たちはあなたに感謝しています。私たちは、Flutter 2.8が皆さんにたくさんの探求心を与えてくれることを願っています。まだFlutterを学んだことがない方は、1月初旬まで誰でも無料で入手できるFlutter Apprenticeの本を読んでいる約4万人の開発者の仲間入りをしてください。皆様が楽しく安全なホリデーシーズンを過ごされることをお祈りいたします。

Michael Thomsen氏に感謝します。

(CC BY 4.0)

FlutterKaigi 2021 Day 1 #FlutterKaigi

YouTubeアーカイブがある(神)

www.youtube.com

一通り見たが以下の2本がとくに参考になった。

  • FlutterでのMaterial You対応の状況と今後の展望
  • Flutterにおける過不足のないセキュリティの実装

FlutterでのMaterial You対応の状況と今後の展望

speakerdeck.com

  • Material Design 2と3の違い
    • 2はブランドごと、3はユーザーごとのカスタマイズが可能になった(Material You)

Color Schemeがどう変わったか

f:id:kumamotone:20211129224806p:plain

大変そうだがKey Colorsだけ5色とりあえず決めてそこから機械的に生成すれば良い

f:id:kumamotone:20211129225235p:plain

Key Colorを決めて

f:id:kumamotone:20211129231214p:plain

ユーザーが設定している壁紙から5つのKey Colorsを抽出できる(特定のメーカーのAndroid 12端末のみ)

アプリ全体に適用する必要はなく、プロフィール画面やアカウント画面など、部分的に適用するのもアリ

f:id:kumamotone:20211129231452p:plain

Buttonに新しいタイプが加わり、形もちょっと変わった

f:id:kumamotone:20211129231535p:plain

FABがかわいくなった うれしい

f:id:kumamotone:20211129231615p:plain

2021年11月29日現在、stableにまだ全然取り込まれてない←Oh....

ThemeDataにMaterial3をOptinするためのフラグuseMaterial3は追加されていて、これをtrueにすると、Material3対応が完了しているものは3になる

f:id:kumamotone:20211129231924p:plain

Material2のものがMaterial3になるとどうなるかというのは決められているので、予め3の想定で作っておけば、dart fixコマンドであとで一括修正できる予定

色の生成にはmaterial-theme-builderが使える Androidxml ではすでに出力できる Flutter もできると嬉しい

material-foundation.github.io

Flutterにおける過不足のないセキュリティの実装

これ使えばKeyStoreに保存してくれるっぽい

pub.dev

Windows. Linux, macOS, Web の実装もある すご

若干ややこしいpath_providerの使い方も説明してくれている

apkの難読化は以下打てばできる

f:id:kumamotone:20211129231006p:plain

M1 Mac(Big Sur)にHoRNDISをインストールする

MacAndroid のUSBテザリングを使うために必要なカーネル拡張HoRNDISをインストールするのに、GitHubのissueに書いてある方法を色々試しに試し再起動に再起動を重ね、時間を食ってしまった。うまくいった方法だけここに書き残しておく。

github.com

結論からいうと thpryrchn 氏の方法でインストールできた。

1. リカバリモードに入る

リカバリモードに入る方法は、起動時にcmd+Rを押しっぱなしにする方法ではなく、Touch IDを長押しする方法に変わったっぽい。表面にふれるだけじゃなくてガッツリ押し込む必要がある。

終了している最中に電源ボタン長押しは不安になるので再起動じゃなくてシステム終了にしたほうがいい。

2. カーネル拡張を無効にする

リカバリモードに入ったら optionsを選択して、メニューバーのユーティリティからターミナルを起動する。

csrutil enable --without kext

そのままrebootと打ち込んで再起動する。

3. HoRNDISをインストール

git clone https://github.com/thpryrchn/HoRNDIS.git -b BigSur

thpryrchn氏のリポジトリからソースコードを取得して make する。

build/pkg に HoRNDIS-kext.pkg ができるのでダブルクリックしてインストールする。

このタイミングでセキュリティとプライバシーが何かダイアログを出してきたらうまくいっている。そこから再起動して、テザリングする端末を繋げば、自動的に接続されている。

f:id:kumamotone:20210724103809p:plain

Wi-Fiアクセスポイントの方はエコのため切っておくと良さそう。USBテザリングのすぐ上のメニューから変更できる。

Skebの中途採用に「求める条件」の感想

Skebの中途採用に関するツイートを見かけた。

自分はSkebに対しては素晴らしいサービスだと思っていて、クリエイターさんを支援したいという気持ちから生まれたという話も聞いたことがあったので、その点共感していて応援している。

ただ主にこの「推しのVTuberやクリエイターが「いない」方」という部分に関して、文脈的には「アイドルのマネージャーにオタクを採用しない方がトラブルにならなくて良い」みたいな話で、意味のある意図が想像できる一方、クリエイターが好きなエンジニアとして、かなりもやっとしてしまった。

まず1つ目に、クリエイターを支援したいという気持ちから生まれたサービスなのであれば、Skebはクリエイターが好きな、クリエイターを応援したい人を仲間に募集しています、という呼びかけが妥当なのでは?好条件とはいえ、そこまでドライに採用者をただの作業者扱いするようなところで働きたいか?

2つ目に、宗教などと同じで、採用で特定の思想を差別的に扱うのは社会的にNGなのでは?なぜクリエイターのファンというだけで犯罪者予備軍のような扱いを受けなければならないのか?

Skebアカウントはユーザー向けのアカウントで、クリエイターさんが基本的にはお客さんだというところ、また、エッジの効いた文章を入れたことによって拡散されるので、炎上前提の告知としては上手なのかもしれないが、ただ単にあんまり深く考えてないような気もする。

potatotips #70 に参加しました (iOS/Androidブログまとめ) #potatotips

potatotips #70iOS ブログまとめ枠で参加させていただきました(Androidのもまとめました)。

今回はLINE Fukuokaさん主催で、Zoomのウェビナーを使ったオンラインでの開催となりました。

f:id:kumamotone:20200710200640p:plain

自分で見直すときのわかりやすさ重視でガッツリ元資料を引用していますが問題あればご連絡ください。

[iOS] Contributing to XcodeGen / @freddi

XcodeGen という YAMLでxcodeprojを管理できる OSS にコントリビュートした。

f:id:kumamotone:20200710201421p:plain

Swift Packageの依存が、Remoteにあるものしか解決できなかった。これをLocalでもできるようにした。

f:id:kumamotone:20200710201558p:plain

気をつけること、CONTRIBUTING.md というのがあるので読むでからPRする、後方互換性に気をつけるなど。

xcodegenの自動生成の機能もあるけどまだ実装中。

[Android] Jetpack Composeでテキストを装飾する話 / @uecchi

Jetpack Composeでテキストを装飾する方法を紹介。

テキスト全体を修飾

ふつうにTextの引数で設定する。

@Composable
fun StyledGreeting(name: String){
Text(
text = "Hello $name!",
color = Color.Green,
fontSize = 30.sp,
fontFamily = FontFamily.Cursive,
fontStyle = FontStyle.Italic,
fontWeight = FontWeight.Bold
)}

テキストの一部を修飾

従来のやつでは Spanned に対応するやつだが、 Annotated String というクラスを使う

@Composable
fun StyledGreeting2(name: String){
val greetingText = annotatedString {
pushStyle(SpanStyle(color = Color.Green))
append ("Hello ")
// 前にpushしたstyleは引き継がれる
pushStyle(SpanStyle(
fontSize = 40.sp,
// Snip fontFamily, fontStyle, fontWeight
fontSynthesis = FontSynthesis.All,
textDecoration = TextDecoration.Underline
append("$name!!")
pop()// 直近でpushしたstyleはpopできる
Text(text =
greetingText, fontSize = 30.sp)

こうなる

f:id:kumamotone:20200710203021p:plain

テキスト内にカスタム画像を表示

inline content というのがある。

@Composable
fun StyledGreeting3(name: String){
val inlineContentId = "InlineContent"
val greetingText = annotatedString {
append("Hello $name!!")
// inline contentを挿入
appendInlineContent(id = inlineContentId, alternateText = ":droid:")
// snip

inlineContent: map<String, InlineTextContent> を Text に渡す

@Composable
fun StyledGreeting3(name: String) {
val inlineContentId = "InlineContent"
val greetingText = // snip
val inlineContent = map0f(
inlineContentId to InlineTextContent(
Placeholder(
width = 30.sp,
height = 30.sp,
placeholderVerticalAlign = PlaceholderVerticalAlign.Center
){ alternateText ->
// このlambdaはComposable関数
CustomEmojiImage(imageResId = R.drawable.ic_android_robot)
})
Text(text = greetingText, fontSize = 30.sp, inlineContent = inlineContent)
}
@Composable
fun CustomEmojiImage(imageResId: Int){
Image(
modifier = Modifier.fillMaxSize(),
asset = vectorResource(id = imageResId),
contentScale = ContentScale.FillWidth
)}

こうなる

f:id:kumamotone:20200710203003p:plain

Jetpack Composeはこのようにプレビューが横に表示される。便利

f:id:kumamotone:20200710202859p:plain

サンプルコード

https://github.com/tsuyosh/JetpackComposeTextDemogithub.com

[iOS] ARKit 4.0 / @TachibanaKaoru

speakerdeck.com

f:id:kumamotone:20200710203115p:plain

ARKitの歴史

ARKit4 新機能を紹介していく。

Geo Anchor

f:id:kumamotone:20200710203555p:plain

AppleがMap情報を取得するときに収集した実際の建物の3D情報と、カメラ画像から分析した3D情報と、端末のGPS情報を組み合わせた仕組みで、非常に正確な位置測定が可能。

セカイカメラと同じようなことが簡単に実装できる。

現時点ではサンフランシスコ、シカゴ、マイアミ、ニューヨーク、ロサンゼルスだけで使える。

f:id:kumamotone:20200710203707p:plain

使い方

Depth with LIDAR (Scene Geometry with LIDAR?)

f:id:kumamotone:20200710203800p:plain

新しいiPad Pro だけで使える、センサーから光を照射してその反射光を使って物体までの距離や物体の種類がわかるようになる。

判定可能な物体は天井、ドア、床、椅子、テーブル、壁、窓、その他、の8種類。

3.5でも距離と種類は取得できたのだが、APIが使いやすくなった。

Face Tracking

TrueDepthカメラ搭載のみだったが、A12以上のプロセッサでも使えるようになった。(新しいiPhoneSEとか)

Reality Converter

Reality Converterというのが2020年1月にリリースされて、他のモデリングツールのファイルからUSDZファイルへ簡単に変換できるようになった。

f:id:kumamotone:20200710211458p:plain

次のiPhoneにLiDARが搭載されなかったらTachibanaさんのカシオミニがもらえます

[Android] license-list-pluginを使ってOSSライセンス画面を自動生成する / @syarihu

speakerdeck.com

OSSライセンス画面を手軽に作るためのツール、いくつかある

github.com

以下のような特徴がある。

  • ライセンスリストを自動生成し、yamlに定義ファイルを出力人が読みやすい形なので、ライセンスの追加/変更/削除も簡単にできる
  • oss-license-pluginと違いライセンスリストが隠蔽されていないため、差分も分かりやすい
  • 定義ファイルを元に表示用のhtmlを自動生成したり、カスタマイズした画面を提供するために利用可能なjsonの出力も可能
  • ローカルライブラリにも対応
  • ライセンスリストから除外したいライブラリがある場合は.artifactignoreに記述することで簡単に除外可能
  • cookpad/LicenseToolsPluginを使っている場合はcookpadプラグインで利用するlicenses.ymlからの移行も可能

f:id:kumamotone:20200710204930p:plain

json だけでなく HTML の形式でも吐ける。従来のより見た目も良い。

Github Actions に組み込んで自動でライセンス定義を更新することもできる。

聞いた範囲たいへん良さそうだが This plugin is still under development. とのこと

[iOS] Speech framework tips / @tsuzuki817

note にセルフテキストまとめがあるので詳しくはこちら!

note.com

Apple純正の音声認識フレームワーク。ローカル(iOS13〜)とサーバー版がある。

サーバーのAPIの制限は1リクエスト60秒(音声の長さ)。1時間に1000回まで。

NSSpeechRecognitionUsageDescription と NSMicrophoneUsageDescription を Info.plist に入れて使う。

f:id:kumamotone:20200710210028p:plain

共有会って喋って認識させてみた結果。

通話中は録音ができないのでデバッグ時には注意。

[Flutter] Creating Flutter Animations with Rive

docs.rive.app

Rive は Flutterで使えるアニメーションツール。前まで flare という名前だった。ツール flr ファイルを読み込んで使うだけ。

フリー版でも機能が使えるが、作ったファイル public にしなければならない。 private にしたければ、 21ドル/月か、年間プランだと14ドル/月。

iOSには対応しているけどAndroidには対応していない?(調べてない)

[iOS] UICollectionView iOS14 / @shiz

speakerdeck.com

iOS14 での UICollectionView の更新について。

SectionSnapShot

f:id:kumamotone:20200710211810p:plain

f:id:kumamotone:20200710211828p:plain

SectionSnapShot というのが追加された。セクションごとの折りたたみの状態を保存できたり、それのイベントハンドラがあったりする。

あと並び替えのサポートがされた。

Lists

f:id:kumamotone:20200710211949p:plain

UITableViewのような外見で、スワイプできる、デフォルトのレイアウトが用意されている、Compositional Layoutの上に作成できるなどの特徴がある。

Cell(View)の設定

struct で設定できるようになった。

f:id:kumamotone:20200710212413p:plain

いい感じに型を使ってセルの登録もできるようになった(これUITableViewにはないってことなのかな)

より深く理解したい人はAppleの公式サンプルコードがおすすめ。

Qiita にもまとめてくださっている。

qiita.com

[Android] getChangePayload in DiffUtil / @rmakiyama

speakerdeck.com

音声版

DiffUtil に getChangePayload というのがある。これはareItemsTheSameがtrueかつareContentsTheSameがfalseで呼ばれる。

f:id:kumamotone:20200710213204p:plain

変更に関するペイロードをオブジェクトで返せるので、細かい更新の制御が可能。画像の再読み込みが起こらずチラツキが起こらず、スマート。

f:id:kumamotone:20200710213252p:plain

Groupieにも同様の機能が提供されている。

サンプルコード

github.com

[iOS] Swift UIで勘違いした話 / @koher

speakerdeck.com

Stepper に $counter.count を渡すように、 NumberDisplay にも @Binding の $counter.count を渡していたら、コンパイルエラーでうまくいかなかった

というのも、Stepperでは双方向バインディングなんだが、NumberDisplayは単方向バインディングなので、

Viewでは @Binding ではなくシンプルにプロパティを持っておいて、プロパティを渡せば
単方向バインディングは実現できるということがフォーラムに聞いたらわかった 質問するのは大事ですね

[Android] Material Components for Android 1.2.0 and 1.3.0 / @NabeCott

speakerdeck.com

まだ開発中だが Material Components に入りそうな変更について。

f:id:kumamotone:20200710215506p:plain

SliderはSeekBarのMaterial Component版 目盛りの表示やTooltipの表示、範囲の選択などができる

f:id:kumamotone:20200710215529p:plain

ShapeableなImageViewなど

ほかにも複数行のタイトルが表示できるCollapsingToolbarやProgressBarのMaterial Component版、新しいTimePicker(In development)などが入りそう

[iOS] iOSアプリでWebRTC / @SatoHikaruDev

qiita.com

WebRTCのクライアント実装について理解を深めたい。

github.com

サンプルを参考に、どういう処理がされているのか見ていく。接続、SDPのやりとり、映像キャプチャなどについて実際のコードを交えて紹介。

[Android] Adaptive Cardsを使ってみた / @nakasho_dev

www.slideshare.net

adaptivecards.io

Adaptive Cards は、JSONで作成された、プラットフォームに依存しないUIのスニペット。特定のアプリに配信されると、JSONは周囲に自動的に適応するネイティブUIに変換する。Microsoftが推進していて、 Android iOS JavaScript ASP.NET .NET WPF Windows ReactNative などで使えるもよう

Adaptive Card Designer というのがあって、ノンプログラマーでもいい感じに編集できる。

感想

前回に続きリモート開催だったが、運営さんの頑張りなどによって、なんだったらリモートのほうがいい面あるんではと思えるぐらい良い感じだった ありがとうございます

App Clips の短期間通知を有効にする

kumamotone.hatenadiary.jp

上記の続きになります。

App Clips の短期間通知を有効にする

App Clipの中には、価値を提供するためにスケジュールや通知を送る必要があるものもあります。

配達で食べ物を注文できるApp Clipを考えてみましょう。通知を送信することで、App Clipは予定されている配達についてユーザーに通知します。

通知がApp Clipの機能にとって重要な場合は、各起動後最大8時間まで通知をスケジュールまたは受信できるようにします。さらに、複数のビジネス向けにApp Clipを作成する場合は、通知のペイロードに変更を加えるようにしましょう。

一時的な通知の設定

App Clipが起動後、最大8時間まで通知をスケジュールしたり受信したりできるようにするには、まず、App ClipのInfo.plistファイルにDictionary型のNSAppClipキーを追加します。

次に、NSAppClipRequestEphemeralUserNotificationというキーを持つエントリをDictionaryに追加します。このキーの型はBooleanに、値をtrueに設定します。

f:id:kumamotone:20200625065245p:plain
https://developer.apple.com/documentation/app_clips/enabling_notifications_in_app_clips

App Clipの Info.plist に NSAppClipRequestEphemeralUserNotification のエントリを追加すると、App Clipの起動時に表示されるClip Cardには、App Clipが通知を受信したりスケジュールしたりすることができることをユーザーに知らせる追加のnoteが含まれています。

この権限はデフォルトで有効になっていますが、ユーザーはClip Cardのnoteをタップすることで無効にすることができます。

f:id:kumamotone:20200625065309p:plain
https://developer.apple.com/documentation/app_clips/enabling_notifications_in_app_clips

ユーザーはClip Cardで通知を無効にすることができるので、App Clipが通知をスケジュールして受信する権限を持っているかどうかをチェックするコードを追加します。

以下のコードは、ユーザーが短時間の通知送信の許可を与えているかどうかをチェックしています。

let center = UNUserNotificationCenter.current()
center.getNotificationSettings { (settings) in {
    if settings.authorizationStatus == .ephemeral {

        // ユーザーがアプリのクリップカードで通知を無効にしていなかった場合
        // ここにスケジュールや通知を受信するためのコードを追加します
        return
    }
}

通知を送信するための明示的な許可を要求する

App Clipの機能が1日以上に及ぶ場合は、通知を送信するためのユーザーの許可を明示的に要求します。

例えば、レンタカー会社のApp Clipでは、レンタカーを返却する必要があるときにユーザーに通知を送信する許可を求めることができます。

しかし、この許可を求めるべきかどうかは慎重に検討してください。ユーザーはこの要求を拒否して、App Clipが各起動後最大8時間まで通知を受信してスケジュールする能力を上書きしてしまう可能性があります。

通知ペイロードを変更する

複数のビジネス向けのApp Clipを作成することができます。

例えば、飲食店向けのプラットフォームを提供している企業で、多くの異なる飲食店にサービスを提供するApp Clipを作成することができます。

ユーザーが短時間のうちに複数のビジネス向けのApp Clipを連続して起動した場合、App Clipのインスタンスがデバイス上に複数存在することがあります。

この場合、システムは、通知を受信すると、適切なApp Clipのインスタンスに通知をルーティングする必要があります。

その結果、システムは通知のペイロードに URL をtarget content identifierとして含めることを要求します。

次のコードは、複数のビジネスにサービスを提供するApp Clipの通知ペイロードを示しています。

{
    "aps" : {
        "alert" : {
            "title" : "Order Status",
            "subtitle" : "Restaurant A",
            "body" : "Your order is ready."
        },
        "category" : "order_status",
        "target-content-id" : "https://example.com/restaurants/restaurant_a/order/1234"
    }
} 

target-content-id の値は、対応するAdvanced App Clip Experienceに一致するURLである必要があります。

レストランの例では、これらのURLの両方をApp Store Connectに登録します。

呼び出しURLとtarget content identifiersは、次のようになります。

一般的に、可能な限り具体的なtarget content identifiersを使用します。

同様に、ローカル通知をスケジュールするためにApp Clipを有効にする場合は、通知のペイロードにtarget content identifiersを設定します。

詳細については、App Clipsの起動方法の設定Generating a Remote Notification Scheduling a Notification Locally from Your App を参照してください。

出典