Start a new topic
Answered

Can't save relational data

I want to save following Event object 

class Event: NSObject,KCSPersistable  {
    var entityId: NSString? //Kinvey entity _id
    
    var author: KCSUser?
    var name: NSString?
    var details: NSString?
    var picture: UIImage?
    var date: NSDate?
    var location: String?
    
    var metadata: KCSMetadata? //Kinvey metadata, optional
    override init(){
        super.init()
        author = KCSUser.activeUser()
        name = ""
        details = ""
        picture = nil
        date = nil
        location = ""
    }
    internal override func hostToKinveyPropertyMapping() -> [NSObject : AnyObject]! {
        return [
            "entityId" : KCSEntityKeyId, //the required _id field
            "author" : "author",
            "name" : "name",
            "details" : "details",
            "picture" : "picture",
            "date" : "date",
            "location" : "location",
            "metadata" : KCSEntityKeyMetadata //optional _metadata field
        ]
    }
    
    internal class override func kinveyPropertyToCollectionMapping() -> [NSObject : AnyObject]! {
        return [
            "author" : KCSUserCollectionName
        ]
    }

}

 in the "Events" table
with following code

  

let store = KCSLinkedAppdataStore.storeWithOptions([
            KCSStoreKeyCollectionName : "Events",
            KCSStoreKeyCollectionTemplateClass : Event.self
            ])

        var eventToSend:Event = Event()
        eventToSend.author = KCSUser.activeUser()
        eventToSend.name = eventName.text
        eventToSend.details = eventDescription.text
        eventToSend.date = eventDate
        eventToSend.picture = eventPicture.image
        eventToSend.location = "Location"
        
        store.saveObject(eventToSend, withCompletionBlock: {
            (objects:[AnyObject]!, error:NSError!) -> Void in
            if (error == nil){
                println("saved")
                NSLog("Successfully saved event (id='%@').", (objects[0] as Event).kinveyObjectId())

            }else{

                println("error" + error.description)
                println(error.userInfo!["Kinvey.ExecutedHooks"])
                
                
            }
            }, withProgressBlock: nil) 

 and what I get is, 

The request body is either missing or incomplete.
Tried debugging , but it didn't specify the problem, replaced store's type from KCSAppdataStore to KCSLinkedAppdataStore, still didn't help.


Best Answer

Nevermind,  I found reason of all my troubles, 
I was adding fetched entities to the NSMutableArray  with addobject,
Instead I should have created an array of specific type var events[Event] = [] and add entities by events.append(object)


I am sorry for double-triple posting but seems that my posts don't appear sometimes

Don't worry about it, that's the spam filter, which seems to like to call code spam sometimes, it requires manual approval which generally requires someone being awake.


Thanks,

So basically I fetched the entity , and debugger told me that entity exists,  even though I cant access its properties including image , it receives the imagefile id ,which I can confirm from my table management tools on website, however it still doesnt load the image itself.

Fixed, however now when I extract entity with KCSLinkedDataStore ( it contains UIImage as one of the properties),I get out "no such table: blob__blob"



Tried everything but still can't extract image :(
What I am trying to get is that Entity Event will have a property of picture ,which is extractable, but even though all the rest of 'Event' is being fetched,  picture is still unavailable, still that "blob wasn't registered for your backend".

Grisha,


Can you take a look at the object in the debugger to ensure that it exists?  A lot of times with relational data we will load a "stub" of the data contained in the actual object, which you can then resolve to get the actual object.  Stubs generally don't have downloadURL's, and as such could give this error.


Thanks,

Hello Grisha,


When dealing with references they need to be resolved, you will get back an id and a KinveyRef.   You can check out the iOS guide for fetching relational data over here:  http://devcenter.kinvey.com/ios/guides/datastore#relationaldataretrieve 


Thanks,

Fixed with help of this thread https://support.kinvey.com/support/discussions/topics/5000041252.
However, when I try to fetch the property

 

        let store = KCSLinkedAppdataStore.storeWithOptions([
            KCSStoreKeyCollectionName : "Events",
            KCSStoreKeyCollectionTemplateClass : Event.self
            ])
        
        var query:KCSQuery = KCSQuery()
        store.queryWithQuery(
        query,
        withCompletionBlock: {
            (objectsOrNil: [AnyObject]!, error: NSError!) -> Void in
            if (error == nil){
                var objects = objectsOrNil as [Event]
                for object in objects{
                    EventsData.addObject(object)
                }
                self.TimelineData = EventsData
                self.tableView.reloadData()
                self.refreshControlForTimeLine.endRefreshing()
            }else{
                println("Error: " + error.description)
                self.refreshControlForTimeLine.endRefreshing()

            }

            
        },
        withProgressBlock: nil)

 



that's what I get


