I've started using ZipArchive because I have a testing app that displays images from a server where the content is often changing. I want the app to sort and display the images, without having an explicit list of the new image names. (Or maybe I should also include in the zipped file an XML document that contains the names of the new images.) Either way, I'm now having a problem adding a known image to the zip file on the server and finding it in the app.
The original zipfile.zip file has 2 files: photo.png and text.txt
That works. So I downloaded the zipfile.zip and uploaded it to my server. It still worked, of course.
Then I unzipped it, added a new image to it, and re-zipped it on my server.
The updated zipfile.zip now has 3 files: photo.png, myphoto.png, and text.txt
The image I added, myphoto.png, can't be found. What am I missing?
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:#"http://www.icodeblog.com/wp-content/uploads/2012/08/zipfile.zip"];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
if(!error) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [paths objectAtIndex:0];
NSString *zipPath = [cachePath stringByAppendingPathComponent:#"zipfile.zip"];
[data writeToFile:zipPath options:0 error:&error];
if(!error) {
ZipArchive *za = [[ZipArchive alloc] init];
if ([za UnzipOpenFile: zipPath]) {
BOOL ret = [za UnzipFileTo: cachePath overWrite: YES];
if (NO == ret){
}
[za UnzipCloseFile];
// NSString *imageFilePath=[cachePath stringByAppendingPathComponent:#"photo.png"];
NSString *imageFilePath=[cachePath stringByAppendingPathComponent:#"myphoto.png"];
NSData *imageData = [NSData dataWithContentsOfFile:imageFilePath options:0 error:nil];
if (imageData) {
NSLog(#"found data");
} else {
NSLog(#"no data");
}
UIImage *img = [UIImage imageWithData:imageData];
NSString *textFilePath = [cachePath stringByAppendingPathComponent:#"text.txt"];
NSString *textString = [NSString stringWithContentsOfFile:textFilePath encoding:NSASCIIStringEncoding error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = img;
self.label.text = textString;
});
}
} else {
NSLog(#"Error saving file %#",error);
}
} else {
NSLog(#"Error downloading zip file: %#", error);
}
});
}
When I run this, looking for the image I added, it returns "no data". Why? And the bigger question is: Can I, in my iOS app, list the contents of an unzipped file?
I started this project with this question which mention this code: SSZipArchive. It works well.
I've tested you code ... and is working fine for me...
The main change:
instead:
ZipArchive *za = [[ZipArchive alloc] init];
if ([za UnzipOpenFile: zipPath]) {
BOOL ret = [za UnzipFileTo: cachePath overWrite: YES];
if (NO == ret){
}
[za UnzipCloseFile];
I'm using
[SSZipArchive unzipFileAtPath:zipPath toDestination:cachePath];
You can list the content of a directory (after unzip):
NSArray * directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:cachePath error:&error];
NSLog(#"DIR folder : %#",directoryContents);
You can check here my demo project based on your code https://dl.dropboxusercontent.com/u/19438780/testSSZipArchive.zip
UPDATE
testing with my zip file I have:
(
"__MACOSX",
"Archive.zip",
"error feedly.txt",
"image1.jpg",
"image2.jpg",
"image3.jpg",
"image4.jpg",
"Tony-M.testSSZipArchive"
)
Related
I want to unzip a zip file downloaded from web but my issue is the zip file is not unzipping in if-else statement.
Is it wrong anything if it is then kindly guide me.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:#"http://www.icodeblog.com/wp-content/uploads/2012/08/zipfile.zip"];
NSError *error = nil;
// 2
NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
if(!error)
{
// 3
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *zipPath = [path stringByAppendingPathComponent:#"zipfile.zip"];
[data writeToFile:zipPath options:0 error:&error];
if(!error)
{
// TODO: Unzip
ZipArchive *za = [[ZipArchive alloc] init];
// 1
if ([za UnzipOpenFile: zipPath]) {
// 2
BOOL ret = [za UnzipFileTo: path overWrite: YES];
if (NO == ret){} [za UnzipCloseFile];
// 3
NSString *imageFilePath = [path stringByAppendingPathComponent:#"photo.png"];
NSString *textFilePath = [path stringByAppendingPathComponent:#"text.txt"];
NSData *imageData = [NSData dataWithContentsOfFile:imageFilePath options:0 error:nil];
UIImage *img = [UIImage imageWithData:imageData];
NSString *textString = [NSString stringWithContentsOfFile:textFilePath
encoding:NSASCIIStringEncoding error:nil];
// 4
dispatch_async(dispatch_get_main_queue(),^{
self.imageView.image = img;
self.label.text = textString;
});
}
else
{
NSLog(#"Error saving file %#",error);
}
}
else
{
NSLog(#"Error downloading zip file: %#", error);
}
}
});
As per your code debugging
1) NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
data is "nil"
by adding in plist below lines of code
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
you will get expected output
I am stuck with unziping a zip file and fetch a paritcular file from that unzipped content (index.html) and finally use that index.html to load a UIWebview .
Am using GZIP library to unzip the file which am downloading
[data gunzippedData];
Is the method which am using to unzip the data using GZIP .
For unzipping the file from web use the below code.
Dowbload ZipArchive.h and #import in your file.
NSURL *urlVersion = [NSURL URLWithString: [tempDirOuter objectForKey:#"filename"]];
NSLog(#"txt File : %#",urlVersion);
NSError *error = nil;
// 2
NSData *data = [NSData dataWithContentsOfURL:urlVersion options:0 error:&error];
NSString *textFilePath;
if(!error)
{
// 3
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *strFileName = [tempDirOuter objectForKey:#"fileNameOnly"];
NSString *zipPath = [path stringByAppendingPathComponent:strFileName];
[data writeToFile:zipPath options:0 error:&error];
ZipArchive *za = [[ZipArchive alloc] init];
// 1
if ([za UnzipOpenFile: zipPath])
{
// 2
BOOL ret = [za UnzipFileTo: path overWrite: YES];
if (NO == ret){} [za UnzipCloseFile];
// 3
NSString *StrName = [strFileName stringByReplacingOccurrencesOfString:#".zip" withString:#".txt"];
textFilePath = [path stringByAppendingPathComponent:StrName];
}
if(!error)
{
// TODO: Unzip
}
else
{
NSLog(#"Error saving file %#",error);
}
}
else
{
NSLog(#"Error downloading zip file: %#", error);
}
NSString *webVersion = [NSString stringWithContentsOfFile:textFilePath encoding:NSASCIIStringEncoding error:nil];
In string webVersion you will get the html path.
I want to create an application that automatically downloads a folder from my own server and store it locally on the iPad/iPhone. How can i accomplish this and where does the folder get stored on the local iDevice ? Therefore how will i access it afterwards? Many thanks for your help
The best way to do so was actually putting all the pictures for example in one zip file, downloading it and unzipping it on the real device using this code :
dispatch_queue_t queue = dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:#"someDirectory/newPics.zip"];
NSError *error = nil;
// 2
NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
if(!error)
{
// 3
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *zipPath = [path stringByAppendingPathComponent:#"newPics.zip"];
[data writeToFile:zipPath options:0 error:&error];
if(!error)
{
ZipArchive *za = [[ZipArchive alloc] init];
// 1
if ([za UnzipOpenFile: zipPath]) {
// 2
BOOL ret = [za UnzipFileTo: path overWrite: YES];
if (NO == ret){} [za UnzipCloseFile];
// 3
NSString *imageFilePath = [path stringByAppendingPathComponent:#"newPics/pic1.png"];
//[self removeImage:zipPath];
[[NSFileManager defaultManager] removeItemAtPath:zipPath error: &error];
dispatch_async(dispatch_get_main_queue(), ^{
NSURL *fileURL = [NSURL fileURLWithPath:imageFilePath];
[_webV loadRequest:[NSURLRequest requestWithURL:fileURL]];
});
}
}
else
{
NSLog(#"Error saving file %#",error);
}
}
else
{
NSLog(#"Error downloading zip file: %#", error);
}
});
It's the best way to do it , fast and reliable.
I have a problem when downloading a file. I have a zip file that has 90 MB and it is filling my RAM memory to hudge amounts until the file is downloaded. Could somene help me with some example code that shows any better way to do this and not overload my RAM?
Thanks.
Code:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:#"http://autoskola.1e29g6m.xip.io/mobileData/slike3.zip"];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
if(!error){
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *zipPath = [path stringByAppendingPathComponent:#"slike3.zip"];
[data writeToFile:zipPath options:0 error:&error];
if(!error){
//unziping the files
ZipArchive *za = [[ZipArchive alloc] init];
if([za UnzipOpenFile:zipPath]){
BOOL ret = [za UnzipFileTo:path overWrite:YES];
if(NO == ret){} [za UnzipCloseFile];
}
}else{
NSLog(#"Error saving file %#", error);
}
}else{
NSLog(#"Error downloading zip file: %#", error);
}
});
You may want to consider looking into AFNetworking. It's probably the most commonly used library for accessing the internet. You can use it to download a file and take the output stream and write the data into a file. This will allow you to download and write the file as chunks of data instead of all at once. You'll want to take a look at the AFNetworking Docs for information on downloading the file. You'll also want to look into the docs for NSFileHandle for information on how to write data into a file.
I've created folder called "Image store" using the following code. my requirment is i want to save images to the folder "Image store" on api success and the images should be saved in application itself not in database or photo album.I want to know the mechanism by which i can store images in application
-(void) createFolder {
UIImage *image = [[UIImage alloc]init];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/ImageStore"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
else
{
}
}
//Make a method that has url (fileName) Param
NSArray *documentsDirectory =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:url];
NSFileManager *fileManager =[NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:textPath])
{
return YES;
}
else
{
return NO;
}
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage
imageNamed:#""]];//Placeholder image
if ([url isKindOfClass:[NSString class]])
{
imgView.image = [UIImage imageNamed:[url absoluteString]];
imgView.contentMode = UIViewContentModeScaleAspectFit;
}
else if ([fileManager fileExistsAtPath:url])
{
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:url];
NSError *error = nil;
NSData *fileData = [NSData dataWithContentsOfFile:textPath options:NSDataReadingMappedIfSafe error:&error];
if (error != nil)
{
DLog(#"There was an error: %#", [error description]);
imgView.image=nil;
}
else
{
imgView.image= [UIImage imageWithData:fileData]
}
}
else
{ UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
CGPoint center = imgView.center;
// center.x = imgView.bounds.size.width / 2;
spinner.center = center;
[spinner startAnimating];
[imgView addSubview:spinner];
dispatch_queue_t downloadQueue = dispatch_queue_create("iamge downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner removeFromSuperview];
UIImage *image = [UIImage imageWithData:imgData];
NSError *error = nil;
[imgData writeToFile:url options:NSDataWritingFileProtectionNone error:&error];
if (error != nil)
{
}
else
{
}
imgView.image = image;
});
});
}
Thats UIImageView loading an image if it doesnot exist in document then it Save it , An Activity indicator is added to show image is loading to save,
u can do something like this
u can run a loop for images like this
//at this point u can get image data
for(int k = 0 ; k < imageCount; k++)
{
[self savePic:[NSString stringWithFormat:#"picName%d",k] withData:imageData];//hear data for each pic u can send
}
- (void)savePic:(NSString *)picName withData:(NSData *)imageData
{
if(imageData != nil)
{
NSString *path = [NSString stringWithFormat:#"/ImageStore/%#.png",pincName];
NSString *Dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pngPath = [NSString stringWithFormat:#"%#%#",Dir,path]; //path means ur destination contain's this format -> "/foldername/picname" pickname must be unique
if(![[NSFileManager defaultManager] fileExistsAtPath:[pngPath stringByDeletingLastPathComponent]])
{
NSError *error;
[[NSFileManager defaultManager] createDirectoryAtPath:[pngPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:&error];
if(error)
{
NSLog(#"error in creating dir");
}
}
[imageData writeToFile:pngPath atomically:YES];
}
}
after successful download and saving u can retrieve images like below
- (UIImage *)checkForImageIn:(NSString *)InDestination
{
NSString *Dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pngPath = [NSString stringWithFormat:#"%#%#",Dir,InDestination];//hear "InDestination" format is like this "/yourFolderName/imagename" as i said imagename must be unique .. :)
UIImage *image = [UIImage imageWithContentsOfFile:pngPath];
if(image)
{
return image;
}
else
return nil;
}
link to find path
see this link to find the path ..
aganin do same this run loop like below
NSMutableArray *imagesArray = [[NSMutableArray alloc]init];
for(int k = 0 ; k < imageCount; k++)
{
UIImage *image = [self checkForImageIn:[NSString stringWithFormat: #"/yourFolderName/ImageName%d",k]];//get the image
[imagesArray addObject:image];//store to use it somewhere ..
}
Write this code after creating directory
NSString *path= [documentsDirectory stringByAppendingPathComponent:#"/ImageStore"];
UIImage *rainyImage =[UImage imageNamed:#"rainy.jpg"];
NSData *Data= UIImageJPEGRepresentation(rainyImage,0.0);
[data writeToFile:path atomically:YES]
The document directory is found like this:
// Let's save the file into Document folder.
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
// If you go to the folder below, you will find those pictures
NSLog(#"%#",docDir);
NSLog(#"saving png");
NSString *pngFilePath = [NSString stringWithFormat:#"%#/test.png",docDir];
Thats just a sample of the code provided which tells you where the correct path is to save in your ipone device.
Check the below blog post,it's step by step guide with source code .
Download an Image and Save it as PNG or JPEG in iPhone SDK