shareplay-activities
Build shared real-time experiences using GroupActivities and SharePlay. Use when implementing shared media playback, collaborative app features, synchronized game state, or any FaceTime, Messages, AirDrop, or nearby visionOS group activity on iOS, macOS, tvOS, or visionOS.
By dpearson2699 · 3,108 installs
npx skills add dpearson2699/swift-ios-skills --skill shareplay-activities
Source repository · Upstream listing
GroupActivities / SharePlay
Build shared real time experiences using the GroupActivities framework. SharePlay
connects people over FaceTime, Messages, AirDrop, and nearby visionOS sharing,
synchronizing media playback, app state, or custom data.
Contents
[Setup]( setup)
[Defining a GroupActivity]( defining a groupactivity)
[Session Lifecycle]( session lifecycle)
[Sending and Receiving Messages]( sending and receiving messages)
[Coordinated Media Playback]( coordinated media playback)
[Starting SharePlay from Your App]( starting shareplay from your app)
[GroupSessionJournal: File Transfer]( groupsessionjournal file transfer)
[Common Mistakes]( common mistakes)
[Review Checklist]( review checklist)
[References]( references)
Setup
Capability
Add the Group Activities capability to the app target in Xcode. Xcode adds
the required entitlement and updates the provisioning profile:
Configure this only for app targets. Group Activities are not available in
widgets, extensions, or App Clips.
Checking Eligibility
Observe changes reactively:
Defining a GroupActivity
Conform to GroupActivity and provide metadata:
Activity Types
Type Use Case
.generic Default for custom activities
.watchTogether Video playback
.listenTogether Audio playback
.createTogether Collaborative creation (drawing, editing)
.exploreTogether Shared browsing, planning, or exploration
.learnTogether Shared learning or studying
.readTogether Shared reading
.shopTogether Shared shopping
.workoutTogether Shared fitness sessions
GroupActivity is Codable ; stored activity data must be codable. Add
Transferable only for SwiftUI ShareLink , SharePlay over AirDrop, or
AppKit/UIKit share sheets. Keep payloads minimal: use identifiers or URLs
instead of large data.
Session Lifecycle
Listening for Sessions
Set up a long lived task to receive sessions when another participant starts
the activity:
Session States
State Description
.waiting Session exists but local participant has not joined
.joined Local participant is actively in the session
.invalidated(reason:) Session ended (check reason for details)
Handling State Changes
Leaving and Ending
Sending and Receiving Messages
Use GroupSessionMessenger to sync small, time sensitive app state between
participants.
Defining Messages
Messages must be Codable ; keep each message under 256 KB.
Sending
Receiving
Delivery Modes
Use .reliable for state changing actions such as selections or turns. Use
.unreliable for high frequency ephemeral data such as cursor positions,
drawing strokes, and reactions.
Coordinated Media Playback
For video/audio, use AVPlaybackCoordinator with AVPlayer :
Once connected, AVFoundation synchronizes play/pause, seeking, rate, playback speed,
and time. Do not put AVPlayer transport fields in messenger messages or snapshots,
including late joiner snapshots; use custom messages only for state outside playback.
Starting SharePlay from Your App
Using GroupActivitySharingController (UIKit)
When no conversation is active (i.e., isEligibleForGroupSession is false),
use GroupActivitySharingController to let the user pick contacts first:
Use the shareplay SF Symbol for custom controls. Treat GroupActivityMetadata
as discovery copy: concise title, subtitle, image, and type aligned with the
entry point. Keep sibling domains out: GameKit owns auth, matchmaking,
leaderboards, achievements, and voice/chat; TabletopKit owns seats, board
equipment, spatial placement, turns, rules, and authoritative tabletop state;
AVKit owns playback UI. SharePlay owns invitations, lifecycle, participants, and
coordination handoffs. See [references/shareplay patterns.md](references/shareplay patterns.md) for SwiftUI ShareLink , AirDrop, and direct activation patterns.
GroupSessionJournal: File Transfer
For larger, non time sensitive attachments, use GroupSessionJournal instead
of GroupSessionMessenger . Journal items must conform to Transferable , are
available to late joiners, and are limited to 100 MB. It requires iOS/iPadOS/tvOS
17+, macOS 14+, or visionOS 1+. For larger/protected assets, share a pointer or manifest and use server storage or app managed file transfer.
Common Mistakes
DON'T: Forget to call session.join()
Configure the stored session, messenger, and observers, then call join() . The
canonical long lived manager in Session Lifecycle shows the required order.
DON'T: Forget to leave or end sessions
DON'T: Assume all participants have the same state
DON'T: Use SharePlay transports for large/protected assets
DON'T: Send redundant messages for media playback
DON'T: Observe sessions in a view that gets recreated
Own the sessions() listener in a long lived manager, not a recreatable view.
Use the manager lifecycle shown above and cancel its child tasks on invalidation.
Review Checklist
[ ] Group Activities capability added to the app target only
[ ] GroupActivity struct is Codable with meaningful metadata
[ ] Transferable conformance added when using ShareLink , AirDrop, or share sheets
[ ] sessions() observed in a long lived object (not a SwiftUI view body)
[ ] session.join() called after receiving and configuring the session
[ ] session.leave() called when the user navigates away or dismisses
[ ] GroupSessionMessenger messages stay under 256 KB with appropriate deliveryMode
[ ] Late joining participants receive current state on connection
[ ] $state and $activeParticipants publishers observed for lifecycle changes
[ ] GroupSessionJournal used for non time sensitive Transferable attachments
[ ] AVPlaybackCoordinator used for media sync (not manual messages)
[ ] GroupStateObserver.isEligibleForGroupSession checked before showing SharePlay UI
[ ] GroupActivitySharingController used when no conversation is active
[ ] Session invalidation handled with cleanup of messenger, journal, and tasks
References
Extended patterns (SwiftUI sharing, collaborative canvas, spatial Personas): [references/shareplay patterns.md](references/shareplay patterns.md)
[Configuring Group Activities](https://sosumi.ai/documentation/xcode/configuring group activities)
[GroupActivities framework](https://sosumi.ai/documentation/groupactivities)
[GroupActivity protocol](https://sosumi.ai/documentation/groupactivities/groupactivity)
[GroupSession](https://sosumi.ai/documentation/groupactivities/groupsession)
[GroupSessionMessenger](https://sosumi.ai/documentation/groupactivities/groupsessionmessenger)
[GroupSessionJournal](https://sosumi.ai/documentation/groupactivities/groupsessionjournal)
[GroupStateObserver](https://sosumi.ai/documentation/groupactivities/groupstateobserver)
[GroupActivitySharingController](https://sosumi.ai/documentation/groupactivities/groupactivitysharingcontroller ybcy)
[Defining your app's SharePlay activities](https://sosumi.ai/documentation/groupactivities/defining your apps shareplay activities)
[Presenting SharePlay activities from your app's UI](https://sosumi.ai/documentation/groupactivities/promoting shareplay activities from your apps ui)
[Synchronizing data during a SharePlay activity](https://sosumi.ai/documentation/groupactivities/synchronizing data during a shareplay activity)
[Supporting coordinated media playback](https://sosumi.ai/documentation/avfoundation/supporting coordinated media playback)
[SharePlay HIG](https://sosumi.ai/design/human interface guidelines/shareplay)