Start a new topic

Relational Data - Invalid type in JSON write (KCSKinveyRef)

I am new to Kinvey but I am experiencing difficulties using Relational Data


- I am using KinveyKit-1.40.4

- I am following the steps outlined in http://devcenter.kinvey.com/ios/guides/datastore

- I am using KCSLinkedAppdataStore

- I have confirmed that both entities are configured correctly and save individually but when I attempt to update them with a relationship (single or multiple) I get an exception.


'NSInvalidArgumentException', reason: 'Invalid type in JSON write (KCSKinveyRef)'


Can anyone suggest a possible solution? I am missing an important step?


2 people have this question

Hello,

I have been having problems saving a little more complex relational data so I created some simple tests to pinpoint the problem.  My root object A contains a collection of objects B, object B contains a collection of objects C and object C contains a collection of objects D. In my first test,  I only have one object in every of those collections - A contains one object B, B Contains only one object C, and C contains only one object D - save works fine. However, if the tree has two branches - A contains two B's and the rest is the same - save does not work. It gives no error but never goes to the completion block. Query works fine though.


Then I removed one of the two D objects so that one branch ends with C and the other with D  and save worked. In the KinveyDb, the Kinveyref entry of the object C whose object D was removed, that would normally has the reference info for object D, contains empty square brackets "[]".  

I am using version 1.40.7. The save is done via KCSLinkedAppdataStore and referenceKinveyPropertiesOfObjectsToSave.  Thank you 

Hello Everyone,


Mr LoPinto is absolutely correct. There is a bug with the iOS SDK v1.40.6. When it was discovered, the fix was made immediately and iOS SDK v1.40.7 was created and made available for download last night. I have submitted a request to remove 1.40.6 from the iOS download site but that said, 1.40.7 is the version everyone should use.


Regards,


Billy Gee

Wood Wayfarer:


That might have been a bug in version 1.40.6 of the SDK, rather than directly related to the relational data issue. I also received that error when making queries after upgrading from 1.40.5 to 1.40.6. Upgrading to 1.40.7 solved the problem.


See this thread: https://support.kinvey.com/support/discussions/topics/12000002270.

Thank you very much, Billy and Damien. I look forward to trying it out!

Hi , each time when I use KCSLinkedAppdataStore in  release 1.40.6  I get next exception 


2016-04-07 11:21:19.515 BooksAround[2315:685126] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSDictionaryM: 0x16193b9d0> was mutated while being enumerated.'

*** First throw call stack:

(0x18146ee38 0x180ad3f80 0x18146e86c 0x100431cf4 0x100431f2c 0x10043204c 0x1003c9ea0 0x1003c9fd0 0x1003b8e00 0x1003b99f8 0x1003b9840 0x1003ba3c4 0x1003bb534 0x100438754 0x181e2a904 0x10057da3c 0x10058a554 0x10058172c 0x10058c66c 0x10058c364 0x1810d1470 0x1810d1020)

libc++abi.dylib: terminating with uncaught exception of type NSException


In 1.40.5 it worked ok

Best Regards

Wood


Hello Everyone,


The problem that Damien is referencing in his last update on March 28, 2016, has been fixed in the iOS SDK release 1.40.6 which can be found and downloaded at the following URL.


http://devcenter.kinvey.com/ios/downloads


This fix is identified in the download notice as:


"Bug fix: Handling arrays for Relational Data using KCSLinkedAppdataStore"


Please let us know if you have any difficulties with this update.


Regards,


Billy Gee



2 people like this

I just wanted to follow up on this guys... We are looking to address this issue in the present sprint, it slipped from the last one due to competing priorities.   I'm going to see if I can get this prioritized to be released this week if at all possible.   


Thanks,


2 people like this
Ditto to Edward LoPinto's last comment. Great work guys.

Edward,


I'm just glad that I'm able to help a group of developers out with something, normally it's me writing to Jetbrains about how something in their IDE doesn't work exactly how I want it to, and then it turns out to be my fault.  It's wonderful to have developers finding and reporting bugs in our libraries because it makes the platform better for everyone.


Thanks again :)

Damien:


Thank you very much for looking into this for us, and I really appreciate the responsiveness of the dev team over there.

All,


Using code provided from a few people here (Edward / D Chaudhari, Richard) we have been able to recreate the issue that you guys described above and have filed this as a ticket to be addressed moving forward.   I believe our current development sprint begins today.  I am uncertain of other items that would be of competing priority, but I would expect a patch to our SDK in no longer than 2 weeks time (the end of the sprint) and very likely before then.


Thanks again for your help.


1 person likes this

All,


