0

For my iOS application that uses Parse, I need to store an array of custom objects into a PFObject. I tried doing this, and I am getting the error: 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (JSQMessage)'

Is there any possible way to store an array of custom objects in Parse? I can't seem to find a good answer for this.

For your reference, I am using the JSQMessages view controller library at https://github.com/jessesquires/JSQMessagesViewController

The array that I am trying to add to the PFObject is initialized with the code:

[[NSMutableArray alloc] initWithObjects:
                        [[JSQMessage alloc] initWithText:initialtext sender:[[PFUser currentUser] objectId] date:[NSDate date]],
                                     nil];
4
  • You can only add an array of other PFObjects or base types (Boolean, string..) . You cannot add an array of arbitrary objects Commented Jul 26, 2014 at 21:30
  • @Paulw11 Is there any way to store the information in a PFObject, perhaps by converting it to some other valid data type? Commented Jul 26, 2014 at 21:35
  • Have you read the parse documentation on objects? Commented Jul 26, 2014 at 22:15
  • Yes, you can make a new PFObject type in your Parse.dashboard and create instances of that type for each of your JSQMessages. You can then add these PFObjects to an array column in your existing PFObject. The Parse API automatically resolves the object references - See the relational data section - parse.com/docs/ios_guide#objects-pointers/iOS Commented Jul 26, 2014 at 22:27

1 Answer 1

1

If your custom objects conform to the NSCoding protocol then yes, you can save them most definitely.

Here's an example for a Magic: The Gathering set

@interface MTGSet : NSObject <NSCoding>

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *code;
@property (nonatomic, strong) NSDate *releaseDate;

@end

Implementation

#import "MTGSet.h"

@implementation MTGSet

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeObject:_code forKey:@"code"];
    [aCoder encodeObject:_releaseDate forKey:@"releaseDate"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    return [self initWithJSONDictionary:
            @{@"name" : [aDecoder decodeObjectForKey:@"name"],
              @"code" : [aDecoder decodeObjectForKey:@"code"],
              @"releaseDate" : [aDecoder decodeObjectForKey:@"releaseDate"]}];
}

@end

Usage

MTGSet *set = [MTGSet new];
set.name = @"Magic 2015";
set.code = @"M15";
set.releaseDate = [NSDate date];

NSData *dataFromSet = [NSKeyedArchiver archivedDataWithRootObject:set];
PFObject *object = [PFObject objectWithClassName:@"MyObject"];
object[@"set"] = dataFromSet;
[object save];

MTGSet *unarchivedSet = [NSKeyedUnarchiver unarchiveObjectWithData:object[@"set"]];
NSLog(@"Here's the set: %@", unarchivedSet);

There are libraries out there to make this easier using the objective-c runtime which I recommend.

https://github.com/eladb/Parse-NSCoding

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.