最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - How can I handle multiple live activities of the same type with pushToStartTokens? - Stack Overflow

programmeradmin3浏览0评论

My question is about subscribing to multiple Live Activities of the same type (the same ActivityAttributes) and then handle them separately when using push to start one of them.

I want the user to be able to follow multiple football matches. However, when I listen to pushToStartTokenUpdates sequence, I always get the same token, even when I call the function multiple times.

How am I supposed to have the user start multiple future activities, and then push to start them separately?

I can store the matchId locally, and only pass the update when the received id from the push matches the stored one, but is this really the best way to do this? Am I missing something or have Apple really not thought about this?

Edit:

Here is a simplification of what I mean by the start token only being decided by the type, not the matchId. I do not know any other way of retrieving the start token, but I have probably missed something? Run the code in AppDelegate to test, but the result will be the same token being printed twice.

import ActivityKit
import SwiftUI

struct FootballActivityAttributes: ActivityAttributes {
    var eventId: String
    var homeTeam: String
    var awayTeam: String

    public struct ContentState: Codable, Hashable {
        var homeScore: Int
        var awayScore: Int
    }
}

func getPushToStartToken(eventID: String) async throws -> String? {
    print("Running Live Activity: Fetching pushToStartToken for event \(eventID)...")
    for await data in Activity<FootballActivityAttributes>.pushToStartTokenUpdates {
        let token = data.map {String(format: "%02x", $0)}.joined()
        print("Live Activity: Saved pushToStartToken for event \(eventID): \(token)")
        return token
    }
    print("Live Activity: Found no token")
    return nil
}

for eventId in ["12345", "67890"] {
    Task {
        try await getPushToStartToken(eventID: eventId)
    }
}

My question is about subscribing to multiple Live Activities of the same type (the same ActivityAttributes) and then handle them separately when using push to start one of them.

I want the user to be able to follow multiple football matches. However, when I listen to pushToStartTokenUpdates sequence, I always get the same token, even when I call the function multiple times.

How am I supposed to have the user start multiple future activities, and then push to start them separately?

I can store the matchId locally, and only pass the update when the received id from the push matches the stored one, but is this really the best way to do this? Am I missing something or have Apple really not thought about this?

Edit:

Here is a simplification of what I mean by the start token only being decided by the type, not the matchId. I do not know any other way of retrieving the start token, but I have probably missed something? Run the code in AppDelegate to test, but the result will be the same token being printed twice.

import ActivityKit
import SwiftUI

struct FootballActivityAttributes: ActivityAttributes {
    var eventId: String
    var homeTeam: String
    var awayTeam: String

    public struct ContentState: Codable, Hashable {
        var homeScore: Int
        var awayScore: Int
    }
}

func getPushToStartToken(eventID: String) async throws -> String? {
    print("Running Live Activity: Fetching pushToStartToken for event \(eventID)...")
    for await data in Activity<FootballActivityAttributes>.pushToStartTokenUpdates {
        let token = data.map {String(format: "%02x", $0)}.joined()
        print("Live Activity: Saved pushToStartToken for event \(eventID): \(token)")
        return token
    }
    print("Live Activity: Found no token")
    return nil
}

for eventId in ["12345", "67890"] {
    Task {
        try await getPushToStartToken(eventID: eventId)
    }
}
Share edited Mar 10 at 8:58 Paulw11 115k15 gold badges171 silver badges209 bronze badges Recognized by Mobile Development Collective asked Mar 6 at 19:35 MatiasVianMatiasVian 114 bronze badges 5
  • 1 Use different activity attributes to identify the match or team? – Paulw11 Commented Mar 6 at 20:53
  • As I see it I need to define a new attributes class to get a different token. It is the Type that decides whether I get a unique token, not the content of the class. I can't define hundreds of attribute classes to cater to the different matches. – MatiasVian Commented Mar 7 at 9:10
  • You shouldn't need a new attributes class. Your attribute class should have an associated property such as matchId or similar. You should edit your question to show the relevant code. – Paulw11 Commented Mar 7 at 11:13
  • I've edited my question. – MatiasVian Commented Mar 10 at 8:37
  • Ok, I see the confusion. There is one pushToStartToken but each activity has its own update push token – Paulw11 Commented Mar 10 at 10:54
Add a comment  | 

1 Answer 1

Reset to default 0

There is only one active pushToStartToken at any point for a given Activity<Attributes> type, because that token is just used to start new activities. Each active Activity has its own update token that you use to send updates for that activity.

Broadly, this is what your app needs to do:

  • Observe the pushStartTokenUpdates sequence for Activity<FootballActivityAttributes>
    • Send the token to your server when it is updated
  • Maintain a list of matches that your user is interested in on your server
  • When a match they are interested in starts, send a start activity push to the pushStartToken. The payload for this activity must include the relevant eventId, homeTeam and awayTeam properties
  • Your app also needs to observe the Activity<FootballActivityAttributes>.activityUpdates async sequence
    • When a new activity is started, it will be delivered via this sequence.
    • I suggest keeping a dictionary of live activities, keyed by eventId, that way you can easily detect new live activities.
    • Observe the pushTokenUpdates sequence for this activity and send it to your server along with the eventId from the activity's attributes.
for await activity in Activity<FootballActivityAttributes>.activityUpdates {
    Task {
        for await tokenData in activity.pushTokenUpdates {
            let token = tokenData.map {String(format: "%02x", $0)}.joined()
            print("Push token: \(token)")
            // Send token to your server along with user id and activity.attributes.eventId
         }
     }
}
  • Your server can now send update push notifications to this activity-specific token
  • At the end of the match you can send an end notification to the activity-specific token.
发布评论

评论列表(0)

  1. 暂无评论