So in a block I am getting and parsing a JSON object that looks like this (any time you see "<...>" assume properly formed data)(also this is only one of the objects in question):
{
asset = {
<...>
};
<...>
sections = (
{
<...>
fields = (
);
items = (
);
},
{
<...>
fields = (
);
items = (
);
},
{
<...>
fields = (
);
items = (
{
<...>
properties = {
title = "We welcome guests...";
};
},
{
<...>
properties = {
title = "More text";
};
},
{
<...>
properties = {
title = "Opportunity Insert...";
};
}
);
},
{
<...>
fields = (
{
<...>
values = (
Private,
Public
);
},
{
<...>
values = (
);
},
{
<...>
values = (
);
}
);
items = (
);
},
{
<...>
fields = (
{
<...>
values = (
);
},
{
<...>
values = (
);
}
);
items = (
);
}
);
}
The code to get this(using AFNetworking):
NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:AppsURL([[NSUserDefaults standardUserDefaults] objectForKey:kAuthToken])]];
AFHTTPRequestOperation* op = [[AFHTTPRequestOperation alloc] initWithRequest:req];
[op setResponseSerializer:[[AFJSONResponseSerializer alloc] init]];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (responseObject != nil&&[responseObject isKindOfClass:[NSDictionary class]]) {
NSDictionary* dict = (NSDictionary*)responseObject;
if (dict[#"apps"]&&[dict[#"apps"] isKindOfClass:[NSArray class]]) {
apps = dict[#"apps"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
return;
}
}
NSLog(#"Error Loading apps:%#",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error:%#",error);
NSLog(#"Response:%#",operation.response.description);
}];
[op start];
At this point everything is loading into memory and working perfectly. I set this to a class-level NSArray and then use that NSArray to fill a table. The problem comes when I try to retrieve the data after the user picks one of the items from the table. I then use the index and pull that object from the NSArray to find that is looks like this(note the fact that all item and field arrays are now empty):
{
asset = {
<...>
};
<...>
sections = (
{
<...>
fields = (
);
items = (
);
},
{
<...>
fields = (
);
items = (
);
},
{
<...>
fields = (
);
items = (
);
},
{
<...>
fields = (
);
items = (
);
}
);
}
Code for select:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row < apps.count) {
//the output of this is what I copy and pasted
NSLog(#"app data to be cleaned up:%# \r app data sent:%#",apps[indexPath.row],((NSDictionary*)apps[indexPath.row]).mutableCopy);
//I originally thought the problem was here, but the output above proved me wrong
NSMutableDictionary *app = [Functions recurseDictionaryForNull:((NSDictionary*)apps[indexPath.row]).mutableCopy];
[[NSUserDefaults standardUserDefaults] setObject:app
forKey:#"app"];
MainMenuViewController* mainMenu = (MainMenuViewController*)[self.storyboard instantiateViewControllerWithIdentifier:#"mainMenu"];
[self.navigationController setViewControllers:#[mainMenu] animated:YES];// reset nav stack
}
}
I'm kinda at a lose... any ideas what could be doing this and how to fix it??
It was the data from the server. I was told 2 "apps" were the same except for one item and turns out they were missing all of the fields and items as well. Thanks Dima and Mike for taking the time anyways!
Related
my server sends me an response in hierarchy way i do no how to grab the value from that
here my sample response :
{
id = "-1";
result = (
{
keyname = "Warranty Expiry Date";
value = "06-14-2017";
}
);
},
{
id = "-1";
result = (
{
keyname = Owner;
value = "";
}
);
},
{
id = "-1";
result = (
{
keyname = Model;
value = "";
}
);
},
{
id = "-1";
result = (
{
keyname = "Price $";
value = 1000;
}
);
},
{
id = "-1";
result = (
{
keyname = Vendor;
value = "";
}
);
},
{
id = "-1";
result = (
{
keyname = "Purchase Date";
value = "";
}
);
}
)
here is sample Java code how they extracted the values
Hashtable htAttrs = (Hashtable) editedAttrHash.get(assItmId);
if (htAttrs != null) {
Set<String> keys = htAttrs.keySet();
for (String deAttr : keys) {
xmlSerializer.startTag("", "attribute");
xmlSerializer.attribute("", "keyname", deAttr);
xmlSerializer.attribute("", "value",
htAttrs.get(deAttr).toString());
xmlSerializer.endTag("", "attribute");
}
}
i need to do no how to from this structure past one day i am blocked here anyone can fix my problem
How to extract values from nsmutablearray?If it is really nsmutablearray object, then extract the values is simple.
For example, to get id of first element:
NSString firstId = response[0][#"id"]
But it seems, like for now, it is just a json object. So, you should serialize it to nsarray object first.
I have an array of names and want to count them by having A & B prefix.
For example for this username I want my NSMutableDictionary *cellNum to return the count of names starting with each alphabet, like: "A":"2" & "B":"1".
#interface ...
{
NSArray *users;
NSMutableDictionary *cellNum;
}
#implementation ...
{
users = #[#"Ali",#"Armita",#"Babak"];
for (int i=0;i<users.count;i++)
{
if ( [users[i] hasPrefix:#"A"] )
{
cellNum[#"a"] = #([cellNum[#"a"] intValue]+1);
}
else
{
cellNum[#"b"] = #([cellNum[#"b"] intValue]+1);
}
}
}
Try using this code:
NSMutableDictionary *cellNum = [NSMutableDictionary dictionary];
[cellNum setObject:#(0) forKey:#"a"];
[cellNum setObject:#(0) forKey:#"b"];
NSArray* users = #[#"Ali",#"Armita",#"Babak"];
for (int i=0;i<users.count;i++)
{
if ( [users[i] hasPrefix:#"A"] ) {
cellNum[#"a"] = #([cellNum[#"a"] intValue]+1);
} else {
cellNum[#"b"] = #([cellNum[#"b"] intValue]+1);
}
}
This will surely Give you the desired result: { a = 2; b = 1; }
I have the code below which has ben spat out of an XML parse but i'm unsure as to what I should do to consolidate it. How would I add all the 'string' items into an array??
Parser:
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.url.net/directory/%#",fileName]]];
NSDictionary *dict=[XMLParser dictionaryForXMLData:data error:nil];
NSLog(#"%#",dict);
XMLParser is a custom class.
NSLog:
plist = {
dict = {
key = (
{
text = "\n\n\tmapFile";
},
{
text = "\n\tmapPreviewFile";
},
{
text = "\n\tmapScale";
},
{
text = "\n\tmapper";
},
{
text = "\n\tterrain";
},
{
text = "\n\tTopLeft";
},
{
text = "\n\tTopRight";
},
{
text = "\n\tBottomLeft";
},
{
text = "\n\tBottomRight";
}
);
string = (
{
text = "\n\thttp://www.url.com";
},
{
text = "\n\thttp://www.url.com";
},
{
text = "\n\t1 : 2 500";
},
{
text = "\n\tSeb O'H (2014)";
},
{
text = "\n\tUrban (school)";
},
{
text = "\n\t42.87067222225,147.31143055";
},
{
text = "\n\t42.8645138888888894, 147.3160527777777";
},
{
text = "\n\t42.87067222222222, 147.3160527777777";
},
{
text = "\n\t42.8645138888888894, 147.31143055555555";
}
);
text = "\n";
};
text = "\n";
version = "1.0";
};
I've tried many methods but still can't seem to get it working. So in simple my question is, how do I put a row in an NSDictionary into an NSArray.
Thanks.
You can simply filter the array using valueForKeyPath
NSArray *text = [data valueForKeyPath:#"plist.dict.string.text"];
I am using XMLReader to parse a xml response. I have converted the xml to a NSDictionary. Now i want to access the array named 'cTrx' inside the NSDictionary. This is my NSDictionary:
{
Envelope = {
Body = {
fRetrieveTransactionsforReversalResponse = {
fRetrieveTransactionsforReversalResult = {
pCellularNumber = {
text = 0825669995;
};
pResponseCode = {
text = 00;
};
pResponseMessage = {
text = Approved;
};
pTrx = {
cTrx = (
{
pCardHolderName = {
};
pReference = {
text = 140826121114;
};
pTransactionAccount = {
text = "364241****0016";
};
pTransactionDate = {
text = "8/26/2014 12:11:18 PM";
};
pTransactionID = {
text = 23;
};
},
{
"xsi:nil" = true;
}
);
};
};
};
};
};
}
Thanks.
You can access dictionary and array values with square brackets:
val = dictionary[#"key"];
item = array[i];
It works for nested dictionaries as well:
NSDictionary *nested = #{#"dict_key": dictionary};
dictionaryVal = nexted[#"dict_key"][#"key"];
So, in your case, you could access cTrx array in next way:
NSArray *cTrx = yourDictionary[#"Envelope"][#"Body"][#"fRetrieveTransactionsforReversalResponse"][#"pTrx"][#"cTrx"];
Long string of code :)
I'm using the following function in order to get all the keys and values of the preferences.plist file located in: /private/var/preferences/SystemConfiguration/preferences.plist
- (void)FindKeysAndValuesInPlist:(id)object forKeyNamed:(NSString *)keyName{
if ([object isKindOfClass:[NSDictionary class]])
{
NSLog(#"%#",keyName);
[object enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
[self FindKeysAndValuesInPlist:value forKeyNamed:key];
}];
}
else if ([object isKindOfClass:[NSArray class]])
{
[object enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self FindKeysAndValuesInPlist:obj forKeyNamed:nil];
}];
}
else
{
NSLog(#"%#.%#", keyName, object);
}
}
An example of the content of preferences.plist:
{
CurrentSet = "/Sets/3B9E7BEB-5558-4497-803B-21B03E6A46C0";
NetworkServices = {
"014226AB-75B7-41CF-9B96-48E82FD6A395" = {
Interface = {
DeviceName = ip4;
Hardware = "com.apple.CommCenter";
Type = "com.apple.CommCenter";
UserDefinedName = "com.apple.CommCenter (ip4)";
};
PrimaryRank = Never;
UserDefinedName = "com.apple.CommCenter (ip4)";
"com.apple.CommCenter" = {
AllowNetworkAccess = 0;
Available = 1;
Version = 11;
};
};
"1C01B561-1A55-4E3B-82FC-CDFF5024F0D2" = {
Interface = {
DeviceName = ip1;
Hardware = "com.apple.CommCenter";
Type = "com.apple.CommCenter";
UserDefinedName = "com.apple.CommCenter (ip1)";
};
UserDefinedName = "com.apple.CommCenter (ip1)";
"com.apple.CommCenter" = {
AllowNetworkAccess = 1;
Available = 1;
SettingsHaveBeenAlteredByPreferences = 1;
Setup = {
apn = "";
password = "";
signature = <7ecb277c ad546563 3ac057fb db40aeaa 939f8c0e e7ae68c2 6e0ff602 77d3868d 18a63059 6c83f66d 46b8af57 d1bf83d0 2655ced6 57d773f4 5c7e733e 923aaa07 39165357 a4ecf270 130276f0 59c7470e 0b61a631 dff04fd1 0bc80cb4 a0dc0a03 96a8ebf0 74c24cdb 84c38239 9f6f7f05 ee032982 8ed1b72d b531405b 09e35f5b>;
"type-mask" = 0;
username = "";
};
Version = 11;
};
};
The problem is that I'm trying to create this kind of output format: MAINKEY.SUBKEY.VALUE
For example:
NetworkServices = {
"014226AB-75B7-41CF-9B96-48E82FD6A395" = {
Interface = {
DeviceName = ip4;
Hardware = "com.apple.CommCenter";
Type = "com.apple.CommCenter";
UserDefinedName = "com.apple.CommCenter (ip4)";
};
Would be: NetworkServices.014226AB-75B7-41CF-9B96-48E82FD6A395.Interface.Hardware.ip4
Iterate over the keys in a dictionary. When the value for a key is another dictionary, push the key onto a stack and recurse on the dictionary value. When the value is a string or number, then concatenate the keys in the stack and print the key path and value.
Code:
+ (void)printDict:(NSDictionary *)dict keyStack:(NSArray *)keys
{
if (keys == nil) {
keys = [NSArray array];
}
for (id key in dict) {
id value = dict[key];
if ([value respondsToSelector:#selector(objectForKey:)]) {
[self printDict:value keyStack:[keys arrayByAddingObject:key]];
} else {
NSLog(#"%# = %#", [[keys arrayByAddingObject:key] componentsJoinedByString:#"."], value);
}
}
}