求助:使用推送通知更新LiveActivities无响应问题
问题:Live Activity推送通知无更新响应
相关代码实现
启动LiveActivity方法
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)") } }
用于更新的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
ContentState定义
public struct ContentState: Codable, Hashable { var driverName: String var deliveryTimer: ClosedRange<Date> }
问题现状
已成功生成每个LiveActivity的pushToken,发送上述curl命令后无报错,但LiveActivity的动态内容未发生预期更新。
排查思路
- 校验APNS主题格式:确认
apns-topic中的<Bundle-Id>替换为实际App Bundle ID,格式必须严格为{BundleID}.push-type.liveactivity,无拼写错误。 - 验证时间戳有效性:推送中的
timestamp需为当前或未来的Unix时间戳,检查1663300480在发送推送时是否为有效时间(非过期时间)。 - 修复ContentState序列化逻辑:Swift默认的
ClosedRange<Date>Codable实现可能不匹配APNS要求,需手动实现编码确保日期转为Unix时间戳:public struct ContentState: Codable, Hashable { var driverName: String var deliveryTimer: ClosedRange<Date> enum CodingKeys: String, CodingKey { case driverName case deliveryTimer } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(driverName, forKey: .driverName) var timerContainer = container.nestedContainer(keyedBy: TimerCodingKeys.self, forKey: .deliveryTimer) try timerContainer.encode(Int(deliveryTimer.start.timeIntervalSince1970), forKey: .start) try timerContainer.encode(Int(deliveryTimer.end.timeIntervalSince1970), forKey: .end) } enum TimerCodingKeys: String, CodingKey { case start, end } } - 检查LiveActivity存活状态:确认
deliveryActivity不为nil,且未超过staleDate进入终止状态,过期的LiveActivity无法接收更新。 - 分析APNS响应日志:查看curl命令返回的响应码和内容,
200 OK说明推送成功但客户端未处理;若为400 Bad Request等错误,根据提示调整推送内容。 - 确认推送目标正确性:校验
$DEVICE_TOKEN为当前设备有效token,$AUTHENTICATION_TOKEN是用正确密钥生成的、具备推送权限的APNS令牌。 - 验证UI绑定逻辑:检查Widget的
EntryView是否正确读取ContentState的driverName和deliveryTimer属性,确保UI层能响应状态变化。
内容的提问来源于stack exchange,提问作者Eser Lodhia
相关产品推荐
相关产品推荐

