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

Fix object decoding #76

Merged
merged 4 commits into from
Feb 23, 2017
Merged

Fix object decoding #76

merged 4 commits into from
Feb 23, 2017

Conversation

flovilmart
Copy link
Contributor

The original implementation of the object decoding would let the ParseSDK to believe the object was mutated by the client.

Using the private PFDecoder is actually letting the ParseSDK think the object has been issued by the server (which is what we would expect).

@JoeSzymanski
Copy link
Contributor

Is there any update on moving this forward? We're close to being blocked by this bug, since we need support for complex objects when doing Live Queries.

@flovilmart
Copy link
Contributor Author

@JoeSzymanski does it work for your use case? You can point to the pod with the branch

@JoeSzymanski
Copy link
Contributor

I'm about to start explicit testing today, but I know we'll need support for complex objects. I'll update soon with information on if this worked or not.

@flovilmart
Copy link
Contributor Author

@JoeSzymanski let us know

@JoeSzymanski
Copy link
Contributor

In doing some testing, this change does appear to fix the problem with the objects not being of the correct type on decode. It does not appear to fix anything related to the "Tried to resolve a localId for an object with no localId." issue (though I'm not sure that was ever intended, I was just hopeful).

@ShawnBaek
Copy link

ShawnBaek commented Nov 25, 2016

I had tested this repo.

It returned PFObject but It seems different results.

It is my original PFObject when I request via findObjectInBackGround()

<Post: 0x6080000b0800, objectId: w5qcfMCByF, localId: (null)> {
likeCount = 0;
postBy = "<PFUser: 0x6080000e3100, objectId: rgG7XfAYWj, localId: (null)>";
postImg = "<PFFile: 0x60800024c150>";
postText = nice2MeetYous1211;
sell = 0;
}

When I change postText then I got update event via live query but different.

<Post: 0x6100000b1be0, objectId: w5qcfMCByF, localId: (null)> {
likeCount = 0;
postBy = "<PFUser: 0x6100000e6900, objectId: rgG7XfAYWj, localId: (null)>";
postImg = "<PFFile: 0x61000025d1f0>";
postText = nice2MeetYous;
sell = 0;
}

As you can see..PFUser:0x6080000e3100 and PFFile: 0x60800024c150 has changed to

PFUser: 0x6100000e6900, PFFile: 0x61000025d1f0

Anyway I can't fetchObject when I received events.

Is this problem about live query or parse-server side problem?

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Key "username" has no data. Call fetchIfNeeded before getting its value.'

I added some code to avoid fetchIfNeeded errors.

Here is my snippet code.

extension Post: FeedCellSupport {

var username:String?{
    
    do {
        try postBy?.fetchIfNeeded()
    } catch _ {
        print("There was an error")
    }
    
    
    return postBy?["username"] as? String
    
    
}

var userImg:PFFile?{
    do {
        try postBy?.fetchIfNeeded()
    } catch _ {
        print("There was an error")
    }
    
    return postBy?["profileImg"] as? PFFile
}

Now It works fine but...system says "Warning: A long-running operation is being executed on the main thread. "

I think it is not bestway..

@flovilmart
Copy link
Contributor Author

Parse-server doesn't support includes keys with live query. So until that support come (and it will come at the cost of adding a read for each update) what you're experiencing is correct.

@ShawnBaek
Copy link

@flovilmart Thank you. I understood 👍

@JoeSzymanski
Copy link
Contributor

@flovilmart I've hit the other side of this issue, in that encoding queries looks like it's not using the encoding logic from the main Parse SDK. Would it be possible to look into updating the pull request to support the encoding logic in addition to the decoding logic? That should allow subscriptions to start using where clauses that reference objects, which currently crashes.

@flovilmart
Copy link
Contributor Author

What particular code is crashing?

@JoeSzymanski
Copy link
Contributor

The encoding of the query crashes here: https://github.com/ParsePlatform/ParseLiveQuery-iOS-OSX/blob/master/Sources/ParseLiveQuery/Internal/ClientPrivate.swift#L208

From what I can tell, the encoding logic doesn't support encoding of PFObjects, as it just converts the query into a dictionary (see https://github.com/ParsePlatform/ParseLiveQuery-iOS-OSX/blob/master/Sources/ParseLiveQuery/Internal/Operation.swift#L24)
I'm doing a bit of digging to figure out how to handle this, but it doesn't look like a trivial change, from what I can tell.

@flovilmart
Copy link
Contributor Author

I meant your code that make it crash :) so I can add it to the test suite :)

