iOSのSharePlayアプリをvisionOS対応する方法
SharePlayに対応したiOSアプリのvisionOS版を開発する場合、基本的に何もしなくてもvisionOSでも「従来のSharePlay」は適切に動きます。また、「空間的なSharePlay」も概ね問題なく動作します。ただ、追加で実装した方が良いポイントがいくつかあります。今回はそれらを紹介します。
今回、実際に改修するアプリ
今回は、GroupActivitiesフレームワークを代表するApple純正サンプルコード「DrawTogether」を改修していきます。
DrawTogetherは単一のアクティビティのみで構成されるシングルウインドウアプリです。iOS/iPadOSに対応しています。
完成後のイメージ
SharePlayに関係無い改修部分についての紹介は省略します。
ポイント1: システムUIとの連携
visionOSにおいて、FaceTimeで通話している間はウインドウにSharePlayや画面共有のためのシステムUIが表示されます。
このシステムUIからSharePlayを開始することが出来ます。
この「SharePlayを開始するボタンを表示する実装方法」については以下の記事を参照してください。
ポイント2: 「空間的なSharePlay」時に視覚的不一致を極力避ける
PhotosPickerの写真選択画面が視覚的不一致を起こしてしまい、ユーザーらを混乱させてしまいます。
今回は、PhotosPickerの写真選択画面を呼び出す前に、写真選択画面を呼び出そうとしているユーザーに「視覚的不一致が起きることを明示」することで混乱を避けましょう。
まず、ユーザー自身が「空間的なSharePlay」中かどうかをチェック出来るようにします。
@Published private(set) var spatialSharePlaying: Bool?
self.tasks.insert(
Task {
if let systemCoordinator = await groupSession.systemCoordinator {
for await localParticipantState in systemCoordinator.localParticipantStates {
self.spatialSharePlaying = localParticipantState.isSpatial
}
}
}
)
systemCoordinator.localParticipantStatesからユーザー自身が「空間的なSharePlay」中かどうかのBool値を受け取り、値を保持します。
次に、PhotosPickerの写真選択画面が表示される前に注意書きを表示する実装をします。
@State private var notificationIsPresented: Bool = false
if canvas.groupSession != nil {
if canvas.spatialSharePlaying == true {
Button {
notificationIsPresented = true
} label: {
Image(systemName: "photo.fill")
}
} else {
photosPicker()
}
}
.sheet(isPresented: self.$notificationIsPresented) {
NavigationStack {
VStack {
Text("この画面や、写真選択画面は他の人には見えていません。")
.font(.largeTitle)
photosPicker()
}
.padding(48)
.toolbar {
Button("戻る") {
notificationIsPresented = false
}
}
}
}
ポイント3: 「視覚的不一致」が前提の場合の事前設定
ポーカーや麻雀のような視覚的不一致が前提のコンテンツの場合、「空間的なSharePlay」をオフにするためにアクティビティとSceneの紐付けを回避する必要があります。
struct MyActivity: GroupActivity {
var metadata: GroupActivityMetadata {
var metadata = GroupActivityMetadata()
metadata.title = "MyActivity"
metadata.sceneAssociationBehavior = .none // ←
return metadata
}
}
DrawTogetherは「視覚的一致」が前提のコンテンツなので、この実装は必要ありません。
ポイント4: テンプレートを設定して立ち位置を調整
「空間的なSharePlay」中のペルソナの立ち位置は、プレーンなウインドウではSide-by-Side(横並びモード)というテンプレートがデフォルトで適用されます。もし、参加者同士の会話がメインとなるアプリ(例えばBGM再生アプリなど)の場合、テンプレートをConversational(会話モード)に変更すると良いでしょう。
self.tasks.insert(
Task {
if let systemCoordinator = await groupSession.systemCoordinator {
var configuration = SystemCoordinator.Configuration()
configuration.spatialTemplatePreference = .conversational
systemCoordinator.configuration = configuration
groupSession.join()
}
}
)
余談
【Apple Vision Proを持っている方への相談】「空間的なSharePlay」アプリの動作確認や動画撮影等に協力してくれませんか?
実機が1台だけでは「空間的なSharePlay」を動かすことが出来ません。お互いにApple Vision Pro実機からペルソナでFaceTime通話している時だけ「空間的なSharePlay」を動かすことが出来ます。ただ、残念ながら私にはApple Vision Proを持っている知り合いがいないのです。もし協力してくださる方がいらっしゃれば、こちらのメールアドレス(waggle.slips.0t@icloud.com)に連絡ください!
==== 追記 2024/12/01 ====
12月現在も協力者募集中です!
==== 追記ここまで ====
Discussion