Reputation: 1535
I have a response object that looks like this:
[
{
"ser": "XXX-Demo-L",
"name": "XXX-Demo-L",
"statusId": 2,
"buildVersion": "XXX",
"IP": "192.168.128.123",
"priority": 1,
"bandwidthUpload": 5174.68,
"bandwidthDownload": 1554.88,
"bandwidthInternal": 37.29,
"totalBandwidthUpload": null,
"totalBandwidthDownload": null,
"totalBandwidthInternal": null,
"usage": null,
"protectedDevices": [
{
"deviceType": 3,
"securityModeId": 1,
"statusId": 2,
"uniqueId": "Samsung TV",
"deviceName": "Samsung TV",
"IP": "196.128.0.5",
"MAC": null,
"priority": 1,
"bandwidthUpload": 5184.36,
"bandwidthDownload": 1954.81,
"bandwidthInternal": 98.64,
"totalBandwidthUpload": null,
"totalBandwidthDownload": null,
"totalBandwidthInternal": null,
"usage": null,
"endpointsConnected": []
},
{
"deviceType": 3,
"securityModeId": 1,
"statusId": 2,
"uniqueId": "AARP-Demo-L-100",
"deviceName": "AARP-Demo-L-100",
"IP": "196.128.0.100",
"MAC": null,
"priority": 2,
"bandwidthUpload": 5032,
"bandwidthDownload": 1451.78,
"bandwidthInternal": 81.96,
"totalBandwidthUpload": null,
"totalBandwidthDownload": null,
"totalBandwidthInternal": null,
"usage": null,
"endpointsConnected": [
{
"endpoint": "208.91.197.104",
"ip": "208.91.197.104",
"domain": null,
"latitude": 18.4167,
"longitude": -64.6167
},
{
"endpoint": "209.85.128.2",
"ip": "209.85.128.2",
"domain": null,
"latitude": 37.4192,
"longitude": -122.0574
},
{
"endpoint": "98.137.236.24",
"ip": "98.137.236.24",
"domain": "yahoo.com",
"latitude": 37.4249,
"longitude": -122.0074
},
{
"endpoint": "204.79.197.212",
"ip": "204.79.197.212",
"domain": null,
"latitude": 47.6801,
"longitude": -122.1206
}
]
},
I am trying to add all the endpoint data to a single array, but need the device name to go along with each endpoint (each device can have multiple endpoints).
This is what my code for traversing this response object looks like:
NSLog(@"TELEMETRY DETAILS RESULTS ARRAY: %@", resultsArray);
self.telemetryData = resultsArray;
self.deviceListData = [resultsArray[0] valueForKey:@"protectedDevices"];
self.endpointData = [[NSMutableArray alloc] init];
for(int i = 0; i < [self.deviceListData count]; i++){
if ([self.deviceListData[i] valueForKey:@"endpointsConnected"]) {
[self.endpointData addObjectsFromArray:[self.deviceListData[i] valueForKey:@"endpointsConnected"]];
}
}
NSLog(@"Endpoint data array: %@", self.endpointData);
[self.tableView reloadData];
This is what my new data structure looks like (I would like to add the device name for each endpoint as a key/value pair):
Endpoint data array: (
{
domain = "<null>";
endpoint = "208.91.197.104";
ip = "208.91.197.104";
latitude = "18.4167";
longitude = "-64.61669999999999";
},
{
domain = "<null>";
endpoint = "209.85.128.2";
ip = "209.85.128.2";
latitude = "37.4192";
longitude = "-122.0574";
},
{
domain = "yahoo.com";
endpoint = "98.137.236.24";
ip = "98.137.236.24";
latitude = "37.4249";
longitude = "-122.0074";
},
How would I add the device name to my array of endpoint dictionaries?
Upvotes: 1
Views: 151
Reputation: 1535
This was the solution that worked for me:
self.telemetryData = resultsArray;
self.deviceListData = [resultsArray[0] valueForKey:@"protectedDevices"];
self.endpointData = [[NSMutableArray alloc] init];
for(int i = 0; i < [self.deviceListData count]; i++){
if ([self.deviceListData[i] valueForKey:@"endpointsConnected"]) {
for(int x = 0; x < [[self.deviceListData[i] valueForKey:@"endpointsConnected"] count]; x++){
NSMutableDictionary *m = [[self.deviceListData[i] valueForKey:@"endpointsConnected"][x] mutableCopy];
if ([self.deviceListData[i] valueForKey:@"deviceName"] != (id)[NSNull null]) {
[m setObject:[self.deviceListData[i] valueForKey:@"deviceName"] forKey:@"deviceName"];
}
[self.endpointData addObject:m];
}
}
}
Specifically, the second for loop which iterates through the dictionaries in the endpointsConnected array. Then making a mutable copy of each dictionary in there prior to adding the device key/value pair.
Upvotes: 0
Reputation: 12719
You can only do this by converting your NSDictionary and its leaf to Mutable
, you have got multiple options here,
First when you are parsing the JSON from received data, use NSJSONReadingMutableLeaves
as reading option it will give you all mutable data like below
NSMutableDictionary *dictionary=[NSJSONSerialization JSONObjectWithData:[NSData data] options:NSJSONReadingMutableLeaves error:nil];
If not above, you convert any NSArray
, or NSDictionary
object to mutable using following code..
-(id)deepMutableCopy
{
if ([self isKindOfClass:[NSArray class]]) {
NSArray *oldArray = (NSArray *)self;
NSMutableArray *newArray = [NSMutableArray array];
for (id obj in oldArray) {
[newArray addObject:[obj deepMutableCopy]];
}
return newArray;
} else if ([self isKindOfClass:[NSDictionary class]]) {
NSDictionary *oldDict = (NSDictionary *)self;
NSMutableDictionary *newDict = [NSMutableDictionary dictionary];
for (id obj in oldDict) {
[newDict setObject:[oldDict[obj] deepMutableCopy] forKey:obj];
}
return newDict;
} else if ([self isKindOfClass:[NSSet class]]) {
NSSet *oldSet = (NSSet *)self;
NSMutableSet *newSet = [NSMutableSet set];
for (id obj in oldSet) {
[newSet addObject:[obj deepMutableCopy]];
}
return newSet;
#if MAKE_MUTABLE_COPIES_OF_NONCOLLECTION_OBJECTS
} else if ([self conformsToProtocol:@protocol(NSMutableCopying)]) {
// e.g. NSString
return [self mutableCopy];
} else if ([self conformsToProtocol:@protocol(NSCopying)]) {
// e.g. NSNumber
return [self copy];
#endif
} else {
return self;
}
}
Use it like
NSMutableDictionary *dictionary=[originaldictionary deepMutableCopy];
Finally when you have a Mutable
dictionary, just iterate and modify the values, No problem like below
for(NSMutableDictionary *device in dictionary[@"protectedDevices"]){
NSMutableArray *endpoints=[[NSMutableArray alloc] init];
[device setObject:endpoints forKey:@"endpointsConnected"];
}
And you are done.
Hope it helps you, Cheers.
Upvotes: 2