How to find attribute of root node in touch xml? - objective-c

NSString *xml = #"<?xml version="1.0" encoding="ISO-8859-15"?>
<ServerDateTime DateRequested="" DateSent="20141013_114855">
<DateTime>20141013_114857</DateTime>
</ServerDateTime>";
In above xml, how to find the attribute value of 'DataSent'?
I have tried by following, but i didn't get the value.
CXMLDocument *documentParser = [[CXMLDocument alloc]initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
NSArray *arrayResult = [documentParser nodesForXPath:#"//ServerDateTime" error:nil];
for(CXMLElement *element in arrayResult){
NSString *value = [element name];
if ([value isEqualToString:#"ServerDateTime"]) {
NSString *newLastSyncDate = [[element attributeForName:#"DataSent"] stringValue]; //it gives nil..
}
}

You may want to use XPath-queries to search for elements inside a XML. You have to look up if CXML supports this.
Maybe also take a look at this question.
There someone is searching for a given attribute with an XPath-query.

Related

how to convert an array into string? [duplicate]

In my iPhone aplication I have a list of custom objects. I need to create a json string from them. How I can implement this with SBJSON or iPhone sdk?
NSArray* eventsForUpload = [app.dataService.coreDataHelper fetchInstancesOf:#"Event" where:#"isForUpload" is:[NSNumber numberWithBool:YES]];
SBJsonWriter *writer = [[SBJsonWriter alloc] init];
NSString *actionLinksStr = [writer stringWithObject:eventsForUpload];
and i get empty result.
This process is really simple now, you don't have to use external libraries,
Do it this way, (iOS 5 & above)
NSArray *myArray;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myArray options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
I love my categories so I do this kind of thing as follows
#implementation NSArray (Extensions)
- (NSString*)json
{
NSString* json = nil;
NSError* error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:&error];
json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return (error ? nil : json);
}
#end
Although the highest voted answer is valid for an array of dictionaries or other serializable objects, it's not valid for custom objects.
Here is the thing, you'll need to loop through your array and get the dictionary representation of each object and add it to a new array to be serialized.
NSString *offersJSONString = #"";
if(offers)
{
NSMutableArray *offersJSONArray = [NSMutableArray array];
for (Offer *offer in offers)
{
[offersJSONArray addObject:[offer dictionaryRepresentation]];
}
NSData *offersJSONData = [NSJSONSerialization dataWithJSONObject:offersJSONArray options:NSJSONWritingPrettyPrinted error:&error];
offersJSONString = [[NSString alloc] initWithData:offersJSONData encoding:NSUTF8StringEncoding] ;
}
As for the dictionaryRepresentation method in the Offer class:
- (NSDictionary *)dictionaryRepresentation
{
NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
[mutableDict setValue:self.title forKey:#"title"];
return [NSDictionary dictionaryWithDictionary:mutableDict];
}
Try like this Swift 2.3
let consArray = [1,2,3,4,5,6]
var jsonString : String = ""
do
{
if let postData : NSData = try NSJSONSerialization.dataWithJSONObject(consArray, options: NSJSONWritingOptions.PrettyPrinted)
{
jsonString = NSString(data: postData, encoding: NSUTF8StringEncoding)! as String
}
}
catch
{
print(error)
}
Try like this,
- (NSString *)JSONRepresentation {
SBJsonWriter *jsonWriter = [SBJsonWriter new];
NSString *json = [jsonWriter stringWithObject:self];
if (!json)
[jsonWriter release];
return json;
}
then call this like,
NSString *jsonString = [array JSONRepresentation];
Hope it will helps you...
I'm a bit late to this party, but you can serialise an array of custom objects by implementing the -proxyForJson method in your custom objects. (Or in a category on your custom objects.)
For an example.

Filtering Parsed JSON in Objective-C

I'm trying to take out the "lasttradeprice" in https://www.allcrypt.com/api.php?method=singlemarketdata&marketid=672 but I can't seem to figure out how to grab the "lasttradeprice" piece.
How would I 'filter' the "price" out? None of the other information is relevant.
Current Code:
NSURL * url=[NSURL URLWithString:#"https://www.allcrypt.com/api.php?method=singlemarketdata&marketid=672"]; // pass your URL Here.
NSData * data=[NSData dataWithContentsOfURL:url];
NSError * error;
NSMutableDictionary * json = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &error];
NSLog(#"%#",json);
NSMutableArray * referanceArray=[[NSMutableArray alloc]init];
NSMutableArray * periodArray=[[NSMutableArray alloc]init];
NSArray * responseArr = json[#"lasttradeprice"];
for(NSDictionary * dict in responseArr)
{
[referanceArray addObject:[dict valueForKey:#"lasttradeprice"]];
[periodArray addObject:[dict valueForKey:#"lasttradeprice"]];
}
NSLog(#"%#",referanceArray);
NSLog(#"%#",periodArray);
NOTE: Keep in mind I've never worked with JSON before so please keep your answers dumbed down a tad.
Key value coding provides an easy way to dig through that data. Use the key path for the values you want. For example, it looks like you could get the array of recent trades using the path "return.markets.OMC.recenttrades" like this (assuming your code to get the json dictionary):
NSArray *trades = [json valueForKeyPath:#"return.markets.OMC.recenttrades"];
That's a lot more concise than having to dig down one level at a time.
The value returned for a given key by an array is the array of values returned by the array's members for that key. In other words, you can do this:
NSArray *recentprices = [trades valueForKey:#"price"];
And since that's just the next step in the key path, you can combine the two operations above into one:
NSArray *recentprices = [json valueforKeyPath:#"return.markets.OMC.recenttrades.price"];
The only down side here is that there's no real error checking -- either the data matches your expectations and you get back your array of prices, or it doesn't match at some level and you get nil. That's fine in some cases, not so much in others.
Putting that together with the relevant part of your code, we get:
NSURL *url = [NSURL URLWithString:#"https://www.allcrypt.com/api.php?method=singlemarketdata&marketid=672"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error:&error];
NSArray *recentprices = [json valueforKeyPath:#"return.markets.OMC.recenttrades.price"];
Update: I just noticed that you want the "lasttradeprice", not the array of prices. Given that, the key path to use is simply #"return.markets.OMC.lasttradeprice", and the value you'll get back will be a string. So replace the last line above with:
NSString *lastTradePrice = [json valueforKeyPath:#"return.markets.OMC.lasttradeprice"];
The value you want is buried a few dictionaries deep. One general idea might be to dig recursively, something like this:
- (BOOL)isCollection:(id)object {
return [object isKindOfClass:[NSArray self]] || [object isKindOfClass:[NSDictionary self]];
}
- (void)valuesForDeepKey:(id)key in:(id)collection results:(NSMutableArray *)results {
if ([collection isKindOfClass:[NSDictionary self]]) {
NSDictionary *dictionary = (NSDictionary *)collection;
if (dictionary[key]) [results addObject:dictionary[key]];
for (id deeperKey in [dictionary allKeys]) {
if ([self isCollection:dictionary[deeperKey]]) {
[self valuesForDeepKey:key in:dictionary[deeperKey] results:results];
}
}
} else if ([collection isKindOfClass:[NSArray self]]) {
NSArray *array = (NSArray *)collection;
for (id object in array) {
if ([self isCollection:object]) {
[self valuesForDeepKey:key in:object results:results];
}
}
}
}
Then call it like this:
NSMutableArray *a = [NSMutableArray array];
[self valuesForDeepKey:#"lasttradeprice" in:json results:a];
NSLog(#"%#", a);

Programmatically delete parts of NSString

I have an iOS app which connects to a server via OAuth 2.0. I get returned an access token in this form:
{accessToken="521515.ab6dc96.51dca3d53c4236d2d4f4460b151bc58d6ec91e14"}
And I store that in a NSString. The problem I am having is that I ONLY need the part which is in the quotation marks. How can I extract that?
UPDATE
Here us my code:
GTMOAuth2Authentication *auth_instagram;
auth_instagram = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:#"Instagram" clientID:kMyClientID_instagram clientSecret:kMyClientSecret_instagram];
NSLog(#"%#", auth_instagram);
Printed in the Xcode console is:
GTMOAuth2Authentication 0xb2c0a80: {accessToken="541019.ab6dc96.51dc0d264d2d4f60b151bc8d6ec91e14"}
If I read the class definition at http://code.google.com/p/gtm-oauth2/source/browse/trunk/Source/GTMOAuth2Authentication.h correctly, GTMOAuth2Authentication has a
#property (retain) NSString *accessToken;
so that you can just do
NSString *token = auth_instagram.accessToken;
to get the token as a string.
Remark: Your output
{accessToken="521515.ab6dc96.51dca3d53c4236d2d4f4460b151bc58d6ec91e14"}
is the result of calling the description method of GTMOAuth2Authentication.
This is not JSON. JSON would look like
{ "accessToken" : "521515.ab6dc96.51dca3d53c4236d2d4f4460b151bc58d6ec91e14" }
The right way would be to parse the whole string using the correct format/parser, in this case probably NSJSONSerialization and extract the value from the accessToken element.
NSDictionary *parsedData = [JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding] options:0 error:NULL];
NSString *value = parsedData[#"accessToken"];
NSArray* components = [accessStr componentsSeparatedByString: "\""];
NSString* requiredStr = [components objectAtIndex: 1];
NSDictionary *dic =[NSJSONSerialization JSONObjectWithData: [YourString dataUsingEncoding:NSUTF8StringEncoding] options: NSJSONReadingMutableContainers error: &e];
//yourstring is the string in which u store and &e is just an NSError u can create urself like NSError *e;
NSString access_Token=[dic objectForKey:#"accessToken"];
What you got there is valid JASON. Try the following:
NSDictionary *loginInfo = [NSJSONSerialization JSONObjectWithData:[#"{accessToken=\"521515.ab6dc96.51dca3d53c4236d2d4f4460b151bc58d6ec91e14\"}" dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
NSString *aToken = [loginInfon objectForKey:#"accessToken"];

How to get correct XPath result

When I use XPath I use the following code:
NSArray *version = [doc nodesForXPath:#"/app/version[1]" error:nil];
And if I print the array I get this:
"GDataXMLElement 0x80d5030: {type:1 name:version xml:\"<version>0.6</version>\"}"
But how do I get the "0.6" out of the version? Am I doing this wrong with the array?
EDIT:
I found the solution:
for (GDataXMLElement *version in versions) {
GDataXMLElement *versxml = (GDataXMLElement *) [versions objectAtIndex:0];
NSLog(#"%#", versxml.stringValue);
}

Parsing an NSDictionary in one operation ( remove loop).

Could you please guide me on how not to use a for loop in this example? I want to execute it one operation if possible:
NSArray *statuses = [parser objectWithString:json_string error:nil];
for (NSDictionary *status in statuses) {
test = [status objectForKey:#"USER_ID"];
}
Thanks.
NSArray *statuses = [parser objectWithString:json_string error:nil];
if ([statuses count]>0) {
test=[[statuses objectAtIndex:0] objectForKey:#"USER_ID"];
}
If you know that the NSArray has only one element (or that the NSDictionary you want is always the first, or at some other fixed position), use [statuses objectAtIndex:0] (or whatever index) to fetch the status element.