Path for downloads OSX 10.10.5 and xcode 7.2.1 - xcode

I made for our internal use a app with a today-extension. There I have access to download all files from our server. But I did not get the right path to save it. I want to save it in the users "downloads" or on the users "desktop".
My code to save the file is:
NSArray *docDirs = NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory,NSUserDomainMask, YES);
NSString *doc = [docDirs objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/Page1.pdf", doc];
dispatch_async(dispatch_get_main_queue(), ^{
[urlData writeToFile:filePath atomically:YES];
This saves the file
/Users/itsMe/Library/Containers/com.myCompany.downloadApp.ToDayWidget/Data/Downloads/Page1.pdf
I want to save the file in /users/itsMe/Downloads/Page1.pdf or /users/itsMe/Desktop/Page1.pdf.
How can I do this? I tried without success modifying the path:
NSString *homeDir = NSHomeDirectory();
NSString *homeDir1 = [homeDir stringByDeletingLastPathComponent];
NSString *homeDir2 = [homeDir1 stringByDeletingLastPathComponent];
NSString *homeDir3 = [homeDir2 stringByDeletingLastPathComponent];
NSString *homeDir4 = [homeDir3 stringByDeletingLastPathComponent];
NSString *filePath = [NSString stringWithFormat:#"%#/Page1.pdf", homeDir4];

To access the ~/Downloads folder add the com.apple.security.files.downloads.read-write entitlement by setting File Access > Downloads Folder in the Capabilities > App Sandbox section to Read/Write.
~/Desktop is not accessible outside the sandbox.

Related

How do I read from /Library/Application Support/ folder?

I am making a OX Cocoa app and I want to be able to read and write text files using the app on button press. These text files should be saved in /Library/Application Support/AppName but i can't get my app to reading anything from there. It can write to the folder, but not read what it has written there, even though I can see the file sitting there in finder.
Here is the code I am using the successfully write to the folder.
NSString *text = editor.string;
NSString *path = #"/Library/Application Support/";
NSMutableString *mu = [[NSMutableString stringWithString:path] init];
[mu insertString:FileName.stringValue atIndex:mu.length];
[mu insertString:#".txt" atIndex:mu.length];
path = [mu copy];
[text writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:NULL];
Here is the code I am using (and failing) to read from the text files.
NSArray *path = [[NSBundle mainBundle] pathsForResourcesOfType:#"txt" inDirectory:#"/Library/Application Support/"];
NSString *output = #"";
NSMutableString *mu = [[NSMutableString stringWithString:output] init];
for (int i = 0; i < [path count]; i++) {
NSString *text = [NSString stringWithContentsOfFile:path[i] encoding:NSUTF8StringEncoding error:NULL];
[mu insertString:text atIndex:mu.length];
[mu insertString:#"\n" atIndex:mu.length];
}
[textView setString:mu];
Any tips on what I can correct would be super helpful, I'm a bit stuck here.
Edit: Using your input I have updated my code to this:
NSString *fileLocation = #"~/Library/Application Support/";
NSArray *text = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fileLocation error:nil];
NSString *output = #"";
NSMutableString *mu = [[NSMutableString stringWithString:output] init];
for (int i = 0; i < [text count]; i++) {
[mu insertString:text[i] atIndex:mu.length];
[mu insertString:#"\n" atIndex:mu.length];
}
[textView setString:mu];
However the text from the files is still not appearing.
Most hard-coded paths will fail when you sandbox your app. Even if you get away with this one, or you don't plan to sandbox this app, it's a bad habit that's worth getting out of.
Moreover, are you sure you want /Library and not ~/Library? The former is often not writable by the user. The latter is in the user's Home directory (or your container when sandboxed).
To get the Application Support directory, or the Caches directory, or any other directory that you may want to create things in and later retrieve them from, ask a file manager for it.
/Library/Application Support is not in your bundle. The paths you get using [[NSBundle mainBundle] pathsForResourcesOfType:…] are only useful for accessing files inside your application itself (images, sounds, etc that you included when you built the app).
You want to use [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:error] to get a list of files in a directory outside your application.
Matt Gallagher has a great example of a fault-tolerant method of locating the path to your application support directory at Cocoa With Love. I would recommend using it over hardcoding the /Library/Application Support path.
NSError *error = nil;
NSArray *text = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fileLocation error:&error];
if (!text) {
NSLog( #"Error reading contents of application support folder at %#.\n%#", applicationSupportFolder, [error userInfo] );
}
You're trying to get the path using NSBundle from the main bundle of the app. But the file is not in the bundle, you should specify the path manually. You could hardcode the path, store previously written paths somewhere, or use NSFileManager to get directory contents and analyze it. For example, -[NSFileManager contentsOfDirectoryAtPath:error:].

how to play an audio file which is not in the main bundle?

this is my code to play mp3 file from the directory of the application, and for some reason it's not working. lease find out what's wrong with this code !
-(IBAction)PlayLesson:(id)sender;
{
NSString *folderAndFile = #"/Users/alaaalfadhel/Library/Application Support/iPhone Simulator/5.1/Applications/1021CF5B-F664-4123-B9CB-529217225B74/Documents/file.mp3";
NSString *audioFilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:folderAndFile];
NSURL *url = [NSURL fileURLWithPath:audioFilePath];
ofType:#"mp3"]];
AVAudioPlayer *click = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[click play];
}
Since the NSSearchPathForDirectoriesInDomains supplies everything up to the Documents directory, you don't need to give it a folder/file combination but just the file.
You really want your URL to be /Users/alaaalfadhel/Library/Application Support/iPhone Simulator/5.1/Applications/5515AFBA-1E7D-4B06-A62E-F6FDFD7DD7C7/Documents/file.m‌​p3 instead of the one displayed in your log. This is necessary because the long hex value will change any time you remove the app from the simulator and then launch it again.

make folder in sand box of osx

using the code below to get the file path:
NSString *executableName = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleExecutable"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
path = [path stringByAppendingPathComponent:executableName];
then I want to save data to the file (settings.bundle)
NSString *filePath = [path stringByAppendingPathComponent:#"settings.bundle"];
[someString writeToFile:settingsPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
the error:
Error Domain=NSCocoaErrorDomain Code=4 "The folder “settings.bundle” doesn’t exist." UserInfo=0x7ff8894cecc0 {NSFilePath=/Users/xxxx/Library/Application Support/AppName/settings.bundle, NSUserStringVariant=Folder, NSUnderlyingError=0x7ff8894a1750 "The operation couldn’t be completed. No such file or directory"}
but if I mkdir AppName manual there is no error:
mkdir /Users/xxxx/Library/Application Support/AppName
So My question is : Cocoa can NOT create folder automaticly in osx?
Give this a shot: [[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error];
That method will create not only the directory at the specified path, but also any intermediate ones that may not exist.

NSFileWriteNoPermissionError when trying to create a new directory in /Library/Application Support/

The following code returns a NSCocoaErrorDomain with error code 513 (NSFileWriteNoPermissionError) when running from xcode.
NSError *error;
[[NSFileManager defaultManager]
createDirectoryAtPath:#"/Library/Application Support/myapp"
withIntermediateDirectories:YES
attributes:nil
error:&error];
This is on a Mac OS X 10.6.7, the specified directory does not exist, and my user has admin privileges.
The purpose is to save application support files that are shared among users. Shouldn't there be write permissions to create this directory?
No, that's the system's Library folder. You need the user's Library, at "~/Library/". You could try:
[NSHomeDirectory() stringByAppendingPathComponent:#"Library/Application Support/myapp"]
or:
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString * appSupportPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"myapp"];
Just for one more option, you can also get a URL from the file manager:
NSFileManager * fm = [[NSFileManager alloc] init];
NSArray * urls = [fm URLsForDirectory:NApplicationSupportDirectory inDomains:NSUserDomainMask];
NSURL * appSupportURL = [urls objectAtIndex:0];

Use stringWithFormat: as a file path in cocoa

I'm having a problem with a cocoa application that takes the value of a text field, and writes it to a file. The file path is made using stringWithFormat: to combine 2 strings. For some reason it will not create the file and the console says nothing. Here is my code:
//Get the values of the text field
NSString *fileName = [fileNameTextField stringValue];
NSString *username = [usernameTextField stringValue];
//Use stringWithFormat: to create the file path
NSString *filePath = [NSString stringWithFormat:#"~/Library/Application Support/Test/%#.txt", fileName];
//Write the username to filePath
[username writeToFile:filePath atomically:YES];
Thanks for any help
The problem is that you have a tilde ~ in the path. ~ is expanded by the shell to the user's home directory, but this doesn't happen automatically in Cocoa. You want to use -[NSString stringByExpandingTildeInPath]. This should work:
NSString *fileName = [fileNameTextField stringValue];
NSString *username = [usernameTextField stringValue];
NSString *fileName = [fileName stringByAppendingPathExtension:#"txt"]; // Append ".txt" to filename
NSString *filePath = [[#"~/Library/Application Support/Test/" stringByExpandingTildeInPath] stringByAppendingPathComponent:fileName]; // Expand '~' to user's home directory, and then append filename
[username writeToFile:filePath atomically:YES];
Adding to mipadi's reply, it's better to use -[NSString stringByStandardizingPath] since it does more - and can clean up more problems - than resolving the tilde.

Resources