We are currently reviewing multiple code submissions by your guys and we are working to see if there are issues with our implementation of how relational objects are implemented.  If it turns out there is a bug, it will be addressed in a future version of the SDK.  In the event that it is poorly documented, we will follow up with making the documentation more robust.   It is worth noting that Kinvey development teams observe 2 week sprints and the current sprint ends today (with the next one beginning tomorrow), so there is a bit of a time crunch for our team to finish other things before addressing this.  I have asked one of our developers to take a look at this and I will update this post with his findings.  


Thank you all for your reports, code samples, and help in addressing this issue.



Damien:


I realize you're responding to D Chaudhari's message and the world doesn't revolve around me, but I find it rather frustrating that my questions and code examples are being ignored. You have mentioned the example in the dev center and the dev center's explanation of limitations, but as I've posted several times, I have copied that example and run it in a sample app, and it does not work.


Here is the Event class, copied directly from the example: https://git.io/v2j2b

Here is the Invitation class, copied directly from the example: https://git.io/v2jas

And here is my attempt to save them in a one-many relationship: https://git.io/v2jai


I realize that my attempt to save might be flawed, but I can't figure out why, and it would be wonderful if someone could explain it. It would help me and, I think, the other developers following this thread.


It would also be nice if someone could explain why my saves fail when the referenced objects have properties that are KinveyRefs. I include well-commented examples of that in that GitHub repo.


Thanks


1 person likes this

OK. Let me try explaining:


Lets assume we have Object A and Object B. Object A contains array of Object B. Hence, 1-many relationship.


 ObjectA class: 

class ObjectA: NSObject {
    
    var entityId: String?               // Kinvey entity _id
    var title: String?                   
    var metadata: KCSMetadata?          // Create, Updated and Creator
    var items: [ObjectB]         // Referenced of type ObjectB

    override func hostToKinveyPropertyMapping() -> [NSObject : AnyObject]! {
        return [
            "entityId" : KCSEntityKeyId,
            "title" : "title",
            "metadata" : KCSEntityKeyMetadata,
            "items" : "items"
        ]
    }
    
    class override func kinveyPropertyToCollectionMapping() -> [NSObject : AnyObject]! {
        return [
            // backend to collection name
            "items" : "ItemsCollection"
        ]
    }
    
    class override func kinveyObjectBuilderOptions() -> [NSObject : AnyObject]! {
        return [
            KCS_REFERENCE_MAP_KEY : [
                // property name to object
                "items" : ObjectB.self
            ]
        ]
    }
}

  

Object B class:


 

class ObjectB: NSObject {
    
    var entityId: String?               // Kinvey entity _id
    var subTitle: String?                   
    var metadata: KCSMetadata?          // Create, Updated and Creator

    override func hostToKinveyPropertyMapping() -> [NSObject : AnyObject]! {
        return [
            "entityId" : KCSEntityKeyId,
            "subtitle" : "subtitle",
            "metadata" : KCSEntityKeyMetadata
        ]
    }
 
    }

 

Now, lets say I create an ObjectA and try to save it, it will run into the issue or get [null, null] as reference entries in my collection:

 

"NSInvalidArgumentException, reason: Invalid type in JSON (KCSKinveyRef)

 Why? Because ObjectA contains array of ObjectB in the ObjectA.items property. And Since I haven't yet created ObjectB in the Kinvey database, ObjectB.entityId is "null". What I am trying to do/assume is that IF I save ObjectA and ObjectA contains references to ObjectB, it will also create ObjectB items in the ObjectB collection.

What I am assuming (and expecting) here is that saving ObjectA via KCSLinkedAppdataStore will also create ObjectB entries mentioned in ObjectA.items. But this is not the case -- instead it inserts [null, null, null] in ObjectA's collection.


But, if I create all the ObjectB items in the Kinvey database (collection), and get the ObjectB.entityId from the DB, and then try to save ObjectA via KCSLinkedAppdataStore, then ObjectA collection will save ObjectB references in "items" field.


Looking at the example here: http://devcenter.kinvey.com/ios/guides/datastore#limitations, may be what I am expecting is incorrect. And that what I am observing is the correct behaviour. 


At this point, I just want to verify that the actual behaviour is the expected one.


Actual behaviour:

For saving 1-many relationship references, you need to create child references first before saving the parent object.

If this is the case, you may want to highlight this in your datastore documentation in a yellow box.


Thanks,


The problem is during the save, when I save an Event with a one-to-one relationship Invitation (var invitation: Invitation?) every works but when I try to save the same invitation inside to-many relationship using either an array with the data type declared (var invitations: [Invitation]?) or a mutable set (var invitationsSet: NSMutableSet?) it fails. As if the SDK does not know how to parse an array of Entities.


I have upload a sample to https://github.com/rtrevivian/KinveyRelationalData

Login or Signup to post a comment