Decoding Error when starting a Live Activity via Push Notification

Hi,

I'm a bit stuck when it comes to implementing live activities.

I'm trying to start one by sending a push.

my activity attributes looks like:

import Foundation
import ActivityKit

public struct NeoPrototypeActivity: ActivityAttributes {
    public let classId: String
    public let name: String
    public let room: String
    public let startTime: Date

    public init(classId: String, name: String, room: String, startTime: Date) {
        self.classId = classId
        self.name = name
        self.room = room
        self.startTime = startTime
    }

    public struct ContentState: Codable & Hashable {
        public let participationState: ParticipationState

        public init(participationState: ParticipationState) {
            self.participationState = participationState
        }
    }
}

public enum ParticipationState: String, Codable, Hashable, Equatable {
    case upcoming
    case upcomingOnWaitingList
    case checkedIn
    case waitingList
    case lostSpot
    case lostSpotFromWaitingList
    case classCompleted

    public var description: String {
        switch self {
        case .upcoming: return "Upcoming"
        case .upcomingOnWaitingList: return "Upcoming on Waiting List"
        case .checkedIn: return "Checked In"
        case .waitingList: return "Waiting List"
        case .lostSpot: return "Lost Spot"
        case .lostSpotFromWaitingList: return "Lost Spot from Waiting List"
        case .classCompleted: return "Class completed"
        }
    }
}

which I have in a SPM package that is imported by my widget and iOS targets.

Then I am sending a push notification (to my simulator in this case) with the following payload

{
    "aps": {
        "timestamp": 1728419211,
        "event": "start",
        "content-state": {
            "participationState": "upcoming"
        },
        "attributes-type": "NeoPrototypeActivity",
        "attributes": {
            "classId": "1234",
            "name": "Indoor Running",
            "room": "room 2",
            "startTime": "2024-10-19T13:22:59+02:00"
        },
        "alert": {
            "title": "Hola Mundo",
            "body": "Todo Bien"
        }
    }
  }

I am using the right values for the deviceID when sending the push.

I get a 200 ok from the CloudKit console.

yet my live activity doesn't start.

I'm trying to look at the errors in the Console app and the only relevant thing is see is:

[NeoPrototypeActivity] Error creating activity: NSCocoaErrorDomain (4864) The data couldn’t be read because it isn’t in the correct format.

It seems like a decoding error, but I don't know what exactly failed

I wrote some test to try the decoding like:

import Testing
import Foundation
@testable import PrototypeActivities

@Test func decoding() async throws {
    struct StateContainer: Codable {
        let participationState: ParticipationState
    }

    let jsonString = """
    {
        "participationState": "upcoming"
    }
    """
    let json = try #require(jsonString.data(using: .utf8))
    let result = try JSONDecoder().decode(StateContainer.self, from: json)

    #expect(result.participationState == .upcoming)
}

@Test func decodingActivity() throws {
//    let jsonString = """
//    {
//        "classId": "1234",
//        "name": "Indoor Running",
//        "room": "room 2",
//        "startTime": "2024-10-19T11:22:59Z"
//    }
//    """
    let jsonString = """
    {
        "classId": "1234",
        "name": "Indoor Running",
        "room": "room 2",
        "startTime": 1729337784
    }
    """
    let json = try #require(jsonString.data(using: .utf8))

    let jsonDecoder = JSONDecoder()
//    jsonDecoder.dateDecodingStrategy = .iso8601
    let activity = try jsonDecoder.decode(NeoPrototypeActivity.self, from: json)

    #expect(activity.classId == "1234")
    #expect(activity.name == "Indoor Running")
}```

but even with using the default JSON decoder date format, I still get the same error.

Not sure how to fix this or to get more details.
Answered by fespinozacast in 809875022

After thinking a bit more, I understand the problem.

the decoder already is set to use Dates in Seconds from Epoch format, as the JSON includes the timestamp.

Then any other dates as part of the attributes, need the same format

Which looking back, makes total sense.

It was difficult to build the live activity without knowing that the date was the problem and no other property

I did a test where I changed the type of startDate to String and the decoding error didn't appear anymore.

This was just a lucky guess, I didn't find anywhere that the date was wrong

Accepted Answer

After thinking a bit more, I understand the problem.

the decoder already is set to use Dates in Seconds from Epoch format, as the JSON includes the timestamp.

Then any other dates as part of the attributes, need the same format

Which looking back, makes total sense.

It was difficult to build the live activity without knowing that the date was the problem and no other property

Decoding Error when starting a Live Activity via Push Notification
 
 
Q