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.
Related
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.
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.
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);
I came to notice that executing a for/in operation in objective c on an initialized empty NSMutableArray was not working as expected.
Simplified code is :
+(void) convertArray: (NSMutableArray*)arrayIN {
NSMutableArray *arrayOUT = [NSMutableArray array];
NSLog(#"is nil %d - count %d", !arrayIN, [arrayIN count]);
for(NSObject *o in arrayIN)
[arrayOUT addObject:[o convertToAnotherClass]];
}
Actual code is :
+(BOOL) writeTasks: (NSArray*)tasksArray {
NSMutableArray *arr = [NSMutableArray array];
NSLog(#"is nil %d - count %d", !arr, [arr count]);
for(Task *t in tasksArray)
[arr addObject:[t getDictionary]];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:arr options:NSJSONWritingPrettyPrinted error:&error];
if (! jsonData) {
NSLog(#"Got an error: %#", error);
return NO;
} else {
//NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[jsonData writeToFile:path options:NSDataWritingAtomic error:nil];
return YES;
}
}
the suprising thing is that executing [dummyClass convertArray:[NSMutableArray array]] is showing this :
2012-06-25 13:51:34.236 Planorama[740:707] is nil 0 - count 0
2012-06-25 13:51:34.239 Planorama[740:707] -[__NSArrayM convertToAnotherClass]: unrecognized selector sent to instance 0xde9b580
(lldb)
Why ? arrayIN is empty, why is convertToAnotherClass even called ?
if you use the block based enumeration it will work the way you want.
Also, the output indicates that o is set to some instance of something, so you may have another problem.
Elegant way to get all objects of a specific type in an Objective-C array
Lastly, it looks like this is a static method, but your example calls it as an instance method.
As Joshua Smith pointed out : I am not checking the count of the iterated array. The iterated array was not empty and contained itself because if a mistyped line :
[tasks addObject:tasks]
instead of
[tasks addObject:task]
in a previous method..
Thanks everyone !
PS : the link of Joshua Smith is very useful ! Future readers : check it out !
Please consider this code:
NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:[ NSURL URLWithString:url ]]; // Pulls the URL
NSLog(#"jsonreturn#########=%#",jsonreturn); // Look at the console and you can see what the restults are
NSData *jsonData = [jsonreturn dataUsingEncoding:NSUTF32BigEndianStringEncoding];
CJSONDeserializer *theDeserializer = [CJSONDeserializer deserializer];
theDeserializer.nullObject = NULL;
NSError *error = nil;
NSDictionary *dictt = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
NSLog(#"###dict=%#", dictt);
if (dictt) {
rowsForQuestion = [[dictt objectForKey:#"faqdetails"] retain];// NSArray rowsForQuestion
}
[jsonreturn release];
// I have got this data is in console NOW I WANT TO PRINT IT UITextView but HOW I can do it
faqdetails = (
{
faqAns = "Yes, Jack Kalis is the best crickter";
faqQues = "who is the best cricketer in present year?";
}
);
}
Your question isn't particularly clear regarding what you want to show where, but dropped text into a UITextView couldn't be easier.
[yourTextView setText: [[rowsForQuestion objectAtIndex: 0] objectForKey: #"faqQues"]];
The above code grabs the first dict from rowsForQuestion, and puts its value for #"faqQues" into a UITextView.
Assuming you have a UITextView instance called myTextView, made either programatically or through IB, try this:
[myTextView setText:faqdetails];