Using AFnetworking to save mp4 - objective-c

I've been using AFnetworking to download a video from a remote server. It works great except for the fact it downloads the file as data rather than the original format (in this case mp4).
Is there a way to set AFnetworking to download the file as an mp4? when it comes to playback it seems like a waste of time and resources to convert the data file back into mp4 each time the video is played.
My current code for gaining the file is below:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[URL url]]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[URL title]];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
URL.videolocal = #"YES";
[self saveToCoreData]; // video is not saved in core data, only a reference
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];

If the data coming from the server is already in MP4 format, then just name the file with a .mp4 suffix.

Related

Objective-C Trying to download PDF that is from a short url

I have been trying to get this to work without having it load on the web view first and getting the absoluteString from that so I can download the URL. I have tried many shortURL solutions and they never fully load the URL. They always give me the URL that is not the final url and does not that the PDF url. Any help would be amazing. I am trying to download the PDF when the app first opens or when it checks for updates, but at the time it just gets the short url and I have to wait till the web view is called to get the full url to be able to download the PDF a head of time.
You download the PDF, just like you would download any other file.
Take a look at NSURLDownload
- (void)startDownloadingURL:sender
{
// Create the request.
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.apple.com/index.html"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// Create the download with the request and start loading the data.
NSURLDownload *theDownload = [[NSURLDownload alloc] initWithRequest:theRequest delegate:self];
if (!theDownload) {
// Inform the user that the download failed.
}
}
- (void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename
{
NSString *destinationFilename;
NSString *homeDirectory = NSHomeDirectory();
destinationFilename = [[homeDirectory stringByAppendingPathComponent:#"Desktop"]
stringByAppendingPathComponent:filename];
[download setDestination:destinationFilename allowOverwrite:NO];
}
- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error
{
// Dispose of any references to the download object
// that your app might keep.
...
// Inform the user.
NSLog(#"Download failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)downloadDidFinish:(NSURLDownload *)download
{
// Dispose of any references to the download object
// that your app might keep.
...
// Do something with the data.
NSLog(#"%#",#"downloadDidFinish");
}
Please check AppleDocs about handling redirect request.
try using afnetworking to download pdf file in to the server
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://letuscsolutions.files.wordpress.com/2015/07/five-point-someone-chetan-bhagat_ebook.pdf"]];
[request setTimeoutInterval:120];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSString *pdfName = #"2.zip";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:pdfName];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
};
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Download = %f", (float)totalBytesRead / totalBytesExpectedToRead);
NSLog(#"total bytesread%f",(float)totalBytesRead );
NSLog(#"total bytesexpected%lld",totalBytesExpectedToRead );
});
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
This is a method to open a pdf file from an URL with the UIDocumentInteractionController:
- (void)openURL:(NSURL*)fileURL{
//Request the data from the URL
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:fileURL completionHandler:^(NSData *data, NSURLResponse *response,NSError *error){
if(!error){
//Save the document in a temporary file
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[response suggestedFilename]];
[data writeToFile:filePath atomically:YES];
//Open it with the Document Interaction Controller
_docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
_docController.delegate = self;
_docController.UTI = #"com.adobe.pdf";
[_docController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}
}] resume];
}
And myViewController.h:
#interface myViewController : UIViewController <UIDocumentInteractionControllerDelegate>
#property UIDocumentInteractionController *docController;

Downloading a video file of 1.x MB size takes more than 30 secs with AFNetworking 1.0

I am using below code to download video files from server on my device, but it takes more than 30 secs to download a file of 1.5 MB size. Is there any way to speed up this download process?
Like can we divide the whole video file in chunks and download them in parallel?
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:videoURL]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:videoURL]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSString *outputPath = [[NSString alloc] initWithFormat:#"%#%#", NSTemporaryDirectory(), #"m.mp4"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:outputPath append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", outputPath);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error downloading file");
}];
[httpClient enqueueHTTPRequestOperation:operation];

