
This video is only available to subscribers. Start a subscription today to get access to this and 472 other videos.
Posting Multi-part Forms with AFNetworking
Episode
#31
|
31 minutes
| published on
August 30, 2012
Subscribers Only
In this episode, I take an existing app and add the ability to post information to a server, including photo uploads. We report on the progress of the upload and configure AFNetworking to do a proper muliti-part HTTP form post. In addition, I cover how to build a standalone static TableViewController to represent a form using Storyboards.
Episode Links
- Episode Source Code
- AFNetworking FAQ - "How do I upload a file?"
- KKGridView
Saving the Data
- (void)save:(id)sender {
BLLatte *latte = [[BLLatte alloc] init];
latte.location = self.locationTextField.text;
latte.submittedBy = self.authorTextField.text;
latte.comments = self.commentsTextView.text;
latte.photoData = UIImagePNGRepresentation(self.imageView.image);
[self.view endEditing:YES];
BLProgressView *progressView = [BLProgressView presentInWindow:self.view.window];
// save it
[latte saveWithProgress:^(CGFloat progress) {
[progressView setProgress:progress];
} completion:^(BOOL success, NSError *error) {
[progressView dismiss];
if (success) {
[self.navigationController popViewControllerAnimated:YES];
} else {
NSLog(@"ERROR: %@", error);
}
}];
}
Then, in the model...
- (void)saveWithProgress:(void (^)(CGFloat progress))progressBlock completion:(void (^)(BOOL success, NSError *error))completionBlock {
//make sure none of the parameters are nil, otherwise it will mess up our dictionary
if (!self.location) self.location = @"";
if (!self.submittedBy) self.submittedBy = @"";
if (!self.comments) self.comments = @"";
NSDictionary *params = @{
@"latte[location]" : self.location,
@"latte[submitted_by]" : self.submittedBy,
@"latte[comments]" : self.comments
};
NSURLRequest *postRequest = [[BLAPIClient sharedClient] multipartFormRequestWithMethod:@"POST"
path:@"/lattes"
parameters:params
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:self.photoData
name:@"latte[photo]"
fileName:@"latte.png"
mimeType:@"image/png"];
}];
AFHTTPRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:postRequest];
[operation setUploadProgressBlock:^(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
CGFloat progress = ((CGFloat)totalBytesWritten) / totalBytesExpectedToWrite;
progressBlock(progress);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (operation.response.statusCode == 200 || operation.response.statusCode == 201) {
NSLog(@"Created, %@", responseObject);
NSDictionary *updatedLatte = [responseObject objectForKey:@"latte"];
[self updateFromJSON:updatedLatte];
[self notifyCreated];
completionBlock(YES, nil);
} else {
completionBlock(NO, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completionBlock(NO, error);
}];
[[BLAPIClient sharedClient] enqueueHTTPRequestOperation:operation];
};