2015-05-10 00:44:48.728 Eventer[1998:937325] DB Error: 1 "no such table: blob__blob"
2015-05-10 00:44:48.728 Eventer[1998:937325] DB Query: SELECT * FROM [blob__blob] WHERE id='Events-85431D6D-5809-47A4-8AAE-69C7D183F2DA-picture'
2015-05-10 00:44:48.729 Eventer[1998:937325] DB Path: /var/mobile/Containers/Data/Application/B88F11D3-CA1D-4592-91FB-D246A412201E/Library/Caches/kinvey/com.kinvey.offline_cache.sqlite3
2015-05-10 00:44:48.742 Eventer[1998:937222] DB Error: 1 "no such table: blob__blob"
2015-05-10 00:44:48.742 Eventer[1998:937222] DB Query: SELECT * FROM [blob__blob] WHERE id='Events-45D51013-6024-40EB-8A1C-98A265EC884D-picture'
2015-05-10 00:44:48.743 Eventer[1998:937222] DB Path: /var/mobile/Containers/Data/Application/B88F11D3-CA1D-4592-91FB-D246A412201E/Library/Caches/kinvey/com.kinvey.offline_cache.sqlite3
2015-05-10 00:44:49.098 Eventer[1998:937185] DB Error: 1 "no such table: blob__blob"
2015-05-10 00:44:49.099 Eventer[1998:937185] DB Query: DELETE FROM [blob__blob] WHERE id='Events-85431D6D-5809-47A4-8AAE-69C7D183F2DA-picture'
2015-05-10 00:44:49.100 Eventer[1998:937185] DB Path: /var/mobile/Containers/Data/Application/B88F11D3-CA1D-4592-91FB-D246A412201E/Library/Caches/kinvey/com.kinvey.offline_cache.sqlite3
2015-05-10 00:44:49.101 Eventer[1998:937185] DB Error: 1 "no such table: blob__blob"
2015-05-10 00:44:49.102 Eventer[1998:937185] DB Query: DELETE FROM [blob__blob] WHERE id='Events-45D51013-6024-40EB-8A1C-98A265EC884D-picture'
2015-05-10 00:44:49.103 Eventer[1998:937185] DB Path: /var/mobile/Containers/Data/Application/B88F11D3-CA1D-4592-91FB-D246A412201E/Library/Caches/kinvey/com.kinvey.offline_cache.sqlite3
Error: Error Domain=KCSResourceErrorDomain Code=404 "Error downloading file, id='Events-45D51013-6024-40EB-8A1C-98A265EC884D-picture'" UserInfo=0x174673600 {NSLocalizedDescription=Error downloading file, id='Events-45D51013-6024-40EB-8A1C-98A265EC884D-picture', NSUnderlyingError=0x17044a9e0 "This blob not found for this app backend"}
saved
2015-05-10 00:46:02.689 Eventer[1998:937185] Successfully saved event (id='005917DF-E71D-49EB-AB18-21A33F1F0343').
2015-05-10 00:46:05.939 Eventer[1998:937513] DB Error: 1 "no such table: blob__blob"
2015-05-10 00:46:05.940 Eventer[1998:937513] DB Query: SELECT * FROM [blob__blob] WHERE id='Events-005917DF-E71D-49EB-AB18-21A33F1F0343-picture'
2015-05-10 00:46:05.940 Eventer[1998:937513] DB Path: /var/mobile/Containers/Data/Application/B88F11D3-CA1D-4592-91FB-D246A412201E/Library/Caches/kinvey/com.kinvey.offline_cache.sqlite3
2015-05-10 00:46:06.301 Eventer[1998:937185] DB Error: 1 "no such table: blob__blob"
2015-05-10 00:46:06.302 Eventer[1998:937185] DB Query: DELETE FROM [blob__blob] WHERE id='Events-005917DF-E71D-49EB-AB18-21A33F1F0343-picture'
2015-05-10 00:46:06.302 Eventer[1998:937185] DB Path: /var/mobile/Containers/Data/Application/B88F11D3-CA1D-4592-91FB-D246A412201E/Library/Caches/kinvey/com.kinvey.offline_cache.sqlite3
Error: Error Domain=KCSResourceErrorDomain Code=404 "Error downloading file, id='Events-005917DF-E71D-49EB-AB18-21A33F1F0343-picture'" UserInfo=0x17466c080 {NSLocalizedDescription=Error downloading file, id='Events-005917DF-E71D-49EB-AB18-21A33F1F0343-picture', NSUnderlyingError=0x170448bb0 "This blob not found for this app backend"}

 

2015-05-12 00:36:05.913 Eventer[3163:1459010] Successfully saved event (id='7EE1A74C-A2D9-43EB-9EE0-306A87C7F481').

Then I try to fetch it:

