I am using Sudzc (it uses TouchXML) for parsing my web services WSDL, now I am using multiple web services with almost the same WSDL definitions. I edited my code to use this, this is what happens:
CXMLNode* element = [[Soap getNode: [doc rootElement] withName: #"Body"] childAtIndex:0];
output = [Soap deserialize:element];
And the soap deserialize is as following:
// Deserialize an object as a generic object
+ (id) deserialize: (CXMLNode*) element{
return [element stringValue];
}
I get data back ilke this when I log it:
{
RetrieveSetResult = {
Entities = {
RequestData = {
AccountCode = {
IsDirty = false;
IsNothing = true;
NoRights = false;
Value = "<null>";
};
AccountContactEmail = {
IsDirty = false;
IsNothing = true;
NoRights = false;
Value = "<null>";
};
};
};
SessionID = 40;
};
}
How can I use this data in a user friendly way, so i want to be able to say which field I want to select and read.
try access them like a dictionary
NSDictionary *dic = [myXMLparsedObject valueForKey:#"RetrieveSetResult"];
int sesID = [[dic valueForKey:#"SessionID"] intValue];
NSDictionary *entis = [dic valueForKey:#"Entities"];
// … and so on
looping through all elements:
// for iOS prior 4.0
NSArray *dicKeys = [xmlDic allKeys];
for (NSString *key in dicKeys) {
id obj = [xmlDic valueForKey:key];
}
// way simpler in > 4.0
[xmlDic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
}];
in both cases you can access each key and obj value ;)
Related
This is the output of an NSDictionary:
{
client = {
environment = mock;
"paypal_sdk_version" = "1.0.3";
platform = iOS;
"product_name" = "PayPal iOS SDK";
};
payment = {
amount = "39.95";
"currency_code" = USD;
"short_description" = "Awesome saws";
};
"proof_of_payment" = {
"adaptive_payment" = {
"app_id" = "APP-1245783590";
"pay_key" = "AP-70M62356425642W";
"payment_exec_status" = COMPLETED;
timestamp = "2012-03-03T15:53:55Z";
};
};
Its from Paypal Adaptive Payments. I ended up doing this:
- (void)verifyCompletedPayment:(PayPalPayment *)completedPayment {
NSDictionary *pOPDictionary = [NSDictionary dictionaryWithDictionary:completedPayment.confirmation];
NSLog(#"pOPDictionary: %#",pOPDictionary);
NSDictionary *subDictionary = [pOPDictionary objectForKey:#"proof_of_payment"];
NSDictionary *sub2Dictionary = [subDictionary objectForKey:#"adaptive_payment"];
NSString *proofString = [sub2Dictionary objectForKey:#"payment_exec_status"];
if ([proofString isEqualToString:#"COMPLETED"]) {
NSLog(#"Payment Completed Successfully");
} else {
NSLog(#"Payment Error");
}
NSData *confirmation = [NSJSONSerialization dataWithJSONObject:completedPayment.confirmation options:0 error:nil];
}
Is there a more efficient way to get that key from the dictionary of dictionary of dictionaries? I only really need that key. So i didnt think I should cycle or loop thru the others.
There are two 2 different possibilities how you can simplify the code. You can use the "Modern Objective-C subscripting syntax" (see http://clang.llvm.org/docs/ObjectiveCLiterals.html for more information):
NSDictionary *pOPDictionary = completedPayment.confirmation;
NSString *proofString = pOPDictionary[#"proof_of_payment"][#"proof_of_payment"][#"payment_exec_status"];
Or Key-Value Coding:
NSDictionary *pOPDictionary = completedPayment.confirmation;
NSString *proofString = [pOPDictionary valueForKeyPath:#"proof_of_payment.proof_of_payment.payment_exec_status"];
I don't think that there is an advantage of one over the other, it is just a matter of
taste which one you choose.
I have an array of NSDictionary values that looks like this when NSLogged
{
HASMOD = F;
ISLOCKED = F;
ISREGD = F;
MANU = "HORNET";
ID = 706;
},
{
HASMOD = T;
ISLOCKED = F;
ISREGD = T;
MANU = "BANJI";
ID = 225;
},
//etc
I am trying to save these values to my core data object (with correct types). I have been following this tutorial and have reached the point where I am trying to insert the values into each of the objects, However I am not sure how to do this from an array of dictionaries.. as it only shows how to enter one lot of information
So I have attempted doing it myself.. but its more pseudo code than anything... this is as far I have as I done... hopefully it helps make sense of what I am trying to achieve.
// WRITE TO CORE DATA
NSManagedObjectContext *context = [self managedObjectContext];
Manuf *manuf = [NSEntityDescription insertNewObjectForEntityForName:#"Manuf" inManagedObjectContext:context];
int mycount = [parsedDataArrayOfDictionaries count];
while (mycount != 0) {
// Somehow read Dictionaries and put them into their correct value types
BOOL hasModBool;
hasModelBool =
BOOL isLockedBool;
isLockedBool =
BOOL isRegedBool;
isRegedBool =
NSString *manuString = [[NSString alloc] init];
manuString =
int manuIDInt;
manuIDInt =
// pass all the values into the manuf coredata obj
manuf.hasMod = hasModBool;
manuf.isLocked = isLockedBool;
manuf.isReged = isRegedBool;
manuf.manu = manuString;
manuf.manuID = manuIDInt;
count --; // itterate through the array
}
I am hoping someone can help me run through the array of dictionaries and insert them into the variables of my core data object..
any help would be greatly appreciated.
Just use a for-in loop to iterate through your array, and get the values with valueForKey:.
for (NSDictionary *dict in parsedDataArrayOfDictionaries) {
Manuf *manuf = [NSEntityDescription insertNewObjectForEntityForName:#"Manuf" inManagedObjectContext:context];
BOOL hasModelBool;
BOOL isLockedBool;
BOOL isRegedBool;
if([dict valueForKey:#"HASMOD"] isEqualToString:#"T"]) {
hasModelBool = TRUE;
}else{
hasModelBool = FALSE;
if([dict valueForKey:#"ISLOCKED"] isEqualToString:#"T"]) {
isLockedBool = TRUE;
}else{
isLockedBool = FALSE;
......
......
// pass all the values into the manuf coredata obj
manuf.hasMod = hasModBool;
manuf.isLocked = isLockedBool;
manuf.isReged = isRegedBool;
manuf.manu = manuString;
manuf.manuID = manuIDInt;
}
I'm assuming here that the "T" or "F" values in your dictionaries are strings that need to be converted to TRUE or FALSE.
I need to Count the number of Items (post) in this JSON response,
2012-06-04 14:09:57.872 horitable[72261:11903] JSON : {
posts = (
{
post = {
eventdate = "2012-03-31";
eventid = 2;
eventimage = "http://hernandoz.local/~hernandoz/kopict/02_31march2012.jpg";
eventinfo = "02 event";
eventname = "xplosion 02";
};
},
{
post = {
eventdate = "2012-07-07";
eventid = 3;
eventimage = "http://hernandoz.local/~hernandoz/kopict/greg_vs_turner.jpg";
eventinfo = "02 event";
eventname = "Xplosion 02";
};
},
{
post = {
eventdate = "2012-04-29";
eventid = 4;
eventimage = "http://hernandoz.local/~hernandoz/kopict/ko_itclub_apr_2012.jpg";
eventinfo = "KO East London Interclub";
eventname = "KO Interclub";
};
}
);
}
I know there are only 3 events (post), this is the code I am using
[[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
NSLog(#"JSON : %#", JSON); //get the JSON response
// 6.1 - Load JSON into internal variable
jsonResponse = JSON;
// 6.2 - Get the number of shows (post)
int shows = 0;
for (NSDictionary* day in jsonResponse) {
shows += [[day objectForKey:#"posts"] count];
NSLog(#"count : %d",shows);
}
I get an error , but I don't understand why .
-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x76986f0
can someone please help me out . Thanks
try this
NSLog(#"Response members= %#",responseString);
NSArray *array = [(NSDictionary*)[responseString JSONValue] objectForKey:#"posts"];
NSLog(#"Count value= %d",[array count]);
in your case you can do this
[[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
NSLog(#"JSON : %#", JSON); //get the JSON response
// 6.1 - Load JSON into internal variable
jsonResponse = JSON;
// 6.2 - Get the number of shows (post)
int shows = [[jsonResponse objectForKey:#"posts"] count];
NSLog(#"count : %d",shows);
you need to first fragmentize json as
NSDictionary * dict = [JSON JSONValue];
or
NSDictionary * dict = [JSON JSONFragmentValue];
then
for (NSDictionary* day in dict) {
shows += [[day objectForKey:#"posts"] count];
NSLog(#"count : %d",shows);
}
The problem was JSON as an ID, this works
jsonResponse = [(NSDictionary*)JSON objectForKey:#"posts"];
I think you are mistakely put "posts" instead of "post". The key "posts" contain an array of dictionary, and each dictionary has a key "post". What you are doing is you take all dictionaries from array in lines
for (NSDictionary* day in jsonResponse) {
and check for an key "posts" in dictionary. Really, there is no key called "posts" in dictionary. I is "post". And the value for "post" is a NSDictionary not an array. So you cant call count there. The solution for your issue is remove un-necessary APIs inside for loop
[[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
jsonResponse = JSON;
int shows = 0;
for (NSDictionary* day in jsonResponse) {
shows += 1;
}
NSLog(#"count : %d",shows);
Im quite new to iOS and objective.. heres my question..
if my array looks like this:
myArray = {
parentdict = {
childdict = {
aname = "Aname";
bname - "Bname";
cname = "Cname";
};
childarray = {
{
counter = "1";
close = "25236";
},
{
counter = "2";
close = "12458";
};
};
};
},
{
parentdict = {
childdict = {
aname = "Aname";
bname - "Bname";
cname = "Cname";
};
childarray = {
{
counter = "1";
close = "28556";
},
{
counter = "2";
close = "12118";
};
};
};
},
{
parentdict = {
childdict = {
aname = "Aname";
bname - "Bname";
cname = "Cname";
};
childarray = {
{
counter = "1";
close = "24356";
},
{
counter = "2";
close = "155628";
};
};
};
};
basically its an array of nested dictionary and inside one of the dictionary contains an array of dictionary (childarray) if i want to sort myArray by #"close" of array index 1, which is the one next to counter 2, exactly how should i do this?..(perhaps i should use NSSortDescriptor?)
thanks for the reply
You have presented your structure in the JSON format. I assume it is for sake of presenting it to the audience here. If you are actually starting with JSON string, you will have to convert it to nested NSArrayies and NSDictionaryies using some third-party libs or iOS 5 built-in classes..
Assuming you already have your top level NSArray* myArray, give it a try to the following code:
NSArray* myArray = // ... this is your array
NSArray* sorted_array = [myArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDictionary* left = obj1;
NSDictionary* right = obj2;
NSDictionary* left_parent_dict = [left objectForKey: #"parentdict"];
NSDictionary* right_parent_dict = [right objectForKey: #"parentdict"];
NSArray* left_child_array = [left_parent_dict objectForKey: #"childarray"];
NSArray* right_child_array = [right_parent_dict objectForKey: #"childarray"];
NSDictionary* left_child_first = [left_child_array objectAtIndex: 1];
NSDictionary* right_child_first = [right_child_array objectAtIndex: 1];
NSString* left_close = [left_child_first objectForKey: #"close"];
NSString* right_close = [right_child_first objectForKey: #"close"];
NSNumber* left_val = [NSNumber numberWithInt: [left_close intValue]];
NSNumber* right_val = [NSNumber numberWithInt: [right_close intValue]];
return [left_val compare: right_val];
} ];
You will need, of course, to add some checks which I omitted for simplicity.
If you want to get descending order modify the last statement to:
return [right_val compare: left_val];
I would also suggest you considering SQL database for complex data structures as pointed out by Niko.
Sorting an array can be quite complex, especially when the array contains nested objects. May be you should create an SQLite database
You should use iOS 5.0's built in JSON API. [Here's a link to a great tutorial.] (http://www.raywenderlich.com/5492/working-with-json-in-ios-5). JSON is really easy to work with. And that site also has great tutorials on Core Data (iOS's SQLite API) here. There are two more parts to that tutorial as well.
Try this
[array sortUsingComparator:(NSComparator)^(id obj1, id obj2){
int firstValue = [[obj1 objectForKey:#"someKey"] intValue];
int secondValue = [[obj2 objectForKey:#"someKey"] intValue];
int valueDiff = firstValue - secondValue;
return (valueDiff == 0) ? NSOrderedSame : (valueDiff < 0) ? NSOrderedAscending : NSOrderedDescending;
}];
I am trying to read the following json object using the json-framework and obj-C
{
Sections = {
Now = "Wednesday 9 February 2011 02:40";
Section = (
{
Article = (
{
Exceprt = "text here";
ID = 49011;
Title = "text here";
Type = Politics;
audioCounter = 0;
commentsCounter = 0;
hasMore = false;
important = False;
likesCounter = 0;
photoCounter = 0;
time = "21:12";
timeStamp = "2/8/2011 9:14:16 PM";
timeStatus = True;
videoCounter = 0;
viewsCounter = 0;
},
{
Exceprt = "text here";
ID = 49010;
Title = "text here";
Type = Politics;
audioCounter = 0;
commentsCounter = 0;
hasMore = false;
important = True;
likesCounter = 0;
photoCounter = 0;
time = "20:45";
timeStamp = "2/8/2011 9:10:59 PM";
timeStatus = True;
videoCounter = 0;
viewsCounter = 0;
},
{
Exceprt = "text here";
ID = 49008;
Title = "text here";
Type = Politics;
audioCounter = 0;
commentsCounter = 0;
hasMore = false;
important = False;
likesCounter = 0;
photoCounter = 0;
time = "20:28";
timeStamp = "2/8/2011 9:09:44 PM";
timeStatus = True;
videoCounter = 0;
viewsCounter = 0;
}
);
ID = 22;
Name = "EN Live";
totalNews = 3416;
}
);
};
}
My intent is to have a list of the articles (list of dictionaries) so that I can later access them easily. I have been stuck a while on this and my code is giving me an error about calling a non existent method for NSArray which has led me to suspect that I am misunderstanding the json object. I am totally new to this and any help is greatly appreciated.
Here's my code:
NSDictionary *results = [jsonString JSONValue];
NSDictionary *Articles = [[results objectForKey:#"Sections"] objectForKey:#"Section"];
NSArray *ListOfArticles = [Articles objectForKey:#"Article"];
for (NSDictionary *article in ListOfArticles)
{
NSString *title = [article objectForKey:#"Title"];
NSLog(title);
}
Thanks !
First of all, those aren’t valid JSON data. Names (in name/value pairs) are strings and must be quoted. String values must always be quoted. Boolean values must be either true or false (lowercase). Check http://json.org/ and http://www.ietf.org/rfc/rfc4627.txt?number=4627 and http://jsonlint.com
Here’s the structure of your data:
The top level value is an object (dictionary)
This object has a name (key) called Sections whose value is itself another object (dictionary)
Sections has a name (key) called Section whose value is an array
Each element in the Section array is an object (dictionary)
Each element in the Section array has a name (key) called Article whose value is an array, as well as other names (keys): ID, title, totalNews
Each element in the Article array is an object
If your JSON data were valid, you could parse them as follows:
// 1.
NSDictionary *results = [jsonString JSONValue];
// 2.
NSDictionary *sections = [results objectForKey:#"Sections"];
// 3.
NSArray *sectionsArray = [sections objectForKey:#"Section"];
// 4.
for (NSDictionary *section in sectionsArray) {
// 5.
NSLog(#"Section ID = %#", [section objectForKey:#"ID"];
NSLog(#"Section Title = %#", [section objectForKey:#"Title"];
NSArray *articles = [section objectForKey:#"Article"];
// 6.
for (NSDictionary *article in articles) {
NSLog(#"Article ID = %#", [article objectForKey:#"ID"];
NSLog(#"Article Title = %#", [article objectForKey:#"Title"];
// …
}
}
Your JSON framework is probably parsing out an NSDictionary where you're expecting an NSArray. It'll let you assign an NSDictionary to an NSArray, but then you'll get a runtime exception when you attempt to call a method on your "array". Judging by the JSON you posted (which isn't correct JSON), this is what I would have my parsing code look like. The names of the NSDictionaries and NSArrays are simply named after the JSON attributes they represent.
NSDictionary* results = [jsonString JSONValue];
NSDictionary* sections = [results valueForKey:#"Sections"];
NSArray* section = [sections valueForKey:#"Section"];
NSArray article = [[section objectAtIndex:0] valueForKey:#"Article"];
for (NSDictionary* anArticle in article) {
NSLog(#"%#", [anArticle valueForKey:#"Title"]);
}