accessing the video inside .tmp - ios

this code works and saves the downloaded file to camera roll if the file is an image but it doesn't save it when it's a video file .
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
NSData * data = [NSData dataWithContentsOfURL:location];
UIImage * image = [UIImage imageWithData:data];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
UISaveVideoAtPathToSavedPhotosAlbum(location.path, self, #selector(video:didFinishSavingWithError: contextInfo:), nil);
dispatch_async(dispatch_get_main_queue(), ^{
[self.ProgressView setHidden:NO];
});
}
when I get the path of downloaded file it is a temp file like this:
/private/var/mobile/Containers/Data/Application/DE97D98D-760F-48DC-AFBB-C61C5E3185A0/tmp/CFNetworkDownload_5DOCCe.tmp
and I think since UISaveVideoAtPathToSavedPhotosAlbum wants target video's path to save the reason it doesn't work is that it cannot access the video file inside .tmp
please help! it's been quite a while I'm struggling with this.

try to use the ALAssestsLibrary
#property (strong, nonatomic) ALAssetsLibrary *library;
NSURL *videoURL = [NSURL URLWithString:videoURLString];
dispatch_async(dispatch_get_main_queue(), ^{
NSURLRequest *request = [NSURLRequest requestWithURL:videoURL];
AFURLConnectionOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:videoName];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
NSLog(#"downloadComplete! is %f", (float)totalBytesRead / totalBytesExpectedToRead);
}];
[operation setCompletionBlock:^{
NSLog(#"downloadComplete!");
[self.library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:filePath] completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(#"%#", error.description);
}
else {
NSLog(#"Done :)");
NSString *fileDownloadStatus = [NSString stringWithFormat:#"Downloading of %# Finished", videoName];
[SVProgressHUD showImage:[UIImage imageNamed:#"Mp4_Icon"] status:fileDownloadStatus];
}
}];
}];
[operation start];
});

I found my solution:
NSData * data = [NSData dataWithContentsOfURL:location];
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] error:nil];
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0];
NSString * FilePath = [documentsDirectory stringByAppendingPathComponent:jsonTitle];
[data writeToFile:FilePath atomically:YES];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(FilePath)) {
UISaveVideoAtPathToSavedPhotosAlbum(FilePath, nil, nil, nil);
} else {
NSLog(#"error");
}
NSFileManager * removeDownloadAfterSave;
[removeDownloadAfterSave removeItemAtPath:FilePath error:nil];

Related

How to save the live/animated wallpaper

I am making an app of live photo/wallpaper. I am downloading image and .mov file from server. Now I am stuck to saving these files in document directory. How can I store the live wallpaper in document directory. Is anyone have idea about this please tell me. Here is my code
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
[downloader downloadImageWithURL:[NSURL URLWithString:imgFile]
options:0
progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
if (image && finished) {
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [searchPaths objectAtIndex:0];
NSString* photoPath = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.JPG",strImg]];
[data writeToFile:photoPath atomically:YES];
}
}];
NSURL *URL = [NSURL URLWithString:str];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * downloadProgress){
NSLog(#"%f",downloadProgress.fractionCompleted);
NSString * str = [NSString stringWithFormat:#"%.2f",downloadProgress.fractionCompleted];
NSDictionary * infoDict = #{#"Download": str,
#"id":uniqId};
[[NSNotificationCenter defaultCenter]
postNotificationName:#"DownloadNotification"
object:self userInfo:infoDict];
}destination:^ NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [searchPaths objectAtIndex:0];
NSString* videoPath = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.MOV",strImg]];
NSURL *videoUrl =[NSURL URLWithString:videoPath];
NSLog(#"%#",[videoUrl URLByAppendingPathComponent:videoPath]);
return videoUrl;
} completionHandler:^(NSURLResponse* response, NSURL *filePath, NSError *error) {
if(error)
{
NSLog(#"File Not Dowloaded %#",error);
[self downloadFile];
}
else {
NSLog(#"%#",filePath);
[self.downloadRecord removeObjectAtIndex:0];
if (self.downloadRecord.count > 0) {
[self downloadFile];
}
}
}];
There's no official way to set the wallpaper programatically (or add an image/video to the list of wallpapers) from the inside an app. The closest you can achieve would be saving it to the camera role and then letting the user setting it as a wallpaper from there.
However, I believe Apple have used a private API to achieve this in some of their advertisements, however this isn't documented and using it would cause your app to be rejected from the app store approval.

I'm unable to save or download video in document directory and play from document directory

I want to download or save youtube video in document directory and then play that video using MPMoviePlayerViewController. But I don't know why my code is not working.
I'm using this below code :
prgrma mark- download Or save
-(IBAction)onclick_download:(id)sender
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(#"Downloading Started");
NSString *urlToDownload = #"youtubeurl";
NSURL *url = [NSURL URLWithString:urlToDownload];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"thefile.mp4"];
//saving is done on main thread
dispatch_async(dispatch_get_main_queue(), ^{
[urlData writeToFile:filePath atomically:YES];
NSLog(#"File Saved !");
});
}
});
}
pragma mark- Play video from document directory
-(IBAction)onclick_playvideolocally:(id)sender
{
[self playvideolocally];
}
-(void)playvideolocally
{
NSURL *videoUrl;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
NSLog(#"files array %#", filePathsArray);
NSString *fullpath;
for ( NSString *apath in filePathsArray )
{
fullpath = [documentsDirectory stringByAppendingPathComponent:apath];
videoUrl =[NSURL fileURLWithPath:fullpath];
}
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:videoUrl];
[self presentMoviePlayerViewControllerAnimated:videoPlayerView];
[videoPlayerView.moviePlayer play];
}
As your link you provided in url is for youtube so it is not downloaded or saved in local
Use this for youtube
Ive used classes from this project: https://github.com/larcus94/LBYouTubeView It works fine for me. I can download youtube videos.
LBYouTubeExtractor *extractor = [[[LBYouTubeExtractor alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:(#"http://www.youtube.com/watch?v=%#"), self.videoID ]] quality:LBYouTubeVideoQualityLarge] autorelease];
[extractor extractVideoURLWithCompletionBlock:^(NSURL *videoURL, NSError *error) {
if(!error) {
NSLog(#"Did extract video URL using completion block: %#", videoURL);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL: videoURL];
NSString *pathToDocs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = [NSString stringWithFormat:(#"video_%#.mp4"), self.videoID ];
[data writeToFile:[pathTODocs stringByAppendingPathComponent:filename] atomically:YES];
NSLog(#"File %# successfully saved", filename);
});
} else {
NSLog(#"Failed extracting video URL using block due to error:%#", error);
}
}];

How can download audio? objective-c

I have audio player. I download audio in this way
- (void) song{
if (_index == 0) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"1.mp3"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO];
if (!fileExists) {
NSString *stringURL = #"https://drive.google.com/uc?export=download&id=0B6zMam2kAK39VHZ1cUZsM3BhQXM";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
[urlData writeToFile:filePath atomically:YES];
}
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:filePath] error:nil];
}
}
But when audio downloading I can’t do anything. User interface stop.
How can download audio and do anything in user interface simultaneously?
Give your method a block to execute when finished, then run the download code in the background. Lets say, for your case the output is a local file with the downloaded content:
- (void)songWithCompletion:(void (^)(NSString *))completion {
NSString *filePath = [self song];
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(filePath);
});
}
Change the song method to return filePath. Don't ever call it directly, only via songWithCompletion.
- (void)song {
// ... your code from the OP
// don't allocate the audio player here, just return the local file
return filePath;
}
Call it like this...
[self songWithCompletion:^(NSString *filePath) {
if (filePath) {
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:filePath] error:nil];
// you should really handle audio player error here, too
} else {
// handle error
}
}];
You are downloading the file in the main thread. you need to make an asynchronous call in order to avoid stopping UI.
-(void)downloadAudio
{
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"https://drive.google.com/uc?export=download&id=0B6zMam2kAK39VHZ1cUZsM3BhQXM"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
receivedData = [NSMutableData data] ;
} else {NSLog(#"no connection!");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSLog(#"Succeed! Received %d bytes of data",[receivedData length]);
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//NSLog(#"%#", [documentPaths objectAtIndex:0]);
NSString *documentDirectoryPath = [documentPaths objectAtIndex:0];
NSString *folderPath = [documentDirectoryPath stringByAppendingPathComponent:#"audioFile.mp3"];
[receivedData writeToFile:folderPath atomically:YES];
NSURL *soundURL = [NSURL fileURLWithPath:folderPath];
NSError *error;
if ([[NSFileManager defaultManager] fileExistsAtPath:folderPath]) {
player = [[AVAudioPlayer alloc]initWithContentsOfURL:soundURL error:&error];
player.volume=0.5;
NSError *error = nil;
if (!error) {
[player play];
NSLog(#"File is playing!");
}
else{
NSLog(#"Error in creating audio player:%#",[error description]);
}
}
else{
NSLog(#"File doesn't exist");
}
}

Download and replace file in directory

I am trying download a file from an URL, but the problem is when ever I open the downloaded file it opens the last file which I downloaded before! I mean if I download image1.png and open it , then try to download and replace image2.png,when I am going to open the last downloaded file, the file still image1.png !
Here is my code :
- (void)downloadDataFromMac {
[MBProgressHUD showHUDAddedTo:self.view animated:nil];
NSString *replace = [absulutePath stringByReplacingOccurrencesOfString:#" " withString:#"%20" options:NSLiteralSearch range:NSMakeRange(0, [absulutePath length])];
pathWithData = [NSString stringWithFormat:#"http://192.168.1.36:8888/?req=getimg&key=%#",replace];
NSURL *URL = [NSURL URLWithString:pathWithData];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSProgress *progress;
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *documentsDirectoryURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]objectAtIndex:0];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(#"File downloaded to: %#", filePath);
//Hide HUD
[MBProgressHUD hideHUDForView:self.view animated:YES];
self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:filePath];
[self.documentInteractionController setDelegate:self];
[self.documentInteractionController presentPreviewAnimated:YES];
}];
[downloadTask resume];
}
any help ?,thanks.
Try this:
//Saving images
-(BOOL) saveImage:(UIImage *) image filePath:(NSString *) filePath
{
// Creating path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *fileFullPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:filePath];
// Saving image.
BOOL success = [UIImageJPEGRepresentation(image, 1.0) writeToFile:fileFullPath atomically:YES];
if (!success) {
NSLog(LogPropertyError, #"Couldn't save image to disk %#",fileFullPath);
}
return success;
}

UIProgressview not changing while downloading files

I am making an app where I must download some files from a webserver and save it locally. I have the following JSON:
{
status: 200,
message: "OK",
files: [
"magazines/dentalasia/DentalAsia1/images/toc-thumb-dummy.jpg",
"magazines/dentalasia/DentalAsia1/images/bg-grid-iphone.png",
"magazines/dentalasia/DentalAsia1/images/cover/toc-thumb.jpg",
"magazines/dentalasia/DentalAsia1/images/cover/cover-typo.png",
...
]
}
What I do is I save this string values into an NSArray and then I'm going to download each one of them.
-(IBAction)downloadMagazine:(id)sender{
// 1
progressView.hidden = NO;
NSArray *splitArray = [mag.mag_folder componentsSeparatedByString:#"/"];
NSString *magName = [splitArray lastObject];
NSString *string = [NSString stringWithFormat:#"%#/webservice/magazine/get-book/apikey/%#/magazine/%#/name/%#",baseUrl,apikey,magazine,magName];
NSLog(#"STRING IS %#",string);
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//Create general directory
NSDictionary *JSON = [responseObject copy];
NSArray *files = [JSON valueForKey:#"files"];
reversedFiles = [[files reverseObjectEnumerator] allObjects];
amountFiles = reversedFiles.count;
NSArray *splitArray = [mag.mag_folder componentsSeparatedByString:#"/"];
NSString *magName = [splitArray lastObject];
NSString *rootString = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:magName];
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:rootString])
[[NSFileManager defaultManager] createDirectoryAtPath:rootString withIntermediateDirectories:NO attributes:nil error:&error];
rootString = [rootString stringByAppendingPathComponent:#"/www"];
if (![[NSFileManager defaultManager] fileExistsAtPath:rootString])
[[NSFileManager defaultManager] createDirectoryAtPath:rootString withIntermediateDirectories:NO attributes:nil error:&error];
for(int i = 0 ; i<reversedFiles.count ; i++){
NSString *file = [reversedFiles objectAtIndex:i];
NSString *strUrl = [NSString stringWithFormat:#"%#/%#",baseUrl,file];
NSArray *splitUrl = [file componentsSeparatedByString:#"/"];
NSString *lastObject = [splitUrl lastObject];
if ([lastObject rangeOfString:#"."].location == NSNotFound) {
rootString = nil;
rootString = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:magName];
rootString = [rootString stringByAppendingPathComponent:#"/www"];
for (int i=0; i<splitUrl.count; i++) {
if(i>2){
NSString *pathComponent = [NSString stringWithFormat:#"/%#",[splitUrl objectAtIndex:i]];
rootString = [rootString stringByAppendingPathComponent:pathComponent];
}
}
if (![[NSFileManager defaultManager] fileExistsAtPath:rootString])
[self calculatePie:i];
[[NSFileManager defaultManager] createDirectoryAtPath:rootString withIntermediateDirectories:NO attributes:nil error:&error];
}else{
NSURL *url = [NSURL URLWithString:strUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
if(data)
{
rootString = nil;
rootString = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:magName];
rootString = [rootString stringByAppendingPathComponent:#"/www"];
for (int i=0; i<splitUrl.count; i++) {
if(i>2){
NSString *pathComponent = [NSString stringWithFormat:#"/%#",[splitUrl objectAtIndex:i]];
rootString = [rootString stringByAppendingPathComponent:pathComponent];
}
}
[data writeToFile:rootString atomically:YES];
[self calculatePie:i];
}
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// 4
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving magazine"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
// 5
[operation start];
}
-(void)calculatePie:(int)i{
float progress = (100.0 / amountFiles) * i;
float progress2 = progress / 100.0;
NSLog(#"Progress is %f",progress2);
[progressView setProgress:progress2 animated:YES];
}
And this is how a part of my LOG looks like:
2014-04-24 08:56:18.507 DentalAsia[47301:60b] Progress is 0.340136
2014-04-24 08:56:18.764 DentalAsia[47301:60b] Progress is 0.343537
2014-04-24 08:56:19.041 DentalAsia[47301:60b] Progress is 0.346939
2014-04-24 08:56:19.210 DentalAsia[47301:60b] Progress is 0.350340
2014-04-24 08:56:19.549 DentalAsia[47301:60b] Progress is 0.353741
2014-04-24 08:56:19.714 DentalAsia[47301:60b] Progress is 0.357143
But for some reason my UIProgressview is not moving!
Can someone help me with this ?
Thanks !
Make sure you update the progress view on the main thread:
-(void)calculatePie:(int)i{
float progress = (100.0 / amountFiles) * i;
float progress2 = progress / 100.0;
NSLog(#"Progress is %f",progress2);
dispatch_async(dispatch_get_main_queue(), ^{
[progressView setProgress:progress2 animated:YES];
});
}

Resources