ParseLiveQuery-iOS-OSX received data but unable to trigger event handler in SwiftUI

I’m using ParseLiveQuery-iOS-OSX library to receive live server updates from my Parse Server in a SwiftUI project. I’ve followed closely to various sources online. Below is my current viewmodel:

class InitializationViewModel: ObservableObject{
    var subscription: Subscription<PFObject>?
    var subscriber = Client(server: "ws://xx.xx.xx.xx", applicationId: "xxxx", clientKey: "]")
    let query : PFQuery<PFObject> = Chats.query()!.whereKey("users", contains: "user1")
    
    init(){
        self.subscribeToChats()
    }
    
    func subscribeToChats() {
        self.subscriber.shouldPrintWebSocketLog = false
        self.subscriber.shouldPrintWebSocketTrace = true
        self.subscription = subscriber.subscribe(query).handle(Event.created) { query, object in
            print(object)
        }
    }
}

Since I turned on client tracing, i’m able to see incoming json live query objects from my server, so that part is all working. However, I’m the event handler just won’t be triggered.

I did some further investigation, and find out that error appears in line 23 of ParseLiveQuery/ClientPrivate.swift,

guard let object = PFDecoder.object().decode(objectDictionary) as? T else {
    throw LiveQueryErrors.InvalidJSONObject(json: objectDictionary, details: "cannot decode json into \(T.self)")
}

The decoding part (PFDecoder.object().decode(objectDictionary)) works ok. But the error appears when it tries to cast the decoded object to the type T, which is the type PFObject in my case (Type def here). I checked the decoded object indeed contains all the required fields of a PFObject. So I’m kinda stuck on why this happens / whether there’s a way to fix this problem.

Any help is appreciated

Hey I have this exact same error on iOS with regular UIKit. Did you ever figure this out?

I am actually able to figure it out. It turns out (I think due to some misalignment of versions) that the JSON object that the server sent over is missing a string field called “__type”, and it should be set to “Object” in order for the ParseLiveQuery to cast it to the type ‘PFObject’. Below is a simple solution that I did that should work in most cases (works for me at least), but this is far from a systematic solution. To make it work, just replace parseObject() function in ClientPrivate.swift file to the following:

private func parseObject<T: PFObject>(_ objectDictionary: [String:AnyObject]) throws -> T {
    guard let _ = objectDictionary["className"] as? String else {
        throw LiveQueryErrors.InvalidJSONError(json: objectDictionary, expectedKey: "parseClassName")
    }
    guard let _ = objectDictionary["objectId"] as? String else {
        throw LiveQueryErrors.InvalidJSONError(json: objectDictionary, expectedKey: "objectId")
    }

    var dict = objectDictionary
    dict["__type"] = String("Object") as AnyObject
    guard let object = PFDecoder.object().decode(dict) as? T else {
        throw LiveQueryErrors.InvalidJSONObject(json: objectDictionary, details: "cannot decode json into \(T.self)")
    }

    return object
}

It basically adds the “__type” field to received JSON object.

After you made this change, if you are using cocoapods, then you will need to change the edited pod repo to a local development pod. Check out this stackoverflow post for more info.

Nice! It worked! The error is finally gone. Thank you for that🎉