Reputation: 382
I have to upload a video from gallery and send it to server multipart.
When I select the movie from gallery a have those information :
self.videoDictionary = {
UIImagePickerControllerMediaType = "public.movie";
UIImagePickerControllerMediaURL = "file:///Users/alin/Library/Application%20Support/iPhone%20Simulator/7.0.3/Applications/714D0B71-80EA-4B6C-9ACF-A287C8F40121/tmp/trim.FF287468-B25E-4EEA-8EAB-A485842476FA.MOV";
UIImagePickerControllerReferenceURL = "assets-library://asset/asset.MOV?id=393E740F-B7F4-46DA-BB09-69AB92C34660&ext=MOV";
}
My WS signature look like this :
Params :
video
I have a problem when I tried to upload the video :
-(void)addVideoRequestToWS
{
BusinessLogic *bl = [BusinessLogic sharedManager];
ApiClientBlitzApp *client = [ApiClientBlitzApp sharedClient];
NSString *videoURL = [self.videoDictionary objectForKey:@"UIImagePickerControllerReferenceURL"];
NSData *videoData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath: videoURL]]; // I suppose my problem are from two lines of code
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:@"POST" path:getAddVideo parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFormData:[[NSString stringWithFormat:@"%@",bl.currentUser.hash] dataUsingEncoding:NSUTF8StringEncoding] name:@"hash"];
[formData appendPartWithFormData:[[NSString stringWithFormat:@"%@",self.textFieldTitle.text] dataUsingEncoding:NSUTF8StringEncoding] name:@"title"];
[formData appendPartWithFormData:[[NSString stringWithFormat:@"%@",self.textFieldDescription.text]] dataUsingEncoding:NSUTF8StringEncoding] name:@"description"];
[formData appendPartWithFileData:videoData name:@"video_file" fileName:@"testvideo.mov" mimeType:@"video/quicktime"];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
NSLog(@"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
}];
[client enqueueHTTPRequestOperation:operation];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSData *JSONData = [operation.responseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableContainers error:nil];
NSLog(@"jsonObject of the list = %@", jsonObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error: %@", operation.responseString);
NSLog(@"%@",error);
}];
[operation start];
}
Upvotes: 0
Views: 3808
Reputation: 3508
SWIFT version: Uploading video using AFNetworking. It also tracks progress.
func createVideoPost(completion:(success: Bool) -> Void) {
progressView = NSBundle.mainBundle().loadNibNamed("UploadProgressView", owner: nil, options: nil).first! as? UploadProgressView
progressView?.frame = CGRectMake(0,
0,
self.parentController!.view.frame.size.width,
self.parentController!.view.frame.size.height)
self.parentController!.view.addSubview(progressView!)
self.parentController!.navigationItem.hidesBackButton = true
progressView?.cancelBtn.addTarget(self, action: "cancelUploading:", forControlEvents: .TouchUpInside)
// Add video url to the param if its already on server
if self.videoPath!.hasPrefix("http:") || self.videoPath!.hasPrefix("https:") {
parameter?.setObject(self.videoPath!, forKey: "video_file")
}
let requestSerializer = AFHTTPRequestSerializer()
var request: NSMutableURLRequest?
var error: NSError?
do {
request = try requestSerializer.multipartFormRequestWithMethod("POST", URLString: WebConstants.BaseURL, parameters: parameter! as [NSObject : AnyObject], constructingBodyWithBlock: { (formData: AFMultipartFormData!) -> Void in
//var videoData: NSData?
if self.videoPath!.hasPrefix("http:") || self.videoPath!.hasPrefix("https:") {
//videoData = NSData(contentsOfURL: NSURL(string: self.videoPath!)!)
//formData.appendPartWithFileData(videoData!, name: "files[]", fileName: "movie.mp4", mimeType: "video/mp4")
} else {
//videoData = NSData(contentsOfURL: NSURL(fileURLWithPath: self.videoPath!))
do {
try formData.appendPartWithFileURL(NSURL(fileURLWithPath: self.videoPath!), name: "files[]", fileName: "movie.mp4", mimeType: "video/mp4")
} catch {
print("Error in uploading")
}
}
})
} catch {
//...
}
let manager: AFURLSessionManager = AFURLSessionManager(sessionConfiguration: NSURLSessionConfiguration.defaultSessionConfiguration())
manager.responseSerializer = AFJSONResponseSerializer(readingOptions: NSJSONReadingOptions.AllowFragments)
var progress: NSProgress?
uploadTask = manager.uploadTaskWithStreamedRequest(request,
progress: &progress, completionHandler: { (response: NSURLResponse?, responseObject: AnyObject?, error: NSError?) -> Void in
if (error != nil) {
//print(error?.description)
self.parentController!.navigationItem.hidesBackButton = false
self.progressView?.removeFromSuperview()
completion(success: false)
} else {
// remove the video from my directory as its uploading is completed successfully
do {
try NSFileManager.defaultManager().removeItemAtURL(NSURL(fileURLWithPath: self.videoPath!))
print("memory cleaned, temp videos deleted")
} catch {
print("memory not cleared for temp videos")
}
Utility.clearAllTempFiles()
self.parentController!.navigationItem.hidesBackButton = false
self.progressView?.removeFromSuperview()
NSNotificationCenter.defaultCenter().postNotificationName(Constants.LaunchDidCreatedNotificationKey, object: nil)
completion(success: true)
}
})
uploadTask!.resume()
progress?.addObserver(self, forKeyPath: "fractionCompleted", options: NSKeyValueObservingOptions.Initial, context: nil)
}
func cancelUploading(sender: UIButton) {
uploadTask!.cancel()
progressView?.removeFromSuperview()
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
let progress: NSProgress = object as! NSProgress
dispatch_async(dispatch_get_main_queue(), {
//print(progress.fractionCompleted)
self.progressView!.progressBar!.setProgress(Float(progress.fractionCompleted), animated: true)
})
}
Upvotes: 0
Reputation: 66242
You have a few problems, and haven't mentioned which you're encountering.
First, this line:
[client enqueueHTTPRequestOperation:operation];
may immediately start the operation, which you should never do before you set your completion blocks.
Second, this line:
[operation start];
immediately starts the operation (if the NSOperationQueue you already added it to hasn't started already). You should only do one or the other of these, not both, and whichever you should do should be done after you configure your operation.
Finally, for your multi-part upload:
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:@"POST" path:getAddVideo parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFormData:[[NSString stringWithFormat:@"%@",bl.currentUser.hash] dataUsingEncoding:NSUTF8StringEncoding] name:@"hash"];
[formData appendPartWithFormData:[[NSString stringWithFormat:@"%@",self.textFieldTitle.text] dataUsingEncoding:NSUTF8StringEncoding] name:@"title"];
[formData appendPartWithFormData:[[NSString stringWithFormat:@"%@",self.textFieldDescription.text]] dataUsingEncoding:NSUTF8StringEncoding] name:@"description"];
[formData appendPartWithFileData:videoData name:@"video_file" fileName:@"testvideo.mov" mimeType:@"video/quicktime"];
}];
Unless your server is doing some crazy stuff, this might be wrong. First of all, you don't need to use the string formatter to pass in a string like self.textFieldTitle.text
. Second of all, what is hash
? Typically a hash is an NSUInteger
, which won't work with the string formatter this way. No matter what, it's impossible to say for sure because you haven't provided enough detail about what is happening and what you want to happen.
You should set up an HTTP proxy like Charles in order to inspect the traffic your app is actually transmitting. Or, at least, you should install AFHTTPRequestOperationLogger, which will log most stuff to your Xcode console. Compare what you're sending to what your server is expecting. Set breakpoints inside the success and failure blocks and inspect the error when you see it. And if you get stuck again, post the output of your console on Stack Overflow so we can help you better - include details about what you expect and how it differs from what's actually happening.
Upvotes: 1