RestKit: mapping array of key-value pairs to NSDictionary - objective-c

Webservice sends me JSON that looks like that:
[
{"key":"key1","value":"value1"},
{"key":"key2","value":"value2"},
{"key":"key3","value":"value3"}
]
How should I set up RestKit mapping to get the following NSDictionary?
#{ #"key1" : #"value1", #"key2" : #"value2", #"key3": #"value3" }

This may help you, try this.
NSDictionary *dict1 = [[NSMutableDictionary alloc] init];
NSArray *arr = [[NSArray alloc] initWithArray:<Parse the array here from RESTkit>];
for (int i = 0;i < [arr count], i++)
{
NSDictionary *dict = [arr objectAtIndex:i];
NSString *key = [dict objectForKey:#"key"];
NSString *value = [dict objectForKey:#"value"];
[dict1 setObject:value forKey:key];
}
NSLog(#" Dictionary %#", dict1);
[dict1 release];

Related

NSDictionary Object Disappearing

My app uses a plist to save data between sessions. I use the three below methods to save and read data from the plist file. However, I've been having an enormous problem.
When I save my data, all 12 key/value pairs are set up perfectly in the NSMutableDictionary (I've checked this in the debugger, all 12 pairs are definitely there). However, when I read the data, only 11 pairs show up. The missing 12th key/value pair is "Tab," an NSMutableArray. All other data types are either NSString or NSNumber.
Property declaration for Tab:
#property (strong, nonatomic) NSMutableArray *tab;
Code:
- (NSString *)dataFileName
{
NSError *err = nil;
NSURL *dir = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSAllDomainsMask appropriateForURL:nil create:YES error:&err];
NSString *path = [[dir path] stringByAppendingString:#"/employeeListData.plist"];
return path; //path has not been declared yet
}
- (void)saveDataToFile
{
NSMutableArray *a = [NSMutableArray array];
for (int c = 0; c < [self.employeeList count]; c++) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
id r = [self.employeeList objectAtIndex:c];
[dictionary setObject:[r username] forKey:#"username"];
[dictionary setObject:[r passWord] forKey:#"passWord"];
[dictionary setObject:[r employeeName] forKey:#"employeeName"];
[dictionary setObject:[r grade] forKey:#"grade"];
[dictionary setObject:[r email] forKey:#"email"];
[dictionary setObject:[r phone] forKey:#"phone"];
[dictionary setObject:[r freePeriods] forKey:#"freePeriods"];
[dictionary setObject:[r committee] forKey:#"committee"];
[dictionary setValue:[NSNumber numberWithBool:[r hasKey]] forKey:#"hasKey"];
[dictionary setObject:[r hours] forKey:#"hours"];
[dictionary setObject:[NSArray arrayWithArray:[r tab]] forKey:#"tab"];
float num = [r tabTotal];
NSNumber *floatObject = [NSNumber numberWithFloat:num];
[dictionary setObject:floatObject forKey:#"tabTotal"];
[a addObject:dictionary];
}
[a writeToFile:[self dataFileName] atomically:YES];
}
- (void)readDataFromFile
{
[self createEmployeeList];
NSArray *tempArray = [NSArray arrayWithContentsOfFile:[self dataFileName]];
for (int d = 0; d < [tempArray count]; d++) {
Employee *person = [[Employee alloc] init];
NSDictionary *dict = [tempArray objectAtIndex:d];
[person setUsername:[dict objectForKey:#"username"]];
[person setPassWord:[dict objectForKey:#"passWord"]];
[person setEmployeeName:[dict objectForKey:#"employeeName"]];
[person setGrade:[dict objectForKey:#"grade"]];
[person setEmail:[dict objectForKey:#"email"]];
[person setPhone:[dict objectForKey:#"phone"]];
[person setFreePeriods:[dict objectForKey:#"freePeriods"]];
[person setCommittee:[dict objectForKey:#"committee"]];
[person setHasKey:[[dict valueForKey:#"hasKey"] boolValue]];
[person setHours:[dict objectForKey:#"hours"]];
[person setTab:[[dict objectForKey:#"tab"] mutableCopy]];
NSNumber *floatNumber = dict[#"tabTotal"];
float floatValue = floatNumber.floatValue;
[person setTabTotal:floatValue];
[self.employeeList addObject:person];
}
}
The problem was due to my array of custom objects. I added in the following code in my save method:
NSMutableArray *x = [NSMutableArray array];
for (int y = 0; y < [[r tab]count]; y++) {
NSMutableDictionary *items = [NSMutableDictionary dictionary];
id z = [[r tab] objectAtIndex:y];
[items setObject:[z itemName] forKey:#"tabName"];
[items setObject:[NSNumber numberWithInt:[z price]] forKey:#"tabPrice"];
[x addObject:items];
}
[dictionary setObject:x forKey:#"tab"];
And the following code in my read method:
NSMutableArray *things = [[NSMutableArray alloc] init];
things = dict[#"tab"];
person.tab = [[NSMutableArray alloc] init];
for (int g = 0; g < things.count; g++) {
TabItem *item = [[TabItem alloc] init];
NSDictionary *ion = [things objectAtIndex:g];
[item setItemName:[ion objectForKey:#"tabName"]];
[item setPrice:[[ion objectForKey:#"tabPrice"] intValue]];
[person.tab addObject:item];
}
Since arrays of custom objects can't be stored in NSDictionaries, I used a smaller version of my larger save and read methods to accomplish the task. Full, updated code can be found below.
- (void)saveDataToFile
{
NSMutableArray *a = [NSMutableArray array];
for (int c = 0; c < [self.employeeList count]; c++) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
id r = [self.employeeList objectAtIndex:c];
[dictionary setObject:[r username] forKey:#"username"];
[dictionary setObject:[r passWord] forKey:#"passWord"];
[dictionary setObject:[r employeeName] forKey:#"employeeName"];
[dictionary setObject:[r grade] forKey:#"grade"];
[dictionary setObject:[r email] forKey:#"email"];
[dictionary setObject:[r phone] forKey:#"phone"];
[dictionary setObject:[r freePeriods] forKey:#"freePeriods"];
[dictionary setObject:[r committee] forKey:#"committee"];
[dictionary setValue:[NSNumber numberWithBool:[r hasKey]] forKey:#"hasKey"];
[dictionary setObject:[r hours] forKey:#"hours"];
NSMutableArray *x = [NSMutableArray array];
for (int y = 0; y < [[r tab]count]; y++) {
NSMutableDictionary *items = [NSMutableDictionary dictionary];
id z = [[r tab] objectAtIndex:y];
[items setObject:[z itemName] forKey:#"tabName"];
[items setObject:[NSNumber numberWithInt:[z price]] forKey:#"tabPrice"];
[x addObject:items];
}
[dictionary setObject:x forKey:#"tab"];
[dictionary setObject:[NSNumber numberWithInt:[r tabTotal]] forKey:#"tabTotal"];
[a addObject:dictionary];
}
[a writeToFile:[self dataFileName] atomically:YES];
}
- (void)readDataFromFile
{
[self createEmployeeList];
NSArray *tempArray = [NSArray arrayWithContentsOfFile:[self dataFileName]];
for (int d = 0; d < [tempArray count]; d++) {
Employee *person = [[Employee alloc] init];
NSDictionary *dict = [tempArray objectAtIndex:d];
[person setUsername:[dict objectForKey:#"username"]];
[person setPassWord:[dict objectForKey:#"passWord"]];
[person setEmployeeName:[dict objectForKey:#"employeeName"]];
[person setGrade:[dict objectForKey:#"grade"]];
[person setEmail:[dict objectForKey:#"email"]];
[person setPhone:[dict objectForKey:#"phone"]];
[person setFreePeriods:[dict objectForKey:#"freePeriods"]];
[person setCommittee:[dict objectForKey:#"committee"]];
[person setHasKey:[[dict valueForKey:#"hasKey"] boolValue]];
[person setHours:[dict objectForKey:#"hours"]];
NSMutableArray *things = [[NSMutableArray alloc] init];
things = dict[#"tab"];
person.tab = [[NSMutableArray alloc] init];
for (int g = 0; g < things.count; g++) {
TabItem *item = [[TabItem alloc] init];
NSDictionary *ion = [things objectAtIndex:g];
[item setItemName:[ion objectForKey:#"tabName"]];
[item setPrice:[[ion objectForKey:#"tabPrice"] intValue]];
[person.tab addObject:item];
}
[person setTabTotal:[[dict objectForKey:#"tabTotal"] intValue]];
[self.employeeList addObject:person];
}
}

Value for key from NSMutableDictionary doesn't print

I'm learning "Programming in Objective-C" from Stephen Kochan and I have a problem with a mutable copy of NSDictionary.
So, here is my code:
NSMutableString *value1 = [[NSMutableString alloc ] initWithString: #"Value for Key one" ];
NSMutableString *value2 = [[NSMutableString alloc ] initWithString: #"Value for Key two" ];
NSMutableString *value3 = [[NSMutableString alloc ] initWithString: #"Value for Key three" ];
NSMutableString *value4 = [[NSMutableString alloc ] initWithString: #"Value for Key four" ];
NSString *key1 = #"key1";
NSString *key2 = #"key2";
NSString *key3 = #"key3";
NSString *key4 = #"key4";
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: value1, key1, value2, key2, value3, key3, nil];
NSDictionary *dictionaryCopy = [[NSDictionary alloc] init];
NSMutableDictionary *dictionaryMutableCopy = [[NSMutableDictionary alloc] init];
dictionaryCopy = [dictionary copy];
dictionaryMutableCopy = [dictionary mutableCopy];
[value1 setString: #"New value for Key one" ];
[value2 setString: #"New value for Key two" ];
[value3 setString: #"New value for Key three" ];
dictionaryMutableCopy[key4] = value4;
NSLog(#"All key for value 4");
for (NSValue *key in [dictionaryMutableCopy allKeysForObject:value4]) {
NSLog(#"key: %#", key);
}
NSLog(#"All values");
for (NSValue *val in [dictionaryMutableCopy allValues]) {
NSLog(#"value: %#", val);
}
for (NSValue *key in [dictionaryMutableCopy allKeys]) {
NSLog(#"Key: %# value: %#", key, dictionary[key]);
}
How you see and the end of the code I'm printing all key/values from my NSMutableDictionary, but for key 4 I haven't a value!
Screen from terminal
But how you can see the value for key 4 is't null!
[Content of NSMutableDictionary][2]
What's the problem? Please help
In the final for loop, you are getting the value from dictionary instead of dictionaryMutableCopy:
for (NSValue *key in [dictionaryMutableCopy allKeys]) {
NSLog(#"Key: %# value: %#", key, dictionaryMutableCopy[key]);
// ^^^^^^^^^^^^^^^^^^^^^
}

Sorting an NSDictionary keys

I create a dictionary with this data:
NSString *fileContentMap = [[NSString alloc] initWithContentsOfFile:MapPath];
SBJsonParser *parserMap = [[SBJsonParser alloc] init];
NSDictionary *dataMap = (NSDictionary *) [parserMap objectWithString:fileContentMap error:nil];
NSArray *MaparrayLongitude = [dataMap objectForKey:#"longitude"];
NSArray *MaparrayLatitude = [dataMap objectForKey:#"latitude"];
NSDictionary* DictionaryMap = [NSDictionary dictionaryWithObjects:MaparrayLatitude forKeys:MaparrayLongitude];
..then I read it with this code:
NSArray *allKeys2 = [DictionaryMap allKeys];
NSString *key2 = [allKeys2 objectAtIndex:i];
NSObject *obj2 = [DictionaryMap objectForKey:key2];
...but the keys are not ordered, and I want them to be ordered in the original order. How can I do this??

Objective C How to fill rangeOfString of a NSArray?

I wonder if it is possible to fill rangeOfString objects of a NSArray. Because I have a long list of objects for after rangeOfString:
NSArray biglist´s count is higher than list´s count.
I want to filter away the objects from the small list of the main list.
Please tell me if this is not clear.
My codes below:
NSArray *biglist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"smalllist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
for (NSString *listword in list);
NSMutableArray *wordlist = [[NSMutableArray alloc] init];
NSMutableArray *worindex = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
NSMutableDictionary *mutdic = [[NSMutableDictionary alloc] init];
NSMutableArray *mutarray = [[NSMutableArray alloc] init];
for (NSString *s in mainlist)
{
NSRange ran = [s rangeOfString:listword];
if (ran.location !=NSNotFound)
{
//my codes here
}
}
EDIT:
I think I can solve this by writing
int i;
for (i = 0; i<[list count]; i++)
{
NSString *same = [list objectAtIndex:i];
NSLog (#"listword: %#", same);
}
But I am not sure where to place it, inside the for loop s in mainlist or outside.
EDIT: This for loop works inside the main for loop.
EDIT:
Tried these codes, but it doesnt work somehow..
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"small" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *mainlist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSMutableArray *large = [NSMutableArray arrayWithArray:mainlist];
NSArray *newlarge;
for (NSString *listword in list)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(SELF beginswith[c] %#)",listword];
newlarge = [large filteredArrayUsingPredicate:predicate];
}
NSLog (#"large: %#", newlarge);
NSLog (#"finished!");
"I want to filter away the objects from the small list of the main list."
If I understand correctly, you want to remove an array of items from another array. You don't want to do that much work and allocations inside an n^2 loop.
This removes an array of items from another array. Depending on how large your array is you may need to optimize further but this works:
NSArray *small = [NSArray arrayWithObjects:#"three", #"two", nil];
NSMutableArray *large = [NSMutableArray arrayWithObjects:#"one", #"two", #"three", #"four", nil];
[large removeObjectsInArray:small];
// print
for (NSString *current in large)
{
NSLog(#"item: %#", current);
}
This outputs:
2011-10-13 08:39:21.176 Craplet[5235:707] item: one
2011-10-13 08:39:21.178 Craplet[5235:707] item: four
I figured it out by myself and solved this :)
It works almost perfectly.
My codes:
NSArray *big = [[NSArray alloc] initWithObjects:#"hello ->mache", #"heisann hoppsann ->hiya", #"nei men ->da", #"however ->what", #"may ->april", #"mai ->maj", nil];
NSArray *small = [[NSArray alloc] initWithObjects: #"heisann ", #"nei men ", #"however ", #"mai", nil];
NSMutableArray *smallwithh = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
for (NSString *same in small)
{
NSLog (#"listword: %#", same);
for (NSString *s in big)
{
NSRange ran = [s rangeOfString:same];
if (ran.location !=NSNotFound)
{
[smallwithh addObject:s];
NSUInteger ind = [big indexOfObject:s];
[mindexes addIndex:ind];
}
}
}
NSLog (#"smallwith: %#", smallwithh);
[smallwithh release];
NSMutableArray *newWords =[NSMutableArray arrayWithArray: big];
[newWords removeObjectsAtIndexes: mindexes];
[big release];
[small release];
NSLog (#"newWords: %#", newWords);

Parse JSON in Objective-C with SBJSON

I just want to parse this JSON string in Objective-C using the SBJSON framework, and retrieve the three units of data:
{"x":"197","y":"191","text":"this is a string"}
How can this be done?
NSString * jsonString = #"{\"x\":\"197\",\"y\":\"191\",\"text\":\"this is a string\"}";
SBJSON *jsonParser = [[SBJSON alloc] init];
NSDictionary * dictionary = [jsonParser objectWithString:jsonString];
NSLog(#"x is %#",[dictionary objectForKey:#"x"]);
[jsonParser release];
Here's an example:
NSString *jsonText = #"...";
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *dict = [parser objectWithString:jsonText];
for (NSString *key in [#"x y text" componentsSeparatedByString:#" "]) {
NSLog(#"%# => %#", key, [dict objectForKey]);
}
Here's something similar for SBJson4Parser:
id parser = [SBJson4Parser parserWithBlock:^(id v, BOOL *stop) {
for (NSString *key in [#"x y text" componentsSeparatedByString:#" "]) {
NSLog(#"%# => %#", key, [v objectForKey]);
}
}
allowMultiRoot:NO
unwrapRootArray:NO
errorHandler:^(NSError *err) {
// handle error here
}];
NSString *jsonText = #"...";
[parser parse: [jsonText UTF8String]];