Unable to create ReaderDocument Vfr-Reader - ios

I searched a lot but can't open PDF with vfr-reader from documents folder.
NSString *filePath = #"/Users/***/Library/Application Support/iPhone Simulator/5.0/Applications/F2B7E9DE-9996-4F05-BC81-2A2889B4F504/Documents/Number1.pdf";
ReaderDocument *document = [ReaderDocument withDocumentFilePath:filePath password:password];
if (document != nil)
{// document comes nil here
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self; // Set the ReaderViewController delegate to self
[self.navigationController pushViewController:readerViewController animated:YES];
}
I am sure that filepath is exact the pdf file.
In the example code of reader it opens the pdf from main bundle. But I need to open from resources folder.
Thanks

i facing same issue, may be you also have same one.
if you are not using ARC than just write -fobjc-arc to every pdf reader file in build face. that will solve your problem.

You should use [[NSBundle mainBundle] bundlePath] and stringByAppendingPathComponent: instead of hard-coding the string. This is quite horrible and will only ever work on the iOS Simulator.

You should give file name like below code,don't give directly
NSArray *pathss = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPaths = [pathss objectAtIndex:0];
NSString *filePaths = [documentsPaths stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",fileName]];

I understand this is an old post but none the less I ran into a similar problem as #user1392687 and wanted to share how I resolved the issue (I was loading files from various directories not just the Documents folder).
Problem: Load a series of PDF files out of a directory, populate a table view with filenames and supporting meta data, then upon selecting a cell, open the PDF file using VFR Reader.
Solution: The folder within X-Code is a Folder Reference to enable content updates without having to perform the remove/add cycle of a Group Reference. The function below was used to read all contents - URLs - of a specific folder path then remove all/any simlinks contained within the returned file paths. Prior passing the URL into VRF to load the PDF file [url path] was used for a RFC 1808 (unescaped) path.
+ (NSArray *)enumerateContentsOfFolderWithPath:(NSURL *)aFolderPath
{
NSError *error = nil;
NSArray *contentProperties = #[NSURLIsDirectoryKey,
NSURLIsReadableKey,
NSURLCreationDateKey,
NSURLContentAccessDateKey,
NSURLContentModificationDateKey];
NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:aFolderPath
includingPropertiesForKeys:contentProperties
options:NSDirectoryEnumerationSkipsHiddenFiles
error:&error];
if (error != nil)
DLog(#"Content enumeration error: %#", error);
NSMutableArray *pdfURLs = [NSMutableArray array];
for (NSURL *item in contents)
{
NSURL *fileURL = [NSURL fileURLWithPath: [item path]];
NSURL *noSimlink = [fileURL URLByResolvingSymlinksInPath];
[pdfURLs addObject: noSimlink];
}
return pdfURLs;
}
After populating the table view with the contents of the folder and all supporting metadata, and upon a user touching a row to view the PDF file, the VRF Reader was setup as follows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Other setup code...
NSURL *item = [pdfURLs objectAtIndex:(NSUInteger) indexPath.row];
[self presentPdfViewerForItem: item];
}
- (void)presentPdfViewerForItem:(NSURL *)aItem
{
NSString *phrase = nil; // Document password (for unlocking most encrypted PDF files)
NSString *filePath = [aItem path];
ReaderDocument *document = [ReaderDocument withDocumentFilePath: filePath password:phrase];
if (document != nil) // Must have a valid ReaderDocument object in order to proceed
{
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self;
readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:readerViewController animated:YES completion:nil];
}
}

Related

UIDocumentPickerViewController copied files disappear on download to test iPad

