here am creating the download task
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:[NSURL URLWithString:#"http://app.msf.gov.sg/Portals/0/Summary/assistance/CSSD/ComCare%20#%20a%20Glance%20-%20English%20(final).pdf"]];
[downloadTask resume];
// Do any additional setup after loading the view from its nib.
}
and here am dowloading the pdf file successfully
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
NSData *data = [NSData dataWithContentsOfURL:location];
dispatch_async(dispatch_get_main_queue(), ^{
[self.progressView setHidden:YES];
});
}
Now my question is that how can i store that pdf file and retrieve again
please help me
Thanks in advance..
Just move file from 'location' to your document directory:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *docFolder = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
NSURL *fileURL = [docFolder URLByAppendingPathComponent:#"file.pdf" isDirectory:NO];
[fileManager moveItemAtURL: location toURL:fileURL error:nil];
NSLog(#" pdf file is here %#", fileURL);
We have to copy the location to our documents directory
NSError *error;
NSString *fileName = downloadTask.originalRequest.URL.lastPathComponent;
NSArray *docDir = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *loc = [docDir objectAtIndex:0];
NSString *filePathName = [loc stringByAppendingString:fileName];
NSFileManager *fileMgr = [NSFileManager defaultManager];
if ([fileMgr fileExistsAtPath:filePathName]) {
[fileMgr removeItemAtPath:filePathName error:&error];
}
BOOL success = [fileMgr copyItemAtPath:[location path] toPath:filePathName error:&error];
if (success) {
NSLog(#"FIle is successfully copied to documents directory");
}else{
NSLog(#"error:%#",error.description);
}
Related
I have a problem while trying to session.dataTaskWithRequest in a function to read gzip from URL.
The server side changes .gzip to .bin and stores the file.
I want to read the file with .bin. However, The network connection was lost.
However, a The network connection was lost error will occur.
Could you tell me how to solve this problem?
Server side file name: xxx.bin (this bin file is a gzip file.)
Following the code:
NSURLSessionConfiguration *config = [NSURLSessionConfiguration
defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURL *url = [NSURL URLWithString:#"http://...../xxx.bin"];
NSURLSessionDataTask *task = [session dataTaskWithURL: url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"error [%#]", [error localizedDescription]);
}
else {
NSLog(#"success");
}
}];
[task resume];
You can try two steps of codes to download and extract zip files.
//Fetching zip file from server
-(void)dataSyncFileDonload{
NSString *stringURL = [NSString stringWithFormat:#"http://yourzipfilecontainedURL"];
stringURL = [stringURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
[self extractDownloadedZipFile:urlData];
}
//File Extraction from Zip file
-(void)extractDownloadedZipFile:(NSData *)data {
//If you are using SQlite and storing in local directory for extraction
NSData *outputData = [data gunzippedData];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *dataPath = [path stringByAppendingPathComponent:#"myAppDB.sql"];
NSString *dataPath1 = [path stringByAppendingPathComponent:#"myAppDB.sql.gz"];
dataPath = [dataPath stringByStandardizingPath];
[outputData writeToFile:dataPath atomically:YES];
[data writeToFile:dataPath1 atomically:YES];
[self readExtractedFile:dataPath];
}
//Read upzip file
-(void)readExtractedFile:(NSString *)filepath loaderPercent:(float)loaderPercent loaderTo:(float)loaderTo{
NSData *fileData = [NSData dataWithContentsOfFile:filepath];//destinationPath
NSString *fileString = [[NSString alloc] initWithData:fileData encoding:NSASCIIStringEncoding];
NSArray* allLinedStrings = [fileString componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]];
//You can use you data now.
}
I use SSZipArchive. After downloading file I want to unzip archive and show image. But code doesn’t work. How to fix it?
download file
-(IBAction) downloadButton:(id)sender
{
if (_HighScore == 2) {
_url1 =[NSURL URLWithString:#"link2.zip"];
_downloadTask1 = [_session downloadTaskWithURL:_url1];
[_downloadTask1 resume];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
if (downloadTask == _downloadTask1) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSURL *documentsFolder = [paths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *newLocation = [NSURL URLWithString:[NSString stringWithFormat:#"file://%#/2.zip", documentsFolder]];
NSError *error;
[fileManager copyItemAtURL:location toURL:newLocation error:&error];
NSLog(#"file%#", newLocation.absoluteString);
}
unzip file
_documentsDirectory1 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
_zipPath1 = [_documentsDirectory1 stringByAppendingPathComponent:#"2.zip"];
_destinationPath1 = [_documentsDirectory1 stringByAppendingPathComponent:#"file://%#/2.zip"];
_fileExists1 = [[NSFileManager defaultManager] fileExistsAtPath:_zipPath1 isDirectory:false];
if( [SSZipArchive unzipFileAtPath:_zipPath1 toDestination:_destinationPath1] != NO ) {
NSLog(#"Dilip Success");
}else{
NSLog(#"Dilip Error");
}
UPD
-(IBAction) downloadButton:(id)sender
{
if (_HighScore == 2) {
_url1 =[NSURL URLWithString:#"link2.zip"];
_downloadTask1 = [_session downloadTaskWithURL:_url1];
[_downloadTask1 resume];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
if (downloadTask == _downloadTask1) {
_documentsDirectory1 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
_zipPath1 = [_documentsDirectory1 stringByAppendingPathComponent:#"2.zip"];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (downloadTask == _downloadTask1) { NSData *urlData1 = [NSData dataWithContentsOfURL:_url1]; [urlData1 writeToFile:_zipPath1 atomically:YES];}
});
}
The problem is in saving zip file in DocumentDirectory, _filePath1 is contain the destination folder for unzip, instead of that you need to use filePath that contain zip file name along with path, so use that like this.
[urlData1 writeToFile:filePath atomically:YES];
Also it is batter if you use writeToFile:options:error: method so that you can know it is successfully writing Data or not.
NSError *error = nil;
[self.responseData writeToFile:zipPath options:0 error:&error];
Edit:
You are probably messing with something, so change your code from downloading to saving and unzipping like this.
-(IBAction) downloadButton:(id)sender
{
if (_HighScore == 2) {
_url1 =[NSURL URLWithString:#"link2.zip"];
_downloadTask1 = [session dataTaskWithURL:[NSURL URLWithString:#""] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//Saved in NSDocumentDirectory
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *zipPath = [path stringByAppendingPathComponent:#"2.zip"];
[self.responseData writeToFile:zipPath options:0 error:&error];
//UNZip
NSString *zipPath1 = [path stringByAppendingPathComponent:#"2.zip"];
NSString *destinationPath = [NSString stringWithFormat:#"%#",path];
[SSZipArchive unzipFileAtPath:zipPath1 toDestination:destinationPath];
//Now access the content of zip
}];
[_downloadTask1 resume];
}
}
try like this , its work for me
[SSZipArchive unzipFileAtPath:filePath toDestination:outputPath delegate:self];
after completion of unarchive the following method will call
#pragma mark - Unzipp Delegate
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo: (unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath {
//write code here after unarchive zip file
}
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");
}
}
I am taking the image as NSData and saving it to Documents Folder.
The problem is, when i try to save it Documents Folder, it saves 2 out of 4, or 3 out of 4. It saves randomly.
I could not figure out where the problem is, since after first failure of saving, the second try may be successful for a particular image.
Could you please help me?
NSData * response = [appDel.serviceHelper serviceCall:#"" withURL:[NSString stringWithFormat:#"%#/Application/GetImage/%#",appDel.appPage.editorServiceURL,ID]];
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/Images"];
if(response !=nil)
{
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
{
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
}
UIImage *image = [[UIImage alloc] initWithData:response];
NSString *pngFilePath = [NSString stringWithFormat:#"%#/%#",dataPath,[NSString stringWithFormat:#"%#",fileName]];
NSData *data1;
if([pngFilePath rangeOfString:#".png"].location !=NSNotFound)
{
data1 = [NSData dataWithData:UIImagePNGRepresentation(image)];
NSLog(#"png Image");
}
else if([pngFilePath rangeOfString:#".jpg"].location !=NSNotFound)
{
data1 = [NSData dataWithData:UIImageJPEGRepresentation(image,1.0)];
NSLog(#"jpg Image");
}
else
{
NSLog(#"another extension Image");
}
[data1 writeToFile:pngFilePath atomically:YES];
//[appDel.fileHelper writeToFile:response withFileName:fileName];
}
try taking the response as NSMutableDictionary instead of NSData. That might show you what the exception is.
#define DocumentsPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
NSURLSession *defaultNSURLSession ;
CallMethod:
[self downloadImage_WithImageName:#"HERE YOUR FILENAME" FromFileURL:#"HERE IMAGE URL"];
-(void) downloadImage_WithImageName:(NSString *)imageName FromFileURL:(NSString *)fileURL{
NSString *dataPath = [DocumentsPath stringByAppendingPathComponent:#"/Images"];
NSString *filePath=[[NSString alloc] initWithFormat:#"%#/Images/%#",DocumentsPath,imageName];
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
//NSLog(#"Downloading %# to %#...", fileURL, filePath);
NSURLRequest *request=[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:fileURL]];
NSURLSessionDownloadTask *downTask = [defaultNSURLSession downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
if (!error) {
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder
NSError *err = nil;
if ([[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:&err]) {
//Reload your UITableview or UICollectionView
}else{
NSLog(#"move error %#", error);
}
}else{
NSLog(#"error %#",error);
}
}];
[downTask resume];
} else {
NSLog(#"%# already exists. not downloading.", imageName);
}
}
I use this method inside an NSOperation for check and create a folder:
- (void) checkAndCreateFolderWithPath:(NSString *)path {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *pathDaControllare = [[self getLibraryPath] stringByAppendingPathComponent:path];
NSError *error = nil;
BOOL isDir;
BOOL exists = [fileManager fileExistsAtPath:pathDaControllare isDirectory:&isDir];
if (exists) {
if (isDir) {
}
}
else {
[fileManager createDirectoryAtPath:pathDaControllare
withIntermediateDirectories:YES
attributes:nil
error:&error];
NSLog(#"%#",error);
}
}
Using NSOperation I get this error:
Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed.
if I don't use NSOperation all work perfectly, this is the nsoperation
- (void) main {
NSString *filePath = [fileDict objectForKey:#"url"];
NSString *urlStr = [NSString stringWithFormat:#"http://www.allmyapp.net/wp-content/iFormulario_Update/%#",filePath];
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
if (data) {
NSString *folderPath = [filePath stringByReplacingOccurrencesOfString:[filePath lastPathComponent] withString:#""];
[self checkAndCreateFolderWithPath:folderPath];
NSString *pathFile = [[self getLibraryPath] stringByAppendingString:filePath];
[data writeToFile:pathFile atomically:YES];
[self addSkipBackupAttributeToItemAtURL:[NSURL URLWithString:pathFile]];
[[NSNotificationCenter defaultCenter] postNotificationName:#"endFile" object:nil];
[self willChangeValueForKey:#"isFinished"];
[self willChangeValueForKey:#"isExecuting"];
isExecuting = NO;
isFinished = YES;
[self didChangeValueForKey:#"isExecuting"];
[self didChangeValueForKey:#"isFinished"];
}
}];
}
And this the method for create the queue:
for (NSDictionary *dict in fileDaScaricare) {
DownloadOperation *downloadOperation = [[DownloadOperation alloc] initWithDictionary:dict];
[self.operationQueue addOperation:downloadOperation];
}
You can try something like this:
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:#"/MyFolder"];
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath])
[[NSFileManager defaultManager] createDirectoryAtPath:stringPath withIntermediateDirectories:NO attributes:nil error:&error];
NSString *docFolderPath = [stringPath stringByAppendingString:[NSString stringWithFormat: #"/%#", self.downloadedFilename]];
[data writeToFile:docFolderPath atomically:YES];
It worked for me, and I am able to download a file in MyFolder. Hope it works for you. Please let me know if it works.