Core Data table to NSArray - iphone

I have the following Array which retrieved from the Core Data :
NSArray *dataArray = [context executeFetchRequest:request error:&error];
so I wrote this code to get each row data individually to send it to REST API:
for (NSString *str in dataArray) {
NSString *name =[dataArray valueForKey:#"name"];
NSString *dob = [dataArray valueForKey:#"dob"];
int gender =[[dataArray valueForKey:#"gender"]integerValue];
NSString *childId =[dataArray valueForKey:#"id"];
int response = [network sendName:name withDateOfBirth:dob andGender:gender forID:childId];
if (response == 200) {
// [self performSelectorOnMainThread:#selector(postSuccess) withObject:nil waitUntilDone:YES];
NSLog(#"Success");
}
}
but it's not working, because I couldn't know how data is stored in each index in the array!!
Please help, and if I am not doing this correctly please tell me a better way to do it.
Thanks.

NSString *name =[dataArray valueForKey:#"name"];
This doesn't do what you think it'll do. valueForKey:, when sent to an array, returns an array of the values corresponding to the given key for all the items in the array. So, that line will assign an array of the "name" values for all the items in dataArray despite the fact that you declared name as a NSString. Same goes for the subsequent lines.
What you probably want instead is:
for (NSManagedObject *item in dataArray) {
NSString *name = [item valueForKey:#"name"];
...
Better, if you have a NSManagedObject subclass -- let's call it Person representing the entity you're requesting, you can say:
for (Person *person in dataArray) {
NSString *name = person.name;
...
which leads to an even simpler version:
for (Person *person in dataArray) {
int response = [network sendName:person.name
withDateOfBirth:person.dob
andGender:person.gender
forID:person.id];
although I'd change the name of that method to leave out the conjunctions and prepositions. -sendName:dateOfBirth:gender:id: is enough, you don't need the "with", "and", and "for."

Related

how can adding Key float values from NSDictionary to NSarray?

My brain is fried! I can't think.
i am new to iphone programming
am doing json parsing ....in that am storeing data from json to nsdictionary but .......
I want to add all nsdictionary float values from the dictionary to the array. This is what I am doing right now.As code below:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;
dict = [responseString JSONValue];
NSMutableArray *array = [NSMutableArray array];
for (NSString *key in [dict allKeys])
{
array = [dict objectForKey:key];
// array return float values but
[array addObject:array ]; // geting carsh dude to array return float values like 120.01
}
Please guide me i am not getting a part where i am doing a mistake.
Thanks in advance.
Your app is crashing because you are adding data to NSArray , this is static array, you can not add value at run time, so just Make NSMutableArray and add your data in NSMutableArray.
Your code is broken in a couple of ways.
This line assigns the array pointer to the object in the dictionary:
array = [dict objectForKey:key];
Then you are trying to add the array to itself, which does not make sense. But worse, since array does no longer point to your NSMutableArray you cannot even call that method.
[array addObject:array ];
You probably wanted to do something like this:
for (NSString *key in [dict allKeys])
{
id value = [dict objectForKey:key];
[array addObject:value];
}

How to display Xpath on the iPhone

I'm trying to extract the weather information from here using Xpath on the iPhone. As of now it parses all the data but I'm stuck on how to extract the content and display it in a table.
This is what I have so far:
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[ #"http://aviationweather.gov/adds/metars/?station_ids=1234&std_trans=translated&chk_metars=on&hoursStr=most+recent+only&submitmet=Submit"stringByReplacingOccurrencesOfString:#"1234" withString:self.title]]];
TFHpple * doc = [[TFHpple alloc] initWithHTMLData:data];
NSArray * elements = [doc searchWithXPathQuery:#"//table[1]//tr"];
NSLog(#"%#", elements);
TFHppleElement * element = [elements objectAtIndex:0];
[element content]; // Tag's innerHTML
[element tagName]; // "a"
[element attributes]; // NSDictionary of href, class, id, etc.
[element objectForKey:#"href"]; // Easy access to single attribute
If anybody needs to see what its outputting so far, let me know.
Thanks,
Andrew
I had the same issue I got to the point your at and didn't no where to go but I end up implementing this code. Hope it helps there is still little bits need to make it work correctly but do to the nature of the app I have developed this is all I can give you. its not much more its just the actual implementation into your code that you need really.
#import "XPathQuery.h"
NSMutableArray *weatherArray = [[NSMutableArray arrayWithArray:0]retain]; // Initilize the NSMutableArray can also be done with just an NSArray but you will have to change the populateArray method.
NSString *xPathLookupQuery = #"//table[1]//tr"; // Path in xml
nodes = PerformXMLXPathQuery(data, xPathLookupQuery); // Pass the data in that you need to search through
[self populateArray:weatherArray fromNodes:nodes]; // To populate multiple values into array.
session = [[self fetchContent:nodes] retain]; // To populate a single value and returns value.
- (void)populateArray:(NSMutableArray *)array fromNodes:(NSArray *)nodes
{
for (NSDictionary *node in nodes) {
for (id key in node) {
if ([key isEqualToString:#"nodeContent"]) {
[array addObject:[node objectForKey:key]];
}
}
}
}
You only need either the above code or below code unless you want both.
- (NSString *)fetchContent:(NSArray *)nodes
{
NSString *result = #"";
for (NSDictionary *node in nodes) {
for (id key in node) {
if([key isEqualToString:#"nodeContent"]) {
result = [node objectForKey:key];
}
}
}
return result;
}

help me to get each elements from my json feed ? Please

I have this JSON data:
{
"data":{
"mat_149":{
"id":"149",
"title":"The closing of 40% profit within 9 month",
"teaser":"profit within 9 months only which is equal to 52% annual profit",
"body":" The auction was presented in a very high and commercial lands.\u000d\u000a",
"files":{
"911":{
"fid":"911",
"filename":"22.JPG",
"filepath":"http://mysite/files/22_0.JPG"
}
}
},
"mat_147":{
"id":"147",
"title":"Company launches the city ",
"teaser":"demands for distinguished lands.",
"body":" The area size is quare meters This is evident through projects and many other projects.\u000d\u000a\u000d\u000a",
"files":{
"906":{
"fid":"906",
"filename":"2D7z.jpg",
"filepath":"http://mysite/dlr/files/2D7Z.jpg"
}
}
},
"mat_link":"mysite.com/"
}
}
I'm parsing it like this with the json-framework:
NSString *response = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding] ;
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *data = (NSDictionary *) [parser objectWithString:response error:nil];
NSLog(#"Data : %#", [data valueForKey:#"data"] );
I am getting Data:
NSLog(#"Data : %#", [data objectForKey:#"data"] );
I am getting the data , but what i should do to get the 'file' items like 'fid' , 'filename' , 'filepath' .How can i get each elements from 'Data' n 'files' and store into some NSStrings ........
Can someone point out what I have to do ? Please
They're all sub-dictionaries aren't they,
just try logging the whole dictionary so go:
NSLog(#"%#", data);
Then you can see the structure.
To get all the other data, you're going to need to create a data model to hold it all, which knows which keys to call to get the specific strings.
Or you could call [data allKeys];
Iterating through that, getting dictionaries that you have the model object for.
E.g:
//Somewhere you declare this
NSArray *keys = [data allKeys]
for (NSString *key in [data allKeys]) {
NSDictionary *oneObject = [dictionary objectForKey:key];
MyObjectModel *object = [[MyObjectModel alloc] init];
object.id = [oneObject objectForKey:#"id"];
object.title = [oneObject objectForKey:#"title"];
//etc
//then you create another dict for files
}
Alex

Core Data - JSON (TouchJSON) on iPhone

I have the following code which seems to go on indefinitely until the app crashes. It seems to happen with the recursion in the datastructureFromManagedObject method. I suspect that this method:
1) looks at the first managed object and follows any relationship property recursively.
2) examines the object at the other end of the relationship found at point 1 and repeats the process.
Is it possible that if managed object A has a to-many relationship with object B and that relationship is two-way (i.e an inverse to-one relationship to A from B - e.g. one department has many employees but each employee has only one department) that the following code gets stuck in infinite recursion as it follows the to-one relationship from object B back to object A and so on.
If so, can anyone provide a fix for this so that I can get my whole object graph of managed objects converted to JSON.
#import "JSONUtils.h"
#implementation JSONUtils
- (NSDictionary*)dataStructureFromManagedObject:(NSManagedObject *)managedObject {
NSDictionary *attributesByName = [[managedObject entity] attributesByName];
NSDictionary *relationshipsByName = [[managedObject entity] relationshipsByName];
//getting the values correspoinding to the attributes collected in attributesByName
NSMutableDictionary *valuesDictionary = [[managedObject dictionaryWithValuesForKeys:[attributesByName allKeys]] mutableCopy];
//sets the name for the entity being encoded to JSON
[valuesDictionary setObject:[[managedObject entity] name] forKey:#"ManagedObjectName"];
NSLog(#"+++++++++++++++++> before the for loop");
//looks at each relationship for the given managed object
for (NSString *relationshipName in [relationshipsByName allKeys]) {
NSLog(#"The relationship name = %#",relationshipName);
NSRelationshipDescription *description = [relationshipsByName objectForKey:relationshipName];
if (![description isToMany]) {
NSLog(#"The relationship is NOT TO MANY!");
[valuesDictionary setObject:[self dataStructureFromManagedObject:[managedObject valueForKey:relationshipName]] forKey:relationshipName];
continue;
}
NSSet *relationshipObjects = [managedObject valueForKey:relationshipName];
NSMutableArray *relationshipArray = [[NSMutableArray alloc] init];
for (NSManagedObject *relationshipObject in relationshipObjects) {
[relationshipArray addObject:[self dataStructureFromManagedObject:relationshipObject]];
}
[valuesDictionary setObject:relationshipArray forKey:relationshipName];
}
return [valuesDictionary autorelease];
}
- (NSArray*)dataStructuresFromManagedObjects:(NSArray*)managedObjects {
NSMutableArray *dataArray = [[NSArray alloc] init];
for (NSManagedObject *managedObject in managedObjects) {
[dataArray addObject:[self dataStructureFromManagedObject:managedObject]];
}
return [dataArray autorelease];
}
//method to call for obtaining JSON structure - i.e. public interface to this class
- (NSString*)jsonStructureFromManagedObjects:(NSArray*)managedObjects {
NSLog(#"-------------> just before running the recursive method");
NSArray *objectsArray = [self dataStructuresFromManagedObjects:managedObjects];
NSLog(#"-------------> just before running the serialiser");
NSString *jsonString = [[CJSONSerializer serializer] serializeArray:objectsArray];
return jsonString;
}
- (NSManagedObject*)managedObjectFromStructure:(NSDictionary*)structureDictionary withManagedObjectContext:(NSManagedObjectContext*)moc {
NSString *objectName = [structureDictionary objectForKey:#"ManagedObjectName"];
NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:objectName inManagedObjectContext:moc];
[managedObject setValuesForKeysWithDictionary:structureDictionary];
for (NSString *relationshipName in [[[managedObject entity] relationshipsByName] allKeys]) {
NSRelationshipDescription *description = [[[managedObject entity]relationshipsByName] objectForKey:relationshipName];
if (![description isToMany]) {
NSDictionary *childStructureDictionary = [structureDictionary objectForKey:relationshipName];
NSManagedObject *childObject = [self managedObjectFromStructure:childStructureDictionary withManagedObjectContext:moc];
[managedObject setValue:childObject forKey:relationshipName];
continue;
}
NSMutableSet *relationshipSet = [managedObject mutableSetValueForKey:relationshipName];
NSArray *relationshipArray = [structureDictionary objectForKey:relationshipName];
for (NSDictionary *childStructureDictionary in relationshipArray) {
NSManagedObject *childObject = [self managedObjectFromStructure:childStructureDictionary withManagedObjectContext:moc];
[relationshipSet addObject:childObject];
}
}
return managedObject;
}
//method to call for obtaining managed objects from JSON structure - i.e. public interface to this class
- (NSArray*)managedObjectsFromJSONStructure:(NSString *)json withManagedObjectContext:(NSManagedObjectContext*)moc {
NSError *error = nil;
NSArray *structureArray = [[CJSONDeserializer deserializer]
deserializeAsArray:[json dataUsingEncoding:NSUTF32BigEndianStringEncoding]
error:&error];
NSAssert2(error == nil, #"Failed to deserialize\n%#\n%#", [error localizedDescription], json);
NSMutableArray *objectArray = [[NSMutableArray alloc] init];
for (NSDictionary *structureDictionary in structureArray) {
[objectArray addObject:[self managedObjectFromStructure:structureDictionary withManagedObjectContext:moc]];
}
return [objectArray autorelease];
}
#end
I answered this question when you posted a comment on the original thread. You need to make some changes to how the recursion works so that it doesn't go into a loop. There are many ways to do this.
For example, you can change the call to get all relationships to instead call a method in your NSManagedObject subclasses that only returns the relationships that are downstream. In that design ObjectA would return the ObjectB relationship but Object B would not return any (or relationships to ObjectC, etc.). This creates a tree like hierarchy for the recursion to work through.
Follow the logic of the code. It process the object or objects you hand to it and then it walks through every object associated with that first set of objects. You already, from your post, showed that you understand it is a loop. Now you need to break that loop in your code with logic to change it from a loop to a tree.
Also, I realize this may sound like I am pimping my book, I explained how to do avoid this loop in my book in the Multi-threading chapter in the section on exporting recipes.
Update NSDate
That sounds like a bug in the JSON parser that you are using as it should be able to handle dates. However your workaround is viable except you need to convert it on both sides which is a PITA. I would look into your parser and see why it is not translating dates correctly as that is a pretty big omission.
I just wanted to point out a small typo, that caused the code to crash, and hopefully this will save you a few min.
- (NSArray*)dataStructuresFromManagedObjects:(NSArray*)managedObjects {
NSMutableArray *dataArray = [[NSArray alloc] init];
for (NSManagedObject *managedObject in managedObjects) {
[dataArray addObject:[self dataStructureFromManagedObject:managedObject]];
}
return [dataArray autorelease];
}
The NSMutableArray *dataArray = [[NSArray alloc] init]; // This should be NSMutableArray
really should be NSMutableArray *dataArray = [[NSMutableArray alloc] init];
that is all.
thank you

NSMutableArray not working properly...(count shouldn't be returning zero!)

NSMutableArray count is returning zero after adding objects to it, its been an hour of hacking away trying to figure out why, and I'm still stuck, so that brings me here.
Any ideas based off the following code, what the problem is?
the object 'search' is a custom class defined in the header set as a pointer, with retain, nonatomic attributes.
- (NSMutableArray *) populateArrayFromPlist{
NSLog(#"Populate Array from PList");
NSDictionary *dictionary;
// read "foo.plist" from application bundle
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"asearch.plist"];
dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath];
for (id key in dictionary)
{
search = [[ASearch alloc] init];
[dictionary valueForKey:key];
[search setID:[[dictionary valueForKey:key] intValue] ];
//[[search searchString] initWithString: key];
search.searchString = [[NSMutableString alloc] initWithString: key];
if (search == nil) {
printf("Let me know now\n\n\n\n");
}
NSLog(#"%#", [search searchString]);
NSLog(#"Setting string Value: %s\n", [key cString]);
NSLog(#"Setting ID Value: %i\n", [[dictionary valueForKey:key] intValue]);
//NSLog(#"aSearchArray count == %i", [[aSearchArray count] intValue]);
[aSearchArray addObject:search];
NSLog(#"aSearchArray count == %i", [aSearchArray count] );
aSearchArray is a nil object that is the only reason why you are getting count as zero.
For more confirmation just create a new local array and try to add your object to it.
You will get a proper count