AI iMessage|July 15, 2026|Linq

Putting your iMessage agent in the Dynamic Island

Putting your iMessage agent in the Dynamic Island

Putting your iMessage agent in the Dynamic Island
Linq recently published an engineering look at a BodyBuddy feature we are especially excited about: turning the Dynamic Island into a live companion for an iMessage coaching session. This is the BodyBuddy-side overview; for the complete technical walkthrough, read the original post on Linq.
Video preview
BodyBuddy’s Dynamic Island experience running alongside an iMessage coaching conversation.

What BodyBuddy built

BodyBuddy is an AI health accountability coach you text over iMessage. The conversation happens in Messages, while the BodyBuddy iOS app connects the experience to HealthKit and the rest of your health data. That combination lets coaching feel as natural as texting a person without giving up the richer state an app can maintain.
During an active coaching conversation, the Dynamic Island can keep calories, meals, and current progress visible at the top of the screen. When you log a meal in the thread, the state in the Island updates with it. Messages carries the conversation; the Island carries the compact, glanceable state produced by that conversation.

Why iMessage makes this possible

A Live Activity stays visible while its owning app is in the background. If our coaching chat lived inside the BodyBuddy app, opening that chat would bring our app to the foreground and collapse our own Dynamic Island presentation.
Instead, we coach through iMessage. Messages stays in the foreground while the BodyBuddy app remains backgrounded, so you can read and reply to us while our Live Activity stays visible above the conversation. Linq provides the iMessage-native conversation layer that lets us run both surfaces together.

The two-channel architecture

The experience is built from two independent channels joined by the BodyBuddy backend:
  • Conversation: Linq delivers inbound iMessage webhooks and sends the coach’s replies back to the thread.
  • Ambient state: ActivityKit and Apple Push Notification service update the Live Activity’s content state.
Linq does not render the Dynamic Island, and ActivityKit does not manage the conversation. BodyBuddy’s server connects them. For a typical inbound text, the flow looks like this:
  1. The user texts the BodyBuddy coaching number.
  1. Linq sends BodyBuddy a message-received webhook.
  1. The coach processes the message, records any relevant health event, and calculates the latest user state.
  1. BodyBuddy sends the conversational reply through Linq.
  1. BodyBuddy separately pushes the updated Live Activity state through APNs, and iOS redraws the Island in place.
The reply and the Live Activity update are independent, so they can happen in parallel: one updates the conversation and the other updates the ambient state.

Joining an iMessage user to a Live Activity

The important bridge is identity. An inbound Linq webhook identifies the sender by phone number, while ActivityKit gives the app a push token for an active Live Activity. During onboarding, BodyBuddy associates the phone number with the signed-in app user. When the app starts a Live Activity, it registers that activity’s token to the same account.
That creates the lookup the backend needs: phone number → BodyBuddy user → active Live Activity token. When a coaching text arrives, the server can resolve the sender, update their health state, and target the right Dynamic Island. As with every inbound integration, webhook signatures should be verified before the payload is trusted.

Requesting permissions

If you are building this flow, prepare your agent to walk users through the one-time Live Activities permission step. When the prompt appears on the Lock Screen, the user needs to tap Allow.
Without that permission, the Dynamic Island can still appear, but iOS permits less frequent updates. This can make the experience feel stale or inconsistent, so explain what the prompt is for before it appears. Users only need to complete this setup once.
The one-time “Allow Live Activities from BodyBuddy?” prompt on the Lock Screen.
The one-time “Allow Live Activities from BodyBuddy?” prompt on the Lock Screen.

Designing for a glance

The compact and minimal Dynamic Island presentations have very little room. They work best when they show one number, ring, or status that can be understood immediately. Expanded content can add supporting detail after a deliberate long-press.
The state also needs a clear freshness policy. ActivityKit updates can include a stale date so the UI does not keep presenting old values as current. Push-to-start support can bring the Live Activity up when a coaching session begins, and an end event can remove it when the session is over.

Where this pattern works best

The pattern is useful whenever a conversational agent produces state that changes throughout a session: a calorie total, streak, order amount, delivery ETA, remaining balance, or checklist progress. If someone would otherwise scroll backward through the thread to reconstruct a number, that number may belong in an ambient surface.
It is less useful for one-off questions or anything already represented by the latest message. The Dynamic Island should complement the thread, not repeat it.
Read Linq’s full engineering post for the ActivityKit layout, APNs payloads, identity-join details, and implementation references: Putting your iMessage agent in the Dynamic Island.

Want daily accountability?

BodyBuddy texts you every day.

Build a healthier relationship with food and movement — one text at a time.

or download the iOS app
Join 500+ usersstaying healthy