Using QLPreviewController to display files from Documents folder - iphone

I very much appreciate the tutorial on using QLPreviewController here.
I am trying to implement this code into my application, with modification to display files from the app's Documents folder instead of the Resources folder (so that the user can use iTunes filesharing to manage the documents). However, in doing so I hit the "EXC_BAD_ACCESS" error.
I create an array of files in the Documents folder to produce the tableview list:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
arrayOfDocuments = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsPath error:NULL];
}
I have no problem with displaying a list of files from the Documents folder in this way.
The code to display a chosen file from the list using QuickLook is:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// When user taps a row, create the preview controller
QLPreviewController *previewer = [[[QLPreviewController alloc] init] autorelease];
// Set data source
[previewer setDataSource:self];
// Which item to preview
[previewer setCurrentPreviewItemIndex:indexPath.row];
// Push new viewcontroller, previewing the document
[[self navigationController] pushViewController:previewer animated:YES];
}
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return [arrayOfDocuments count];
}
- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
// Break the path into it's components (filename and extension)
NSArray *fileComponents = [[arrayOfDocuments objectAtIndex: index] componentsSeparatedByString:#"."];
// Use the filename (index 0) and the extension (index 1) to get path
NSString *path = [[NSBundle mainBundle] pathForResource:[fileComponents objectAtIndex:0] ofType:[fileComponents objectAtIndex:1] inDirectory: #"Documents"];
return [NSURL fileURLWithPath:path];
}
When running this code, I receive the error EXC_BAD_ACCESS at the line:
[previewer setDataSource:self];
Any help would be much-appreciated. Thanks in advance.

Related

What mistake is there in my code in iphone

I am new to i Phone programming.In this code i have store images in array that images i have added in bundle,that image i can able to display in thumbnail.Similarly i have create private folder in document directory there i have add 2 images that after that i retrieve that images in array but i am not able display private document directory images in thumbnail but i can able to display bundle images.In below code 2 localImages are there one of the localImages i have store bundle images and one more localImages i have store private document directory folder images.Now bundle images are displaying but i commented that bundle localImages.and i using private document directory images in same localImages that not working its showing some Expection.
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
savedImagePath = [documentsDirectory stringByAppendingPathComponent:#"Tauky"];
NSLog(#"%#",savedImagePath);
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:savedImagePath])
[[NSFileManager defaultManager] createDirectoryAtPath:savedImagePath withIntermediateDirectories:NO attributes:nil error:&error];
dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:savedImagePath error:&error];
localImages = [[NSArray alloc] init];
predicate = [NSPredicate predicateWithFormat:#"self ENDSWITH '.jpeg'"];
imagesOnly = [dirContents filteredArrayUsingPredicate:predicate];
localImages = [NSArray arrayWithArray:imagesOnly];
NSLog(#"%#",localImages);
self.title = #"FGallery";
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
localCaptions = [[NSArray alloc] initWithObjects:#"images53", #"image57",nil];
//localImages =[[NSArray alloc] initWithObjects: #"lava.jpeg",#"hawaii.jpeg",nil];
NSLog(#"%#",localImagess);
Expection is below code
- (void)reloadGallery
{
_currentIndex = _startingIndex;
_isThumbViewShowing = NO;
// remove the old
[self destroyViews];
// build the new
if ([_photoSource numberOfPhotosForPhotoGallery:self] > 0) {
// create the image views for each photo
[self buildViews];
// create the thumbnail views
[self buildThumbsViewPhotos];
// start loading thumbs
[self preloadThumbnailImages];
// start on first image
[self gotoImageByIndex:_currentIndex animated:NO];
// layout
[self layoutViews];
}
}
In console its show like this
self=(FGalleryViewController *)0x6877050
_cmd=(SEL)0x103cf reloadgallery
I not getting i tried so many ways what to do.Please help me
Thanks
You name your method reloadGallery, but you seem to be calling it as reloadgallery (notice the lowercase 'g'!). Change the call to reloadGallery and it should be fine.

Data persistance tableView issue iPhone(reading and writing to plist)

In my application I want to implement a simple Alarm function. I know how to use UILocalNotifications, but I came across this source code with a like UI of the iPhone's native Clock app alarm area as well as it having a believe a type of data persistence. Two things I am not good at interface design and data persistence this source code has. But I downloaded it and started playing around with it to find the alarms are not persistent.
Download
Does anyone know how the source code can be adjusted so that it is persistent and the plist can be saved and read to and from? I am open to learning too, this area is somewhat unknown to me too. Thanks
I review your code and find issue that you not moved your "Alarms.plist" file form resource to document directory. we are not able to edit file which is in resource folder. so write following code in app delegate file.
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *theFileName = #"Alarms.plist"; //Change this appropriately
NSString *oldPath = [[NSBundle mainBundle] pathForResource:#"Alarms" ofType:#"plist"];//[NSString stringWithFormat:#"%#/Inbox/%#", documentsDirectory, theFileName];
NSString *newPath = [NSString stringWithFormat:#"%#/%#", documentsDirectory, theFileName];
if (![[NSFileManager defaultManager] fileExistsAtPath:newPath])
[[NSFileManager defaultManager] moveItemAtPath:oldPath toPath:newPath error:nil];
Perform save operation on file which is in Document directory folder.
try this code... to save plist from bundle to Document Directory
Notice that you will have "Unable to read... " just at the first app launch
- (NSMutableArray *)displayedObjects
{
if (_displayedObjects == nil)
{
NSString *path = [[self class] pathForDocumentWithName:#"Alarms.plist"];
NSArray *alarmDicts = [NSMutableArray arrayWithContentsOfFile:path];
if (alarmDicts == nil)
{
NSLog(#"Unable to read plist file: %#", path);
NSLog(#"copy Alarms.plist to: %#", path);
NSString *pathToSetingbundle = [[NSBundle mainBundle] pathForResource:#"Alarms" ofType:#"plist"];
[[NSFileManager defaultManager]copyItemAtPath:pathToSetingbundle toPath:path error:nil];
}
_displayedObjects = [[NSMutableArray alloc]
initWithCapacity:[alarmDicts count]];
for (NSDictionary *currDict in alarmDicts)
{
Alarm *alarm = [[Alarm alloc] initWithDictionary:currDict];
[_displayedObjects addObject:alarm];
NSLog(#"#disply obj %#", alarm);
}
}
return _displayedObjects;
}

How can I load my UITableView with a list of saved files in my documents directory?

How can I load my UITableView with a list of saved files in my documents directory? I just need a small example or a simple online tutorial as I've been pulling my hair out. All the files are saved to the iOS document directory and all I need to do is list them in my UITableView.
NSArray *filePathsArray;
- (void)setUpTheFileNamesToBeListed
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [filePathsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Insert this line to add the file name to the list
cell.textLabel.text = [documentsDirectory stringByAppendingPathComponent:[filePathsArray objectAtIndex:indexPath.row]];
}
From the above two answers you know how to retrieve the files from the document directory.
and Now you want how to open a file when a user tap on te cell.
you just have to use the UITableView delegate function i.e
-(void)tableView(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//do all your file opening logic here.
//your file data is stored in the NSArray myFileData(refer the previous answer posted above)
//and suppose you want to fetch the data which is in the file, is of type NSURL, means the file data is just a URL link.
//just declare a NSURL in your .h(say myURL) (synthesize it etc)
myURL=[NSURL URLWithString:[myFileData objectAtIndex:indexPath.row]]
}
now your myURL is having the link which is stored in the file and then you can use that url in your webView.
You can get the path of the documents directory using
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
You will get the list of files in it using
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:nil];
This array will contain directories as well as files. Enumerate through dirContents and check if it is a file using
- (BOOL)fileExistsAtPath:(NSString *)path
If the file does not exist, either filter that out from the dirContents or else create a new array with paths of only the files that do exist and use that as a datasource for the table view.

iPhone - track back button event

I have a tableView which lists the contents of my document directory. I have some zip files in that. If I touch a file in the tableView, the corresponding zip file is unzipped and extracted in a temporary directory(newFilePath in my case). The contents unzipped is listed in the next tableView. When I touch the back button, the contents in the directory is listed again.
For example, consider that I have four zip files in my document directory.
songs.zip, videos.zip, files.zip, calculation.zip
When I run the application, all the four files are listed in the tableView. When I touch songs.zip, this file is extracted in the newFilePath and its contents are pushed to the next tableView. When I touch back, the previous tableView, i.e, the four files in the document directory are listed again. Everything works perfect.
The problem is, the extracted files in the newFilePath remains there itself. They occupy the memory unnecessarily. I want them to be removed from that path when I touch the back button, i.e, I want to make newFilePath empty when the back button is touched.
I tried for it. But, no use. I tried removeItemAtPath: method in viewWillAppear: and also in viewWillDisappear:. But it didnt work in both the cases.
Is there any other method to track the action of the back button? I want an event to take place when the back button is touched. So please help me by sharing your ideas. Here is my code for your verification.
This is my didSelectRowAtIndexPath:
NSString *filePath = //filePath
if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSLog(#"File exists at path: %#", filePath);
} else {
NSLog(#"File does not exists at path: %#", filePath);
}
ZipArchive *zip = [[ZipArchive alloc] init];
NSString *newFilePath = //newFilePath
[[NSFileManager defaultManager] createDirectoryAtPath:newFilePath withIntermediateDirectories:NO attributes:nil error:nil];
BOOL result = NO;
if([zip UnzipOpenFile:filePath]) {
//zip file is there
if ([zip UnzipFileTo:newFilePath overWrite:YES]) {
//unzipped successfully
NSLog(#"Archive unzip Success");
result= YES;
} else {
NSLog(#"Failure To Extract Archive, maybe password?");
}
} else {
NSLog(#"Failure To Open Archive");
}
iDataTravellerAppDelegate *AppDelegate = (iDataTravellerAppDelegate *)[[UIApplication sharedApplication] delegate];
//Prepare to tableview.
MyFilesList *myFilesList = [[MyFilesList alloc] initWithNibName:#"MyFilesList" bundle:[NSBundle mainBundle]];
//Increment the Current View
myFilesList.CurrentLevel += 1;
viewPushed = YES;
//Push the new table view on the stack
myFilesList.directoryContent = [AppDelegate getTemporaryDirectoryItemList:newFilePath];
[myFilesList setTitle:detailedViewController.strName];
[self.navigationController pushViewController:myFilesList animated:YES];
[myFilesList release];
Thank you for your answers.
for creating your own action you need custom back button.But i think viewWillDisAppear also can do solve your problem.
use this code for solving your problem
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *databaseFile = [documentsDirectoryPath stringByAppendingPathComponent:#"newFilePath"];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:databaseFile error:NULL];
This may help you.
Edit:
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *secondaryDirectoryPath = [secondaryDirectoryPath stringByAppendingPathComponent:#"secondary"];
NSString *databaseFile = [documentsDirectoryPath stringByAppendingPathComponent:#"newFilePath"];
use these lines in your code if you have directory inside the document directory.
you can add the custom back button on Navigation Bar. Create the method, which will fire on click event of Back button.

Loading a web page in iphone and check history

Pseudo code
pageUrl = "http://www.google.com"
if(pageUrl == never Downloaded)
Download pageUrl
else
{
Display Saved Version
Mean while download pageUrl
When done display new version
}
How can I do something like this in objective C for a UIWebview?
Also what's the best way to save web pages for this scenario? PList, SQLite?
Plist is the best way to solve your problem.
iPhone/Objective-c can access very quickly to plist file as compare to SQLite Database.
Let me give you some sample code.
See - edit After some time.
Edit :
Steps for Creating project & connecting web-view
Create New Project -> View Based Application.
Give name "yourProjName" ( up to you what you give )
Open "yourProjNameViewController.xib"
Drag & drop UIWebView
Open "yourProjNameViewController.h" File
Place a variable IBOutlet UIWebView *wView;
Connect in interface builder
Steps for adding Property list file to your project
Expand Resources Group under your project tree
Right click on "Resources" -> Add -> New File
Select Template Category - osx -> Resource
Select Property List file
Give file name "LoadedURL.plist"
Change Root type to Array
Save "LoadedURL.plist" file
Now place following code to "yourProjNameViewController.m" file.
#import "yourProjNameViewController.h"
#define documentsDirectory_Statement NSString *documentsDirectory; \
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); \
documentsDirectory = [paths objectAtIndex:0];
#implementation WebViewLoadViewController
- (void)viewDidLoad {
[super viewDidLoad];
// your url to load
NSString *strToLoad=#"http://www.mail.yahoo.com";
// file management code
// copy file to documents directory
documentsDirectory_Statement;
NSFileManager *fm=[NSFileManager defaultManager];
if(![fm fileExistsAtPath:[documentsDirectory stringByAppendingPathComponent:#"LoadedURL.plist"]]){
[fm copyItemAtPath:[[NSBundle mainBundle] pathForResource:#"LoadedURL" ofType:#"plist"]
toPath:[documentsDirectory stringByAppendingPathComponent:#"LoadedURL.plist"]
error:nil];
}
// array from doc-dir file
NSMutableArray *ar=[NSMutableArray arrayWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:#"LoadedURL.plist"]];
// check weather file has url data or not.
BOOL fileLocallyAvailable=NO;
NSString *strLocalFileName=nil;
NSUInteger indexOfObject=0;
if([ar count]>0){
for (NSDictionary *d in ar) {
if([[d valueForKey:#"URL"] isEqualToString:strToLoad]){
fileLocallyAvailable=YES;
strLocalFileName=[d valueForKey:#"FileName"];
break;
}
indexOfObject++;
}
}
if(fileLocallyAvailable){
NSDictionary *d=[ar objectAtIndex:indexOfObject];
strLocalFileName=[d valueForKey:#"FileName"];
} else {
NSMutableDictionary *d=[NSMutableDictionary dictionary];
[d setValue:strToLoad forKey:#"URL"];
NSString *str=[[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:strToLoad]];
[str writeToFile:[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%02i.htm",[ar count]]]
atomically:YES
encoding:NSUTF8StringEncoding error:nil];
strLocalFileName=[NSString stringWithFormat:#"%02i.htm",[ar count]];
[d setValue:[NSString stringWithFormat:#"%02i.htm",[ar count]] forKey:#"FileName"];
[ar addObject:d];
[ar writeToFile:[documentsDirectory stringByAppendingPathComponent:#"LoadedURL.plist"]
atomically:YES];
}
NSURL *u=[[NSURL alloc] initFileURLWithPath:[documentsDirectory stringByAppendingPathComponent:strLocalFileName]];
NSURLRequest *re=[NSURLRequest requestWithURL:u];
[wView loadRequest:re];
[u release];
}
`