Using AFNetworking to download a pdf from the web in appdelegate and then trying to load that stored pdf in a UIWebview on another page

I am using AFNetworking to download a pdf (that will change on a weekly basis) and save it into the documents directory with this code:
//Get the PDF
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.somewebsiteaddress/CurrentEdition1.pdf"]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"CurrentEdition1.pdf"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", filePath);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
I then want to read that saved file in another section of the app in a UIWebView (after it has downloaded) and use this code:
//Now create Request for the file that was saved in your documents folder
NSString *resourceDocPath = [[NSString alloc] initWithString:[[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:#"Documents"]];
NSString *filePath = [resourceDocPath stringByAppendingPathComponent:#"CurrentEdition1.pdf"];
NSURL *url = [NSURL fileURLWithPath:filePath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webVieweedition setUserInteractionEnabled:YES];
[webVieweedition setDelegate:self];
[webVieweedition loadRequest:requestObj];
I have used a few single page pdf documents to test with - loading them up on the server and then seeing if they are downloaded and then viewed when changed. Problem is, this seems to only be working about 50% of the time. I'll put a new file up and sometimes the correct one will be shown in the UIWebView and sometimes it will show the previous one and not the new one. I am waiting until I see the download completed message before I try to go to the UIWebView (although I know clients won't do that, but that's a whole other question). Anyway, I'm new to XCode and have just been a web html guy. This has had my head spinning for two days. Using Storyboards, ARC, XCode 4.6.2.
If i understood right, sometimes you see the same pdfs in app, although you changed them on webserver?May be the reason is cache, try construct request this way, ignoring caching
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://www.somewebsiteaddress/CurrentEdition1.pdf"] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];

Downloading File using AFHTTPRequest Operating isn't working?

This is the code I'm using (from this Stack Overflow question, although it's slightly modified):
NSLog(#"Saving File...");
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[detailDataSourceDict valueForKey:#"filepath"]]];
NSLog(#"This is the link you are downloading: %#",request);
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
I get the NSLog "Successfully downloaded file to /Users/xxxx/Library/Application Support/iPhone Simulator/6.0/Applications/F29C1E99-A277-41DC-8205-6556B6123A85/Documents" but when I open up that folder in Finder, I don't see the file. Is there anything that I am doing wrong? I am not getting errors in my code. Any help would be appreciated, thanks.
Update
I am using the AFNetwork library...
You're setting the download location to the actual Documents Directory, rather than a file in the directory. Update your code to use a specific file within the directory.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0]; //filepath to documents directory!
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:[path stringByAppendingPathComponent:#"filename.extension"] append:NO];
Also, I think you may want to be setting the inputStream property rather than the outputStream because you are downloading a file rather that uploading one.

AFnetworking downloading multiple files

I'm using this code to loop through an array to download multiple files and write to disk.
-(void)download
{
//set url paths
for (NSString *filename in syncArray)
{
NSString *urlpath = [NSString stringWithFormat:#"http://foo.bar/photos/%#", filename];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlpath]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:filename];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
but the problem is it calls the success block after each file is done, (which it should) but I just need one final call back to reload some data and end a progress HUD.
Any pointers in the right direction would be great.
Maybe someday this will help someone, but I was able to use a workaround that probably has major issues but its okay for my simple usage.
I just deleted each line from the sync array after it was processed then ran my code i needed.
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
[SVProgressHUD showWithStatus:#"Updating Photos"];
[syncArray removeObject:filename];
if (!syncArray || !syncArray.count)
{
NSLog(#"array empty");
[[NSNotificationCenter defaultCenter] postNotificationName:#"TestNotification" object:self];
[SVProgressHUD dismissWithSuccess:#"Photos Updated"];
}
You can use AFHTTPClient to enqueueBatchOperations and this has a completionBlock which is called when all operations are finished. Should be exactly what you're looking for.