Property 'jsonData' not found on object of type 'MapViewController *' - iphone

I am trying to draw the route on the graphic layer of my app application and i do not know is this the right approach to do it, or is there another way to do it? Where i am trying to use NSArray with ArgGIS to draw out the map am i have problem with it.
*edit I tried to change the NSArray back to a JSON string and try to draw it using ArcGIS with a JSON string
This is what i have done:
NSArray *BusRoute=[jsonResult objectForKey:#"BusRoute"];
int i;
int count = [BusRoute count];
for (i = 0; i < count; i++)
{
NSDictionary *dic = [BusRoute objectAtIndex: i];
NSString *Duration = [dic valueForKey:#"Duration"];
//---PATH---
NSArray *PATH = [dic valueForKey:#"PATH"];
NSLog(#"PATH = %#", PATH);
self.path = PATH;
}
NSError *writeError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:path options:NSJSONWritingPrettyPrinted error:&writeError];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"JSON Output: %#", jsonString);
if (self.jsonString) {
// symbolize the returned route graphic
self.jsonString.routeGraphic.symbol = [self routeSymbol];
// add the route graphic to the graphic's layer
[self._graphicsLayer addGraphic:self.jsonString.routeGraphic];
// tell the graphics layer to redraw
[self._graphicsLayer dataChanged];
}
*Output for JSON string
JSON Output: [
[
"38909,35576;38872,35589;38861,35593;38848,35597;38697,35650;38695,35651;38695,35651;38609,35681;38583,35689;38553,35697;38508,35700;38476...;29560,40043"
]
]
This is a portion of the path that i have to draw on the map:
PATH = (( "38909,35576;38872,35589;38861,35593;38848,35597;38697,35650;38695,35651;38695,35651;38609,35681;38583,35689;38553,35697;38508,35700;38476,35696;38476,35696;....))
for this line self.jsonData.routeGraphic.symbol = [self routeSymbol]; i am getting an error Property 'Property 'jsonData' not found on object of type 'MapViewController *'
what should i do to solve? pls help
*How can i draw the line of the path using the NSArray and using ArcGIS?

routeGraphic property does not have any association with NSArray Class. NSArray is the Collection.
Your code is a little strange.
what is routeGrphic???
Are not you forgotten the like code below?
YourObject *object = [path objectAtIndex:index];
object.routeGraphic.symbol = [self routeSymbol];

Related

iPhone - difference between GDataXMLNode and GDataXMLElement, and how to use them

As the google doc is not available anymore, I'm lost with those concepts.
What is a node, and what is an element (that inherits the node) ?
How can I switch from nodes to elements. I mean, for example, if I write :
NSError* error;
NSData* xmlData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"ForTesting" ofType:#"xml"]];
error = nil;
GDataXMLDocument* XMLDoc = [[[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error] autorelease];
if (XMLDoc == nil) {
NSLog(#"%#", error.description);
return;
}
GDataXMLNode* xmlElement = [[XMLDoc nodesForXPath:#"//root/fileVersion" error:nil] objectAtIndex:0];
NSString* fileVersion = xmlElement.stringValue;
GDataXMLNode* xmlList = [[XMLDoc nodesForXPath:#"//root/list" error:nil] objectAtIndex:0]; // single item
After that code, how can I write something like that to switch to GDataXMLElement instead of continuing with GDataXMLNode, that would requires me to continue using XPath (I don't want to use it past that point) :
// code don't work : elementsForName is not defined for GDataXMLNode
for (GDataXMLElement* xmlObject in [xmlList elementsForName:#"object"]) {
MyClass* obj = [[[MyClass alloc] initWithXMLElement:xmlObject] autorelease];
}
GDataXMLNode is obviously the classes you use for XML parser- GDataXMLNode.h/.m
In the code you have given returns an array. You can use.
NSArray *myArray = [XMLDoc nodesForXPath:#"//root/fileVersion" error:nil];
You can iterate myArray like this.
for (GDataXMLElement *nodeXmlElt in myArray)
{
//some code
}
Each of my nodeXmlElt will be like given below.
<fileVersion>
<title>San Francisco CBS News</title>
<link>http://news.google.com/news/</link>
<fileVersion>
//getting title
NSArray *elementArray = [nodeXmlElt elementsForName:#"title"];
GDataXMLElement *gdataElement = (GDataXMLElement *)[elementArray objectAtIndex:0];
NSString *title = gdataElement.stringValue; //returns 'San Francisco CBS News'

How can I parse this xml using GDataXML parser?

<list>
<OrderData HASH="1408108039"></OrderData>
<OrderData HASH="208524692">
<id>97</id>
<customer>
<CustomerData HASH="2128670187"></CustomerData></customer>
<billingAddress></billingAddress><deliveryAddress></deliveryAddress>
<orderDetail>
<list>
<OrderDetailData HASH="516790072"></OrderDetailData>
<OrderDetailData HASH="11226247"></OrderDetailData>
<OrderDetailData HASH="11226247"></OrderDetailData>
</list>
</orderDetail>
<log/>
</OrderData>
<OrderData HASH="1502226778"></OrderData>
</list>
I cannot find a solution to find the number of OrderDetailData elements? I also read http://iphonebyradix.blogspot.com/2011/03/using-gdata-to-parse-xml-file.html this url.
Thanks in advance.
Edit:
I am explaining my requirement again. In this xml there will be multiple OrderData element. Now I have to count the number of OrderDetailData elemnts from a particular OrderData element. Suppose that, according to my xml, the current parsed xml has one OrderData element, named id and its value is 97. Now, I have to count how many OrderDetailData elements are contained in the OrderData(whichid` is 97).
This is a simple example how to retrieve some data. This example is very simple and not use XPath expression. I suggest you first understand how it works and then use XPath expression. In my opinion it is not useful to use XPath expression if you cannot understand how the parser works.
NSString* path = [[NSBundle mainBundle] pathForResource:#"test2" ofType:#"xml"];
NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:path];
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData
options:0 error:&error];
//NSLog(#"%#", doc.rootElement); // print the whole xml
NSArray *orderDataArray = [doc.rootElement elementsForName:#"OrderData"];
for (GDataXMLElement *orderDataElement in orderDataArray) {
if([orderDataElement childCount] > 0)
{
NSString *attributeForOrderDataElement = [(GDataXMLElement *) [orderDataElement attributeForName:#"HASH"] stringValue];
NSLog(#"attributeForOrderDataElement has value %#", attributeForOrderDataElement);
GDataXMLElement* idElement = (GDataXMLElement*)[[orderDataElement elementsForName:#"id"] objectAtIndex:0];
NSLog(#"id has value %#", idElement.stringValue);
GDataXMLElement* orderDetailElement = (GDataXMLElement*)[[orderDataElement elementsForName:#"orderDetail"] objectAtIndex:0];
GDataXMLElement* listElement = (GDataXMLElement*)[[orderDetailElement elementsForName:#"list"] objectAtIndex:0];
NSArray* orderDetailDataArray = [listElement elementsForName:#"OrderDetailData"];
int count = 0;
for (GDataXMLElement *orderDetailDataElement in orderDetailDataArray) {
NSString *attributeForOrderDetailDataElement = [(GDataXMLElement *) [orderDetailDataElement attributeForName:#"HASH"] stringValue];
NSLog(#"attributeForOrderDetailDataElement has value %#", attributeForOrderDetailDataElement);
count++;
}
NSLog(#"%d", count);
}
}
[doc release];
[xmlData release];
This is the output console:
attributeForOrderDataElement has value 208524692 <-- HASH value
id has value 97 <-- id value
attributeForOrderDetailDataElement has value 516790072 <-- HASH value
attributeForOrderDetailDataElement has value 11226247
attributeForOrderDetailDataElement has value 11226247
3 <-- the count
Hope it helps.
Edit
test2.xml contains your file but you could pass it as a string. You can also pass as parameters as string like the following:
NSString* xmlString = #"<list>"
"<OrderData HASH=\"1408108039\"></OrderData>"
"<OrderData HASH=\"208524692\">"
"<id>97</id>"
"<customer>"
"<CustomerData HASH=\"2128670187\"></CustomerData>"
"</customer>"
"<billingAddress></billingAddress>"
"<deliveryAddress></deliveryAddress>"
"<orderDetail>"
"<list>"
"<OrderDetailData HASH=\"516790072\"></OrderDetailData>"
"<OrderDetailData HASH=\"11226247\"></OrderDetailData>"
"<OrderDetailData HASH=\"11226247\"></OrderDetailData>"
"</list>"
"</orderDetail>"
"<log/>"
"</OrderData>"
"<OrderData HASH=\"1502226778\"></OrderData>"
"</list>";
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithXMLString:xmlString options:0 error:&error];
I found TouchXML easy in parsing and you can directly access data needed from xml
First of all Download TouchXML and add libxml2.dylib framework to your project.
change buildsetting for "Header Search Path" and add "/usr/include/libxml2"
Import TouchXML.h to your file
//Access document
CXMLDocument *parserDoc = [[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:&err];
//Access root element and access children in heirarchy
CXMLElement *root = [parserDoc rootElement];
NSArray *places = [[[root children] objectAtIndex:0] children];
Else
//Access node by node
NSString *location =[[[[[parserDoc nodesForXPath:#"/xml_api_reply/weather/forecast_information/city" error:nil] objectAtIndex:0] attributeForName:#"data"] stringValue] retain];
If the OrderDetailData is present in 2nd object of array all the time, u can use the below
NSArray* arr = [[XMLelement elementForName:#"list"] elementsForName:#"OrderData"];
NSXMLElement* listElement = [[[arr objectAtIndex:1] elementForName:#"orderDetail"] elementForName:#"list"];
NSArray* orderDetailArray* = [listElement elementsForName:#"OrderDetailData"];
In this u can get the OrderDetailData elements in the array, and u can parse the data in loop. to get HASH value use.
NSString* hash = [[orderDetailArray objectAtIndex:0] stringValueForAttribute:#"HASH"];
This is the below code, i have tried. I got the right output.. check out
NSString* xmlString = #"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<list>"
"<OrderData HASH=\"1408108039\"></OrderData>"
"<OrderData HASH=\"208524692\">"
"<id>97</id>"
"<customer>"
"<CustomerData HASH=\"2128670187\"></CustomerData></customer>"
"<billingAddress></billingAddress><deliveryAddress></deliveryAddress>"
"<orderDetail>"
"<list>"
"<OrderDetailData HASH=\"516790072\"></OrderDetailData>"
"<OrderDetailData HASH=\"11226247\"></OrderDetailData>"
"<OrderDetailData HASH=\"11226247\"></OrderDetailData>"
"</list>"
"</orderDetail>"
"<log/></OrderData>"
"<OrderData HASH=\"1502226778\"></OrderData>"
"</list>";
NSXMLDocument* doc = [[NSXMLDocument alloc] initWithData:[xmlString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
NSXMLElement* rootElement = [doc rootElement];
NSArray* arr = [rootElement elementsForName:#"OrderData"];
NSXMLElement* orderDataElement;
for (int i = 0; i < [arr count]; i++)
{
int Id = 0;
Id = [[arr objectAtIndex:i] integerValueForNode:#"id"];
if (Id != 0)
{
orderDataElement = [arr objectAtIndex:i];
break;
}
}
NSArray* orderDetailArray = [[[orderDataElement elementForName:#"orderDetail"]
elementForName:#"list"]
elementsForName:#"OrderDetailData"];
for (int j = 0; j < [orderDetailArray count]; j++)
{
NSLog(#"%#", [[orderDetailArray objectAtIndex:j] stringValueForAttribute:#"HASH"]);
}

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;
}

Getting the error in JSON parsing in iphone

I am trying to pars the json data and display in table
My JSON data is like this
{"isError":false,"ErrorMessage":"","Result":{"Count":4,"Data":[{"ContentID":"127_30_1309793318065","ContentTypeID":1,"UserCaption":"Gandhinagar(Kanjurmarg)","UserComment":"central\n","DateRecorded":"\/Date(1309793318000+0530)\/","Data":"","ShareType":true,"Views":0,"PlayTime},{},{},{}];};isError = 0;}
I am prasing like this
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *loginStatus = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSLog(#"%#",loginStatus);
//this is for the getting the data from the server with help of JSON
NSString *json_string = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];
NSDictionary *result = [json_string JSONValue];
/
//this for holding the Array value which come from the server
NSMutableArray *results = [[NSMutableArray alloc] init];
for (int index = 0; index<[reviewsvalues count]; index++)
{
NSMutableDictionary * value = [reviewsvalues objectAtIndex:index];
ReviewsResult * result = [[ReviewsResult alloc] init];
result.User_Caption = [value objectForKey:#"UserCaption"];
result.ContentType_Id = [value objectForKey:#"DateRecorded"];
result.Average_Rating = [value objectForKey:#"AverageRating"];
//OVER here MY APP GET CRASH
}
}
BUt it get crash and give error
[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance
The problem is simple.
reviewsvalues should be an NSDictionary and you should not be calling objectAtIndex: for the reviewsvalues.
Instead you should call valueForKey like
int count = [[reviewsvalues valueForKey:#"Count"] intValue];
NSArray *reviewsArray = [reviewsvalues valueForKey:#"Data"];
int count = [reviewsArray count];
cell.textLabel.text = [[reviewsArray objectAtIndex:indexPath.row] valueForKey:#"ContentID"];
Hope this helps you.
Please let me know if you want more help on this.
You set reviewsvalues = [result objectForKey:#"Result"];
Which means reviewsvalues is now an NSDictionary.
"Result" is a dictionary, not an array:
{"Count":4,"Data":[...]}
NSDictionary doesn't respond to -objectAtIndex:, that's one of NSArray's methods.
You need another step:
NSArray *reviewsArray = [reviewsvalues objectForKey:#"Data"];
and while you are at it, you can use fast enumeration.
for (NSDictionary *review in reviewsArray) {
ReviewsResult * result = [[ReviewsResult alloc] init];
result.User_Caption = [review objectForKey:#"UserCaption"];
result.ContentType_Id = [review objectForKey:#"DateRecorded"];
result.Average_Rating = [review objectForKey:#"AverageRating"];
}
Edit: also, you should know that you've not coded this very defensively. What happens if the data isn't exactly as it is in your example? what happens if a value is missing, like "Data", or "Result"?
Your app should be robust enough to not choke if something slightly unexpected happens.

obj-c problem setting array with componentsSeperatedByString

I have a data source with about 2000 lines that look like the following:
6712,Anaktuvuk Pass Airport,Anaktuvuk Pass,United States,AKP,PAKP,68.1336,-151.743,2103,-9,A
What I am interested in is the 6th section of this string so I want to turn it into an array, then i want to check the 6th section [5] for an occurrance of that string "PAKP"
Code:
NSBundle *bundle = [NSBundle mainBundle];
NSString *airportsPath = [bundle pathForResource:#"airports" ofType:#"dat"];
NSData *data = [NSData dataWithContentsOfFile:airportsPath];
NSString *dataString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
NSArray *dataArray = [dataString componentsSeparatedByString:#"\n"];
NSRange locationOfAirport;
NSString *workingString = [[NSString alloc]initWithFormat:#""];
NSString *searchedAirport = [[NSString alloc]initWithFormat:#""];
NSString *airportData = [[NSString alloc]initWithFormat:#""];
int d;
for (d=0; d < [dataArray count]; d=d+1) {
workingString = [dataArray objectAtIndex:d];
testTextBox = workingString; //works correctly
NSArray *workingArray = [workingString componentsSeparatedByString:#","];
testTextBox2 = [workingArray objectAtIndex: 0]; //correctly displays the first section "6712"
testTextBox3 = [workingArray objectAtIndex:1] //throws exception index beyond bounds
locationOfAirport = [[workingArray objectAtIndex:5] rangeOfString:#"PAKP"];
}
the problem is that when the workingArray populates, it only populates with a single object (the first component of the string which is "6712". If i have it display the workingString, it correctly displays the entire string, but for some reason, it isn't correctly making the array using the commas.
i tried it without using the data file and it worked fine, so the problem comes from how I am importing the data.
ideas?
You code works. You should run it with the debugger to see what's happening. At a guess, your input data isn't what you think it is - possibly a different encoding, or different line endings.
See sample:
NSString *dataString = #"6712,Anaktuvuk Pass Airport,Anaktuvuk Pass,United States,AKP,PAKP,68.1336,-151.743,2103,-9,A";
NSArray *dataArray = [dataString componentsSeparatedByString:#"\n"];
for (NSString *workingString in dataArray) {
NSString *testTextBox = workingString; //works correctly
NSArray *workingArray = [workingString componentsSeparatedByString:#","];
NSString *testTextBox2 = [workingArray objectAtIndex: 0]; //correctly displays the first section "6712"
NSString *testTextBox3 = [workingArray objectAtIndex:1]; //throws exception index beyond bounds
NSRange locationOfAirport = [[workingArray objectAtIndex:5] rangeOfString:#"PAKP"];
}
there was a problem in the data where there were a few "\"s that caused the errors.