APNSwift icon indicating copy to clipboard operation
APNSwift copied to clipboard

Add ability to start live activities

Open nakajima opened this issue 1 year ago • 8 comments

I believe this PR brings things in line with the JSON payload described in the docs.

This makes the APNSLiveActivityNotificationEvent type a bit more clunky to deal with, so I'd love to hear if anyone has any ideas on how to improve that.

I also ran swift-format --configuration .swift-format on my changes which seems to have brought in some unrelated format changes. If this is a PR worth pursuing I'm happy to clean those up.

See also https://github.com/swift-server-community/APNSwift/pull/191.

nakajima avatar Apr 03 '24 21:04 nakajima

~~Ok actually it looks like I need to include an alert as well. On it.~~

Done in https://github.com/swift-server-community/APNSwift/pull/196/commits/93565bda2238e6b4b1995bf553dd3a37981f1048.

nakajima avatar Apr 03 '24 21:04 nakajima

OK, I've verified that this is working in a test app so it's ready for review!

nakajima avatar Apr 03 '24 22:04 nakajima

@FranzBusch Thanks so much for the review! I've moved things around to just introduce a separate object for the additional data a start event needs. I think the one downside to this approach is that if you pass a start event without the startOptions, the push just won't get sent. I don't think that's the end of the world though since that's also what APNS does afaik.

We can't just add these requirements to the generic type. This is a breaking API change otherwise. We can make the conformance to those protocols conditional though and that should work.

Fixed in https://github.com/swift-server-community/APNSwift/pull/196/commits/5af6d92d57faddf3e9412303a8df81e383a87299 and https://github.com/swift-server-community/APNSwift/pull/196/commits/fffc9eaa7f9eaa95892c2e6c52080773e08f43d8.

This is a breaking change and we can't just change from a struct to a protocol. We should try and continue to model it with the current struct type.

Fixed in https://github.com/swift-server-community/APNSwift/pull/196/commits/4671d0ada8a65122fd7ee33e8916d5ec5439bf15.

nakajima avatar Apr 04 '24 16:04 nakajima

Actually this PR is wrong. I think we need to pass the ActivityAttributes as the attributes field, not the content state.

nakajima avatar Apr 04 '24 19:04 nakajima

Ok I've reworked things to support sending the correct attributes value. I added a new type for start notifications because otherwise the existing types would have to know about an Attributes generic value, which I believe would be a breaking change?

nakajima avatar Apr 04 '24 20:04 nakajima

Can confirm this works, was able to start a live activity from a push notification with:

let notification = APNSStartLiveActivityNotification(
    expiration: .immediately,
    priority: .immediately,
    appID: "com.example.example",
    contentState: TestContentState(),
    timestamp: 1_672_680_658,
    attributes: TestAttributes(),
    attributesType: "TestAttributes",
    alert: .init(title: .raw("Test"), body: .raw("Test"))
)
do {
    let response = try await apnsClient.send(
        APNSRequest(
            message: notification,
            deviceToken: kit.token,
            pushType: .liveactivity,
            expiration: notification.expiration,
            priority: notification.priority,
            apnsID: notification.apnsID,
            topic: notification.topic,
            collapseID: nil
        )
    )
    // Success
} catch {
    // Failure
}

chrisschlitt avatar May 11 '24 15:05 chrisschlitt

I know this is somewhat off topic, but while everyone is here and I can solicit advice, Apple's docs state:

When the system receives the ActivityKit push notification on a device, it starts a new Live Activity, wakes up your app, and grants it background run time to allow you to download assets that the Live Activity needs.

Does anyone know what method is invoked or what happens when the start notification goes out? I'm severely doubting it's just application:didFinishLaunchingWithOptions: but I could be wrong. I'm going to play around with it because I need it to download image assets, but just figured I'd just check to see if anyone has already figured it out

alex-taffe avatar May 13 '24 14:05 alex-taffe

I know this is somewhat off topic, but while everyone is here and I can solicit advice, Apple's docs state:

When the system receives the ActivityKit push notification on a device, it starts a new Live Activity, wakes up your app, and grants it background run time to allow you to download assets that the Live Activity needs.

Does anyone know what method is invoked or what happens when the start notification goes out? I'm severely doubting it's just application:didFinishLaunchingWithOptions: but I could be wrong. I'm going to play around with it because I need it to download image assets, but just figured I'd just check to see if anyone has already figured it out

I only recently added an app delegate (I’m in a SwiftUI app), so I’m not sure which handler gets called there yet, but in SwiftUI I noticed that the onChange handler for scenePhase was triggered with the .background value, where I’m iterating over ActivityKit’s static activities property to grab the push tokens and sending them to my backend.

chrisschlitt avatar May 13 '24 14:05 chrisschlitt