我正在尝试使用推送通知更新实时活动,我使用两种方法,一种是启动实时活动,另一种是更新实时活动,如下所示:
func startActivity(completion: @escaping (String) -> Void) {
print("startActivity() is running")
let attributes = PizzaDeliveryAttributes(numberOfPizzas: 2, totalAmount: "420", orderNumber: "359")
let future = Calendar.current.date(byAdding: .minute, value: 35, to: Date())!.addingTimeInterval(40)
let date = Date.now...future
let initialContentState = PizzaDeliveryAttributes.ContentState(driverName: "Bill James", deliveryTimer:date)
let activityContent = ActivityContent(state: initialContentState, staleDate: Calendar.current.date(byAdding: .minute, value: 30, to: Date())!)
do {
self.deliveryActivity = try Activity.request(attributes: attributes, content: activityContent, pushType: .token)
print("Requested a pizza delivery Live Activity \(String(describing: self.deliveryActivity?.id)).")
Task {
for await data in self.deliveryActivity!.pushTokenUpdates {
let myToken = data.map {String(format: "%02x", $0)}.joined()
print("Token printed: \(myToken)")
completion(myToken)
}
}
} catch (let error) {
print("Error requesting pizza delivery Live Activity \(error.localizedDescription).")
}
}
func updatePizzaDeliveryStatus(minutes: String, seconds: String) async {
var future = Calendar.current.date(byAdding: .minute, value: (Int(minutes) ?? 0), to: Date())!
future = Calendar.current.date(byAdding: .second, value: (Int(seconds) ?? 0), to: future)!
let date = Date.now...future
let updatedDeliveryStatus = PizzaDeliveryAttributes.PizzaDeliveryStatus(driverName: "Anne Johnson", deliveryTimer: date)
let alertConfiguration = AlertConfiguration(title: "Delivery update", body: "Your pizza order will arrive in 25 minutes.", sound: .default)
let updatedContent = ActivityContent(state: updatedDeliveryStatus, staleDate: nil)
do {
try await self.deliveryActivity?.update(updatedContent, alertConfiguration: alertConfiguration)
} catch {
print("Failed to update Live Activity: \(error)")
}
}
我能够在每个新的实时活动开始时生成 pushTokens,还可以发送 curl 命令来更新我将在下面提供的实时活动。我希望属性的动态内容能够更新,但是推送通过时什么也没有发生。
curl -v \
--header "apns-topic:<Bundle-Id>.push-type.liveactivity" \
--header "apns-push-type:liveactivity" \
--header "authorization: bearer $AUTHENTICATION_TOKEN" \
--data \
'{"aps": {
"timestamp":1663300480,
"event": "update",
"content-state": {
"driverName": "Tony Stark",
"deliveryTimer": {
"start": 1663300480,
"end": 1663301480
}
},
"alert": {
"title": "Race Update",
"body": "Tony Stark is now leading the race!"
}
}}' \
--http2 \
https://${APNS_HOST_NAME}/3/device/$DEVICE_TOKEN
这就是属性中的内容状态:
public struct ContentState: Codable, Hashable {
var driverName: String
var deliveryTimer: ClosedRange<Date>
}
非常感谢任何帮助或见解。
当您运行 curl 时,如果您收到状态代码
200
响应,则推送通知正在发送到设备。
假设您得到 200,我认为问题在于您的
ContentState
。 iOS 正在使用 codable 将推送通知 content-state
反序列化为结构 ContentState
。为此,键必须与两者的exactly匹配。 (我知道这个 ContentState 来自他们的示例,但他们使用 更简单的 作为推送示例)
ClosedRange 可编码,但我不知道键是什么(可能不是
start
和 end
)。
尝试只将基本类型放入您的 ContentState 中,看看是否可以解决问题。如果是这样,您可以调查 ClosedRange 的可编码性。让我知道情况如何!
"content-state": {
"driverName": "Tony Stark",
"deliveryStartInt": 1663300480,
"deliveryEndInt": 1663301480,
}
},
public struct ContentState: Codable, Hashable {
var driverName: String
var deliveryStartInt: Int
var deliveryEndInt: Int
}
好吧,我想通了。
我没有意识到的是 apns 有效负载中的时间戳键,即;
"timestamp":1663300480
每次发送有效负载时都需要更新。您可以从 here 获取最新的时间戳。希望这有帮助!