gamda
gamda

Reputation: 580

NSURLConnection calling connectionDidFinishLoading before it should?

I am developing a iOS application that fires a few NSURL requests. I created a WebService class that implements didReceiveData like this:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Append the new data to the instance variable you declared
    [_responseData appendData:data];
}

where _responseData is a NSMutableData* property. Then I created several subclasses that create their specific request and implement connectionDidFinishLoading. Specifically, I have a RegisterService class that implements it like this:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // The request is complete and data has been received
    // You can parse the stuff in your instance variable now
    NSError *error = nil;
    _parsedData = [NSJSONSerialization JSONObjectWithData:_responseData options:kNilOptions error:&error];
    NSLog(@"register data: %@",_parsedData);
    registerAnswer serverAnswer = [[_parsedData objectForKey:@"success"] integerValue];

    if (serverAnswer == REGISTER_SUCCESS) {
        // Give data to delegate to handle
        [self.delegate successRegister];
    }
    else { // serverAnswer == REGISTER_FAIL
        NSLog(@"register message: %@",[[_parsedData objectForKey:@"message"] stringValue]);
        [self.delegate failedRegister];
    }
}

I have 2 different view controllers that use this service. One of them calls it like this:

self.personRegistering.username = self.txtUsername.text;
self.personRegistering.password = self.txtPassword.text;
if (self.personRegistering.isCustomer) {
    // register customer
    DGRegisterService* myRegisterService = [[DGRegisterService alloc] initWithDelegate:self];
    [myRegisterService registerPerson:self.personRegistering];
}
else {
    // continue to get picture
    [self performSegueWithIdentifier:@"RegisterPageThreeToFour" sender:self];
}

and it works perfectly. The other one (page four) has the user take a picture before they can register. Here's the code:

- (IBAction)btnTakePicture:(id)sender {
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        // Camera is available
        UIImagePickerController* myCamera = [[UIImagePickerController alloc] init];
        myCamera.sourceType = UIImagePickerControllerSourceTypeCamera;
        myCamera.delegate = self;
        [self presentViewController:myCamera animated:YES completion:NULL];
    }
}

#pragma mark - UIImagePicker Delegate

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissViewControllerAnimated:YES completion:NULL];
    // Register person first
    DGRegisterService* myRegisterService = [[DGRegisterService alloc] initWithDelegate:self];
    [myRegisterService registerPerson:self.personRegistering];

//    // Now send pic
//    UIImage* picture = [info objectForKey:UIImagePickerControllerOriginalImage];
//    DGUploadService* myUploadService = [[DGUploadService alloc]     initWithDelegate:self];
//    [myUploadService uploadImage:picture forUsername:self.personRegistering.username];
}

Now, the second one sends the request and the server processes it properly, sending back this JSON object:

{"success":1,"message":"Account successfully created."}

Which is what I expected. However, both NSLog statements show "(null)". Sometimes, the app crashes because objectForKey was sent to an instance that doesn't respond to it. Some other times, the console will show the JSON object after I hit "Stop" on XCode. The rest of the times it doesn't crash or show the object.

Since this page uses the camera, I must test only on an iPhone, not the simulator. The other page shows the JSON object correctly every single time in both the simulator and the iPhone. THe iPhone I'm using is a 4S with iOS7.1.1.

Upvotes: 2

Views: 1301

Answers (2)

gamda
gamda

Reputation: 580

There was nothing wrong with this code. Per sergio's suggestion, I NSLogged the data received and the error. The JSON parsing was failing, and printing the raw data revealed that the php script on the server side was sending an error message with the JSON object, causing it to not be parsed properly. We fixed the php file and this works now.

Upvotes: 0

sergio
sergio

Reputation: 69027

If you mean that the NSLog in the following lines:

NSError *error = nil;
_parsedData = [NSJSONSerialization JSONObjectWithData:_responseData options:kNilOptions error:&error];
NSLog(@"register data: %@",_parsedData);

sometimes prints "(null)", this could be caused by an error in the JSONObjectWithData call.

I would suggest to add

NSLog(@"received data: %@", _responseData);

to check that all is fine with the data, and

NSLog(@"register data: %@ -- (error: %@)",_parsedData, [error localizedDescription]);

to see if an error was returned.

Upvotes: 1

Related Questions