ActivityKit

RSS for tag

Help people keep track of tasks and events that they care about with Live Activities on the Lock Screen, the Dynamic Island, and in StandBy.

Posts under ActivityKit tag

107 Posts

Post

Replies

Boosts

Views

Activity

Using App Intents in Live Activity to Pause a Timer
Hello, I am trying to test a concept of a timer stopwatch with Live Activities and integrating buttons like Pause/Resume. When the stopwatch starts, a new Live Activity is created. The stopwatch is managed by the ViewModel, which has functions like start(), pause(), resume(), reset(), and also startLiveActivity(), etc. It uses @AppStorage to store keys like stopWatchModeRaw values, startTimeInterval, etc. The Live Activity state is stored here in the view model using: private var currentActivity: Activity? = nil The Live Activity is started using: private func startActivity() async { guard currentActivity == nil, Activity<StopwatchAttributes>.activities.isEmpty else { if currentActivity == nil { findAndAssignExistingActivity() await updateActivity() } return } let attributes = StopwatchAttributes() let state = StopwatchAttributes.ContentState( .... pass in the content state variables .... ) let content = ActivityContent(state: state, staleDate: nil) do { let activity = try Activity<StopwatchAttributes>.request( attributes: attributes, content: content, pushType: nil ) // Store the activity instance self.currentActivity = activity } catch { print("Error requesting Live Activity: \(error.localizedDescription)") } } and FindAndAssignExistingAcivity does: private func findAndAssignExistingActivity() { if let existingActivity = findActivity(), existingActivity.activityState == .active || existingActivity.activityState == .stale { print("Found existing activity on launch: \(existingActivity.id)") self.currentActivity = existingActivity } else { print("No existing activity found on launch.") self.currentActivity = nil } } UpdateActivity if the activity exists with a guard statement, and then update the activity. This is also used when the user taps Pause in the Stopwatch. The main issue I am facing is with the PauseIntent, it can't find the Live Activity and will always exit at that guard statement. struct PauseIntent: AppIntent { static var title: LocalizedStringResource = "Pause Stopwatch" func perform() async throws -> some IntentResult { guard let defaults = UserDefaults(suiteName: appGroupID) else { return .result() // Simple failure } let currentModeRaw = defaults.integer(forKey: "stopwatchModeRawValue") let currentMode = StopwatchMode(rawValue: currentModeRaw) ?? .reset let startTimeInterval = defaults.double(forKey: "startTimeInterval") // TimeInterval when current running segment started let accumulatedTime = defaults.double(forKey: "accumulatedTime") guard let activity = Activity<StopwatchAttributes>.activities.first else { Self.logger.error("PauseIntent EXIT: No Live Activity found to update. (Activity<StopwatchAttributes>.activities is empty)") return .result() // EXITING HERE, No Live Activity Found, there was nothing found to update... -> It always exits here } followed by rest of the code to update the state of the live activity, but it never executes because the activity = Activity.activities.first always returns false. What seems to be the issue? 1 .Is the method wrong to check for the live activity before attempting to Pause? 2. Can the Live Activity actually Pause the Stopwatch Timer in the main App since the Live Activity is actually a Widget Extension and not the App itself, so it cannot see the data directly?
1
0
128
May ’25
Can I listen to user choice when asked for update permissions on Live Activity?
We would like to better understand the discrepancy between a Push To Start and the subsequent Updates where I see a number of recipients drop greatly. Our assumption is that this is a result of the end user not clicking the "Allow" prompt when a push to start widget is shown on the screen for the first time, but we currently do not have a way to listen to the user's choice when prompted. Is there any way of tapping into this, to determine if this is in fact where the variance is coming from, or if there is actually just a problem with the request to retrieve the update token from our end?
1
0
81
Apr ’25
Live Activity animate without updating data
Is it actually possible to display animation (even a simple one) on Live Activity? But on these cases: The main app is terminated - of course, I know I can use the main app to keep updating the Live Activity to make simple animations work, but in this case, the main app is killed. Live Activity data is not updating - I also understand that the Live Activity can perform animations when its data is being update via push notification or other means, but the current case is the data is not being updated. I’ve tried several ways to achieve this, but nothing seems to work. Just when I was about to give up, I found this video from Apple’s official channel: https://www.youtube.com/watch?v=m6WMwSj_EbA At 4:14 in this video, you can see the text "Locating Driver" with the breathing animation. Could someone please help me understand how to implement that kind of animation in a Live Activity when: The main app is not running, and The Live Activity data is not updating?
0
0
146
Apr ’25
Dynamic island not displaying UI views
i finally got previews for dynamic island to work and I'm just trying to first work on adding a static UI elements to my dynamic island like i did for my live screen live activity, but my dynamic island view is showing up totally empty, if i add my app icon image to the compact leading closure, it doesn't appear, if i ad text to an expanded region closure it doesn't appear. am really stuck on this and would approeciate the help. var body: some View { Image("dynamicrep") .resizable() .scaledToFit() .clipShape(.circle) } } struct DynamicRepLiveActivity: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: DynamicRepAttributes.self) { context in VStack { HStack(spacing: 257) { Text("from \(context.attributes.titleName ?? "no title")") .fontWeight(.light) .font(.system(size: 16)) .foregroundStyle(Color.gray) Circle() .frame(width: 53, height: 50) .foregroundStyle(Color.gray).opacity(0.23) .overlay { Image("mmicon") } } .frame(maxWidth: 500, maxHeight: 210) Spacer() Text("\(context.attributes.contentBody ?? "no content")") } .activityBackgroundTint(Color.cyan) .activitySystemActionForegroundColor(Color.black) .frame(width: 500, height: 300) } dynamicIsland: { context in DynamicIsland { // Expanded UI goes here. Compose the expanded UI through // various regions, like leading/trailing/center/bottom DynamicIslandExpandedRegion(.leading) { Text("from \(context.attributes.titleName ?? "no title")") } DynamicIslandExpandedRegion(.trailing) { Circle() } DynamicIslandExpandedRegion(.bottom) { Text("\(context.attributes.contentBody ?? "no content")") } } compactLeading: { AppLogo() } compactTrailing: { Text("") //empty for now } minimal: { Text("hello") //empty for now } .widgetURL(URL(string: "MuscleMemory.KimchiLabs.com")) .keylineTint(Color.white) } } }
1
0
134
Apr ’25
Live Activity - ActivityState - case .dismissed
Hi everyone, I'm working with Live Activities using the ActivityKit(Activity), and I'm trying to find a way to detect when a user manually dismisses a Live Activity by swiping it away — either from the Lock Screen or the Dynamic Island. Currently, when a Live Activity ends, the activityState changes to .dismissed, which is defined as: /// The Live Activity ended and is no longer visible because a person or the system removed it. case dismissed This doesn’t allow me to determine whether the dismissal was triggered by the user or by the system. Is there any way — either through ActivityState, notifications, or another approach — to distinguish if a Live Activity was manually dismissed by the user vs. ended by the system? Thanks in advance!
0
0
193
Apr ’25
Live Activity - Firebase Cloud Messaging, APNs iOS 18+
Hello, We are using the Firebase Admin SDK (firebase-admin framework) to send push notifications via Firebase Cloud Messaging (FCM) for Live Activity updates in our iOS app. With the introduction of iOS 18, a new key "input-push-token": 1 has been added to the Live Activities push payload structure. 1) Can this new key ("input-push-token": 1) be used when sending payloads via FCM? We noticed that FCM is still using the push update format introduced in iOS 17.2. Will FCM be updated to support the new push structure introduced with iOS 18? Or is the "input-push-token" feature only available when sending notifications via direct APNs? 2) We are concerned about the expiration of the Live Activity start push token. If a user doesn't open the app for a long time, the token may expire, and this could result in failed updates. That’s why we are looking into the new "input-push-token" behavior in iOS 18. Do you have any recommendations on how to manage or prevent token expiration? Is there any official guidance on the lifespan of the Live Activity push tokens? Will FCM support the delivery of start/update/end Live Activity actions even when the app is completely terminated? We would highly appreciate any official clarification or roadmap regarding this. It would help us determine whether we should wait for FCM support or switch to sending notifications directly via APNs. Thank you for your help!
1
0
240
Apr ’25
How to Keep Live Activity in Expanded Dynamic Island State (ActivityKit, iOS 17+)
I'm building a Live Activity using ActivityKit in iOS, and I'm trying to understand how apps like Uber or Lyft manage to keep the Dynamic Island always in its expanded state, without transitioning through the compact phase. In my implementation, the Live Activity always starts in the compact state, and only expands temporarily when I interact with it. I've tried the following: Updating the ContentState frequently using activity.update(using:) I tried updating the activity every 1 second, but it didn’t make a difference. Leaving the compactLeading, compactTrailing, and minimal regions empty using EmptyView() — also didn’t change the behavior. Delaying the initial update by 1 second — no effect. What I'm trying to figure out: Is there any way to programmatically force or request the Dynamic Island to stay in the expanded state? Could this behavior be achieved through push updates, using apns-push-type: liveactivity and a high priority (apns-priority)? What I’m trying to achieve is similar to the behavior shown in the images below — the apps do not transition to the compact island, but instead displays the expanded view immediately. Example:
0
0
78
Apr ’25
Interactive Live Activity Bug in iOS 18 - perform not called
In iOS 18 (beta 1-4) when you set openAppWhenRun = false in your AppIntent of your live activity the perform function never gets called. In iOS 16 and 17 my live activities work. I have downloaded other apps and in their live activities any button tab which doesn´t open the app is also doing nothing in iOS 18. Has anyone got this working? Any comments from an Apple engineer on this?
4
2
1.4k
Apr ’25
How can you tick between live activities?
I have been watching the following moment from wwdc (Design dynamic Live Activities): https://developer.apple.com/videos/play/wwdc2023/10194/?time=728 It suggest that you should 'tick' between multiple live activities of your app: When you want to show multiple sessions for your app going on at once, consider ticking between the display of them to continue to give users an eye on everything that’s going on. How can I tick between them? More specifically how can I do that when my app is in the background?
1
1
241
Apr ’25
Unable to start a live activity
I'm unable to get live activity to show up in my app so I started to play with the demo app Emoji Rangers. The demo project initially only created a live activity in-app and then you're able to update it via the demo buttons. I added the following code to have it be able to start a live activity from the backend: func observePushToStartToken() { Task { for await data in Activity.pushToStartTokenUpdates { let token = data.map {String(format: "%02x", $0)}.joined() // Send token to the server print("got PUSHTOSTART TOKEN: (token)") } } } I get the token and then I use it to send this payload that should start the activity: { "aps":{ "timestamp":1743719911, "event":"start", "content-state":{ "currentHealthLevel":100, "eventDescription":"Adventure has begun!", "supercharged":true }, "input-push-token":1, "attributes-type":"AdventureAttributes", "attributes":{ "currentHealthLevel":100, "eventDescription":"Adventure has begun!", "supercharged":true }, "alert":{ "title":{ "loc-key":"%@ is on an adventure!", "loc-args":[ "Power Panda" ] }, "body":{ "loc-key":"%@ found a sword!", "loc-args":[ "Power Panda" ] }, "sound":"chime.aiff" } } } But unfortunately I get an error when I send it: [AdventureAttributes] Error creating activity: NSCocoaErrorDomain (4865) The data couldn't be read because it is missing. First step is to get this working, so I want to get your help in figuring out what I'm missing.
1
0
73
Apr ’25
iOS Team Provisioning Profile oesn't include the com.apple.developer.activitykit entitlement.
I would like to add a Live Activity to my app, but unfortunately I always get an error message. When I go into the Identifiers via the Developer Portal and look at my app, there is no Activity Kit or Live Activity in the Capabilites that I could activate. In XCode I don't see the option for Signing & Capabilities either... Can anyone help me how to add this correctly? Thanks in advance!
1
0
190
Apr ’25
Live Activity Start Token not generating after certain days of usage for non Production builds
Live Activity Start Token not generating after certain days of usage. We have implemented Live Activity feature where the initial activity is launched by our backend. But to start that first live activity I need push to start token which is generating for few days but all of sudden after certain days it stops generating. Currently we are in development phase so we test it on multiple devices and multiple time we are doing install and uninstall. STEPS TO REPRODUCE Install the app Start token gets generated which is sent to our server After certain duration server sends the first live activity using that token user opens the app then we receive the updated token and send that token to server server uses that updated token to further update the live activity. All this works fine. But after a week of usage we are observing that we stop getting start token from APNS. Not sure where exactly the thing is breaking. We have tried with different devices and different bundle identifiers but behaviour is same for all. func generateStartToken() { Task.detached { [weak self] in guard let self else { return } await self.observeActivityPushTokenAndState() for await data in ActivityKit.Activity<LiveActivityAttribute>.pushToStartTokenUpdates { let token = data.map { String(format: "%02x", $0) }.joined() print("Activity Start token: ", token) } } } func observeActivityPushTokenAndState() { Task.detached { for await activity in ActivityKit.Activity<LiveActivityAttribute>.activityUpdates { Task { for await tokenData in activity.pushTokenUpdates { let updatedToken = tokenData.map { String(format: "%02x", $0) }.joined() print("Activity Update token: ", updatedToken) } } Task { for await content in activity.contentUpdates { let updatedContent = content.state print("Activity Updated: ", updatedContent) } } } } }
2
0
182
Apr ’25
Live Activity resets to initial state after 8+ hours in background
Hi Apple team and community, We’re encountering a strange issue with Live Activity that seems related to memory management or background lifecycle. ❓ Issue: Our app updates a Live Activity regularly (every 3 minutes) using .update(...). However, after the app remains in the background for around 8 hours, the Live Activity reverts to the initial state that was passed into .request(...). Even though the app continues sending updates in the background, the UI on the Lock Screen and Dynamic Island resets to the original state.
0
0
69
Apr ’25
LiveActivity start via APNs not working
I am trying to issue the "start" APNs push notification to start a live activity for my iOS app. The notification appears to send correctly, there is no error message, but the live activity never appears for any of my users (users are in TestFlight). In addition to issuing the APNs commands from my server, I have also tried using the CloudKit Push Notification Console to manually generate a "start" notification. It submits correctly but the live activity never starts. I have also checked the Console app to watch the device logs and see if iOS is rejecting/throttling the live activity but I don't see any activity related to the start message at all. Here are some details: App bundle ID: `com.penzu.moodmoji` APNs topic: `com.penzu.moodmoji.push-type.liveactivity` APNs push type: `liveactivity` Recent apns-id: `7b633309-b7fd-4163-b620-776efa04f315` APNs payload: { "aps": { "timestamp": 1742651625, "event": "start", "content-state": { "totalDays": 7, "currentDay": 2, "progress": 0.29, "status": "ACTIVE", "reportReady": false }, "attributes-type": "GoalActivityAttributes", "attributes": { "totalDays": 7, "currentDay": 2, "progress": 0.29, "status": "ACTIVE", "reportReady": false }, "alert": { "title": "It's day 2!", "body": "Don't forget to record every time you feel anxious today." } } } I can confirm that LiveActivities started by the iOS app with ActivityKit work correctly, and the app does appear to be receiving pushToStartTokenUpdates: struct GoalActivityAttributes: ActivityAttributes, Sendable { struct ContentState: Codable & Hashable, Sendable { let totalDays: Int let currentDay: Int let progress: Double let status: String let reportReady: Bool } let goal: SimpleGoal } for await nextStartToken in Activity<GoalActivityAttributes>.pushToStartTokenUpdates { // send nextStartToken to server... } The app I'm testing with is in TestFlight, using the production APNs environment.
1
0
145
Mar ’25
Push Live Activity not showing up
This is in an iOS Simulator running iOS 18.2 I send a start live activity push notification from the Push Notifications Console on icloud.developer.apple.com. When checking the console.log output it seems to receive the message, yet the activity does not appear in the dynamic island. (the app is backgrounded when I test this) Can anyone tell me why it's not showing? Starting the same activity from within the app using Swift code works fine. Here is the console.app output: default 11:01:59.060954+0100 apsd <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0>: Sending push to client. UUID: (null) default 11:01:59.061012+0100 apsd Dispatching high priority message on server: <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0> default 11:01:59.061770+0100 apsd Looking up connection on peer: 4304b50 found <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0> default 11:01:59.062283+0100 liveactivitiesd APSXPCDeliverMessageEvent: Created APSIncomingMessage. UUID: (null) default 11:01:59.062642+0100 liveactivitiesd <APSConnection: 0x600003d18000> Delivering message from apsd: <APSIncomingMessage: 0x600000c2e9a0> 2897852514 com.****.****.push-type.liveactivity default 11:01:59.062763+0100 liveactivitiesd <APSConnection: 0x600003d18000> Delivering message from apsd. UUID: (null) default 11:01:59.063374+0100 liveactivitiesd <APSConnection: 0x600003d18000> making delegate (<SessionPushNotifications.APSPushConnection: 0x600000227460>) calls to deliver message 2897852514 { aps = { alert = { "loc-key" = "recording_started_message"; "title-loc-key" = "recording_started_title"; }; attributes = { isRecording = 1; }; "attributes-type" = SWAutomaticTripRecorderActivityAttributes; "content-state" = { distance = 0; }; event = start; timestamp = 1742374701; }; } for topic com.****.****test.push-type.liveactivity default 11:01:59.063440+0100 liveactivitiesd <APSConnection: 0x600003d18000> calling <SessionPushNotifications.APSPushConnection: 0x600000227460> connection:didReceiveIncomingMessage: default 11:01:59.063740+0100 liveactivitiesd Acquiring keep-alive with reason: Received message default 11:01:59.063785+0100 liveactivitiesd Keep-alive reasons: ["Received message": 1] default 11:01:59.063803+0100 liveactivitiesd <APSConnection: 0x600003d18000> returned from <SessionPushNotifications.APSPushConnection: 0x600000227460> connection:didReceiveIncomingMessage: default 11:01:59.063883+0100 liveactivitiesd <APSConnection: 0x600003d18000> responding with an ack for message with guid E19D7D04-12A0-4F1B-B33C-F6BF57EE2EFF default 11:01:59.063921+0100 liveactivitiesd <APSConnection: 0x600003d18000> responding with an ack. UUID: (null) default 11:01:59.063996+0100 apsd Looking up connection on peer: 4304b50 found <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0> default 11:01:59.064019+0100 apsd <APSUserCourier 0x100f052a0 development 0> informed that <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0> acknowledges incoming message with guid E19D7D04-12A0-4F1B-B33C-F6BF57EE2EFF tracingUUID (null) default 11:01:59.064063+0100 liveactivitiesd Received message: topic: Topic(unsuffixed: "com.****.****test"); channelID: nil; token: Optional(128 bytes); eventType: start(SessionPushNotifications.IncomingMessage.EventType.StartParameters(attributesType: "SWAutomaticTripRecorderActivityAttributes", attributesData: 20 bytes, inputs: [])) for environment: development default 11:01:59.064198+0100 liveactivitiesd Received push event for com.****.****test::pushToStart default 11:01:59.064232+0100 liveactivitiesd Adding push-to-start budget for com.****.****test::pushToStart default 11:01:59.064273+0100 liveactivitiesd Acquiring keep-alive with reason: Database default 11:01:59.064296+0100 liveactivitiesd Keep-alive reasons: ["Database": 1, "Received message": 1] default 11:01:59.064313+0100 liveactivitiesd Acquiring keep-alive with reason: Database default 11:01:59.064330+0100 liveactivitiesd Keep-alive reasons: ["Database": 2, "Received message": 1] default 11:01:59.064342+0100 liveactivitiesd Reduced budget for com.****.****test::pushToStart to: 9 default 11:01:59.064358+0100 liveactivitiesd Topic com.****.****test.push-type.liveactivity has remaining budget for pushToStart of 9 default 11:01:59.064369+0100 liveactivitiesd Topic com.****.****test.push-type.liveactivity has not used any budget for activity default 11:01:59.064436+0100 liveactivitiesd Scheduling wake to re-evaluate push subscription budgets at 2025-03-19 11:01:59 +0000 default 11:01:59.064547+0100 liveactivitiesd Earliest nonwaking date from task "Push server budget timeout expiration": 2025-03-19T12:01:59+01:00, finalWakeTarget: 2025-03-19T12:01:59+01:00 3599.999696 default 11:01:59.064593+0100 liveactivitiesd Earliest waking date from task "Push server budget timeout expiration": 2025-03-19T12:01:59+01:00, finalWakeTarget: 2025-03-19T12:01:59+01:00 3599.999651 default 11:01:59.064620+0100 liveactivitiesd Scheduling nonwaking task for: 2025-03-19T12:01:59+01:00 in 3599.999622s default 11:01:59.064659+0100 liveactivitiesd Scheduling waking task for: 2025-03-19T12:01:59+01:00 in 3599.999584s default 11:01:59.064671+0100 liveactivitiesd Acquiring keep-alive with reason: wake scheduling default 11:01:59.064692+0100 liveactivitiesd Keep-alive reasons: ["Database": 2, "Received message": 1, "wake scheduling": 1] default 11:01:59.064734+0100 liveactivitiesd Scheduling waking task for adjusted date: 2025-03-19T12:01:59+01:00 in 3599.999508s default 11:01:59.064768+0100 liveactivitiesd xpc_activity_register: com.apple.sessionkit.wake, criteria: dictionary default 11:01:59.064843+0100 liveactivitiesd Received pushToStart notification for com.****.****test::pushToStart default 11:01:59.064955+0100 liveactivitiesd Keep-alive reasons: ["Database": 2, "Received message": 1] default 11:01:59.064979+0100 liveactivitiesd Publishing event: timestamp: 2025-03-19 08:58:21 +0000; activityIdentifier: F432AB2F-1799-4437-B54B-6D9D70A0B260; eventType: start(SessionPushNotifications.PushEvent.EventType.ActivityStartParameters(attributesType: "SWAutomaticTripRecorderActivityAttributes", attributesData: 20 bytes, contentSourceRequests: [ActivityKit.ActivityContentSource.Request.push(request: ActivityKit.PushActivityContentSource.Request.push, target: ProcessDescriptor.Request("com.****.****test")), ActivityKit.ActivityContentSource.Request.process(target: ProcessDescriptor.Request("com.****.****test"))]))
1
0
102
Mar ’25
Symbol not found: NSUserActivityTypeLiveActivity and WidgetCenter.UserInfoKey.activityID
The app I'm working on has iOS 16.0 as target. Recently Live Activities support was added, but then it started crashing when running on iOS 16.0 devices. After some investigation, I've found that the culprit was the presence of NSUserActivityTypeLiveActivity and WidgetCenter.UserInfoKey.activityID, even though they were inside an @available(iOS 17.2, *) block. If I comment these two variables, the app work as expected. I've also tried adding #if canImport(ActivityKit) around the code, but without success. But if the @available isn't working, how can I prevent this? It looks like a bug, since the documentation says that NSUserActivityTypeLiveActivity is supported but iOS 14.0+, but I'm pretty sure it was introduced on 16.1. This is the only output I get with the crash: dyld[66888]: Symbol not found: _$s9WidgetKit0A6CenterC11UserInfoKeyV10activityIDSSvgZ Referenced from: <D6EFF120-2681-34C1-B261-8F3F7B388238> /Users/<redacted>/Library/Developer/CoreSimulator/Devices/8B5B4DC9-3D54-4C91-8C88-E705E851CA0F/data/Containers/Bundle/Application/DB6671FF-CB07-4570-BD63-C851D94FAF29/<redacted>.app/<redacted>.debug.dylib Expected in: <C5E72BB5-533F-3658-A987-E849888F4DFC> /Library/Developer/CoreSimulator/Volumes/iOS_20A360/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 16.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/WidgetKit.framework/WidgetKit
0
0
111
Mar ’25
How to properly share code between launch in background and launch in foreground?
I've been reading this question: https://developer.apple.com/forums/thread/701945 and watching the videos on background tasks But can't arrive to a concrete solution. Q1: Are there any tips (or sample app) on how to handle a launch in background in a streamlined way? How to have a shared code that is ran for both 'launch in background' & 'launch in foreground'? Specifically the case I'm talking about is: You set up some observance of some OS callback at a Foo screen of your app. Example app should request and then send push-to-start live activity tokens to server. Or setup location tracking. App is then suspended and then later terminated but is eligible for relaunch App is then launched in background because it has requested a push-to-start live activity token or an update for location tracking. User DOES NOT go back to screen Foo. So at this point app is no longer tracking / listening to updates for token update or location changes. How should I architecture my code for this? I'm trying to see if there's a an approach where I can avoid having multiple places in code where I do the same thing. Currently what I'm doing is as such: Q2: Is it then correct to say that anytime you've launched your app, whether it's in foreground or background then you must immediately match 'all observations done by the previous app launch'? Like store items in UserDefaults and upon launch retrieve them and do: handleGeneralAppLaunchFlow() // ALSO if defaults.contains("didLastLaunchSetupLiveActivtiyTokenObservance") { for await ptsToken in Activity<EmojiRangers> .pushToStartTokenUpdates { ... } } if defaults.contains("didLastLaunchSetupLocationTracking") { locationManager = CLLocationManager() locationManager?.delegate = itsDelegate locationManager?.allowsBackgroundLocationUpdates = true locationManager?.showsBackgroundLocationIndicator = true locationManager?.startUpdatingLocation() } // Other checks for prior observance setup Q3: Actually I think even if app is launched in foreground then because you may not end up at screen Foo again, then you must setup things regardless of app state and just based on prior observations set. Right? Q4: And then later if the user ever made it again to screen Foo, then we just skip the re-do of the observance, or maybe to just keep things simple, we'd just redo without over-engineering things? I tried to mark my questions with Q1- Q4.
1
0
217
Mar ’25
Start multiple Live Activities in the perform() of App Intents
In my case, when two functions that start each Live Activity(not connected each other) are performed in LiveActivityIntent's perform(), it seems that only one will start. (It's the same to start independently with two Task{}) And, set one to 'opensIntent' and separate it by opening another LiveActivityIntent, the result is same. Also, every time I tap the Intent directly in the shortcut app, one activity will end within a matter of seconds, even if there are two for a while. But, If openAppWhenRun to true, it seem to works without any problems. I would appreciate it if you could give me a tip to fix this problem.
0
0
214
Mar ’25