@JoeSzymanski
Copy link
Contributor

I think that this covers a simple variation without having to reference specific code I'm writing:

let object = PFObject(withoutDataWithClassName:"PFObjectSubclass" objectId: "objectId")
let query = PFQuery(className: "PFObjectSubclass").whereKey("relatedObject", equalTo: object)
Client.shared.subscribe(query)

There are already a number of issues opened for this: #40

@JoeSzymanski
Copy link
Contributor

I believe that I have a working fix for the query encoding case that takes a similar path to what's done for decoding.

By making some internal headers to expose the classes associated with PFEncoder (most of the specific subclasses are needed), then updating the dictionary encoding methods to use the PFEncoder, it looks like the matching works on the server side.

The update would have to be made here and looks like it can just be

else if let object = val as? PFObject {
    encodedQueryDictionary[key] = PFPointerObjectEncoder.object().encode(object) as? Value
}

It's possible that this can supersede most of the encoding logic there, as all of my testing so far has given the same output for the encode method as the final output of the entire encode function, but I'm not 100% confident that there wouldn't be edge cases.

How do you want to proceed with getting this fix in place?

@flovilmart
Copy link
Contributor Author

Just open a new PR, either on the top of this branch or directly against master. And add the relevant tests :)

@JoeSzymanski
Copy link
Contributor

Thanks. I'll look into getting that done shortly.

@simpleshadow
Copy link

simpleshadow commented Jan 20, 2017

@JoeSzymanski Did you ever get around to committing or making a PR for the PFEncoder header changes you mentioned? I'm running into an issue where pointers are causing LiveQuery to crash on iOS and thinking what you were suggesting would fix it. 😬

EDIT: I managed to figure out how bridge the necessary headers to access PFEncoder in QueryEncoder.swift and added your suggested code and all seems to be working! 🙌 I've confirmed the pointer objects are being returned properly in my LiveQuery. 👍

@JoeSzymanski
Copy link
Contributor

@simpleshadow That should be fixed with #87 We've been using it in our recent work without any problems.

Create private headers to access the PFEncoder classes. Update the
encoding of queries into dictionaries to properly use Parse's encoder
for any PFObject subclasses.
@flovilmart flovilmart merged commit 5eb6f37 into master Feb 23, 2017
@flovilmart flovilmart deleted the fix-object-decoding branch February 23, 2017 20:44
@chlebta
Copy link

chlebta commented Mar 10, 2017

@flovilmart still get this error : Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (PFObject)' when trying to use live query with equalTo pointer :

let query = PFQuery(className: "Message")
            .whereKey("covnersation", equalTo: PFObject(withoutDataWithClassName: "Conversation", objectId: conversationId))
        
        let subscription = ParseLiveQuery.Client.shared.subscribe(query)

@flovilmart
Copy link
Contributor Author

What version are you using?

@flovilmart
Copy link
Contributor Author

And what triggers the error?

@simpleshadow
Copy link

simpleshadow commented Mar 14, 2017

@chlebta I just recently tried updating to the latest and was seeing the issue upon attempting to use pod 'ParseLiveQuery', but it appears this installs v1.1.

Once I used pod 'ParseLiveQuery', '~> 2.0' to install 2.0, all seems to be good.

Thanks for knocking this out @flovilmart. 🙌

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

Successfully merging this pull request may close these issues.

7 participants