-1

I'm building my first real iOS app - I'm a webdeveloper from origin. It communicates with a server and then gets data back from the server, formatted like this:

{
    "data": {
        "firstname": "Test",
        "lastname": "User",
        "username": "TestUser",
        "photo_link": "http://placehold.it/500x500"
    }
}

However, when I try to use these variables, I always get 'null'. res is outputted correctly, though, so that's okay. What am I doing wrong?

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *xAuthToken = [[NSUserDefaults standardUserDefaults]
                            stringForKey:@"AuthToken"];

    NSLog(xAuthToken);

    self.responseData = [NSMutableData data];
    NSURLRequest *request = [NSURLRequest requestWithURL:
                         [NSURL URLWithString:@"http://www.example.com/api/user"]];

    NSMutableURLRequest *mutableRequest = [request mutableCopy];
    [mutableRequest addValue:xAuthToken forHTTPHeaderField:@"X-Auth-Token"];

    request = [mutableRequest copy];

    [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [super viewDidLoad];

}

- (void)viewWillAppear:(BOOL)animated
{
    [self.navigationController setToolbarHidden:YES animated:YES];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"didReceiveResponse");
    [self.responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"didFailWithError");
    NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"connectionDidFinishLoading");
    NSLog(@"Succeeded! Received %d bytes of data",[self.responseData length]);


    // convert to JSON
    NSError *myError = nil;
    NSDictionary *res = [NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:&myError];

    NSDictionary *switchValues = [res objectForKey:@"data"];

    NSString *photoLink = [switchValues objectForKey:@"photo_link"];
    NSString *firstName = [switchValues objectForKey:@"firstname"];
    NSString *lastName = [switchValues objectForKey:@"lastname"];

    self.tableView.separatorColor = [UIColor colorWithRed:150/255.0f green:161/255.0f blue:177/255.0f alpha:1.0f];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.opaque = NO;
    self.tableView.backgroundColor = [UIColor clearColor];
    self.tableView.tableHeaderView = ({
        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 184.0f)];
        NSURL *url = [NSURL URLWithString: photoLink];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 40, 100, 100)];
        imageView.image = image;
        imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
        imageView.layer.masksToBounds = YES;
        imageView.layer.cornerRadius = 50.0;
        imageView.layer.borderColor = [UIColor whiteColor].CGColor;
        imageView.layer.borderWidth = 3.0f;
        imageView.layer.rasterizationScale = [UIScreen mainScreen].scale;
        imageView.layer.shouldRasterize = YES;
        imageView.clipsToBounds = YES;

        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 150, 0, 24)];
        label.text = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
        label.font = [UIFont fontWithName:@"HelveticaNeue" size:21];
        label.backgroundColor = [UIColor clearColor];
        label.textColor = [UIColor colorWithRed:62/255.0f green:68/255.0f blue:75/255.0f alpha:1.0f];
        [label sizeToFit];
        label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

        [view addSubview:imageView];
        [view addSubview:label];
        view;
    });
};

res outputs:

{
    "data": {
        "firstname": "Test",
        "lastname": "User",
        "username": "TestUser",
        "photo_link": "http://placehold.it/500x500"
    }
}
user4191537
  • 203
  • 2
  • 14
  • 1
    check if "res" is correct first by NSLog – John Nov 22 '14 at 11:42
  • Can you show some more code that runs before what you posted. more precisely, code that related to the `res` variable. Plus, the example above is the complete `NSLog` of `res`? – AMI289 Nov 22 '14 at 11:43
  • Plus, if you say that you get `NULL` when trying to use them, meaning you already get `NULL` on the 3 `NSString` calls at the top, the rest of the code you've posted is irrelevant and you haven't posted much code which is relevant to your problem... – AMI289 Nov 22 '14 at 11:46
  • Again- Is what you've posted above is the exact `NSLog` for the `res` variable? – AMI289 Nov 22 '14 at 11:50
  • I edited my question; sorry for posting irrelevant code. Above is the code and the output of the `res variable.` – user4191537 Nov 22 '14 at 11:52
  • No need to sorry mate, just wanted to avoid confusion by not providing too much information that is not related to the problem, if the `NSString`s are already `NULL`, what happens after them is not part of the problem, but the problem happens before. – AMI289 Nov 22 '14 at 11:54
  • Where in the code you output `res`? I'm not seeing it. try to also output the `switchValues` dictionary right after creating it. `NSLog(@"%@", switchValues);` – AMI289 Nov 22 '14 at 11:58
  • It's so strange, because I added `NSLog(@"%@", switchValues);`, `NSLog(@"%@", photoLink);`, etc. and it stil gave me `null`. However, once I added `NSLog(@"%@", res);` it suddenly works. – user4191537 Nov 22 '14 at 12:02
  • This is weird....So now everything is working correctly? – AMI289 Nov 22 '14 at 12:08
  • Also, try to add an `if` statement to check if it returned an error and print it if so, just to be safe. `NSLog(@"Error: %@", [myError localizedDescription]);` will return a human readable output. – AMI289 Nov 22 '14 at 12:10
  • Where is `res` "outputted"? I don't see it NSLogged anywhere. – Hot Licks Nov 22 '14 at 13:19

1 Answers1

0

Did you try to catch the class name of the elements stored in the NSDictionary? Maybe you have to try with a code like this

if ([[switchValues objectForKey:@"photo_link"] isKindOfClass: [NSString class])
{
    NSString *photo = (NSString *) [switchValues objectForKey:@"photo_link"];
}

Maybe this will help you reflection - Create objective-c class instance by name

That's because using the JSONReadingOption choose by the author, the JSONString will be converted in NSMutableString and these, accessed in a text property, will not be like a normal NSString. Try this out:

NSMutableString *test = [[NSMutableString alloc] init];
[test appendString:@"Hello"];

UITextField *firstPart = [[UITextField alloc] initWithFrame:CGRectZero];
firstPart.textAlignment = NSTextAlignmentCenter;
firstPart.text = test;

You will see that the text property will be empty. Solution will be a code like this:

if ([[switchValues objectForKey:@"photo_link"] isKindOfClass: [NSMutableString class]])
{
    NSString *photo = [NSString stringWithFormat: @"%@", [switchValues objectForKey:@"photo_link"]];
}

Or you can set the JSONReadingOptions = 0 so it will create a normal NSDictionary.

Community
  • 1
  • 1
Luca D'Alberti
  • 4,749
  • 3
  • 25
  • 45