How to create PFObject <SubClassing> with NSDictionary - nsdictionary

I Have a PFobject subclassing registered in AppDelegate but when I try to set a NSDictionary, it crash with message:
'NSInvalidArgumentException', reason: 'PFObject values must be serializable to JSON'
Does anyone know how to do it right, using PFObject with ???
Here's my class:
Ranking.h
#interface Ranking : PFObject<PFSubclassing>
#property (nonatomic, retain) NSDictionary *final;
#end
Ranking.m
#implementation Ranking
#dynamic final;
+(NSString *)parseClassName{
return #"FinalRanking";
}
#end
And here's the method:
-(void)saveNewRanking{
Ranking *newRanking = [[Ranking alloc]init];
NSDictionary *dic = #{#1:#20,
#2:#18};
newRanking.final = dic;
[newRanking saveInBackground];
}

Related

How do I get out data from my NSDirectory (not just a property typo)?

I'm missing something simple I think, but been at it for days now without solving this. Even Started to create a "work-around" just to solve it for now, but still want to solve this the "right" way. Any suggestions? Thank's!
.
The problem:
Seems to be missing the class Adealer (get error "-[Adealer objectAtIndex:]: unrecognized selector sent to instance 0x8c5f8b0"), but I did the import Adealer.h to this "detailsVC". But it's not just a simple error of naming the property wrong (objectForKey:#"CustName" instead of "custname" etc - tested this a lot).
Also, I've got similar "listVC"s without a class like Adealer in them, that also transfer data the same way to the same "detailsVC" and they work just fine! Then I just get the data with calls like;
self.labelRestName.text = [restDetails objectForKey:#"CustName"];
Overview:
I got a tableViewController "listVC" that creates the data and show a list, then a ViewController "detailsVC" to show the details. The data (selected row object in "listVC" is transfered via a seque and "destVC.restGPSTransfer" (NSDictionary). The data arrives ok in the "detailsVC" and looks like this in the terminal;
dealerName = Uppsala Centrum Test
dealerAdressStreet = Dragarbrunnsgatan 55
dealerAdressZip = 75320
dealerAdressCity = Uppsala
dealerLongitude = 17.63893
dealerLatitude = 59.85856
dealerDistance2 = 8586398.000000
etc
.
Following the data:
"listVC"
1) First fetching data from web via a AFNetworking json object into an NSMutableArray "restFeed" - ok.
2) Then creating my own data to an NSMutableArray within this loop into a NSMutableArray "updatedDealers" - ok;
NSMutableArray *updatedDealers = [[NSMutableArray alloc]init];
while (i+1 < [_restFeed count]) {
i++;
// Get dealer position function here
// Get distance function here
// Then create my own data here (also #imported Adealer to "listVC";
Adealer *theDealer = [[Adealer alloc]init];
theDealer.dealerName = [[_restFeed objectAtIndex:i]objectForKey:#"CustName"];
theDealer.dealerLongitude = [[_restFeed objectAtIndex:i]objectForKey:#"long"];
theDealer.dealerLatitude = [[_restFeed objectAtIndex:i]objectForKey:#"lat"];
theDealer.dealerDistance2 = theDistance;
// etc...
// Check if data ok
NSLog(#"theDealer = %#",[theDealer description]);
// Don't add dealer object without positiondata to the new array
if (![theDealer.dealerLatitude isEqualToString:#""]) {
[updatedDealers addObject:theDealer];
}
3) Then I use NSSortdescriptor to sort the dealers in NSMutableArray "updatedDealers" into distance order and finally creates the new NSMutableArray "restFeed" with this; (also did "#synthesize dealerFeed = _dealerFeed;" in "listVC") - ok.
_dealerFeed = [NSMutableArray arrayWithArray:sortedContestArray];
4) The populating some tableViewCells with this array and it works just fine - ok.;
cell.cellDealerName.text = [NSString stringWithFormat:#"%#",[[_dealerFeed objectAtIndex:indexPath.row]dealerName]];
5) In the function didSelectRowAtIndexPath transfer the selected object with the "detailsVC"'s NSDictionary "restGPSTransfer" - ok;
destVC.restGPSTransfer = [_dealerFeed objectAtIndex:myIndexPath.row];
"detailsVC":
6) The data seems to transfer ok (se top of this post) but when trying to call the data with;
self.labelRestName.text = [restGPSTransfer objectForKey:#"dealerName"];
I get this error and the app crashes: "-[Adealer objectAtIndex:]: unrecognized selector sent to instance 0x8c5f8b0".
Some more testing done...
Tried to verify the structure + it's keys and properties of the NSDictionary "restGPSTransfer", but using description only got me so far. And have not solved my problem and I still get the "unrecognized selector" error. Could it maybe have become dictionaries within dictionary's or something?
Constructed this little simple if-test to see if the property is really there. But I have to check every property "manually". There's propably a smarter way to check the hole NSDictionary / NSArray?
if ([restGPSTransfer objectForKey:#"dealerName"]) {
NSLog(#"= YES! key exists.");
} else {
NSLog(#"= Nope! key don't exists");
}
THANK'S for any help on this :-)
.
UPDATE the Adealer class files;
Adealer.h
#import <Foundation/Foundation.h>
#interface Adealer : NSObject
#property (nonatomic, retain) NSString * dealerName;
#property (nonatomic, retain) NSString * dealerAdressCity;
#property (nonatomic, retain) NSString * dealerAdressStreet;
#property (nonatomic, retain) NSString * dealerAdressZip;
#property (nonatomic, retain) NSNumber * dealerID;
#property (nonatomic, retain) NSString * dealerImages;
#property (nonatomic, retain) NSString * dealerLogo;
#property (nonatomic, retain) NSString * dealerMail;
#property (nonatomic, retain) NSString * dealerProducts;
#property (nonatomic, retain) NSString * dealerTel;
#property (nonatomic, retain) NSString * dealerText;
#property (nonatomic, retain) NSString * dealerWeb;
#property (nonatomic, retain) NSString * dealerLongitude;
#property (nonatomic, retain) NSString * dealerLatitude;
#property (nonatomic, retain) NSString *dealerDistance;
#property float dealerDistance2;
#end
Adealer.m
#import "Adealer.h"
#implementation Adealer
#synthesize dealerAdressCity, dealerAdressStreet, dealerAdressZip, dealerID, dealerImages, dealerLogo;
#synthesize dealerMail, dealerName, dealerProducts, dealerTel, dealerText, dealerWeb;
#synthesize dealerLongitude, dealerLatitude, dealerDistance,dealerDistance2;
- (NSString *)description {
// Added extension of description
NSMutableString *string = [NSMutableString string];
[string appendString:#"\ntheDealer object and it's properties:\n"];
[string appendFormat:#"dealerName = %#\n", dealerName];
[string appendFormat:#"dealerAdressStreet = %#\n", dealerAdressStreet];
[string appendFormat:#"dealerAdressZip = %#\n", dealerAdressZip];
[string appendFormat:#"dealerAdressCity = %#\n", dealerAdressCity];
[string appendFormat:#"dealerTel = %#\n", dealerTel];
[string appendFormat:#"dealerMail = %#\n", dealerMail];
[string appendFormat:#"dealerWeb = %#\n", dealerWeb];
[string appendFormat:#"dealerLogo = %#\n", dealerLogo];
[string appendFormat:#"dealerImages = %#\n", dealerImages];
[string appendFormat:#"dealerText = %#\n", dealerText];
[string appendFormat:#"dealerProducts = %#\n", dealerProducts];
[string appendFormat:#"dealerLongitude = %#\n", dealerLongitude];
[string appendFormat:#"dealerLatitude = %#\n", dealerLatitude];
[string appendFormat:#"dealerDistance = %#\n", dealerDistance];
[string appendFormat:#"dealerDistance2 = %f\n\n", dealerDistance2];
return string;
}
#end
SOLVED!
Posted if anyone else needs it here.
The solution
In my "detailsVC" I first did this iVar declaration;
.h:
Adealer *theDealer;
#property (nonatomic, retain) Adealer *theDealer;
.m:
#synthesize theDealer;
Then in my "listVC" i did this to transfer the Adealer object and it's properties to the "detailsVC" (remember that the Adealer object already has got it's properties earlier in the described "loop");
Instead of my earlier;
destVC.restGPSTransfer = [_dealerFeed objectAtIndex:myIndexPath.row];
I changed it to;
destVC.theDealer = [_dealerFeed objectAtIndex:myIndexPath.row];
And to actually show and check the transferred property in "detailsVC" I can now simply call this to get the dealers name (or any other properties);
self.labelRestName.text = theDealer.dealerName;
NSLog(#"theDealer.name = %#",theDealer.dealerName);
Works great! Happy Coding everyone!

Json serialize array in objective-c

I want to serialize array to JSON.
Here is my JSON -
{
"User":{"Id":"1222","Email":"asdad#adasd.com"},
"Person":{"Name":"John","Surname":"Smith"}
}
values 1222, asdad#adasd.com, John, Smith are examples. this values will be define in controller.
I don't know how to handle serialize this arrays inside JSON.
I need to send objects - user and person to the server with different values, depending on the user. This is my model. Both are arrays.
Here is my code
Header
#import <Foundation/Foundation.h>
#import "BaseRequest.h"
#interface SaveUserProfileRequest : BaseRequest {
NSMutableArray *_user;
NSMutableArray *_person;
NSMutableArray *_address;
NSString *_userId;
NSString *_userEmail;
NSString *_userName;
NSString *_userSurname;
}
- (id)initWithUser:(NSMutableArray*)user andPerson:(NSMutableArray*)person andAddress:(NSMutableArray*)address andUserId:(NSString*)userId andUserEmail:(NSString*)userEmail andUserName:(NSString*)userName andUserSurname:(NSString*)userSurname;
#property (nonatomic, strong) NSMutableArray* user;
#property (nonatomic, strong) NSMutableArray* person;
#property (nonatomic, strong) NSMutableArray* address;
#property (nonatomic, strong) NSString* userId;
#property (nonatomic, strong) NSString* userEmail;
#property (nonatomic, strong) NSString* userName;
#property (nonatomic, strong) NSString* userSurname;
#end
Implementation
#import "SaveUserProfileRequest.h"
#import "SaveUserProfileResponse.h"
#import "OrderedDictionary.h"
#import "BaseData.h"
#implementation SaveUserProfileRequest
#synthesize user=_user, person=_person, address=_address, userId=_userId, userEmail=_userEmail, userName=_userName, userSurname=_userSurname;
- (id)initWithUser:(NSMutableArray*)user andPerson:(NSMutableArray*)person andAddress:(NSMutableArray*)address andUserId:(NSString*)userId andUserEmail:(NSString*)userEmail andUserName:(NSString*)userName andUserSurname:(NSString*)userSurname; {
self = [super init];
if(self){
self.user = user;
self.person = person;
self.address = address;
self.userId = userId;
self.userEmail = userEmail;
self.userName = userName;
self.userSurname = userSurname;
}
return self;
}
- (NSDictionary*) serialize{
OrderedDictionary *sup = [OrderedDictionary dictionaryWithCapacity:3];
[sup setValue:self.user forKey:#"User"];
[sup setValue:self.person forKey:#"Person"];
NSArray *users = [OrderedDictionary valueForKey:#"User"];
_user = [NSMutableArray arrayWithCapacity:[users count]];
for(NSDictionary *user in users){
OrderedDictionary *userDict = [OrderedDictionary dictionaryWithCapacity:2];
[userDict setValue:self.userId forKey:#"Id"];
[userDict setValue:self.userEmail forKey:#"Mail"];
return userDict;
}
NSArray *persons = [OrderedDictionary valueForKey:#"Person"];
_person = [NSMutableArray arrayWithCapacity:[persons count]];
for(NSDictionary *person in persons){
OrderedDictionary *personsDict = [OrderedDictionary dictionaryWithCapacity:2];
[personsDict setValue:self.userName forKey:#"Name"];
[personsDict setValue:self.userSurname forKey:#"Surname"];
return personsDict;
}
return sup;
}
Please, help me a little
Every little hint will be really appreciate.
Thanks !
For handeling JSON in Objective-C, I always use JSONKit. You can fork it here: https://github.com/johnezang/JSONKit
Some examples on how it can be used:
NSArray *array = #[..];
NSString *arrayAsJsonString = [array JSONString];
NSString *string = #"..";
id objectFromJsonString = [string objectFromJSONString]; // i.e an NSArray or NSDictionary
If your app is for iOS 5 or greater, you can use NSJSONSerialization:
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html
Otherwise I recommend SBJson.

add data to my data member

Hello I'm new to iPhone development.
I try to add move data from NSDictionary to data member of calls that i created.
When i "setWeightMeasure" nothing happened.
any suggestions?
the code that don't work:
NSDictionary *responseBodyProfile = [responseBody objectFromJSONString];
NSLog(#"%#",responseBodyProfile);
// the output is :
"{ "profile": {"goal_weight_kg": "77.0000", "height_cm": "179.00",
"height_measure": "Cm", "last_weight_date_int": "15452",
"last_weight_kg": "99.0000", "weight_measure": "Kg" }}""
[responseBody release];
if (responseBodyProfile != nil ){
NSDictionary *profile =[responseBodyProfile valueForKey:#"profile"];
NSLog(#"%#\n",[profile objectForKey:#"weight_measure"]);// Output : "kg"
[self.myUser setWeightMeasure:[profile objectForKey:#"weight_measure"]];
NSLog(#"%#", [self.myUser WeightMeasure]); // Output : "(null)"
}
the H file properyty:
#property (nonatomic, retain) UserData* myUser;
UserData.h:
#import <Foundation/Foundation.h>
#interface UserData : NSObject{
NSString* Weight;
NSString* Height;
NSString* GolWeight;
NSString* WeightMeasure;
}
#property (nonatomic, retain) NSString* Weight;
#property (nonatomic, retain) NSString* Height;
#property (nonatomic, retain) NSString* GolWeight;
#property (nonatomic, retain) NSString* WeightMeasure;
#end
UserData.m
#import "UserData.h"
#implementation UserData
#synthesize Weight, Height, GolWeight, WeightMeasure;
-(id)init{
self.Weight = #"0";
self.Height = #"0";
self.GolWeight = #"0";
self.WeightMeasure = #"0";
return self;
}
-(void)dealloc{
[Weight release];
[Height release];
[GolWeight release];
[WeightMeasure release];
[super dealloc];
}
#end
Use valueForKey instead of objectForKey in this line:
[self.myUser setWeightMeasure:[profile objectForKey:#"weight_measure"]];
like this:
[self.myUser setWeightMeasure:[profile valueForKey:#"weight_measure"]];
You might also want to use, since the values could be read as NSNumbers
[self.myUser setWeightMeasure:[[profile valueForKey:#"weight_measure"] stringValue]];
And why do you use strings instead of floats? Wouldn't that make your life easier when you'd need to perform some comparisons?
Also check if you have allocated memory for "myUser", that might be the case as well.
As Eugene mentioned, you should use valueForKey instead of objectForKey
The other thing is you might wanna use property and dot notation whenever you reference your object members, as Apple recommend. It is generally good for you to manage memory.
The previous answer about not initialize your string members in your -init() was totally wrong, if that cause some confusion, I do apologize for it.

EXC_BAD_ACCESS when calling class init in Objective C

I've been trying to figure this out but I can't figure out what I'm doing wrong.
I wrote a class and whenever I try to initialize it, I get a EXC_BAD_ACCESS error. I can't even step into the initialization.
Anyone have any idea what I'm doing wrong?
User *myUser = [myUser init];
.h file:
#import <Foundation/Foundation.h>
#interface User : NSObject {
long rowId;
NSString *email;
NSString *password;
NSString *fileVersion;
}
#property long rowId;
#property (assign) NSString *email;
#property (assign) NSString *password;
#property (assign) NSString *fileVersion;
#end
.m file
#import "User.h"
#implementation User
#synthesize rowId, email, password, fileVersion;
-(id)init {
self = [super init];
return self;
}
#end
You have to actually allocate the object:
User *myUser = [[User alloc] init];
Don't forget to release it when you're done using it.

objective C filling array with custom class pointers

favorites = [[NSMutableArray alloc] init];
for (int i=0; i<9; i++) {
[favorites addObject:[[[Favorite alloc] constructUnknown] autorelease]];
}
i'm getting:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[Favorite size]: unrecognized selector sent to instance 0x380d9c0'
why?
Favorite is my custom class, favorites an array containing 9 instances of my custom class
edit:
Favorite.h:
-(Favorite*)constructUnknown;
Favorite.m:
- (Favorite*)constructUnknown{
self=[super init];
if (self) {
image=[UIImage imageNamed:#"unknown.png"];
}
return self;
}
COMPLETE FAVORITES.h
#interface Favorite : NSObject {
NSString *identity;
bool ready;
UIImage *image;
NSURL *telephone;
}
#property (nonatomic,retain) UIImage *image;
#property (nonatomic,retain) NSURL *telephone;
#property (nonatomic,retain) NSString *identity;
//passare unknown al nome per costrutire un oggetto unknown.
-(Favorite*)constructWithID:(NSString*)name withPhoto:(UIImage*)photo andNumber:(NSString*)number;
-(Favorite*)constructUnknown;
-(NSURL*) convertToUrl:(NSString*)phone;
- (UIImage*) getImage;
#end
The exception is likely because your image is not retained. Try
image = [[UIImage imageNamed:#"unknown.png"] retain];
BTW, initializers should be named as -initXXX and return an id by convention. e.g.
-(id)initWithUnknown{ ... }
Just in case someone reads this and still doesn't reach a solution, my problem was a little different I declared the object as:
#class LoginViewController;
#interface LoginViewDelegate : NSObject <UIApplicationDelegate> {
}
....
#property (nonatomic, retain) AppConfiguration *CurrentAppConfig;
....
#End
And when I was calling it:
[[self.CurrentAppConfig alloc] init];
I was getting the same error, all I had to do was use the synthesize keyword:
#implementation LoginViewDelegate
....
#synthesize CurrentAppConfig;