스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
SharePlay의 새로운 기능
SharePlay의 최신 업데이트를 소개합니다. SharePlay 세션을 앱에서 바로 시작할 수 있는 방법을 보여드리고, 보다 풍부한 경험을 만들 수 있는 API의 향상된 기능을 안내하며, GroupSessionMessenger의 향상된 기능을 알아봅니다. 또한 SharePlay를 앱에 추가하기 위한 모범 사례를 살펴보겠습니다.
리소스
관련 비디오
WWDC23
WWDC22
-
다운로드
♪ ♪
안녕하세요, SharePlay 팀의 엔지니어 Adam입니다 SharePlay의 새로운 기능과 이를 앱에 적용하는 방법에 대해 이야기하게 되어 기쁩니다 먼저 앱에서 SharePlay를 시작하기 위한 새 API 몇 가지를 얘기하겠습니다 다음으로 흥미로운 GroupSessionMessenger 업데이트에 대해 알아보겠습니다 마지막으로 SharePlay 경험 구현과 관련된 몇 가지 모범 사례입니다 앱의 SharePlay부터 시작합니다 여러분의 의견을 듣고 반영했습니다 iOS 15.4부터 새 API를 활용해 기존 FaceTime 호출 없이 앱에서 SharePlay를 시작할 수 있습니다 그럼 어떻게 생겼는지 봅시다 가장 좋아하는 SharePlay 앱을 찾기만 하면 됩니다 뮤직 앱을 예로 들어 보겠습니다 Viral Hits처럼 SharePlay하고 싶은 노래를 찾아서 길게 누릅니다 이제 상황에 맞는 메뉴에 새 SharePlay 버튼이 있는 것을 볼 수 있습니다 그래서 그걸 누르면 사람 선택기가 나타납니다 수를 선택하고 FaceTime 통화를 시작할 수 있습니다
그리고 보시다시피 여기 예정된 활동이 위에 표시됩니다 수가 합류하면 통화를 시작해서 그룹 세션을 열 수 있습니다
이것만으로도 꽤 멋지지만 좀 더 세부적으로 나누어 봅시다
사용자가 ShareSheet에서 SharePlay를 시작할 수 있는 이 기능을 작동하려면 뭘 해야 하는지 궁금하시겠죠 앱이 SharePlay를 사용할 자격이 있는 경우 제로 채택 플로우로 버튼을 무료로 얻을 수 있습니다 그러나 사용자가 시스템 UI에서 'GroupActivity'를 시작할 수 없기 때문에 최적의 사용자 경험이 아닙니다 사용자가 앱과 다시 상호작용해야 SharePlay에서 콘텐츠를 선택할 수 있죠 그러니 앱에 새 API를 채택하는 방법을 살펴보겠습니다 NSItemProvider에 GroupActivity를 등록하기만 하면 됩니다 그런 다음 ItemProvider를 ShareSheet에 제공합니다
SharePlay 버튼을 제공하고 싶지만 눈에 띄게 표시하고 싶지는 않습니까? 문제 없어요 UIActivityViewController에서 allowsProminentActivity로 동작을 조정할 수 있습니다 allowsProminentActivity를 false로 설정하기만 하면 됩니다
또는 앱에 SharePlay를 지원하지 않는 콘텐츠가 있으면 어떡할까요? 모든 것이 SharePlay를 지원하면 좋겠지만 UIActivityViewController에서 SharePlay 활동 유형을 제외하게 해서 ShareSheet에 표시되지 않도록 할 수 있습니다
앱 내에 직접 버튼을 배치하려면 새로운 API GroupActivitySharingController를 사용할 수 있습니다 UIViewController를 생성하고 그걸 제시하면 됩니다!
누군가가 인앱 경험을 누르고 FaceTime 또는 SharePlay 세션을 시작하면 준비된 GroupActivity를 활성화할 수 있는 기능이 표시됩니다 활성화되면 앱이 GroupSession을 수신합니다 혹시라도 '잠깐, 애덤' '준비된 GroupActivity라고요?' 이런 생각 하셨나요? 맞아요, 그렇게 말했어요 그러나 그건 잠시 미뤄두고 나중에 모범 사례에 대해 이야기할 때 더 깊이 들어가 보겠습니다 지금은 DrawTogether 앱에서 어떻게 채택할 수 있는지 봅시다
DrawTogether 앱입니다 2021년 WWDC 토크에서와 동일한 앱입니다 '그룹 활동으로 맞춤형 경험 구축' 그러니 아직 안보셨다면 꼭 보시길 추천합니다 그걸 보셨다면 우리 앱에는 공유 버튼이 없다는 것을 기억하실 겁니다 그러나 GroupSession에 대한 자격이 있으면 SharePlay 버튼이 있었습니다 isEligibleForGroupSession이 false인 경우에도 버튼을 표시하고 SharePlay 세션을 시작할 수 있도록 해당 동작을 수정해 보겠습니다
이제 어떻게 동작하는지 볼 수 있습니다 계속해서 ControlBar 코드로 이동하겠습니다 여기에서 볼 수 있듯이 그룹 세션이 없고 그룹 세션에 참여할 자격이 있는지 확인하는 if 문이 있습니다 이제 후자의 문을 제거하고 여기로 이동해 보겠습니다
이제 GroupActivity 공유 컨트롤러를 표시할 때를 알 수 있도록 새 변수를 등록해야 합니다 그래서 여기 새 변수를 넣고 그 변수가 true로 바뀔 때를 처리해 봅시다
이제 SwiftUI에서 GroupActivity 공유 컨트롤러를 표시할 수 있도록 래퍼가 있어야 합니다
마지막으로 else 문만 넣어서 GroupSession에 대한 자격이 없는 경우 isSharingControllerPresented를 true로 설정합니다
이제 코드가 작동하는 것을 볼 수 있습니다 DrawTogether 앱으로 이동해 SharePlay 버튼이 있는 걸 볼 수 있습니다 그걸 누르면 사람 선택기가 주어집니다
앱에서 SharePlay를 시작할 수 있는 훌륭한 경험을 갖게 되었습니다 그러나 이게 유일한 업데이트는 아닙니다 GroupSessionMessenger 업데이트를 얘기해 보겠습니다 GroupSessionMessenger에 흥미로운 새 업데이트 두 가지가 있습니다 첫 번째 업데이트에서 이 마법의 숫자를 봤을지 모릅니다 GroupSessionMessenger로 보낼 수 있는 페이로드 크기였죠 이젠 아닙니다 이제 페이로드 크기가 256KB로 4배 더 커졌습니다 이 변화로 앱이 메시지를 더 작은 메시지로 나눌까 봐 걱정할 필요가 없습니다 단순히 메시지를 보내고 훌륭한 경험 구축에 집중할 수 있죠 그걸로는 큰 감흥이 없었다면 다음 업데이트에서는 놀라실 거라고 확신합니다 신뢰할 수 없는 메시징 GroupSessionMessenger의 일부로 이제 메시지의 신뢰성을 선택할 수 있습니다 이를 통해 원하는 경험에 따라 신뢰할 수 있는 메시징과 신뢰할 수 없는 메시징 중에서 선택할 수 있습니다
GroupSessionMessenger에서 새로운 이니셜라이저를 활용하기만 하면 됩니다 MessageReliability를 지정할 수 있습니다
API를 사용하는 방법을 알았는데 경험은 어떨까요? 신뢰할 수 없는 메시지를 언제 사용해야 할까요? 훌륭한 질문입니다
FaceTime 및 SharePlay에서 실시간 작업을 수행하고 있습니다 세 사람이 있다고 상상해 보세요 에이미, 브라이언, 크리스 세 사람은 모두 세션에 참여하고 동기화됩니다 시간이 지남에 따라 영화도 진행되죠 그러나 에이미가 어떤 특정 순간에 뭔가를 하고 싶어 하면 어떻게 될까요? 신뢰할 수 있는 메시징을 사용한다면 메시지가 모든 장치에서 수신됩니다 하지만 기대하는 시간에 도착할 거라는 의미는 아닙니다 예를 들어 크리스는 메시지를 받았지만 브라이언은 처음에 메시지를 받지 못하고 나중에 제대로 수신합니다 영화는 여전히 재생 중이라는 걸 기억하세요 이제 에이미가 메시지를 반영하려고 의도했지만 브라이언은 메시지를 받지 못했습니다 메시지를 나중에 받으면 그땐 너무 늦습니다 이게 신뢰할 수 없는 네트워킹을 쓰기에 완벽한 경우입니다 개발자가 상대방이 안정적으로 수신해야 하는 정보와 그렇지 않은 정보가 어느 것인지 알 수 있게 해줍니다 사용자 경험이 지연 시간에 크게 영향을 받는 프로토콜을 설계할 때 이해해야 하는 중요 개념입니다 신뢰할 수 없는 메시지는 UDP를 사용하며 각 메시지의 대기 시간과 오버헤드가 적습니다 결과적으로 신뢰할 수 없는 메시징을 쓰면 더 실시간으로 경험할 수 있습니다 DrawTogether 앱에 활용하는 법을 얘기해 봅시다 WWDC 21의 이 화면이 기억나실지 모르겠네요 제가 멋지게 그린 이 웃는 얼굴요 화면에 웃는 얼굴을 그릴 때 어떤 일이 발생하는지 조금 살펴보겠습니다
앱에는 GestureRecognizer를 수신하는 코드가 있으며 변경 사항을 발견할 때마다 메시지를 보냈습니다 우리가 웃는 얼굴을 그릴 때 GestureRecognizer가 제공하는 각 포인트에 대해 끊임없이 새 메시지를 보내고 있었다는 뜻입니다 엄청나게 많은 양이죠 이제 더 원활한 그리기 경험을 만들기 위해 신뢰할 수 없는 메시징을 사용하도록 프로토콜을 변경할 수 있습니다
여기서 우리가 할 일은 GestureRecognizer에서 업데이트를 받을 때마다 신뢰할 수 없는 메시징으로 신규 추가 포인트를 보내는 겁니다 제스처가 완료되면 신뢰할 수 있는 메시징을 사용해 클라이언트가 놓친 포인트를 따라잡게 모든 포인트를 제공합니다 이렇게 신뢰할 수 없는 메시징이 제공하는 짧은 지연 시간으로 보다 즉각적인 드로잉 경험을 할 수 있습니다 코드에서 어떻게 하는지 봅시다 먼저 Messages 파일로 이동합니다
계속해서 새 메시지 유형을 정의하겠습니다 이 새 메시지 유형은 이전 메시지 유형과 거의 동일하지만 이번에는 획에 대한 모든 포인트가 포함됩니다 이제 Canvas 파일로 이동합니다
우리가 받을 새 메시지를 처리하기 위해 핸들러 함수를 설정해야 합니다
그리고 신뢰할 수 없는 메신저를 만들어 봅시다 먼저 변수를 생성하겠습니다
이제 시작해 봅시다
완성된 획 메시지를 듣겠습니다
그리고 이전 메시지도 신뢰할 수 없는 메신저로 표시합니다
하지만 메시지를 보낼 방법이 필요합니다 그래서 FinishedStroke를 사용합니다
계속해서 새로운 메시지 유형을 보냅니다
그리고 신뢰할 수 없는 메신저를 사용하기 위해 모든 포인트를 보내는 기존 함수를 변경해 보겠습니다
이제 코드가 작동하는 것을 볼 수 있습니다 DrawTogether 앱에서 얼마나 원활한지 확인할 수 있습니다 이걸로 끝입니다!
이제 약속한 대로 SharePlay 구현을 위한 몇 가지 모범 사례에 대해 이야기하겠습니다 전에 말씀드린 이 용어를 기억하시겠죠 준비된 GroupActivity 앱에서 이 용어는 무엇을 의미할까요? 자, 시나리오를 통해 이야기해 봅시다
왼쪽 장치인 애덤이 오른쪽 장치인 브라이언과 함께 SharePlay를 시작한다고 가정해 보겠습니다 그러나 애덤은 보고 있던 쇼를 재생하려고 합니다 준비된 GroupActivity를 활성화하면 쇼를 처음부터 재생하지 않고 특정 시점부터 재생하고자 합니다 애덤은 쇼가 11분 남았다는 것을 알지만 브라이언의 장치는 그렇지 않아서 문제가 됩니다 브라이언의 장치가 준비된 GroupActivity를 활성화한 경우 쇼가 다시 시작될 수 있습니다 그러면 여기서 어떡하면 될까요? 그것은 여러분의 앱과 경험에 달려 있습니다
몇 가지 아이디어를 살펴보겠습니다 재생 사례의 경우 각 장치가 초기 재생 상태를 기여하도록 해서 다른 장치가 따라잡게 하고 싶습니다 애덤의 장치가 23초를 재생하고 있었다면 세션에 참여할 때 모든 장치에 의도된 재생 상태를 알린다는 뜻입니다 그리고 그걸 정보 소스로 사용합니다 이 원칙이 SharePlay로 생성되는 모든 경험에 적용됩니다 세션에 참여하는 각 사람은 세션에 대한 이해를 다른 사람에게 제공해야 합니다 세션은 피어 투 피어이고 소유자가 없기 때문입니다 그럼 거기에 대해 조금 더 이야기해 보겠습니다 소유자 없는 세션은 이해하기 어려운 개념이지만 적절한 SharePlay 경험을 설계할 때 중요합니다 이 경우 왼쪽에 있는 애덤은 세션을 Apple TV로 전달하려고 합니다 휴대폰은 GroupSession에서 나가지고 TV가 참여하게 됩니다 하지만 소유권을 구현했다면 어떻게 될까요? 주인이 나갔으니… 이건 TV만이 아니라는 걸 기억하세요
iOS 16에서는 이제 FaceTime 핸드오프가 있습니다 애덤이 iPad에서 손을 뗀다고 합시다 같은 상황이 벌어집니다 짜잔 그게 다가 아닙니다 방금은 한 장치에서 다른 장치로 세션을 이동하려고 하는 사용자 흐름의 예시 몇 가지였습니다 그러나 다른 경우도 생각해 봐야 합니다 좋아요, 걱정하지 마세요 예를 들어 간단히 설명할게요 이 화면이 조금 낯익게 느껴질 수 있습니다 FaceTime HUD입니다 하지만 SharePlay 버튼을 클릭하면 어떻게 될까요?
이제 End SharePlay 버튼이 표시됩니다 그렇게 하면 SharePlay를 종료할 수 있습니다 이를 통해 GroupSession에서 .end()를 호출해 모든 사람에 대해 SharePlay를 종료할 수 있습니다 애플리케이션을 대신해서요 .end()를 호출하지 않으려고 아무리 주의를 기울이더라도 해당 장치가 소유자가 아닌 한 시스템이 GroupSession에 .end()를 호출할 수 있습니다 이해하기 어려운 개념일 수 있지만 애플리케이션에 소유권이 없는지 확인하세요 전반적으로 훨씬 더 나은 경험을 제공할 수 있게 됩니다 이제 세션 전체를 들었으니 앱 내에서 SharePlay를 시작할 수 있도록 새 API를 도입하세요 또 신뢰할 수 없는 메시징으로 새롭고 지연 시간이 낮은 앱 통신 방법을 탐색해 보세요
피드백 도우미를 사용해 여러분 모두의 의견을 계속해서 제출해 주세요 모든 변경 사항이 마음에 드시기를 바라며 여러분이 구축한 모든 놀라운 경험을 기대하겠습니다 아직 확인하지 않았다면 다른 WWDC 강연인 Make a great SharePlay experience를 확인하세요 또는 미디어 재생과 관련한 놀라운 개선 사항을 찾고 있다면 Display ads and other interstitials in 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() } }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.