Skip to content
This repository has been archived by the owner on Jun 13, 2023. It is now read-only.

iOS Swift LiveQuery not receiving events #105

Closed
seanfeeley opened this issue Mar 12, 2017 · 19 comments
Closed

iOS Swift LiveQuery not receiving events #105

seanfeeley opened this issue Mar 12, 2017 · 19 comments

Comments

@seanfeeley
Copy link

Hello I have a subscription to a query that signals the subscribed event but does not signal any other event.

When I run the following code I get the "subbed" message. And on my remote server I can see the following logs.

2017-03-12T22:31:11.565923+00:00 app[web.1]: �[36mverbose�[39m: Push Response : "{\"op\":\"subscribed\",\"clientId\":9,\"requestId\":1}"
2017-03-12T22:31:11.566125+00:00 app[web.1]: �[36mverbose�[39m: Create client 9 new subscription: 1
2017-03-12T22:31:11.566293+00:00 app[web.1]: �[36mverbose�[39m: Current client number: 1
Code:

Swift code:

class ActiveLetterLoader {
    var subscription: Subscription<RemoteLetter>?
    let liveQueryClient = ParseLiveQuery.Client()
    
    init() {
        self.register()
    }
    
    
    func register() {
        RemoteLetter.registerSubclass()
        
        let remoteQ: PFQuery<RemoteLetter>  = RemoteLetter.query()!.whereKey("oid", notEqualTo: "whatever") as! PFQuery<RemoteLetter>
        remoteQ.findObjectsInBackground { (objects, errors) in
            print(objects)
            print(errors)
        }
        self.subscription = liveQueryClient.subscribe(remoteQ).handleSubscribe { [weak self]  (_) in
            print("Subbed")
            }.handleEvent { [weak self] (_, event) in
                self?.handleEvent(event: event)
        }
        
    }
    
    func handleEvent(event: Event<RemoteLetter>) {
        // Make sure we're on main thread
        if Thread.current != Thread.main {
            return DispatchQueue.main.async { [weak self] _ in
                self?.handleEvent(event: event)
            }
        }
        
        switch event {
        case .created(let obj),
             .entered(let obj):
            print("Object is entered!")
            
        case .updated(let obj):
            print("Object is updated!")
            
        case .deleted(let obj),
             .left(let obj):
            print("Object is deleted!")
        }
    }  
}


class RemoteLetter: PFObject, PFSubclassing {
    @NSManaged var  oid: NSString?
    @NSManaged var  clat: NSNumber?
    @NSManaged var  clon: NSNumber?
    @NSManaged var  olat: NSNumber?
    @NSManaged var  olon: NSNumber?
    
    override init(){
        super.init()
    }
    
    init(letter: ActiveLetter) {
        super.init()
        self.oid = letter.objectId as NSString
        self.clat = letter.latitude as NSNumber
        self.clon = letter.longitude as NSNumber
        self.olat = letter.original_latitude as NSNumber
        self.olon = letter.original_longitude as NSNumber
        self.acl = make_acl()
    }
    
    func make_acl() -> PFACL{
        let acl = PFACL()
        acl.getPublicReadAccess = true
        acl.getPublicWriteAccess = true
        return acl
    }
    
    class func parseClassName() -> String {
        return "ActiveLetters"
    }
}

A sample object on my remote database

{
    "_id": "A5Y8dPfalr",
    "clat": 51.51613894350632,
    "olon": -0.142,
    "clon": -0.1404333170731588,
    "oid": "51.516/-0.142",
    "olat": 51.516,
    "_wperm": [
        "*"
    ],
    "_rperm": [
        "*"
    ],
    "_acl": {
        "*": {
            "w": true,
            "r": true
        }
    },
    "_created_at": {
        "$date": "2017-03-12T22:10:16.686Z"
    },
    "_updated_at": {
        "$date": "2017-03-12T22:10:16.686Z"
    }
}

I am connecting to a remote database that I set up on Heroku with the parse server example.
The config for that server is

{
  "name": "parse-server-example",
  "version": "1.4.0",
  "description": "An example Parse API server using the parse-server module",
  "main": "index.js",
  "repository": {
    "type": "git",
    "url": "https://github.com/ParsePlatform/parse-server-example"
  },
  "license": "MIT",
  "dependencies": {
    "express": "~4.11.x",
    "kerberos": "~0.0.x",
    "parse": "~1.8.0",
    "parse-server": "~2.3.6"
  },
  "scripts": {
    "start": "node index.js"
  },
  "engines": {
    "node": ">=4.3"
  }
}

Locally my app I am using the following dependancy versions.

  • Bolts (1.8.4)
  • Bolts-Swift (1.3.0)
  • Parse (1.14.2)
  • ParseLiveQuery (2.0.0)
  • Starscream (2.0.3)
@justinshuls
Copy link

Similar issue.

@justinshuls
Copy link

Have you made any headway?

@flovilmart
Copy link
Contributor

Does it work when you run on your local dev machine? That can help rule our some issues. How many dynos are you running on Heroku?

@justinshuls
Copy link

I will try, but if the was a problem between the client-server would we see Current client number:?

@kuyazee
Copy link

kuyazee commented Mar 28, 2017

I'm having the same problem. I've tried creating a one using the javascript version and it seems that ParseLiveQuery works. This might be an SDK issue but I'm not really sure, I'm still debugging the code myself looking as to where the code gets stuck (I'm not a pro though) :(

@justinshuls
Copy link

Anyone figure this out?

@flovilmart
Copy link
Contributor

Not sure how to help without more informations, do you have server logs, that would show which query you're subscribed too and objects that enter/leave the query constraints?

@justinshuls
Copy link

Thats exactly it. No logs on queries subscribing, likely because the never subscribe and never send events. The only thing that occurs is Current client number: 1. What version configuration gives you a working system?

@flovilmart
Copy link
Contributor

I was talking about object creation logs, like an object gets created and it should be reported to the client but is not reported. Does it work locally?

@justinshuls
Copy link

Yes I think that is it. Object gets created/modified and is not reported to the client or is reported, but not handled. Running locally:

verbose: REQUEST for [PUT] /parse/classes/Spots/Bzs1aOVCQW: {
  "isOccupied": true
} method=PUT, url=/parse/classes/Spots/Bzs1aOVCQW, host=localhost:1337, content-type=text/plain, origin=http://localhost:1337, accept-encoding=gzip, deflate, cookie=session=eyJjc3JmU2VjcmV0IjoidEgzWVNXbUFka2ZmNUdYWmFNV3ljMU1rIiwiZmxhc2giOnt9LCJwYXNzcG9ydCI6eyJ1c2VyIjoianVzdGluc2h1bHMifX0=; session.sig=czS6Z-WL6bZcgW6kjDK2DYxKY4A, connection=keep-alive, accept=*/*, user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30, referer=http://localhost:1337/dashboard/apps/lot%20it/browser/Spots, content-length=201, accept-language=en-us, isOccupied=true
verbose: Raw request from cloud code current : {"spotNumber":"Bzs","rating":3,"rotation":0,"owner":{"__type":"Pointer","className":"_User","objectId":"chj82a4IMS"},"comment":"","isVerified":true,"longRate":0,"isOccupied":true,"shortRate":0.95,"coordinate":{"__type":"GeoPoint","latitude":39.17174512771101,"longitude":-86.5345158801418},"status":"deleted","features":["large space","lit","paved","cctv"],"createdAt":"2017-04-08T19:40:47.718Z","updatedAt":"2017-04-11T22:16:44.289Z","objectId":"Bzs1aOVCQW"} | original : {"spotNumber":"Bzs","rating":3,"rotation":0,"owner":{"__type":"Pointer","className":"_User","objectId":"chj82a4IMS"},"comment":"","isVerified":true,"longRate":0,"isOccupied":false,"shortRate":0.95,"coordinate":{"__type":"GeoPoint","latitude":39.17174512771101,"longitude":-86.5345158801418},"status":"deleted","features":["large space","lit","paved","cctv"],"createdAt":"2017-04-08T19:40:47.718Z","updatedAt":"2017-04-09T14:11:52.232Z","objectId":"Bzs1aOVCQW"}
verbose: Subscribe messsage "{\"currentParseObject\":{\"spotNumber\":\"Bzs\",\"rating\":3,\"rotation\":0,\"owner\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"chj82a4IMS\"},\"comment\":\"\",\"isVerified\":true,\"longRate\":0,\"isOccupied\":true,\"shortRate\":0.95,\"coordinate\":{\"__type\":\"GeoPoint\",\"latitude\":39.17174512771101,\"longitude\":-86.5345158801418},\"status\":\"deleted\",\"features\":[\"large space\",\"lit\",\"paved\",\"cctv\"],\"createdAt\":\"2017-04-08T19:40:47.718Z\",\"updatedAt\":\"2017-04-11T22:16:44.289Z\",\"objectId\":\"Bzs1aOVCQW\",\"__type\":\"Object\",\"className\":\"Spots\"},\"originalParseObject\":{\"spotNumber\":\"Bzs\",\"rating\":3,\"rotation\":0,\"owner\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"chj82a4IMS\"},\"comment\":\"\",\"isVerified\":true,\"longRate\":0,\"isOccupied\":false,\"shortRate\":0.95,\"coordinate\":{\"__type\":\"GeoPoint\",\"latitude\":39.17174512771101,\"longitude\":-86.5345158801418},\"status\":\"deleted\",\"features\":[\"large space\",\"lit\",\"paved\",\"cctv\"],\"createdAt\":\"2017-04-08T19:40:47.718Z\",\"updatedAt\":\"2017-04-09T14:11:52.232Z\",\"objectId\":\"Bzs1aOVCQW\",\"__type\":\"Object\",\"className\":\"Spots\"}}"
verbose: lotitafterSave is triggered
verbose: ClassName: Spots | ObjectId: undefined
verbose: Current client number : 2
verbose: RESPONSE from [PUT] /parse/classes/Spots/Bzs1aOVCQW: {
  "response": {
    "updatedAt": "2017-04-11T22:16:44.289Z"
  }
} updatedAt=2017-04-11T22:16:44.289Z
verbose: Original {"spotNumber":"Bzs","rating":3,"rotation":0,"owner":{"__type":"Pointer","className":"_User","objectId":"chj82a4IMS"},"comment":"","isVerified":true,"longRate":0,"isOccupied":false,"shortRate":0.95,"coordinate":{"__type":"GeoPoint","latitude":39.17174512771101,"longitude":-86.5345158801418},"status":"deleted","features":["large space","lit","paved","cctv"],"createdAt":"2017-04-08T19:40:47.718Z","updatedAt":"2017-04-09T14:11:52.232Z","__type":"Object","className":"Spots","objectId":"Bzs1aOVCQW"} | Current {"spotNumber":"Bzs","rating":3,"rotation":0,"owner":{"__type":"Pointer","className":"_User","objectId":"chj82a4IMS"},"comment":"","isVerified":true,"longRate":0,"isOccupied":true,"shortRate":0.95,"coordinate":{"__type":"GeoPoint","latitude":39.17174512771101,"longitude":-86.5345158801418},"status":"deleted","features":["large space","lit","paved","cctv"],"createdAt":"2017-04-08T19:40:47.718Z","updatedAt":"2017-04-11T22:16:44.289Z","__type":"Object","className":"Spots","objectId":"Bzs1aOVCQW"} | Match: true, true, true, true | Query: Spots:objectId|[{"$exists":true}]
verbose: Push Response : "{\"op\":\"update\",\"clientId\":5,\"requestId\":1,\"object\":{\"spotNumber\":\"Bzs\",\"rating\":3,\"rotation\":0,\"owner\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"chj82a4IMS\"},\"comment\":\"\",\"isVerified\":true,\"longRate\":0,\"isOccupied\":true,\"shortRate\":0.95,\"coordinate\":{\"__type\":\"GeoPoint\",\"latitude\":39.17174512771101,\"longitude\":-86.5345158801418},\"status\":\"deleted\",\"features\":[\"large space\",\"lit\",\"paved\",\"cctv\"],\"createdAt\":\"2017-04-08T19:40:47.718Z\",\"updatedAt\":\"2017-04-11T22:16:44.289Z\",\"__type\":\"Object\",\"className\":\"Spots\",\"objectId\":\"Bzs1aOVCQW\"}}"

let query = PFQuery(className: "Spots")
        query.whereKeyExists("objectId")
        query.findObjectsInBackground(block: {
            _ in
            
            let subscription = liveServer.subscribe(query).handleSubscribe { [weak self]  (_) in
                print("Subbed")
            }.handleEvent { [weak self] (_, event) in
                print("event")
            }
            
        })

@AnChiChang
Copy link

AnChiChang commented Apr 19, 2017

I got the same issue, and my verbose response message like below:

verbose: REQUEST for [PUT] /parse/classes/Posts/3SQbn6pJft: {
"like": 3
} method=PUT, url=/parse/classes/Posts/3SQbn6pJft, host=192.168.200.45:1337, connection=keep-alive, content-length=208, origin=http://59.124.92.142:1337, user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36, content-type=text/plain, accept=/, referer=http://xx.xxxxx.xxx:1337/dashboard/apps/ReadycomERP/browser/Posts, accept-encoding=gzip, deflate, accept-language=zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4,zh-CN;q=0.2, like=3
verbose: Raw request from cloud code current : {"title":"test2","createdAt":"2017-04-19T04:13:50.692Z","updatedAt":"2017-04-19T08:19:34.450Z","content":"this is test 2","like":3,"objectId":"3SQbn6pJft"} | original : {"title":"test2","createdAt":"2017-04-19T04:13:50.692Z","updatedAt":"2017-04-19T08:02:55.681Z","content":"this is test 2","like":4,"objectId":"3SQbn6pJft"}
verbose: Subscribe messsage "{"currentParseObject":{"title":"test2","createdAt":"2017-04-19T04:13:50.692Z","updatedAt":"2017-04-19T08:19:34.450Z","content":"this is test 2","like":3,"objectId":"3SQbn6pJft","__type":"Object","className":"Posts"},"originalParseObject":{"title":"test2","createdAt":"2017-04-19T04:13:50.692Z","updatedAt":"2017-04-19T08:02:55.681Z","content":"this is test 2","like":4,"objectId":"3SQbn6pJft","__type":"Object","className":"Posts"}}"
verbose: 4k3eJ0S60c9qwd06z2dsHX6TP4Br17oiafterSave is triggered
verbose: ClassName: Posts | ObjectId: undefined
verbose: Current client number : 0
verbose: RESPONSE from [PUT] /parse/classes/Posts/3SQbn6pJft: {
"response": {
"updatedAt": "2017-04-19T08:19:34.450Z"
}
} updatedAt=2017-04-19T08:19:34.450Z

and source code:

    var subscription: Subscription<Posts>?
    let query: PFQuery<Posts> = PFQuery(className: "Posts").whereKey("objectId", equalTo: "3SQbn6pJft")
    query.findObjectsInBackground {
        (posts: [Posts]?, error: Error?) in
        if error == nil {
            print("count \(posts?.count)")
                
                subscription = liveQueryClient.subscribe(query).handle(Event.updated) { _, post in
                print("Object updated")
            }
        }
    }

@justinshuls
Copy link

is anyone out there?

@flovilmart
Copy link
Contributor

@justinshuls not sure what your issue is, is your subscription properly retained? Using the memory tool in Xcode, the object should appear.

Also, we're running it in production now, have have no issue receiving events.

Did you try with a local parse-server?

@justinshuls
Copy link

Do you have an example project that works that you could share? My local verbose is above if that helps. I am lost.

@flovilmart
Copy link
Contributor

@Thons
Copy link

Thons commented May 29, 2017

make sure that the live query client object and the subscription object did NOT release(auto release) BEFORE they actually received events. eg. Declare the client object and subscription object in viewDidLoad method and initialize, two objects will be release after finished executing of the method, and never received any events after that moment.

@EtgarSH
Copy link

EtgarSH commented May 31, 2017

https://stackoverflow.com/questions/44273455/parse-cloud-livequeries-ios-client-doesnt-work
@Thons I've also tried declaring the Subscription as a static variable in my Channel class.

@EtgarSH
Copy link

EtgarSH commented Jun 23, 2017

I'm pretty convinced that there is a problem with the current version of LiveQueries for iOS.
Put a bounty on my SOF question: https://stackoverflow.com/questions/44273455/parse-cloud-livequeries-ios-client-doesnt-work

@kuyazee
Copy link

kuyazee commented Jun 23, 2017

Forgot to update this thread, Look at my answer on @EtgarSH's stackoverflow question.

I have found out why the project wasn't retrieving any events, the problem wasn't with the SDK, but with the lack of explanation as to how and what was happening on the Subscription object's memory address.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants