Start a new topic

Saving UIImage property causing NSInvalidArgumentException

I'm trying to save an entity with an UIImage property, but am getting a *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (KCSFile)' error. Is there an error in my code?


 Header file:

@interface Obj : NSObject <KCSPersistable>

@property (atomic, strong) NSString* entityId;
@property (atomic, strong) UIImage* photo;
@end


Implementation file: 

#import "Obj.h"

@implementation Obj

@synthesize entityId, photo;

- (NSDictionary *)hostToKinveyPropertyMapping
{
    return @{
             @"entityId" : KCSEntityKeyId, //the required _id field
             @"photo" : @"photo"
             };
}

+ (NSDictionary *)kinveyPropertyToCollectionMapping {
    return @{@"photo" : KCSFileStoreCollectionName};
}

@end

   

Saving: 

KCSCollection* collection = [KCSCollection collectionFromString:@"Ojb" ofClass:[Obj class]];
KCSLinkedAppdataStore* store = [KCSLinkedAppdataStore storeWithOptions:@{ KCSStoreKeyResource : collection }];

...


[store saveObject:objWithImage withCompletionBlock:^(NSArray *objectsOrNil, NSError *errorOrNil) {
    NSLog(@"saved");
} withProgressBlock:nil];

   


have you been able to get any relationships save? I have been struggling with this for most of the day... the example documentation is weak and I cannot find any example code in the wild, I wonder if that is because no one is really using the IOS API?

Isaac / Aaron, 


We have a lot of people using the iOS SDK, some of which are large enterprise companies, relations do work as intended.


At present our iOS engineer has identified that there may be a bug relating to nested relations (when you nest a relation inside of another object) which may cause them to fail at this time.  We are still investigating this at this time however.


I will update this ticket with news on that issue.


Thanks,

I''m looking forward to it as well. Since parse shutdown kinvey has been my favourite so we've got fingers crosses waiting ....

Has Image linking with Data been fixed yet? 

Josh, it has not.  Our sprints run for 2 weeks here at Kinvey.  At the end of a 2 week period we'll typically release an update to the SDK, sooner if it's an urgent bug.   In this case our library team has been made aware and they should be following up soon.


I'll update this thread when a fix goes live.


Thanks,

Hi Damien,

since yesterday I have a similar problem..  

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__NSSetM)'


I was able to pinpoint my problem.. !

I have added the push notification and uploaded the .p12 file ... 

and since then I get this problem every time I update my user.

although sometimes it worked however, usually I get this error with the first Update on the user.


e.g:


let myUser:KCSUser = KCSUser.activeUser()!

let geocoord = locationManager.location

myUser.setValue(geocoord, forAttribute: KCSEntityKeyGeolocation)

myUser.saveWithCompletionBlock{ (results, error) -> Void in



so.. at the moment I can't save my own additional data to KCSUser

MUST I add an extension to the KCSUser class ?  I did not specify any KCSUser class in swift


till yesterday without the push notification it worked perfect !


if you need any additional information.. just drop me an e-mail: peter@schafflechner.com







2 people like this

@Peter Schafflechner I'm having hard time adding additional info to the active user... I wanna add profile picture to the user and location . If you could post your entire code I think it'd be helpful!

Hi Samuel,

as mentioned before.. adding data to the active user worked well before I added the push notification certificate on Friday..

however, this is the code which worked for me adding the location


its not the cleanest.. I know.. however I changed it from parse to kinvey this way and it worked


  

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
    //        let latitude  = locationManager.location!.coordinate.latitude
    //        let longitude = locationManager.location!.coordinate.longitude
        
        if KCSUser.activeUser() != nil
        {

          let myUser:KCSUser = KCSUser.activeUser()!
          let geocoord = locationManager.location

          myUser.setValue(geocoord, forAttribute: KCSEntityKeyGeolocation)
          myUser.saveWithCompletionBlock{ (results, error) -> Void in

            if(error != nil) {
                print(error)
            } else {
                print("User details are now updated")
            }
          }
        }
    }

 

for the profile pic, I am currently using a workaround.. my app is going only to accept Facebook logins and I am not copying currently the profile pic to Kinvey DB.. I only save the Facebook url link from the profile image in a String 

to save the profile in pic I suggest you work through this article : Kinvey part 1


however, here is my code for loading the Facebook data to the Kinvey user..  sorry for all the print(..) statements.. It was also my first with this app.. so I was a lot of troubleshooting too..  (did not had time yet to clean up the code)


  

func loadFBDetails()  {
        
        print("get FB Details")
    
        let requestParameters = ["fields": "id, email, first_name, last_name"]
        
//        let userDetails = FBSDKGraphRequest(graphPath: "me", parameters: requestParameters)
        let userDetails = FBSDKGraphRequest(graphPath: "me", parameters: requestParameters, tokenString: self.fbRequestToken, version: nil, HTTPMethod: "GET")
        
        print ("before connection")
            
         userDetails.startWithCompletionHandler({ (connection, result, error:NSError!) -> Void in
            
            print ("connection")
            if(error == nil)
            {
             print("result")
             print(result)
            }
            else
            {
                print("FB Graph error")
                print("\(error.localizedDescription)")
                return
            }
            
            if(result != nil)
            {

                let userId:String = result.valueForKey("id") as! String
                let userNameFB:String? = result.valueForKey("name") as? String
                let userFirstName:String? = result.valueForKey("first_name") as? String
                let userLastName:String? = result.valueForKey("last_name") as? String
                let userEmail:String? = result.valueForKey("email") as? String
//                let geocoord:CLLocation =  CLLocation()
                
                print("id\(userId)")
                print("\(userEmail)")
                
                let myUser:KCSUser = KCSUser.activeUser()!
                
                // Save first name
                if(userFirstName != nil)
                {
                    myUser.setValue(userFirstName!, forAttribute: "givenname")
                }
                
                // Save user name
                if(userNameFB != nil)
                {
                    myUser.setValue(userNameFB!, forAttribute: "nameFB")
                    
                }
                
                //Save last name
                if(userLastName != nil)
                {
                    myUser.setValue(userLastName!, forAttribute: "surname")
                }
                
                // Save email address
                if(userEmail != nil)
                {
                    myUser.setValue(userEmail!, forAttribute: "email")
                }
                
 /*
                let geocoord = CLLocation()
                myUser.setValue(geocoord, forAttribute: KCSEntityKeyGeolocation)
 */               
                
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
                    
                    //  let image =  UIImage(data: NSData(contentsOfURL: NSURL(string:"https://graph.facebook.com/" + userId + "/picture?type=large")!)!)

                    // Get Facebook profile picture
                    let userProfile = "https://graph.facebook.com/" + userId + "/picture?type=large"
                    
                    let profilePictureUrl = NSURL(string: userProfile)
                    
                    let profilePictureData = NSData(contentsOfURL: profilePictureUrl!)
                    
                    if(profilePictureData != nil)
                    {
                        myUser.setValue(userProfile, forAttribute: "profile_url")
                    }
                    
                    
                    myUser.saveWithCompletionBlock{ (results, error) -> Void in
                        
                        if(error != nil) {
                            print(error)
                        } else {
                            
                            print("User details are now updated")
                        }
                    }
                }
                
            }
            
        })
        
    }
     

  

 

Thanks for your help. I've been able to  add location to the active User. I'm waiting for their new SDK before i can attach profile picture. Well, I didn't plan of adding facebook login but i may consider that . Parse was easier but i guess we don't have much choice now.  

Hi Damien,

any Feedback on the:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__NSSetM)'


I still have the problem and can not save any additional data to the user


thanks..

@Damien, we're looking forward to the release of the new SDK..

In the mean time i believe that migrating my database to REALM Solved all my problms https://realm.io/

All


This issue should be resolved in the most recent version of the application, available over here:  http://devcenter.kinvey.com/ios/downloads


Thanks,


1 person likes this
Login or Signup to post a comment