Uploading video to youtube using AFNetworking 2.0 - ios

I'm trying to upload a video to YouTube using v3 API using AFNetworking 2.0. The upload itself is working fine and I am able to see a video at my channel. What I'm having a problem is the parameters (the video resource) to specify the title, description etc which I have to put as my request body (along with the video itself) Here is the code I am using.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"Bearer #_token_goes_here#" forHTTPHeaderField:#"Authorization"];
NSDictionary *parameters = #{#"snippet" : #{#"title" : #"random_title",
#"description" : #"random_description"}};
NSURL *filePath = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"video" ofType:#"mov"]];
[manager POST:#"https://www.googleapis.com/upload/youtube/v3/videos?part=snippet,status" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:filePath name:#"video" fileName:#"video.mov" mimeType:#"video/*" error:NULL];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
How do I properly set the JSON parameters for the request?
Thanks.

Ok, so if anyone is interested, the only solution I found for this is to send the second PUT update request to set the proper title and description.

You have to append the snippet to the multipart form data
NSData *jsonData = [NSJSONSerialization dataWithJSONObject: parameters options:NSJSONWritingPrettyPrinted error:NULL];
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:#"form-data; name=\"%#\"", #"snippet"] forKey:#"Content-Disposition"];
[mutableHeaders setValue:#"application/json" forKey:#"Content-Type"];
[formData appendPartWithHeaders:mutableHeaders body:jsonData];
[formData appendPartWithFileURL:filePath name:#"video" fileName:#"video.mov" mimeType:#"video/*" error:NULL];
One request, and only need the permissions to upload.

Related

How To Send NSData with AFNetworking 3 Without Using AFMultipartFormData

I am trying to send wav file as a NSData to rest service with AFNetworking 3. I figured out how to send with AFMultipartFromData but i got an error like that
errorMessage = "Can Not Map Content-Type String multipart/form-data; boundary=Boundary+02588C5 To Media Type ";
When i spoke with the guy who created rest service then he told me i have to send just NSData not anything like AFMultipartFormData. I need some help here because i could not find any way to send "just" NSData.
My code is below;
NSURL *URL = [NSURL URLWithString:#"http://xxxMyService"];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.HTTPAdditionalHeaders = #{#"xx": #"yy ; zz"};
AFHTTPSessionManager *manager2 = [[AFHTTPSessionManager alloc] initWithBaseURL:URL sessionConfiguration:configuration];
manager2.responseSerializer = [AFJSONResponseSerializer serializer];
//I converted wav file to NSData
NSData *data=[self setVoiceRecordToNSData];
[manager2 POST:#"http://xxxMyService" parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
[formData appendPartWithFileData:data name:#"data" fileName:#"Path.wav" mimeType:#"audio/wav"];
}
progress:nil success:^(NSURLSessionTask *task, id responseObject
{ NSLog(#"JSON: %#", responseObject);}
failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error); }];
Try add this code before POST
manager2.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"multipart/form-data"];

Nested Json with multipart/form-data in AFNetworking 2.x

I am trying to send nested json with an image from my ios app using AFNetworking library.I am able to send the json data and image successfully but in server the json structure is coming differently.
HTTP request inside my app :-
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = #{#"requestData":#{#"username":#"200OK",#"password":#"password"}};
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:Self_URL
parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:UIImagePNGRepresentation(image)
name:#"file"
fileName:#"file"
mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
So in my django server I am expecting the params as a dictionary same as params but request.POST is coming as
content_type---> multipart/form-data; boundary=Boundary+247685AB6DF2B3BA
<QueryDict: {'requestData[password]': [u'password'], 'requestData[username]': [u'200OK']}>
How can I send json data so that it will be easy to access from server ?
Anything I am missing or what is going wrong?
constructingBodyWithBlock is overriding your AFJSONRequestSerializer and your dictionary is encoded as form data. There is no way to have two content types (multipart/form-data and application/json) for a request at the same time, so you'll have to do this another way.
One possibility is to encode the JSON as an NSData object and append it to the multipart form along with the image data:
NSError *error = nil;
NSData *paramData = [NSJSONSerialization dataWithJSONObject:params
options:0
error:&error];
[formData appendPartWithFileData:paramData
name:#"params"
filename:#"params"
mimeType:#"application/json"]
You can access the serialized parameters through request.FILES['params']. Despite the mime-type, I doubt that django will automatically parse the JSON data into a dictionary, but you could do that manually with json.loads.
In AFNetworking3.0, you can introduce JSON in a form using the appendPartWithFormData function
[formData appendPartWithFormData:params name:#"params"];
On the server side, you can access the serialized data using json.loads() on the object. Here is a full snippet from some code I wrote:
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST"
URLString:requestUrl parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFormData:[self dictToJson:params] name:#"params"];
[formData appendPartWithFileData:fileData name:fileGeneralName fileName:fileName mimeType:mimeType];
} error:nil];
[[manager uploadTaskWithStreamedRequest:request progress:nil completionHandler:^(NSURLResponse* response, id responseObject, NSError* error) {
[self callCompletionBlock:responseObject withError:error withResponse:response completionHandler:completionBlock];
}] resume];
There's a serialization function in that snippet, which I'll also paste for completion:
+(NSData*)dictToJson:(NSDictionary*)dict {
NSError* error = nil;
return [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error]; }

AFNetworking form data uploading issue

I want to POST form data using AFNetworking. I am using this piece of code to achieve this:
// Create service request url
NSString *urlString = [NSString stringWithFormat:#"%#%#", kBaseURL, webServiceAPIName];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:#"myUser" forHTTPHeaderField:#"X-User-Agent"];
[manager.requestSerializer setValue:#"multipart/form-data" forHTTPHeaderField:#"Content-Type"];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// Set calling keys
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#"5341" forKey:#"Id"];
[dict setObject:#"f1" forKey:#"refDataId"];
[dict setObject:#"f1" forKey:#"customRefDataId"];
[dict setObject:#"587" forKey:#"cost"];
[manager POST:urlString parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:UIImagePNGRepresentation(files[0]) name:#"ImageName" fileName:#"file1" mimeType:#"image/png"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"upload successful");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error image upload");
}];
After execution of this block after waiting some time it goes in Failure Section. Logging : "Error image upload". without giving any error.
I tried my API in POSTMAN API CLIENT and there it is working fine.I am able to send data and get response back.
And after running this block i am not able to run any other API call I have to stop my app and run again to run any other API call.
What is the issue with this code why I am not able to upload any form data and Why it block my any other API calls
Try below code:
-(void) uploadImage {
NSString *imagePath = [[NSUserDefaults standardUserDefaults] objectForKey:#"userimage"];
NSString * urlString = [stagingURL stringByReplacingOccurrencesOfString:#"user/" withString:#""];
NSString * uploadURL = #"Your URL where image to be uploaded";
NSLog(#"uploadImageURL: %#", uploadURL);
NSData *imageData = UIImageJPEGRepresentation([UIImage imageWithData:[NSData dataWithContentsOfFile:imagePath]], 0.5);
NSString *queryStringss = [NSString stringWithFormat:#"%#",uploadURL];
queryStringss = [queryStringss stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer=[AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/html"];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/plain"];
[manager POST:queryStringss parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"file" fileName:#"file" mimeType:#"image/jpeg"];
}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];}

responseObject is not JSON but NSInLineData for AFHTTPRequestOperationManager

Following code is to submit images through an operationQueue. The requests are all fired one by one correctly, the server response contains the image file name which client needs to get hold of. The problem is that the reponseObject for the success/failure block is not expected parsed JSON but type of NSInLineData shown in debugger. Now I suspect the code to construct the operation from the NSMutableURLRequest caused the issue. Please help.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSMutableURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:#"POST"
URLString:podURLString parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
NSError *error;
BOOL success =[formData appendPartWithFileURL:imgURL name:#"images" fileName:img.path
mimeType:#"image/jpg" error:nil];
if (!success)
NSLog(#"appendPartWithFileURL error: %#", error);} error:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Image Success: %#", [responseObject description]);
NSString *imagePath = [response objectForKey:#"imageFileName"];
[self.delegate networkManager:self didSubmitDeliveryImageForImageID:imagePath];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Image Error: %#", error);
NSLog(#"image error: %#", [operation.responseObject description]);
NSString *imageFilePath = [operation.responseObject objectForKey:#"imageFileName"];
[self.delegate networkManager:self didFailSubmitDeliveryImageForImageID:imageFilePath];
}];
[manager.operationQueue addOperation:operation];
When you get the response as NSInLineData. It's good to go now. You can write below single line of code to get NSDictionary if it supports json format.
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseObjec options:0 error:nil];
Just add this line of code before your AFHTTPRequestOperation block
**operation.responseSerializer = [AFJSONResponseSerializer serializer];**

AFNetworking - Upload video along with other parameters

I want to upload video to web service along with some other parameters. I want to upload userID, videoID and video to web service. While uploading, all the parameters other than video is being sent to web service. I've checked at web service end, and the video is not coming with the request. I am using the following code.
- (void)uploadVideoAtLocalPath:(NSString *)videoPath videoID:(NSString *)videoID userID:(NSString *)userID {
NSString *strServerURL = #"www.mysite.com/user/uploadVideo";
NSURL *URL = [NSURL URLWithString:strServerURL];
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:URL];
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:#"POST" path:#"" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
// userID
NSData *userIDData = [userID dataUsingEncoding:NSUTF8StringEncoding];
[formData appendPartWithFormData:userIDData name:#"userID"];
// videoID
NSData *videoIDData = [videoID dataUsingEncoding:NSUTF8StringEncoding];
[formData appendPartWithFormData:videoIDData name:#"videoID"];
// video
NSData *videoData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoPath]];
[formData appendPartWithFileData:videoData name:#"video" fileName:#"video.mov" mimeType:#"video/quicktime"];
}];
[request setURL:URL];
[request setTimeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[AFHTTPRequestOperation addAcceptableStatusCodes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(100, 500)]];
[operation setCompletionBlockWithSuccess: ^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response String: %#", operation.responseString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", error);
}];
[client enqueueHTTPRequestOperation:operation];
}
Could anyone let me know whether I am doing it correct? If not, could anyone please tell me how to upload video to web service along with other parameters?
Thanks Everyone!
I'm not well in this method. I had the same issue. But, i have fixed it like mixing of POST & GET methods. I just sent my parameters as GET method like below -
NSString *strServerURL = [NSString stringWithFormat:#"www.mysite.com/user/uploadVideo&userID=%d&videoID=%d", 1, 55];
and, sent my video data in POST method as per your method -
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:#"POST" path:#"" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
// video
NSData *videoData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoPath]];
[formData appendPartWithFileData:videoData name:#"video" fileName:#"video.mov" mimeType:#"video/quicktime"];
}];
You better try to modify your webservice and try like above way. It should works.
Cheers!

Resources