2015-05-12 00:37:04:791 KCSNSURLSessionOperation:128 [INFO (NETWORK)] received response: 404 {

 "Content-Length" = 103;

 "Content-Type" = "application/json; charset=utf-8";

 Date = "Mon, 11 May 2015 23:37:04 GMT";

 Server = "ngx_openresty";

 "X-Kinvey-API-Version" = 3;

 "X-Kinvey-Request-Id" = ca593b57ff1d4fde98d467e804691f1e;

 "X-Powered-By" = Express;

} (KinveyKit ID F71F7D3A-C765-4C99-8B21-26AB49476334)

2015-05-12 00:37:04:795 KCSRequest2:470 [INFO (NETWORK)] Kinvey Server Error (404) {

 debug = "";

 description = "This blob not found for this app backend";

 error = BlobNotFound;

} [KinveyKit id: 'F71F7D3A-C765-4C99-8B21-26AB49476334' {

 "Content-Length" = 103;

 "Content-Type" = "application/json; charset=utf-8";

 Date = "Mon, 11 May 2015 23:37:04 GMT";

 Server = "ngx_openresty";

 "X-Kinvey-API-Version" = 3;

 "X-Kinvey-Request-Id" = ca593b57ff1d4fde98d467e804691f1e;

 "X-Powered-By" = Express;

}]

2015-05-12 00:37:04:800 KCSEntityPersistence:507 [DEBUG (FILESYSTEM)] Deleting obj Events-7EE1A74C-A2D9-43EB-9EE0-306A87C7F481-picture from cache

2015-05-12 00:37:04.803 Eventer[3163:1459010] DB Error: 1 "no such table: blob__blob"

2015-05-12 00:37:04.804 Eventer[3163:1459010] DB Query: DELETE FROM [blob__blob] WHERE id='Events-7EE1A74C-A2D9-43EB-9EE0-306A87C7F481-picture'

2015-05-12 00:37:04.805 Eventer[3163:1459010] DB Path: /var/mobile/Containers/Data/Application/5774B830-72FC-47EF-AE87-A1A98B5A6D4C/Library/Caches/kinvey/com.kinvey.offline_cache.sqlite3

2015-05-12 00:37:04:806 KCSEntityPersistence:515 [ERROR (FILESYSTEM)] Cache error 1: no such table: blob__blob

Error: Error Domain=KCSResourceErrorDomain Code=404 "Error downloading file, id='Events-7EE1A74C-A2D9-43EB-9EE0-306A87C7F481-picture'" UserInfo=0x17486ba00 {NSLocalizedDescription=Error downloading file, id='Events-7EE1A74C-A2D9-43EB-9EE0-306A87C7F481-picture', NSUnderlyingError=0x170851340 "This blob not found for this app backend"}

That's what happens, it shows that object was found and added to NSMutableArray but image cant be found

That's my Entity object declaration:

 

class Event: NSObject,KCSPersistable  {
    var entityId: NSString? //Kinvey entity _id
    
    var author: KCSUser?
    var name: NSString?
    var details: NSString?
    var picture: UIImage?
    var date: NSDate?
    var location: NSString?
    
    var metadata: KCSMetadata? //Kinvey metadata, optional
    override init(){
        super.init()
        author = KCSUser.activeUser()

    }
    internal override func hostToKinveyPropertyMapping() -> [NSObject : AnyObject]! {
        return [
            "entityId" : KCSEntityKeyId, //the required _id field
            "author" : "author",
            "name" : "name",
            "details" : "details",
            "picture" : "picture",
            "date" : "date",
            "location" : "location",
            "metadata" : KCSEntityKeyMetadata //optional _metadata field
        ]
    }
    
    internal class override func kinveyPropertyToCollectionMapping() -> [NSObject : AnyObject]! {
        return [
            "author" : KCSUserCollectionName,
            "picture": KCSFileStoreCollectionName
        ]
    }
}

 

I realized that my problem was that I can't acess ANY property of entities , even usual NSString one.What do I do ?

 

var event:Event!
var query:KCSQuery = KCSQuery()
store.queryWithQuery(
query,
withCompletionBlock: {
    (objects: [AnyObject]!, error: NSError!) -> Void in
    if (error == nil){
         
        if objects.count > 0{
            event = objects[0] as Event
            println(event.name)
        }
         
        self.TimelineData = EventsData
        self.tableView.reloadData()
        self.refreshControlForTimeLine.endRefreshing()
    }else{
        println("Error: " + error.description)
        self.refreshControlForTimeLine.endRefreshing()
    }
},
withProgressBlock: nil)

 

 This is exactly as in your tutorial , however I get app crash on println(event.name) line

Answer

Nevermind,  I found reason of all my troubles, 
I was adding fetched entities to the NSMutableArray  with addobject,
Instead I should have created an array of specific type var events[Event] = [] and add entities by events.append(object)

Apologies that I didn't notice that earlier Grisha,


Are you all set now?



Yes , problem is solved, thank you.

Login or Signup to post a comment