arcade16
arcade16

Reputation: 1535

How to add value to JSON dictionary?

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

Answers (2)

arcade16
arcade16

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

iphonic
iphonic

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

Related Questions