ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
SharePlayの最新情報
SharePlayの最新情報を紹介しますので、是非ご覧ください。AppからSharePlayセッションを開始する方法をはじめ、エクスペリエンスの向上をもたらす改善されたAPI、GroupSessionMessengerの機能強化について解説します。また、SharePlayをAppに追加するベストプラクティスも紹介します。
リソース
関連ビデオ
WWDC23
WWDC22
-
ダウンロード
♪ ♪
こんにちはSharePlayの エンジニアAdamです SharePlayの新機能と Appへの導入方法について お話します まずAppからSharePlayを起動する 新APIについて説明します 次にGroupSessionMessenger の更新についてです 最後にSharePlayの実装に関する ベストプラクティスを紹介します AppからSharePlayを 起動するというのは 皆さんの声を聞いて 実現しました iOS 15.4以降 新しいAPIを利用して Appで開始できるようになりました 既存のFaceTimeの通話 がなくても開始できます では どのように見えるか 見てみましょう お気に入りの SharePlayしたいAppを見つけます たとえばミュージックAppと しましょう そしてViral Hitsのように SharePlayしたい曲を見つけ それを長押しします コンテキストメニューで 新しいSharePlay ボタンがあります では それを 押してみましょう するとユーザーを選択する画面が 表示されます そこでSueを選択し FaceTime 通話を開始します
そして ご覧の通り ここにはアクティビティを確認できる ピルがあります Sueが参加すれば先に進んで グループセッションを 開始します
さて かなり良い感じでは ないでしょうか もう少し詳しく 見ていきましょう
ユーザーは共有シートから SharePlayを開始できます これが機能するために何が 必要か疑問かもしれません 答えはAppにSharePlayの エンタイトルメントがあるなら 何もすることなく このボタンを無料で入手できます しかし これは最適な ユーザー体験ではありません ユーザーはシステムUIから 「GroupActivity」を開始できず SharePlayするコンテンツを 選択するのに Appと再度相互作用の 必要があります では Appに新しいAPIを 導入する方法を見てみましょう 答えはGroupActivityを NSItemProviderに 登録して ItemProviderを共有シート に提供するだけです
SharePlayボタンを 提供したいけれど 目立たないように 表示したいですか? 問題ありません UIActivityViewControllerの 「allowsProminentActivity」で 動作を調整できます 「allowsProminentActivity」を 「false」に設定するだけです
App内にSharePlayをサポートしていない コンテンツがある場合はどうでしょうか? 全コンテンツがSharePlayを サポートすることを望みますが UIActivityViewControllerに SharePlayアクティビティタイプを 除外するように指示することでSharePlayを 共有シートに表示しないようにできます
またApp内に直接ボタンを 配置したい場合は 新しいAPI 「GroupActivity SharingController」を使用して UIViewControllerを作成し それを提示するだけです
誰かがApp内体験を 押して FaceTimeやSharePlayの セッションを開始すると 段階的なGroupActivityを 起動する機能が表示されます 有効化されるとAppは GroupSessionを受け取ります また 次のように感じたとしても 心配はいりません 「Adam 待って"StagedGroup Activity"って言った?」 はい そうなんです 言いました しかし その考えを持ち続けて ベストプラクティスの話をするときに さらに深く掘り下げましょう DrawTogether Appで導入 する方法を見てみましょう
これが私たちの DrawTogether Appです 2021年の前回WWDCでの お話と同じAppです 「Group Activities によるカスタムエクスペリエンスの構築」 まだご覧になっていない方は ぜひご覧ください さて 前回のセッションを見ていただいた ということで Appには共有ボタンがなかった ことを覚えているでしょう しかしGroupSessionの 対象となる場合は SharePlayボタンが ありました 先に進んで その動作を 変更しましょう 「isEligibleForGroupSession」 が「false」の場合でも ボタンを表示し ユーザーが SharePlay セッションを開始できるようにします
そして今 実際に動作 しているのを確認できます ではControlBarの コードを見てみましょう ここでわかるように 「if」文を使って グループセッションが ないこと グループセッションの資格が あることを確認しています では 先に進んで 後者の文を削除し 下に移動します
GroupActivity共有コントローラ をいつ表示するかを知るのに 新しい変数を登録する 必要があります したがって ここに新しい 変数を用意しています この変数が「true」になった ときの処理をします
SwiftUIでGroupActivity共有 コントローラーを表示できるように ラッパーを用意する 必要があります
最後にすべきことは 「else」文を持つことで GroupSessionの 資格がない場合は 「isSharingControllerPresented」 を「true」に設定します
これで コードの動作を 確認できます 次にDrawTogether Appに移動し SharePlayボタンが あることを確認します このボタンを押すとユーザー ピッカーが表示されます
AppからSharePlayを起動する 素晴らしい体験をしました しかし私たちが行った更新は これだけではありません GroupSessionMessengerの 更新について説明します GroupSessionMessengerに 2 つの新しい更新があります 最初の更新では この不思議な数字に 遭遇したことがあるかもしれません これはGroupSessionMessengerで 送信できるペイロードサイズです でも もう大丈夫です ペイロードサイズは4倍の 256KBになりました この変更によりAppは メッセージを小さく分割する 必要がなくなりました 単にメッセージを送信し素晴らしい 体験を構築することに集中できます もしこれで十分でなければ これから紹介する二つ目の更新は どうでしょう 信頼性の低いメッセージングです GroupSessionMessenger の一部として メッセージの信頼性を 選択できるようになりました 信頼性の高いメッセージング と低いメッセージングを 希望に応じて選択できる ようになりました
私たちがすべきことは GroupSessionMessengerで 新しい初期化子を 利用するだけです MessageReliability を指定することができます
さてAPIの使い方を 理解したので 体験はどうでしょうか? 信頼性の低いメッセージング をいつ使用するべきでしょうか? これは良い質問です
人々はFaceTimeとSharePlayで リアルタイムで活動しています そこでセッションに次の3人が いると想像してみましょう Amy Brian Chrisです 全員セッションに参加し 同期されているので 時間の経過とともに 動画も進行します しかしAmyが ある特定の時間の その瞬間に関連したことを したい場合はどうでしょうか 信頼性の高い メッセージングを使えば すべてのデバイスで 受信されることを保証します しかし 彼らが 期待している時間に 受信されるとは限りません たとえば Chrisは メッセージを受け取ったが Brianは最初で メッセージを落とし その後きちんと 受信するとします ただ動画はまだ再生中である ことを忘れないでください 動画はAmyが意図した 時間に行き着くのですが Brianはそれに関連する情報を 持っていません 彼は後でメッセージを受け取りますが その時点では手遅れです これは信頼性の低いネット ワークの完璧なケースです これによりデベロッパは どういう情報が 相手側に確実に 受信される必要があり どういう情報がそうではない のかを知ることができます これはユーザー体験が 遅延に深く影響される プロトコルを設計する際に 理解すべき重要な概念です 信頼性の低いメッセージは UDPを使用しており 関係する各メッセージの遅延 とオーバーヘッドが少なく その結果 それを通して メッセージを送信した際 よりリアルタイムの 体験が得られます ではDrawTogetherのAppで これをどのように使うか説明します WWDC '21 でのこの画面を 覚えているかもしれません 美しい笑顔マークが 描かれています 画面上に笑顔マークを描いて いるときに何が起こるか 少し掘り下げてみましょう
このAppにはGestureRecognizer をリッスンするコードがあり 変化に気づくたびに メッセージを送信しています つまり 笑顔マークを 描いている間 GestureRecognizerが 提供する各ポイントで 常に新しいメッセージを 送信しています これはたくさんの数の メッセージです! よりシームレスな描画体験のために 信頼性の低いメッセージングを 使用するよう プロトコルを 変更できるようになりました
ここではGestureRecognizer から更新を受け取るたびに 新しく追加されたポイントを 信頼性の低いメッセージング を使って送信します ジェスチャーが完了したら 信頼性の高いメッセージングを使用し すべてのポイントを提供することで顧客が 逃したポイントを取り戻すことができます これにより信頼性の低い メッセージングに提供される 低レイテンシーを利用し 迅速な描画を体験できます では これをコードでどう 行うかを見てみましょう 最初にメッセージファイルに 移動しましょう
次に新しいメッセージタイプ を定義します この新しいメッセージタイプは 以前のものとほとんど同じですが 今回はストロークのすべて のポイントを含んでいます 次に キャンバスファイルに 移動します
これから受け取る新しい メッセージを処理するために ハンドラー関数を設定する 必要があります
先に進み信頼性の低い メッセンジャーを作りましょう まず 変数を作成します
そして 初期化しましょう
次に ストロークが終了した メッセージをリッスンします
前のメッセージも信頼できない メッセンジャーとしてマークします
しかしメッセージを送信する 方法が必要です そこでfinishedStrokeに 移動します
先に進み新しいメッセージ タイプを送信します
すべてのポイントを送信する ため古い関数を変更し 信頼性の低いメッセンジャー を使用します
これで コードの動作を 確認できます DrawTogether Appに 移動して いかにシームレスであるかを 確認できます 以上です
さて 約束通りSharePlayの 実装に関する ベストプラクティスについて お話しましょう この用語は以前から 覚えているかもしれません 段階的なGroupActivity この用語はAppにとって 何を意味するのでしょうか? では シナリオを説明しましょう
左側のデバイス「Adam」が 右側のデバイス 「Brian」と SharePlayを開始したとします Adamは見ていた番組を 再開しようとしています そこで誰かが段階的な GroupActivityを起動し 最初からやり直すのではなく 特定の時間に再開された 番組にジャンプしたいのです 「Adam」は番組の残りが 11分だと知っていましたが Brianのデバイスは 知らなかったので問題が発生します つまりBrianのデバイスが段階的な GroupActivityを起動した場合 番組が初めから再生される 可能性があります では どうすれば 良いのでしょうか? それはAppとエクスペリエンスに よります
それでは いくつかの アイデアを紹介しましょう 再生の場合 各デバイスが追い付く際に 最初の再生状態を 他のデバイスに 提供するようにします つまりAdamのデバイスは再生状態が 23 秒であることを知っていたので セッションに参加すると 他のすべてのデバイスに 自分の意図する 再生状態を伝えます そして それを真実の ソースとして使用します この原則はSharePlayを使用して 作成するあらゆる体験に適用されます セッションに参加する各自が セッションの理解度を他の人 に提供する必要があります セッションがピアツーピアで 所有者がいないためです では それについてもう少し 詳しく説明しましょう 所有者のいないセッションは 把握しにくい概念ですが 適切なSharePlay体験を 設計する上で重要です この場合 左側のAdamは セッションを Apple TVに渡したいと 考えています その結果 彼の携帯電話は GroupSessionから外れテレビが参加します しかし所有権を実装して いたらどうなるのでしょうか オーナーが脱落した わけですから… これはテレビだけのものでは ないことを忘れないでください
iOS 16 では FaceTime のHandoffが可能です Adamが自分のiPadを Handoffすると... 同じことが起こります ああ それだけではありません セッションをあるデバイス から別のデバイスに 移動させようとするユーザー フローの例を紹介しました しかし考えるべきケースは 他にもあります もう1つの例で手短に説明します ので心配しないでください この画面は少し見覚えが あるかもしれません これはFaceTimeの HUDです SharePlayボタンをクリック するとどうなるでしょうか?
「End SharePlay」 ボタンが表示され 推測したとおりSharePlay を終了できます これにより すべての人のために SharePlayを終了できます 基本的にはAppに代わって システムがGroupSession で 「.end()」を呼び出します つまり デバイスが所有者でない限り 「.end()」を呼び出さないように 注意していても システムが皆さんに代わって GroupSessionの「.end()」を 呼び出すことができるのです 理解するのは難しい概念かも しれませんが覚えておいてください Appに所有者がない ことを意識することは 全体として より良い体験に つながるのです さて セッションをすべて お聞きいただきました AppからSharePlayを起動 する新しいAPIを導入し Appが信頼性の低い メッセージングを使用して 新しい低遅延の方法で 通信法を探ってください
皆さんからのご意見を お待ちしております フィードバックアシスタントで お声をお聞かせください これらのアップデートを楽しんで いただけたらと思います 皆さんが構築する素晴らしい 体験を楽しみにしています まだの方はWWDCでの お話をご覧ください 「優れたSharePlayエクスペリエンスを 提供する」です メディア再生に関する 素晴らしい 機能強化をお探しなら 「SharePlayで広告とインタースティシャルを 表示する」をご覧ください ご質問があれば GroupActivities ラボとチャレンジをご覧ください WWDC をお楽しみください ありがとうございました 皆さんが何を構築するか 楽しみです
-
-
2:06 - Register GroupActivity
// Register GroupActivity let itemProvider = NSItemProvider() itemProvider.registerGroupActivity(WatchTogether()) // Provide the ItemProvider to the ShareSheet let configuration = UIActivityItemsConfiguration(itemProviders: [itemProvider]) UIActivityViewController(activityItemsConfiguration: configuration)
-
2:14 - Not as prominent
let shareSheet = UIActivityViewController(activityItemsConfiguration: configuration) // Show SharePlay non-prominently shareSheet.allowsProminentActivity = false
-
2:15 - Exclude
let shareSheet = UIActivityViewController(activityItemsConfiguration: configuration) // Exclude SharePlay activity shareSheet.excludedActivityTypes = [.sharePlay]
-
2:44 - Show your own button to start SharePlay
let controller = GroupActivitySharingController(WatchTogetherActivity()) present(controller, animated: true)
-
8:21 - Stroke Gesture
var strokeGesture: some Gesture { DragGesture() .onChanged { value in canvas.addPointToActiveStroke(value.location) } .onEnded { value in canvas.addPointToActiveStroke(value.location) canvas.finishStroke() } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。