I am trying to get path of legal.txt in my project. However, whatever I do. I am getting a null path back. it is in the Policies directory. How do I get it's path as a string. I need to send that path to a webview controller. Can someone help.
-(void)linkPressedOnTextView:(PPLinksTextView *)tv url:(NSURL *)url{
if ([url.host isEqualToString:#"sign_up"]) {
GetStartedController *getStartedVC = [[GetStartedController alloc] init];
[self.navigationController pushViewController:getStartedVC animated:YES];
}
else if([url.host isEqualToString:#"consentMedicalSevices"]){
PPNavigationViewController *vc = [[PPNavigationViewController alloc]init];
[vc openPolicies:#"Policies/privacy.txt"];
Will this work. I need a way to direct user to a webview once he clicks on the link and privacy text opens up.
From apple doc:
pathForResource:ofType:inDirectory:
Returns the full pathname for the resource file identified by the specified name and extension and residing in a given bundle directory.
NSString *filePath = [NSBundle pathForResource:#"file" ofType:#"txt" inDirectory:[[NSBundle mainBundle] bundlePath]];
NSLog(#"File Path: %#", filePath);
Output:
File Path: /Users/Ashok/Library/Developer/CoreSimulator/Devices/F629F99F-C745-46EB-8A11-01BC9FF1E592/data/Containers/Bundle/Application/EB4EA25F-65E6-4CA8-B8C2-C7C0C64C6C0F/Sample.app/file.txt
Related
I use this code to save some PDF data to a file, send it to another app using the "Open In" menu, then delete the file when that's done:
- (void)openIn:(NSData *)fileData {
// save the PDF data to a temporary file
NSString *fileName = [NSString stringWithFormat:#"%#.pdf", self.name];
NSString *filePath = [NSString stringWithFormat:#"%#/Documents/%#", NSHomeDirectory(), fileName];
BOOL result = [fileData writeToFile:filePath atomically:TRUE];
if (result) {
NSURL *URL = [NSURL fileURLWithPath:filePath];
UIDocumentInteractionController *controller = [[UIDocumentInteractionController interactionControllerWithURL:URL] retain];
controller.delegate = self;
[controller presentOpenInMenuFromBarButtonItem:self.openInButton animated:TRUE];
}
}
- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller {
// when the document interaction controller finishes, delete the temporary file
NSString *fileName = [NSString stringWithFormat:#"%#.pdf", self.name];
NSString *filePath = [NSString stringWithFormat:#"%#/Documents/%#", NSHomeDirectory(), fileName];
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
}
This has worked fine until iOS 8. Now, the file is created and I can verify that it contains the correct content, the Open In menu appears, I can select an app, and the delegate method runs and cleans up the file. But instead of iOS switching to the selected app and copying the file into it as it did before, the Open In menu simply closes when I select an app, and the file is not copied.
This works if I give the UIDocumentInteractionController an existing file. It also works if I use the provided fileData but change the destination filename to the filename of an existing file. This suggests a permissions problem -- as if new files are created in iOS 8 with default permissions that UIDocumentInteractionController can't read.
Does anyone know what's happening and how I can work around it?
It looks like the order of operations has changed slightly in iOS 8. DidDismissOpenInMenu used to run after the file was finished sending, but now it runs after the file begins sending. This means my cleanup code was sometimes running before the file was finished sending, leaving no file to send. I figured this out after noticing that smaller files were being sent okay; apparently the processing for smaller files was finishing before my cleanup code got them, but the processing for larger files was not.
To ensure the correct timing, but also clean up files that are created when the user opens the DocumentInteractionController and then dismisses the controller without doing anything, I changed my methods like this:
- (void)openIn:(NSData *)fileData {
// save the PDF data to a temporary file
NSString *fileName = [NSString stringWithFormat:#"%#.pdf", self.name];
NSString *filePath = [NSString stringWithFormat:#"%#/Documents/%#", NSHomeDirectory(), fileName];
BOOL result = [fileData writeToFile:filePath atomically:TRUE];
if (result) {
self.sendingFile = FALSE;
NSURL *URL = [NSURL fileURLWithPath:filePath];
UIDocumentInteractionController *controller = [[UIDocumentInteractionController interactionControllerWithURL:URL] retain];
controller.delegate = self;
[controller presentOpenInMenuFromBarButtonItem:self.openInButton animated:TRUE];
}
}
- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application {
// the user chose to send the file, so we shouldn't clean it up until that's done
self.sendingFile = TRUE;
}
- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller {
if (!self.sendingFile) {
// the user didn't choose to send the file, so we can clean it up now
[self openInCleanup];
}
}
- (void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application {
// the user chose to send the file, and the sending is finished, so we can clean it up now
[self openInCleanup];
self.sendingFile = FALSE;
}
- (void)openInCleanup {
// delete the temporary file
NSString *fileName = [NSString stringWithFormat:#"%#.pdf", self.name];
NSString *filePath = [NSString stringWithFormat:#"%#/Documents/%#", NSHomeDirectory(), fileName];
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
}
Update for iOS 11
Before iOS 11, it seems that the operating system kept a copy of the file available until the receiving app was finished reading it, even though my cleanup function ran as soon as the file was sent out from my app. In iOS 11, this changed and the receiving app fails to read the file because my app deletes it before that's done. So now instead of saving the temporary file to Documents and using the openInCleanup method to delete it immediately, I'm saving the temporary file to tmp and emptying the tmp folder next time the app launches. This approach should also work with older iOS versions. Just remove openInCleanup, change Documents to tmp in the paths, and add this to applicationDidFinishLaunching:
// clear the tmp directory, which will contain any files saved for Open In
NSString *tmpDirectory = [NSString stringWithFormat:#"%#/tmp", NSHomeDirectory()];
NSArray *tmpFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:tmpDirectory error:NULL];
for (NSString *tmpFile in tmpFiles) {
[[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:#"%#/%#", tmpDirectory, tmpFile] error:NULL];
}
After reading this post, I already hoped to have found the solution to a similar problem:
For me, as of iOS 8, sharing was only working with Mail.app. It was failing for Dropbox, etc.
Turns out it was something else:
On my interactionController I was setting an annotation like this:
interactionController.annotation = #"Some text"
For unknown reasons, this prevented Dropbox to open at all. There were no error messages or anything. Removing this line solved the issue.
I have made an app that creates a pdf and stores it in the apps documents folder. I would now like to open it and view it from within the app when a 'View pdf' UIButton is pressed.
I have already looked at a few questions on here and I have considered either a separate view controller or perhaps a scroll view.
What is the best method to use?
UPDATE:
I have followed advice and I am trying to use QLPreviewController. I have added QuickLook framework and now have the following, but I am stuck on how to get the path recognised in the pathForResource. Any suggestions?
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller
{
return 1;
}
- (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
NSString *path=[[NSBundle mainBundle] pathForResource:[pdfPathWithFileName] ofType:nil];
return [NSURL fileURLWithPath:path];
}
- (IBAction)viewPdfButton:(id)sender {
NSString *filename= #"ObservationPDF.pdf";
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documnetDirectory = [path objectAtIndex:0];
NSString *pdfPathWithFileName = [documnetDirectory stringByAppendingPathComponent:filename];
[self generatePdf: pdfPathWithFileName];
QLPreviewController *previewController=[[QLPreviewController alloc]init];
previewController.delegate=self;
previewController.dataSource=self;
[self presentViewController:previewController animated:YES completion:nil];
}
If the PDF file is in the app documents folder then you shouldn't be thinking about passing it to another app, you should be looking to present the file inside the app. 2 general options:
Add a UIWebView and load the local file into it
Use QLPreviewController to show a new view containing the PDF
The web view is simple and requires no transition on the UI. The preview controller needs a transition but offers some sharing / printing support for free.
This line is confused (and invalid syntax by the looks of it):
NSString *path=[[NSBundle mainBundle] pathForResource:[pdfPathWithFileName] ofType:nil];
You only use NSBundle to get items out of the bundle, and that isn't what you have. You should just be creating the URL with the file path where you save the file:
[NSURL fileURLWithPath:pdfPathWithFileName];
(which you may store or you may need to recreate in the same way as when you save the file)
I was reading about Plist just before and I saw this Bit of code:
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"projects" ofType:#"plist"];
projects = [NSArray arrayWithContentsOfFile:path];
}
Now I've been manually putting in the file path of my property list, I'm curious is this the correct way to universally find the file path?
if so could someone please explain how it works to me, thanks.
Yes, for getting the file from your Main resources bundle.
For getting the resource path from you application document directory you can try like
/**
Returns the URL to the application's Documents directory.
*/
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
which could be use like
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"yourFile.ext"];
Yes this is the right way and its self explanatory too..first step you find the path of plist file and by then you are populating an array with the contents of plist file. If you use mutable array instead of array you can also edit the plist file and save back
I want to start off by saying that this block of code worked before the implementation and roll out of iOS 7.
Basically I have a file name that I'm looking for in the NSCachesDirectory, so I create a URL object as my search item. Then I enumerate the directories (using the same NSFileManager object) and look for file names that equal each other, and that's how I know the file exists.
+ (BOOL)itemExistsInMemory:(NSString *)itemName
{
BOOL itemExists = NO;
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSArray *mySandboxDirs = [fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask];//get the directories for the application
NSURL *searchForURL = [[mySandboxDirs lastObject] URLByAppendingPathComponent:[NSString stringWithFormat:#"%#%#", itemName, FileNameAppendix]];//look for the specific file
NSArray *enumerator = [fileManager contentsOfDirectoryAtURL:[mySandboxDirs lastObject] includingPropertiesForKeys:[NSArray arrayWithObjects:NSURLNameKey, NSURLIsRegularFileKey, NSURLCreationDateKey, nil] options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];
for(NSURL *url in enumerator)
{//find out if any of the URLs within the NSCachesDirectory match what we're looking for
NSNumber *isRegularFile = nil;
[url getResourceValue:&isRegularFile forKey:NSURLIsRegularFileKey error:NULL];
if([isRegularFile boolValue])
{
if([url relativeString] isEqualToString:[searchForURL relativeString]])
{
itemExists = YES;
break;
}
}
}
return itemExists;
}
The file DOES INDEED EXIST in the NSCachesDirectory, however, the code doesn't find it because the searchForURL object was created without a path component (the path component is private/...). Why? Even stranger is that I save the data to a URL that's created with the
[[mySandboxDirs lastObject] URLByAppendingPathComponent:[NSString stringWithFormat:#"%#%#", itemName, FileNameAppendix]];
instruction! So it doesn't include the private/ path component in the URL, but when I write the data with [NSData writeToURL:] it "redirects" it to the private/ directory.
So why can't [NSFileManager URLsForDirectory: inDomains:] get me the correct directories for NSCachesDirectory?
More info moved from the comment for better formatting:
By the way, here's an example of what's contained in the URLs I'm creating and looking for ->
When I create a URL for saving:
file:///var/mobile/Applications/C63B378E-5EBE-417C-A465-8C3A3DCE013A/Library/Caches/Experimental%20Post.cnt
When I create a URL for searching:
file:///var/mobile/Applications/C63B378E-5EBE-417C-A465-8C3A3DCE013A/Library/Caches/Experimental%20Post.cnt
What the enumerator sees:
file:///private/var/mobile/Applications/C63B378E-5EBE-417C-A465-8C3A3DCE013A/Library/Caches/Experimental%20Post.cnt
I could simply take the URLs that the enumerator comes up with and remove the "private" part of the URL so that the strings match and I can proceed, but I'd like to understand why this is happening. Please also note that this only happens when you put the app on an iDevice since the directories are different than when you simulate it with the iOS Simulator.
Thanks to anyone that can be of assistance.
/var is a symlink to /var/private, use [NSURL URLByResolvingSymlinksInPath] to resolve the symlink.
In your example:
for(NSURL *url in enumerator) {
NSURL *resolvedSymlinksURL = [url URLByResolvingSymlinksInPath];
...
}
More detailled discussion: What does the /private prefix on an iOS file path indicate?
in the for loop, see if the url object have some return characters (like \r or \n) and remove it before proceeding.
I use vfr/reader to open PDF files. When I open first PDF file my app opens it correctly but when I open another one, my app opens the first file again.
This is my function to read PDF file
-(void)readIssue:(IssueMath *)issue {
NSString *filePath = [[issue.contentURL path] stringByAppendingPathComponent:#"Mathematics.pdf"];
NSLog(#"Read Path 1: %# ",filePath);
ReaderDocument *document = [ReaderDocument withDocumentFilePath:filePath password:nil];
NSLog(#"Read Path 2: %# ",document.fileURL);
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self; // Set the ReaderViewController delegate to self
readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentModalViewController:readerViewController animated:YES];
}
And this is NSLog output:
2012-11-02 20:09:31.081 MAGAZINE[314:15203] Read Path 1: /Users/eakmotion/Library/Application Support/iPhone Simulator/5.0/Applications/EC25BC08-E1E7-44B6-9AD8-0A321EEAC8B6/Library/Caches/ISSUE3_2011/Mathematics.pdf
2012-11-02 20:09:31.109 MAGAZINE[314:15203] Read Path 2: file://localhost/Users/eakmotion/Library/Application%20Support/iPhone%20Simulator/5.0/Applications/EC25BC08-E1E7-44B6-9AD8-0A321EEAC8B6/Library/Caches/ISSUE2_2011/Mathematics.pdf
I want to read "ISSUE3_2011/Mathematics.pdf" but app still reads first path "ISSUE2_2011/Mathematics.pdf"
Why filePath is still the same?
How can I solve this problem?
Yeah your solution works but if you want to keep track of your all pdf documents (ex. current page no)
You have to give unique names for your local pdf files.. Because it will search for Mathematics.plist file on local device folder to read the current page number..
/Users/eakmotion/Library/Application Support/iPhone Simulator/5.0/Applications/EC25BC08-E1E7-44B6-9AD8-0A321EEAC8B6/Library/Caches/ISSUE3_2011/Mathematics.pdf
file://localhost/Users/eakmotion/Library/Application%20Support/iPhone%20Simulator/5.0/Applications/EC25BC08-E1E7-44B6-9AD8-0A321EEAC8B6/Library/Caches/ISSUE2_2011/Mathematics.pdf
these files are looking for the same Mathematics.plist file
in the class ReaderDocument "unarchiveFromFileName" method
NSString *archivePath = [ReaderDocument applicationSupportPath]; // Application's "~/Library/Application Support" path
NSString *archiveName = [[filename stringByDeletingPathExtension] stringByAppendingPathExtension:#"plist"];
try to modify this code section or give your files unique names like Mathematics_ISSUE3_2011.pdf and Mathematics_ISSUE2_2011.pdf
I know this question is quite a few months old, but just in case anyone is experiencing this same issue (as myself), I have found a solution for it.
In the vfr/Reader's source, locate the Sources/ReaderDocument.m file, and look for a function named + (ReaderDocument *)withDocumentFilePath:.
There, comment out the conditional which prevents the document from reloading as shown below.
+ (ReaderDocument *)withDocumentFilePath:(NSString *)filePath password:(NSString *)phrase
{
ReaderDocument *document = nil; // ReaderDocument object
document = [ReaderDocument unarchiveFromFileName:filePath password:phrase];
//if (document == nil) // Unarchive failed so we create a new ReaderDocument object
//{
document = [[ReaderDocument alloc] initWithFilePath:filePath password:phrase];
//}
return document;
}
This was my quick and dirty approach to get documents to reload. The caveat to this solution is that the pdf reader won't keep track of where you left off in your pdf pages, which in my app, was not of importance.
I was facing the same problem and found following solution:
// Path to first PDF file
NSString *filePath =
[[NSBundle mainBundle] pathForResource:#"someBookeName" ofType:#"pdf"];
Just change the file path like shown above. As you can see, now you don't need NSArray * PDF.