swift 使用推送通知更新LiveActivities

laawzig2  于 2023-05-16  发布在  Swift
关注(0)|答案(1)|浏览(266)

我尝试使用推送通知更新实时活动,我使用两种方法,一种是启动实时活动,另一种是更新实时活动,如下所示:

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>
        }

任何帮助或见解都非常感谢。

pw9qyyiw

pw9qyyiw1#

当你运行curl时,如果你得到一个状态码200响应,那么推送通知就会发送到设备上。
假设你得到了200分,我认为问题出在你的ContentState上。iOS正在使用codable将推送通知content-state反序列化为结构体ContentState。要做到这一点,两个密钥必须完全匹配。(我知道这个ContentState来自他们的示例,但他们在推送示例中使用了simpler one
ClosedRange is codable,但我不知道键是什么(可能不是startend)。
尝试只在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
        }

相关问题