I am using UIDocumentPickerViewController to allow the user to select files that will be "attached" and available within the App. The concept is allow the user to send detail via email with the selected file attachments.
As each file is attached, I copy the file from the tmp Inbox (where fileManager puts the imported file) to a directory I create within the App document directory called "fileAttachments".
I list the files in a UITableView and the user can select each entry and preview the content within a QLPreviewController view using the path stored in the file object fileOJ.filePath.
It all works swimmingly well, until a reload of the project down to my test iPad, then all the files seem to disappear. My list of the files is still fine, but there is no file at the path location.
Any help with just what is happenning would be greatly appreciated.
- (IBAction)selectFilesAction:(UIBarButtonItem *)sender {
NSArray *UTIs = [NSArray arrayWithObjects:#"public.data", nil];
[self openFilePicker:UTIs];
}
- (void)openFilePicker:(NSArray *)UTIs {
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:UTIs inMode:UIDocumentPickerModeImport];
documentPicker.delegate = self;
documentPicker.allowsMultipleSelection = FALSE;
documentPicker.popoverPresentationController.barButtonItem = self.selectFilesButton;
[self presentViewController:documentPicker animated:TRUE completion:nil];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls {
NSLog(#"picked URLs %#", urls);
// selecting multiple documents is cool, but requires iOS 11
for (NSURL *documentURL in urls) {
//get file details
NSDictionary *attr = [documentURL resourceValuesForKeys:#[NSURLFileSizeKey,NSURLCreationDateKey] error:nil];
NSLog(#"object: %#", attr);
NSNumber *fileSize = [attr valueForKey:NSURLFileSizeKey];
NSDate *dateFileCreated = [attr valueForKey:NSURLCreationDateKey];
NSDateFormatter *storageDateFormat = [[NSDateFormatter alloc] init];
[storageDateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *createdDateString = [storageDateFormat stringFromDate:dateFileCreated];
MMfile *fileObj = [[MMfile alloc]init];
fileObj.fileName = documentURL.lastPathComponent;
fileObj.meetingID = _meetingID;
fileObj.fileSize = fileSize;
fileObj.fileCreateDate = createdDateString;
//move file to new directory
fileObj.filePath = [self movefile:documentURL.lastPathComponent sourceFilePath:documentURL.path directory:#"fileAttachments"];
//save file details
[self.meetingModel saveFile:fileObj];
//refresh array and reload table
self.fileArray = [self.meetingModel getFiles:self.meetingID];
[self.tableView reloadData];
}
}
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
NSLog(#"cancelled");
}
-(NSString *)movefile:(NSString *)filename sourceFilePath:(NSString *)sourcePath directory:(NSString *)directoryName{
// Move file from tmp Inbox to the destination directory
BOOL isDir;
NSError *error;
NSFileManager *fileManager= [NSFileManager defaultManager];
//get directory path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString* directoryPath;
if (paths>0) {
NSString *documentsDirectory = [paths objectAtIndex:0];
directoryPath = [NSString stringWithFormat:#"%#/%#",documentsDirectory,directoryName];
}
if(![fileManager fileExistsAtPath:directoryPath isDirectory:&isDir])
if(![fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:NO attributes:nil error:NULL])
NSLog(#"Error: Create folder failed %#", directoryPath);
NSString *destinationPath = [NSString stringWithFormat:#"%#/%#",directoryPath,filename];;
BOOL success = [fileManager moveItemAtPath:sourcePath toPath:destinationPath error:&error];
if (success) {
NSLog(#"moved file");
}else{
NSLog(#"error %#",error.description);
}
return destinationPath;
}
Found the issue. When the project is rebuilt and downloaded to the iPad the AppID changes, and as the documents path includes the AppID, so the documents path changes. Key is not to save the file path, only the file name and rebuild the path each instance. After having found the issue, I now see other similar posts I didn't find earlier. Also see Document directory path change when rebuild application

how to store an image path in a plist?

I know this is probably a silly question but I'm storing most of my game data in a plist - with that I'd like to include references to images used within my game - same hierarchal level as 'supporting files'. I have different types of images stored in 3 separate folders. One folder for example is called imageclue. How could I store the path in my plist, I'm stuck because I can't just store the path in my plist as string - filename.jpg. I've tried getting the path of the file but when I log it out it .
Sorry if I'm not explaining well and thank you in advance for any help :)
EDIT**
I have a plist file added to my program I don't want to programatically add to it as the images are constants - the screenshots below show a tutorial instead of the filename.jpg (because that won't work seen as my images are stored in a file) I wondered what path name do I use as a string.
The image is from a tutorial off of appcoda.com - where it says thumbnails are the image path files. If you look at where the images are stored on the left - they are stored with the program files. My images are in a folder in there so I'm confused as to what to enter in my plist for the image file.
Hope this clears up what I meant, sorry :)
Store three variables in .h file
#interface YourViewController : UIViewController
{
NSString *folder1;
NSString *folder2;
NSString *folder3;
}
in viewdidload:
-(void) viewdidLoad
{
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//getting the folder name:
folder1 = [NSString stringWithFormat:#"%#/imageclue",
documentsDirectory];
folder2 = [NSString stringWithFormat:#"%#/folder2",
documentsDirectory];
folder3 = [NSString stringWithFormat:#"%#/folder3",
documentsDirectory];
}
-(NSArray*) getPlistFromFolder:(NSString*)folder imageName:(NSString*)image
{
NSString *imageTitle = [NSString stringWithFormat:#"%#/image",
folder];
NSArray *data = [[NSArray alloc] initWithContentsOfFile:plistName];
return data;
}
So in the plist file, just store the image name.
Hope this helps...
Do it like this,
NSDictionary *imagePaths = #{#"image 1": [NSHomeDirectory() stringByAppendingPathComponent:#"image 1"]};
[self writeToPlist:imagePaths];
- (void)writeToPlist:imagePaths:(id)plist{
NSError *error;
NSData *data = [NSPropertyListSerialization dataWithPropertyList:plist format:kCFPropertyListXMLFormat_v1_0 options:0 error:&error];
if(error){
NSLog(#"Could not write to file");
return;
}
[data writeToFile:[self plistPath] atomically:YES];
}
Like wise loading is simple as this;
[self loadImagePathForImageNamed:#"image 1"];
- (NSString*)loadImagePathForImageNamed:(NSString*)imageName{
}
- (NSString*)loadImagePathForImageNamed:(NSString*)imageName{
NSData *data = [NSData dataWithContentsOfFile:[self plistPath]];
NSString *error;
NSPropertyListFormat format;
NSDictionary *dictionary = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
if(error){
NSLog(#"Could not open plist %#", error);
return nil;
}
return dictionary[imageName];
}
You may have to handle the error when the file is not there by creating a new one, otherwise this should work.
You are storing path right way, just need to store filename of image with extension in plist when your images are in your Application Bundle, for more reference you can define key name Instead "item1", "item2" in your plist.
Now coming to actual Question, how to access image from plist
Step 1 : Read your recipes.plist from Application Bundle
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:bundlePath];
Step 2 : Now Get Image/Thumbnails name out of it, which you want to load
Step 3 : Define following Function in your Controller, which returns image from name
- (UIImage *)getImageWithName:(NSString *)imageFileName
{
NSString *ext = [imageFileName pathExtension];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:[imageFileName stringByDeletingPathExtension] ofType:ext];
return [UIImage imageWithContentsOfFile:imagePath];
}
HOW TO USE
Suppose you want to load Image with key "Item2" then write following code
NSString *imageFileName = [[dict objectForKey:#"Thumbnail"] valueForKey:#"Item2"];
UIImage *item2Image = [self getImageWithName:imageFileName];
For "Item6"
NSString *imageFileName1 = [[dict objectForKey:#"Thumbnail"] valueForKey:#"Item6"];
UIImage *item6Image = [self getImageWithName:imageFileName1];

iOS plist is null

I know there are a multitude of questions about this on SO but I can't see where I am making the mistake and am hoping some extra eyes will help. I've verified the plist is in my bundle and it is also in my docs directory and it contains data. Here's a screen capture of the app package with the plist at top:
I pass the plist in from another class and have verified that it is the correct plist.
Here's my code:
-(id)init {
if (self = [super init]) {
//set up the appTracker
appTracker = [[OAI_AppTracker alloc] init];
//set up a file manager and error container
fileManger=[NSFileManager defaultManager];
//docs directory path
documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//track event
appTracker.appEvent = #"File Manager initialized";
[appTracker recordEvent];
}
return self;
}
- (NSDictionary* ) readPlist {
NSError* error;
//set up dictionary to hold our app data
NSDictionary* appData;
//set up destination path
NSString* destinationPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#", plistToRead]];
if ([fileManger fileExistsAtPath:destinationPath]){
//read plist
appData = [[NSDictionary alloc] initWithContentsOfFile:destinationPath];
} else {
//file doesn't exist so we have to move it to the doc folder
NSString *sourcePath=[[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:plistToWrite];
[fileManger copyItemAtPath:sourcePath toPath:destinationPath error:&error];
//now read the plist
appData = [[NSDictionary alloc] initWithContentsOfFile:destinationPath];
}
NSLog(#"%#", appData);
return appData;
}
My log shows NULL instead of the data in the plist. Appreciate any help as to what I am doing wrong.
To read your plist try something like this:
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"PlistFileName" ofType:#"plist"];
NSDictionary *plistData = [[NSDictionary alloc] initWithContentsOfFile:plistPath];

What is the correct way to save user data using NSFileManager?

I am having trouble initializing dictionaries I use throughout my program to store user achievements and scores.
I have almost identical code for the two dictionaries and only the gameCenterData dictionary seems to be working properly. I have tried altering the plist file name and contents yet nothing seems to make the playerData dictionary properly load info from the file as it should
In the Root View Controller I have the following code (playerData and gameCenterData are both NSMutableDictionaries and the plist files are in the proper place)
-(NSString *)scoreFilePath
{
NSArray *scorePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [scorePath objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"PlayerScoreData.plist"];
}
-(NSString *)gameCenterFilePath
{
NSArray *gameCenterPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [gameCenterPath objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"GameCenterData.plist"];
}
then the view did load
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *playerDataPath = [self scoreFilePath];
if (! [[NSFileManager defaultManager] fileExistsAtPath:playerDataPath])
{
playerData = [NSMutableDictionary dictionaryWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"scoreData.plist"]];
[playerData writeToFile:[self scoreFilePath] atomically:YES];
NSLog(#"Player data file does not exist");
}
else
{
playerData = [[NSMutableDictionary alloc] initWithContentsOfFile:[self scoreFilePath]];
NSLog(#"player data file exists");
}
NSLog(#"scoreData is %#",playerData);
NSString *gameCenterPath = [self gameCenterFilePath];
if (! [[NSFileManager defaultManager] fileExistsAtPath:gameCenterPath])
{
gameCenterData = [NSMutableDictionary dictionaryWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"gameCenterData.plist"]];
[gameCenterData writeToFile:[self gameCenterFilePath] atomically:YES];
NSLog(#"game center data file does not exist");
}
else
{
gameCenterData = [[NSMutableDictionary alloc] initWithContentsOfFile:[self gameCenterFilePath]];
NSLog(#"game center data file exists");
}
NSLog(#"gameCenterData is %#",gameCenterData);
the output is as follows
2012-08-05 11:46:49.991 GlobeRoller[6410:1be03] Player data file does not exist
2012-08-05 11:46:49.992 GlobeRoller[6410:1be03] playerData is (null)
2012-08-05 11:46:50.061 GlobeRoller[6410:1be03] game center data file does not exist
2012-08-05 11:46:50.062 GlobeRoller[6410:1be03] gameCenterData is {
"Career Odometer" = 0;
"Career Score" = 0;
"Cities Found" = 0;
"Offline Games Played" = 0;
"Online Games Played" = 0;
"Online Games Won" = 0;
}
I have searched all of the questions and answers to see if I can find out why this isn't working for both methods. Any help you could offer, or resources you could point me to I would greatly appreciate.
Thank you,
CF
The plist file you are trying to load from the bundle is either not there, or has been created improperly. Directly from the documentation of dictionaryWithContentsOfFile:.
Return Value
A new dictionary that contains the dictionary at path, or
nil if there is a file error or if the contents of the file are an
invalid representation of a dictionary.
You should make sure you are using the proper file name, and then open your plist in Xcode to see if it is properly formatted.
iOS is case sensitive. Are you sure that your file in the bundle is lower case, i.e. "#"scoreData.plist", and not upper case like the name your code uses? Also, verify that these two files are in your bundle - check the build phase or select the files (one at a time) and look in the 3rd Xcode pane in the file attribute section (to verify they are included in your target). If all that looks good then when you try to retrieve the files from your bundle:
Also, don't try to find the file at the root level of the bundle - you should be using:
NSString *path = [[NSBundle mainBundle] pathForResource:#"GameCenterData" ofType:#"plist"];
NSLog(#"PATH is %#", path);
...then use path instead of the code you are using now

is it possible to share images across NSBundles?

Apologies for the vague question title...
here is my scenario:
I am dynamically loading UIView content from nib files stored in NSBundles
BOOL bundlePathExists = [fm fileExistsAtPath:bundlePath];
if (bundlePathExists) {
NSBundle *tempBundle = [NSBundle bundleWithPath:bundlePath];
UIViewController *vc = [[UIViewController alloc] initWithNibName:nibName bundle:tempBundle];
[self.view addSubview:vc.view];
}
(note: the above is a simplified excerpt of the actual code, as not to confuse the nature of the question - the mechanics of doing this is relatively well documented here)
these nib files contain a number of images, some of which are unique to that bundle, and others that are shared across multiple bundles.
i'd like to be able to store the images that are common inside the main bundle, so they don't take up space in the other bundles, and to minimise the maintenance of the project as a whole - eg if i change one of those common images, i'd rather not have to rebuild every bundle it is referenced by.
i realize i could do this programatically by using
[commonImageViewIvar setImage:[UIImage imageWithName:commonImageName]];
however i would prefer to achieve this without writing custom code for each view (ie the view controller instantiated is not customised per nib, hence all information needs to be stored in the nib)
As promised here is the solution i came up with:
The bundle files themselves are downloaded as described here. To add to the information listed there, I found that if you create the views in an iphone app first, you can then preview them in the simulator. then, you can create a new project, as a bundle, and drag and drop ALL the image files & the xib &.h file into the new project. don't drag the .m file across as this creates build issues. then, ensure that the project settings define the BASE SDK as "Latest IOS", and not the default Mac OS X setting that would have been selected. you can then still edit the xib by double clicking on it. any common files can be deselected from the build by unticking the "target" column for that file. see "Additional Information" later in this answer post.
once i have downloaded each bundle in a zip file from the server, i utilize the following methods i coded for this purpose:
-(NSArray *) imageFileExtensions {
return [NSArray arrayWithObjects:#".png",#".gif",#".jpg",#".jpeg",#".bmp", nil];
}
and
-(void) cloneImageFilesInPath:(NSString *)path toPath:(NSString*)clonePath {
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *extensions = [self imageFileExtensions];
if ([fm fileExistsAtPath:path]) {
NSArray *files = [fm contentsOfDirectoryAtPath:path error:nil];
for (NSString *file in files){
for (NSString *ext in extensions) {
if ([file hasSuffix:ext]) {
NSString *targetFile = [clonePath stringByAppendingPathComponent:file];
if (![fm fileExistsAtPath:targetFile]) {
[fm createSymbolicLinkAtPath:targetFile withDestinationPath:[path stringByAppendingPathComponent:file] error:nil];
}
break;
}
}
}
}
}
these methods create scan the main app bundle directory and for each image file that is NOT in the custom bundle directory, a symbolic link is created inside the custom bundle directory to point back to the main app bundle directory.
They are invoked in my app delegate as follows:
...(insert code to unzip the file to bundlePath here)...
[self cloneImageFilesInPath:[[NSBundle mainBundle] bundlePath] toPath:bundlePath];
Additional information
to create the actual bundles, i made a separate app that removed any image files from a custom bundle directory, if those filenames are present in a directory that contains the common image files that are deployed in the main app bundle. i later discovered you can prevent xcode from including certain files from the build by deselecting the target column checkbox for that file, so this step is not necessarily needed - if you have a lot of views to create however, it may be easier to just leave them in the bundles, and strip them out using this method.
-(void) removeDuplicatedImageFilesInPath:(NSString *)sourcePath fromTargetPath:(NSString*)path {
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *extensions = [self imageFileExtensions];
if ([fm fileExistsAtPath:path]) {
NSArray *files = [fm contentsOfDirectoryAtPath:sourcePath error:nil];
for (NSString *file in files){
for (NSString *ext in extensions) {
if ([file hasSuffix:ext]) {
NSString *targetPath = [path stringByAppendingPathComponent:file];
if ([fm fileExistsAtPath:targetPath]) {
[fm removeItemAtPath:targetPath error:nil];
}
break;
}
}
}
}
}
Further Information for dealing with the zip files
I opted on using ObjectiveZip (following a suggestion by a poster here. To simplify the task, i wrapped this in the following 2 app delegate methods (one is used in the actual app, another in the the offline bundle creation app)
in the main app
-(void) unzipArchive:(NSString *)zipFileName toPath:(NSString *)path {
NSFileManager *fm = [NSFileManager defaultManager];
ZipFile *unzipFile = [[ZipFile alloc] initWithFileName:zipFileName mode:ZipFileModeUnzip];
NSArray *infos= [unzipFile listFileInZipInfos];
[unzipFile goToFirstFileInZip];
for (FileInZipInfo *info in infos) {
ZipReadStream *read1= [unzipFile readCurrentFileInZip];
NSMutableData *fileData = [[[NSMutableData alloc] initWithLength:info.length] autorelease];
int bytesRead1 = [read1 readDataWithBuffer:fileData];
if (bytesRead1 == info.length) {
NSString *fileName = [path stringByAppendingPathComponent:info.name ];
NSString *filePath = [fileName stringByDeletingLastPathComponent];
[fm createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
[fileData writeToFile:fileName atomically:YES];
}
[read1 finishedReading];
[unzipFile goToNextFileInZip];
}
[unzipFile close];
[unzipFile release];
}
and in the custom bundle creation offline app.
-(void) createArchive:(NSString *) zipFileName usingPath:(NSString *)path {
NSArray *files = [self filesInDirectory:path];
ZipFile *zipFile= [[ZipFile alloc] initWithFileName:zipFileName mode:ZipFileModeCreate];
for (NSString *file in files) {
NSString *fileNameForZip = [file substringFromIndex:path.length];
ZipWriteStream *stream= [zipFile writeFileInZipWithName:fileNameForZip fileDate:[NSDate dateWithTimeIntervalSinceNow:-86400.0] compressionLevel:ZipCompressionLevelBest];
[stream writeData:[NSData dataWithContentsOfFile:file]];
[stream finishedWriting];
}
[zipFile close];
[zipFile release];
}
note: the previous method relies on the following 2 methods, which create an NSArray containing the fully qualified path to all files in the given path (recursing into sub directories)
-(void)loadFilesInDirectory:(NSString *)path intoArray:(NSMutableArray *)files {
NSFileManager *fm = [NSFileManager defaultManager];
NSMutableArray *fileList = [NSMutableArray arrayWithArray:[fm contentsOfDirectoryAtPath:path error:nil]];
for (NSString *file in fileList) {
BOOL isDirectory = NO;
NSString *filePath = [path stringByAppendingPathComponent:file];
if ([fm fileExistsAtPath:filePath isDirectory:&isDirectory]) {
if (isDirectory) {
[self loadFilesInDirectory:filePath intoArray:files];
} else {
[files addObject:filePath];
};
};
}
}
-(NSArray *)filesInDirectory:(NSString *)path {
NSMutableArray *files = [NSMutableArray array];
[self loadFilesInDirectory:path intoArray:files];
return files;
}

Resources