Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Alex Taylor
2,758 PointsError when saving PFObject(subclass) as PFRelation - Invalid Type
Hi All,
I have created an object (subclass PFObject) and am trying to set the object as a relation to the current user. Upon save, I get the error message: Error: invalid type for key score, expected string, but got number (Code: 111, Version: 1.2.18)
I have been stuck on this for a few days. On reading the documentation I thought all property types (int etc) were automatically handled by parse? So I am not sure why it is expecting a string?
Here is my code below. The interface and implementation for my GolfScore Class. Then in the PostScore View Controller implementation I am trying to initialise an instance of GolfScore, and set the properties with data entered from the user. (I have set some properties to type (int) as I need to do a calculation on them.) Then I am trying to save the object Golf Score as a relation to PFUser.
//Initialise instance of golf score object (PFObject subclass)
GolfScore *newScore = [[GolfScore alloc] init];
newScore.datePlayed = [dateFormatter dateFromString:self.datePlayedField.text];
newScore.courseName = courseName;
newScore.courseRating = [courseRating intValue];
newScore.courseSlope = [courseSlope intValue];
newScore.score = [score intValue];
//Calculate handicap differential
[newScore HandicapDifferentialCalc];
//Save object in background
[newScore saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
//If successful save, then set relation to current user, and add new object.
if (!error)
self.golfScoreRelation = [self.currentUser relationforKey:@"golfScoreRelation"];
[self.golfScoreRelation addObject:newScore];
[self.currentUser saveInBackground];
I have followed all the guidelines provided by parse on how to set up a subclass of PFObject. Any help would be really appreciated as this is starting to drive me crazy :) Thanks heaps, Alex
3 Answers
Guillaume Maka
Courses Plus Student 10,224 PointsWhat's king of relation do you want to implement ? Many-to-Many, One-to-Many... ? For a one-to-many you can do the opposite and store the PFUser into GolfScore (a score has one user, a user has many score)
GolfScore *newScore = [[GolfScore alloc] init];
newScore.datePlayed = [dateFormatter dateFromString:self.datePlayedField.text];
newScore.courseName = courseName;
newScore.courseRating = [courseRating intValue];
newScore.courseSlope = [courseSlope intValue];
newScore.score = [score intValue];
// create a new property in GolfScore.h
newScore.user = [PFUser currentUser];
[newScore saveEventually];
// To retrieve all score for the currentUser;
PFQuery * userScoresQuery = [PFQuery queryWithClassName:@"GolfScore"]l
[userScoresQuery whereKey:@"user" equalTo:[PFUser currentUser]];
[userScoresQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(@"Successfully retrieved %d golf scores.", objects.count);
// Do something with the found objects
for (PFObject *object in objects) {
NSLog(@"%@", object.objectId);
}
} else {
// Log details of the failure
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
Guillaume Maka
Courses Plus Student 10,224 PointsThe documentation state:
Initializing Subclasses
You should create new objects with the object class method. This constructs an autoreleased instance of your type and correctly handles further subclassing. To create a reference to an existing object, use objectWithoutDataWithObjectId:.
in GolgScore.m
// - remove the init method
// - change user property type from NSObject to PFUser
@property(nonatomic, strong) PFUser *user;
In AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// make sure your register the subclass
[GolfScore registerSubclass];
// setup parse
[Parse setApplicationId:parseAppId clientKey:parseClientKey];
}
then in your code
GolfScore *newScore = [GolfScore object];
newScore.datePlayed = [dateFormatter dateFromString:self.datePlayedField.text];
newScore.courseName = courseName;
newScore.courseRating = [courseRating intValue];
newScore.courseSlope = [courseSlope intValue];
newScore.score = [score intValue];
newScore.user = [PFUser currentUser];
[newScore saveEventually];
// To retrieve all score for the currentUser;
PFQuery * userScoresQuery = [PFQuery queryWithClassName:@"GolfScore"]l
[userScoresQuery whereKey:@"user" equalTo:[PFUser currentUser]];
[userScoresQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(@"Successfully retrieved %d golf scores.", objects.count);
// Do something with the found objects
for (PFObject *object in objects) {
NSLog(@"%@", object.objectId);
}
} else {
// Log details of the failure
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
Alex Taylor
2,758 PointsThanks for taking the time on this, I followed it all, but got the error message below:
2014-05-28 09:17:19.824 GolfHandicapCalc[65110:60b] Successfully retrieved 0 golf scores. 2014-05-28 09:17:19.863 GolfHandicapCalc[65110:5413] Error: invalid type for key score, expected string, but got number (Code: 111, Version: 1.2.18) 2014-05-28 09:17:19.864 GolfHandicapCalc[65110:380f] runEventually command failed. Error:Error Domain=Parse Code=111 "The operation couldn’t be completed. (Parse error 111.)" UserInfo=0x10a260ee0 {error=invalid type for key score, expected string, but got number, code=111}
Guillaume Maka
Courses Plus Student 10,224 PointsDo you use Cloud Code features ? I made some research and many result involve Cloud Code, because this code and yours should work.
Alex Taylor
2,758 PointsOh my goodness, I cracked it. I am so sorry for wasting your time, and so grateful for you trying to help me out. The problem was I had initially set up an object "GolfScore" in parse, but then decided it was better to set it up as a subclass as wanted to include more logic. Parse had saved the initial field types and set them in stone, so I had to delete the previous data, and go through and rename all the properties, and it worked. Again, so sorry for wasting your time, thank you so much, Alex
Guillaume Maka
Courses Plus Student 10,224 PointsIt's ok, I'm glad you be able to resolve your problem !
Alex Taylor
2,758 PointsAlex Taylor
2,758 PointsHi there, thanks so much for your reply! I will try this out and get back to you, thanks again!
Alex Taylor
2,758 PointsAlex Taylor
2,758 PointsHi, I got the error :runEventually command failed. Error:Error Domain=Parse Code=111 "The operation couldn’t be completed. (Parse error 111.)" UserInfo=0x10a446da0 {error=invalid type for key score, expected string, but got number, code=111}
It looks like it is still not happy with the int types, darn!
Guillaume Maka
Courses Plus Student 10,224 PointsGuillaume Maka
Courses Plus Student 10,224 PointsTry to replace int by NSNumber or NSInteger and can you paste the GolfScore.h because parse says:
The key 'score' expected string, but got a numberAlex Taylor
2,758 PointsAlex Taylor
2,758 PointsI tried changing the int to NSNumber and the same error occurred. I also removed the int properties and ran the code, and the datePlayed property caused an error. "Expected NSString but got NSDate..." It seems parse will only accept NSString, but in the documentation on subclassing it states: "NSNumber properties can be implemented either as NSNumbers or as their primitive counterparts..... The dynamic getter will automatically extract the BOOL or int value and the dynamic setter will automatically wrap the value in an NSNumber. You are free to use either format."
Here are my GolfScore.h and GolfScore.m files
I warn I am new at this so hopefully I haven't made a ridiculous error...
Thanks again, Alex