I am using the code below to upload an image to my server. The code is working good but the Indicator is not stopping. I am using Xcode 6 and Objective-c and her is my code:
-(void) uploadImage
{
NSData *imageData = UIImageJPEGRepresentation(self.createdImage.image,0.2);
if (imageData != nil)
{
NSString * filenames = [NSString stringWithFormat:@"TextLabel"];
NSLog(@"%@", filenames);
NSString *urlString = @"http://myWebSite/sendVideo.php";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"POST"];
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"filenames\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[filenames dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@%@%@%@.mov\"\r\n", toSaveVideoLink, myString, FormattedDate, FormattedTime]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"Response : %@",returnString);
if([returnString isEqualToString:@"Success"])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"Image Saved Successfully" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[spinner stopAnimating];
// [[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
NSLog(@"Finish");
}
}
I do not know where is the problem. The alert message appearing but the Indicator is not stopping. How could I stop it?
It's possible that spinner
is not referencing the UIActivityIndicatorView
that you think it is. Log the value of spinner
and see what it contains. Also make sure it was added to the view correctly, etc. It's impossible to tell without seeing how you're instantiating the spinner, how you added it to the view, etc.
But, there's a deeper problem here, that you should not be doing a synchronous request. You are issuing your request like so:
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"Response : %@",returnString);
if([returnString isEqualToString:@"Success"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"Image Saved Successfully" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[spinner stopAnimating];
}
You should be doing this asynchronously:
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// this portion happens in the background
NSString *returnString;
if (data) {
returnString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Response : %@",returnString);
// do something with response
} else {
NSLog(@"Error: %@", error);
}
// dispatch UI update (and any model updates) back to the main queue
dispatch_async(dispatch_get_main_queue(), ^{
if([returnString isEqualToString:@"Success"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"Image Saved Successfully" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
}
NSAssert(spinner, @"Spinner is `nil`, but it should not be.");
[spinner stopAnimating];
});
}];
[task resume];
// do not do anything contingent upon the response here; the above runs asynchronously, so anything dependent upon the response must go in the block above
Also, if you're doing this block synchronously (which is very bad), I wonder if you're doing anything after this synchronously too (which would make it not respond to the stopping of the spinner in a timely manner). Again, it's impossible to tell without seeing the code, but that's another possible issue. Bottom line, just make sure you never do anything synchronously, and your UI will generally be more responsive.