Timelines: Working with Notifications
Sending notifications from code to trigger a behavior, and sending notifications from a timeline to trigger code.
We can set up two-way communication between a code and an entity/timeline from Reality Composer Pro. Let’s start from the Swift side. We’ll send a notification that will trigger a behavior, which will run a timeline.
func notifyTimeline(_ identifier: String) {
if let scene = scene {
NotificationCenter.default.post(
name: NSNotification.Name("RealityKit.NotificationTrigger"),
object: nil,
userInfo: [
"RealityKit.NotificationTrigger.Scene": scene,
"RealityKit.NotificationTrigger.Identifier": identifier
]
)
}
}notifyTimeline("MoveRightMessage")In Reality Composer Pro, we add a Behavior Component to the entity that should receive this. Then we select the Timeline to run.

Now when we call notifyTimeline("MoveRightMessage"), the red sphere will play the MoveRight timeline.
Notice the Notification action at the end of the timeline? We can use this to send another message, this time in the other direction. We just enter an identifier for the notification.

Note: Reality Composer Pro prompts us to select a Target entity. From what we can tell, this entity is not passed with the other notification data. For consistency, we’ll select the same entity the other actions used. Technically this action will fire without a Target set, but you may see a warnings in RCP.
We can listen for a RealityKit.NotificationTrigger using the onReceive modifier. This object contains the scene that sent the notification and the identifier. We can use Scene if we need to do something inside the RealityKit context. We use Identifier to determine what notification was sent.
.onReceive(NotificationCenter.default.publisher(for: Notification.Name("RealityKit.NotificationTrigger"))) { notification in
guard
let userInfo = notification.userInfo,
let scene = userInfo["RealityKit.NotificationTrigger.Scene"] as? RealityKit.Scene,
let identifier = userInfo["RealityKit.NotificationTrigger.Identifier"] as? String
else { return }
switch identifier {
case "ReachedRight":
print("Timeline sent: ReachedRight")
isRight = true
case "ReachedLeft":
print("Timeline sent: ReachedLeft")
isLeft = true
default:
print("Unknown message from timeline: \(identifier) in \(scene)")
break
}
}Video Demo
Full Example Code
Make sure to check out the SimpleTimeline scene in the Reality Composer Pro bundle in the repo.
struct Example119: View {
@Environment(\.realityKitScene) var scene
@State var isLeft: Bool = true
@State var isRight: Bool = false
var body: some View {
RealityView { content in
guard let scene = try? await Entity(named: "SimpleTimeline", in: realityKitContentBundle) else { return }
scene.position.y = -0.4
content.add(scene)
}
.ornament(attachmentAnchor: .scene(.back), ornament: {
VStack(spacing: 12) {
HStack {
Button(action: {
notifyTimeline("MoveLeftMessage")
isLeft = false
isRight = false
}, label: {
Text("MoveLeft")
})
Spacer()
Button(action: {
notifyTimeline("MoveRightMessage")
isLeft = false
isRight = false
}, label: {
Text("MoveRight")
})
}
HStack {
Circle()
.fill(isLeft ? .green : .white)
.frame(width: 60, height: 60)
Spacer()
Circle()
.fill(isRight ? .green : .white)
.frame(width: 60, height: 60)
}
.frame(width: 300)
}
.padding()
.glassBackgroundEffect()
})
// 2. Timelines can use the Notification action to send a message that we can receive here
.onReceive(NotificationCenter.default.publisher(for: Notification.Name("RealityKit.NotificationTrigger"))) { notification in
// We can unpack Scene and Identifier
// We use Identifier to determine what notification was sent
// We can use Scene if we need to do something inside the RealityKit context
guard
let userInfo = notification.userInfo,
let scene = userInfo["RealityKit.NotificationTrigger.Scene"] as? RealityKit.Scene,
let identifier = userInfo["RealityKit.NotificationTrigger.Identifier"] as? String
else { return }
switch identifier {
case "ReachedRight":
print("Timeline sent: ReachedRight")
isRight = true
case "ReachedLeft":
print("Timeline sent: ReachedLeft")
isLeft = true
default:
print("Unknown message from timeline: \(identifier) in \(scene)")
break
}
}
}
// 1. Send notifications to trigger a behavior on an entity, which will run a timeline
func notifyTimeline(_ identifier: String) {
if let scene = scene {
NotificationCenter.default.post(
name: NSNotification.Name("RealityKit.NotificationTrigger"),
object: nil,
userInfo: [
"RealityKit.NotificationTrigger.Scene": scene,
"RealityKit.NotificationTrigger.Identifier": identifier
]
)
}
}
}Support our work so we can continue to bring you new examples and articles.
Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Follow Step Into Vision