iPhone DrillDown - iphone

Hai all. 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(NSTemporaryDirectory()).
The problem is how to navigate the contents which I extracted in a tableView. If suppose, the extracted zip file contains folders, I should able to view them in a tableView. Actually the flow should be like a DrillDown.
I can able to extract the zip files, but problem is, have to navigate them in a tableView. Please give me some ideas or some source codes which helps my problem.
This is my didSelectRowAtIndexPath: part,
NSString *filePath = //filePath;
if([[NSFileManager defaultManager]fileExistsAtPath:filePath]) {
NSLog(#"File exists at path: %#",filePath);
} else {
NSLog(#"File does not exists at path: %#", filePath);
}
NSString *tmpDir =NSTemporaryDirectory();
ZipArchive *zip = [[ZipArchive alloc] init];
BOOL result = NO;
if([zip UnzipOpenFile:filePath]) {
//zip file is there
if ([zip UnzipFileTo:tmpDir overWrite:YES]) {
//unzipped successfully
NSLog(#"Archive unzip Success");
result= YES;
} else {
NSLog(#"Failure To Extract Archive, maybe password?");
}
} else {
NSLog(#"Failure To Open Archive");
}
if([[NSFileManager defaultManager]fileExistsAtPath:tmpDir isDirectory:&isDir] && isDir) {
NSLog(#"Its Folder");
//Prepare to tableview.
RootViewController *rvController =[[RootViewController alloc]initWithNibName:#"RootViewController"bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:rvController animated:YES];
}
But its not working. Its pushing the same contents in the document directory in the tableView
Please help me..
Thank you..

where do you tell your RootViewController to open a new path? For me it looks like you open the same RootViewController again with the old path so it's sure to open the same path again

You should add a property for setting the current file path to your controller class.
You can write a designated initializer like:
- (id)initWithDirectoryPath:(NSString*)path {
self = [super initWithNibName:#"DirectoryViewController" bundle:nil];
if (self != nil) {
self.directoryPath = path;
self.navigationItem.title = [path lastPathComponent];
}
}
Then you can create your view controller and push it on the navigation controller with:
DirectoryViewController *viewController = [[DirectoryViewController alloc] initWithDirectoryPath:path];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
Don't forget to release the VC!

Related

how to create folder on Google Drive using Google Drive SDK for iPhone?

I am using Google Drive SDK for iPhone and trying to upload Audio file in "TestAudio" folder.If "TestAudio" folder is not created at google drive then first create that folder and after that my audio should store to that folder only. Every thing is working gr8 except folder creation. can any buddy please help?
I am using below code for upload audio file.
GTLUploadParameters *uploadParameters = nil;
NSString *soundFilePath = [[NSBundle mainBundle]
pathForResource:#"honey_bunny_new"
ofType:#"mp3"];
if (soundFilePath) {
NSData *fileContent = [[NSData alloc] initWithContentsOfFile:soundFilePath];
uploadParameters = [GTLUploadParameters uploadParametersWithData:fileContent MIMEType:#"audio/mpeg"];
}
self.driveFile.title = self.updatedTitle;
GTLQueryDrive *query = nil;
if (self.driveFile.identifier == nil || self.driveFile.identifier.length == 0) {
// This is a new file, instantiate an insert query.
query = [GTLQueryDrive queryForFilesInsertWithObject:self.driveFile
uploadParameters:uploadParameters];
} else {
// This file already exists, instantiate an update query.
query = [GTLQueryDrive queryForFilesUpdateWithObject:self.driveFile
fileId:self.driveFile.identifier
uploadParameters:uploadParameters];
}
UIAlertView *alert = [DrEditUtilities showLoadingMessageWithTitle:#"Saving file"
delegate:self];
[self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFile *updatedFile,
NSError *error) {
[alert dismissWithClickedButtonIndex:0 animated:YES];
if (error == nil) {
self.driveFile = updatedFile;
self.originalContent = [self.textView.text copy];
self.updatedTitle = [updatedFile.title copy];
[self toggleSaveButton];
[self.delegate didUpdateFileWithIndex:self.fileIndex
driveFile:self.driveFile];
[self doneEditing:nil];
} else {
NSLog(#"An error occurred: %#", error);
[DrEditUtilities showErrorMessageWithTitle:#"Unable to save file"
message:error.description
delegate:self];
}
}];
I don't see your code to create a folder, but I was having the same problem with folder creation myself. As you know, the mimeType must be "application/vnd.google-apps.folder". I ran into assert failures if the NSData parameter to uploadParametersWithData was nil. So I tried a zero length NSData object and that failed. Using a 1 byte NSData object also failed. The trick is to call queryForFilesUpdateWithObject with uploadParameters:nil. Then the folder creation works fine. I also discovered that the Objective-C code shown at the end of:
https://developers.google.com/drive/v2/reference/files/insert
is incorrect. The file.parents should be as follows:
GTLDriveParentReference *parentRef = [GTLDriveParentReference object];
parentRef.identifier = parentID;
if (parentID.length>0) file.parents = [NSArray arrayWithObjects:parentRef,nil];

Can't use core database in IOS5

I am working with a core database, it is working in IOS 6 but when I trying to test it on IOS 5. It does not do anything. Let me explain what I'm doing.
First I do this in my viewWillAppear.
- (void)viewWillAppear:(BOOL)animated
{
NSLog(#"view appeared");
[super viewWillAppear:animated];
if (!self.genkDatabase) {
NSLog(#"comes to here");
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:#"Default appGenk Database2"];
// url is now "<Documents Directory>/Default Photo Database"
self.genkDatabase = [[UIManagedDocument alloc] initWithFileURL:url]; // setter will create this for us on disk
NSLog(#"database created on disk");
}
}
Then it comes in the UseDocument method.
- (void)useDocument
{
NSLog(#"Comses in the use document");
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.genkDatabase.fileURL path]]) {
// does not exist on disk, so create it
[self.genkDatabase saveToURL:self.genkDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
NSLog(#"create");
[self setupFetchedResultsController];
[self fetchGenkDataIntoDocument:self.genkDatabase];
}];
} else if (self.genkDatabase.documentState == UIDocumentStateClosed) {
NSLog(#"closed news");
// exists on disk, but we need to open it
[self.genkDatabase openWithCompletionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
} else if (self.genkDatabase.documentState == UIDocumentStateNormal) {
NSLog(#"normal");
// already open and ready to use
[self setupFetchedResultsController];
}
}
And finally it goes into the setDatabase Method.
- (void)setGenkDatabase:(UIManagedDocument *)genkDatabase
{
if (_genkDatabase != genkDatabase) {
_genkDatabase = genkDatabase;
[self useDocument];
}
NSLog(#"Comes in the setdatabase methode.");
}
Doing all this gives the following log.
2012-10-22 10:42:47.444 RacingGenk[4786:c07] view appeared
2012-10-22 10:42:47.445 RacingGenk[4786:c07] comes to here
2012-10-22 10:42:47.459 RacingGenk[4786:c07] Comses in the use document
2012-10-22 10:42:47.460 RacingGenk[4786:c07] Comes in the setdatabase methode.
2012-10-22 10:42:47.461 RacingGenk[4786:c07] database created on disk
Like you can see it does not print the create log in my use document. So it isn't able to execute the method FetchDataIntoDocument.
Can anybody help me with this problem. I am searching at this problem for ages for now.
Many thanks in advace.
Stef
Are you testing with the simulator or on the device?
The simulator is case-insensitive - the device is case-sensitive on file access, remember that!
But beside from that the documentation for NSFileManager recommends not checking to see if files exist, and instead just trying to read the file and handle any errors gracefully (e.g. file not found error). So just try loading the file instead of checking to see if it exists.
And i don't see any file extension for your database file! It just states ""Default appGenk Database2".
Is this already the file name or jut another subdirectory so far?
EDIT:
You can try the following code:
- (void) setupStore {
NSString* storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"mydatabase.sqlite"];
// Set up the store.
NSFileManager* fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, create one.
if (![fileManager fileExistsAtPath: storePath]) {
// create your store here!
}
}
- (NSString*) applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
"mydatabase.sqlite" is the name of the database-file you expect to be present in your documents directory.
If you would like to see a full-fledged example on how to set-up a core data persistent store you could check out apples own iPhoneCoreDataRecipes example. Just take a look at the
RecipesAppDelegate.m
implementation.

Would like to keep cache data when changing to other UIView

i would love to have some help or any keyword that i can use to search for.
My problem is I have one UIView, called "UpdateViewController.xib" that load 20 small images and text below those images by programmatically.
and when user click on those images it will change to next view that i created by IB, called "imageSumVuew.xib" and i have a button to link back to UpdateViewController.
#import "imageSumView.h" // next view that i wanna load//
// the transition to next view
imageSumView *nextView = [[imageSumView alloc]init];
self.modalPresentationStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:nextView animated:YES completion:NULL];
[nextView release];
in the nextView i have code similar to this which come back to this view
#import "UpdateViewController.h" // old that i wanna load back//
// the transition to old view
UpdateViewController *oldView = [[UpdateViewController alloc]init];
self.modalPresentationStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:oldView animated:YES completion:NULL];
[oldView release];
the problem is when it did load back to UpdateViewController, all my images and text has to reload all over again.
The question is " how can i keep cache of the UpdateViewController view?", i don't want user to reload images all over again because they have to go back and forth between this page for several times to see which image that they wanna pick.
Think of Instragram that you see list of your friends images then you wanna check your first friends's photo and after that you come back to overall image of your friends without loading and choose second friends.
Store image data with unique id to temporary directory once it is downloaded for the first time. For the next time check for that user id's image in your directory, if it is there then load image from there. For example :
#define TMP NSTemporaryDirectory()
NSString *filename=[NSMutableString stringWithFormat:#"userimage_%#",userId];
NSString *uniquePath = [TMP stringByAppendingPathComponent:filename];
NSData *dataImage = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]]
UIImage *image = [[UIImage alloc] initWithData: dataImage];
[UIImageJPEGRepresentation(image, 1.0f) writeToFile: uniquePath atomically: YES];
[image release];
To get ur image you can do something like below:
- (NSData *) getImage: (NSString *)userId
{
NSString *filename=[NSMutableString stringWithFormat:#"userimage_%#,userId];
NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];
if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
return [[NSData alloc] initWithContentsOfFile:uniquePath];
}
return nil;
}

iPhone - tracking back button

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.
Oh ya, thats quite simple:
in LoadView,
self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:self
action:#selector(backButtonHit)];
-(void)backButtonHit
{
// removeItemAtPath: newFilepath stuff here
[self.navigationController popViewControllerAnimated:YES];
}

How to call a method on background thread

in my app i am unzipping a zip file(in splash view controller) later i am displaying an image and firing a timer with 4 secs to change image of the previous image view. and later in view did appear i am firing another timer with 10 secs to call next view controller(home view controller).. and there i have a button to go Story view controller...in this i am using the unzipped data...its taking some time to unzip in this case. so the images r displaying later a few seconds...it fine here
the problem is... i called the unzipping on background thread so its displaying the images quickly and its moving to home view controller..while going to next view controller by clicking a button its crashing on device but its working fine in simulator..
can any body help me out please
Thanks.
code...
-(void)viewWillAppear:(BOOL)animated{
[self performSelectorInBackground:#selector(unXip) withObject:nil];
CGRect imageFrame = CGRectMake(0,20,320,460);
splashView.frame = imageFrame;
splashView.image = [UIImage imageNamed:#"Default.png"];
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(changeImg) userInfo:nil repeats:NO];
[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(changeImg2) userInfo:nil repeats:NO];
}
-(void)unXip{
self.fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
self.documentsDir = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/temp", self.documentsDir];
NSString *filePathbmlg = [NSString stringWithFormat:#"%#/temp/bmlg", self.documentsDir];
NSString *updateURL = [[NSBundle mainBundle] pathForResource:#"bmlg" ofType:#"zip" inDirectory:#"res"];
[fileManager createDirectoryAtPath:filePath
withIntermediateDirectories:NO
attributes:nil
error:nil];
if([fileManager fileExistsAtPath:filePath]) {
NSLog(#"File exists at path: %#", updateURL);
} else {
NSLog(#"File does not exists at path: %#", updateURL);
}
NSLog(#"Checking update at : %#", updateURL);
NSLog(#"Checking filepath at : %#", filePath);
if(![fileManager fileExistsAtPath:filePathbmlg]) {
ZipArchive *zipArchive = [[ZipArchive alloc] init];
if([zipArchive UnzipOpenFile:updateURL]) {
if ([zipArchive UnzipFileTo:filePath overWrite:YES]) {
//unzipped successfully
NSLog(#"Archive unzip Success");
//[self.fileManager removeItemAtPath:filePath error:NULL];
} else {
NSLog(#"Failure To Unzip Archive");
}
} else {
NSLog(#"Failure To Open Archive");
}
[zipArchive release];
}
}
- (void)changeImg{
splashView.image = [UIImage imageNamed:#"screen2.png"];
}
- (void)changeImg2{
splashView.image = [UIImage imageNamed:#"screen3.png"];
}
- (void)viewDidAppear:(BOOL)animated{
[NSTimer scheduledTimerWithTimeInterval:15 target:self selector:#selector(pushCVC) userInfo:nil repeats:NO];
}
- (void)pushCVC{
homeViewController = [[HomeViewController alloc] initWithNibName:#"HomeView" bundle:nil];
[self presentModalViewController:homeViewController animated:YES];
}
It's kind of hard to answer this witout any sample code. One thing to be aware of when using background threads is to make sure that all code that updates the UI runs on the main thread.
Ok, I think this is probably a threading issue. Your unXip method is modifying something on a background thread and then you try to access that "something" from another thread (main thread if you access it from UI code). You need to implement some kind of locking/synchronization mechanism (e.g. NSLock or NSConditionLock).
It looks a bit strange that you are using a timer to call pushCVC. Now, I don't know exactly what your app does but wouldn't it be better to call pushCVC when the unzip has finished by adding this to the end of your unXip method:
[self performSelectorOnMainThread:#selector(pushCVC) withObject:nil waitUntilDone:NO];
and removing the timer.
thanks for your comments and answers....
The problem is the unzipping process is taking a long time...so if i click start button on the home screen before the completion of the unzipping the file, its crashing...because i have to use the data from unzipped file...
Thanks again..