Search code examples
iosswiftparse-platformlivequeryparse-cloud-code

Parse Cloud - LiveQueries - iOS Client doesn't work


I'm trying to use Parse LiveQueries. I use this Parse "Bootstrap": "https://github.com/parse-community/parse-server",
I can see the logs: info: Create new client: 1,
but I just do not get the update in the query although I have subscribed it. It doesn't even reach the handler of the subscription.handle.

config.json:

{
  "appId": "",
  "masterKey": "",
  "appName": "",
  "cloud": "./cloud/main",
  "databaseURI": "",
  "publicServerURL": "",    

  // Relevant
  "startLiveQueryServer": true,
  "liveQuery": {
    "classNames": ["Channel"]
  },
}

AppDelegate.swift:

// Initialize Parse.
let configuration = ParseClientConfiguration {
    $0.applicationId = self.PARSE_APP_ID
    $0.server = self.PARSE_SERVER
}
Parse.initialize(with: configuration)

AppDelegate.liveQueryClient = ParseLiveQuery.Client()

The Subscription Code (iOS Swift):

public static func listenSubscribedChannels(handler: @escaping (_ channel: Channel) -> Void) {
    var subscription: Subscription<PFObject>?

    let query: PFQuery<PFObject> = PFQuery(className: "Channel").whereKey("subscribers", containedIn: [PFUser.current()!.objectId])

    subscription = AppDelegate.liveQueryClient!.subscribe(query).handle(Event.updated) { _, channel in
        handler(channel)
    }
}

Solution

  • The problem with this code is that you are placing this code var subscription: Subscription<PFObject>? inside the function.

    This object must be able to retain it's memory address in order for it to receive events.

    For example.

    class SomeClass {
        var objects: [PFObject] = []
        var subscription: Subscription<PFObject>?
        var subscriber: ParseLiveQuery.Client!
        let query = PFQuery(className: "Locations")
    
        func startListener() {
            // initialize the client
            subscriber = ParseLiveQuery.Client()
    
            // initialize subscriber and start subscription
            subscription = subscriber.subscribe(conversationQuery)
    
            // handle the event listenrs.
            _ = subscription?.handleEvent({ (_, event) in
                switch event {
                case .created(let object): 
                    self.objects.append(object)
                    // do stuff 
    
                default: 
                    break // do other stuff or do nothing
                }
            })
        }
    }
    

    As you can see from this code, I've placed the variables outside the function definition in order for the Subscription's memory address to be retained.