OSX Application, get file data that user selected using NSOpenPanel - objective-c

I am new to developing OSX Applications. I normally do iOS Apps, so alot of the concepts carry over. However, I cannot quite seem to figure out why I cannot retrieve the data of a file on my system.
Is there something that needs to be done first in order to read files on the users system?
Here is what I have:
- (IBAction)btnBrowse:(id)sender {
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel beginWithCompletionHandler:^(NSInteger result){
if (result == NSFileHandlingPanelOKButton) {
//Get the file url user selected
NSURL *file = [[panel URLs] objectAtIndex:0];
//Get the file data
NSError *error;
NSString *fileData = [NSString stringWithContentsOfFile:[NSString stringWithFormat:#"%#", file] encoding:NSUTF8StringEncoding error:&error];
//This returns null
NSLog(#"%#", fileData);
//This says that the file does not exist
NSLog(#"Error: %#", error.localizedDescription);
}
}];
}

NSOpenPanel returns NSURL objects, the easiest solution is to use the NSURL related API
NSString *fileData = [NSString stringWithContentsOfURL:file encoding:NSUTF8StringEncoding error:&error];
If you don't know the text encoding you could use this API, if the reading succeeds, encoding contains the used encoding.
NSStringEncoding encoding;
NSString *fileData = [NSString stringWithContentsOfURL:file usedEncoding:&encoding error:&error];

Use the -[NSURL path] method instead of calling 'file' directly, as it's a NSURL, not NSString.

Related

Using NSOpenPanel and copying selected file - Objective-C

I'm trying to create an app that will copy the selected sound file to the app's directory. To do it, I've written the following code :
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setCanChooseFiles:YES];
[openDlg setAllowsMultipleSelection:NO];
[openDlg setCanChooseDirectories:NO];
[openDlg setAllowedFileTypes:[NSArray arrayWithObjects:#"aif",#"aiff",#"mp3",#"wav",#"m4a",nil]];
if ( [openDlg runModalForDirectory:nil file:nil] == NSOKButton )
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dataPath = [[NSBundle mainBundle] bundlePath];
NSLog(#"Datapath is %#", dataPath);
NSLog(#"Selected Files : %#",[[openDlg URLs] objectAtIndex:0]);
if ([fileManager fileExistsAtPath:dataPath] == NO)
{
[fileManager copyItemAtPath:[[openDlg URLs] objectAtIndex:0] toPath:[[NSBundle mainBundle] bundlePath] error:&error];
NSLog(#"File copied");
}
}
The problems are that I can select each types of files (not only aif, wav, mp3 etc.) and I never get File copied. Although, the paths are correct. When I delete the if statement, I get an error saying : [NSURL fileSystemRepresentation]: unrecognized selector sent to instance 0x1005a0b90.
What's wrong in this code?
You're passing an NSURL to an API that expects a path in an NSString. You might consider using the URL-based API:
- (BOOL)copyItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error NS_AVAILABLE(10_6, 4_0);
Like this:
[fileManager copyItemAtURL: [[openDlg URLs] objectAtIndex:0] toURL: [NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]] error:&error];
Also, I'm guessing that the file has already been copied to the bundle since your description indicates that [fileManager fileExistsAtPath:dataPath] is returning NO (since your NSLog is never executed.) You can either check that manually, or you can ask the NSFileManager to delete any existing file before copying in a newly selected file.

Obj C Reading Files, txt file not found

I'm trying to read information from a text file in an Obj. C program and whenever I try to NSLog the output, I'm getting (null). I've made sure that the text files I'm working with are in my Copy Bundle Resources, which is what all of the other answers I've found have suggested. I'm using the following to access the files:
NSString *rightsPath = [[NSBundle mainBundle] pathForResource:#"Sample Maze Rights" ofType:#"txt"];
NSString *rightsContent = [NSString stringWithContentsOfFile:rightsPath encoding:NSUTF8StringEncoding error:NULL];
Can anyone make any suggestions?
That's what error argument is for.
NSError *error = nil;
NSString *rightsContent = [NSString stringWithContentsOfFile:rightsPath
encoding:NSUTF8StringEncoding
error:&error];
if (rightsContent == nil)
NSLog(#"error: %#", [error description]);

iOS - appending text to a file in the application bundle

I'm trying to append some text to a file that resides in the application bundle with the following code:
NSString *dotsStr = [NSString stringWithFormat:#"%i", dots];
NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%i_500", dots] ofType:#"txt"];
NSString *contents = [NSString stringWithContentsOfFile:path encoding:NSASCIIStringEncoding error:nil];
NSString *newpath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%i_50", dots] ofType:#"txt"];
[contents appendToFile:newpath encoding:NSASCIIStringEncoding];
When appending to the file, I'm using a category on NSString:
- (BOOL) appendToFile:(NSString *)path encoding:(NSStringEncoding)enc;
{
BOOL result = YES;
NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:path];
if (!fh)
{
[[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
fh = [NSFileHandle fileHandleForWritingAtPath:path];
}
if (!fh) return NO;
#try {
[fh seekToEndOfFile];
[fh writeData:[self dataUsingEncoding:enc]];
}
#catch (NSException * e)
{
result = NO;
}
[fh closeFile];
return result;
}
This is working fine on the simulator, however, when I restart the app, the old file gets loaded, without the appended text. I have no idea how this is possible.
Does anyone know how I could change this category so that the changes are persistent?
Thanks in advance! :)
You can't write to the app bundle.
(For quite obvious security reasons, by the way.)
If you're intending to change a file, copy it to a writable location, for example in the Documents directory.
(Oh, and before you ask it: the simulator uses OS X's file system, where this restriction is not present, so that's why it works on the simulator. Another thing the simulator fails to simulate.)
Application bundle is read-only. You need to copy your file to application's Documents directory before modifying it.

Writing to a file in Objective C

I'm just trying to write into a .txt file in Objective C. Here is the code:
BOOL success = [str writeToFile:#"tmp/cool.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error];
if(success)
{
NSLog(#"done writing!");
}
else
{
NSLog(#"writing failed: %#", [error localizedDescription]);
}
The output of this code is "The folder cool.txt does not exist". I dont understand this, since the ".txt" would deem it to be file.
What am I doing wrong?
I wrote a demo for you, assume that you use iOS.
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:#"tmp"]; //get tmp path
NSString *filePath = [path stringByAppendingPathComponent:#"cool.txt"];
NSString *str = #"hello world";
NSError *error;
[str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSString *str1 = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", str1);
Assume you use iOS as the platform...
You need to first get application's document directory so that you can write into that directory (you can use library or temporary directory but document directory is most common)
You have to make sure that 'tmp' directory exists under the document directory.

NSURL with http:// works fine but with ftp:// not

NSString *adress = [NSString stringWithFormat:#"ftp://%#:%##%#/%#x050-pegel.txt", benutzer.text, passwort.text, server.text, pfad.text];
NSURL *aURL = [[NSURL alloc]initWithString:adress];
NSString *theData = [NSString stringWithContentsOfURL:aURL];
textview.text = theData;
can some one help me please ?
AFAIK, FTP support is not part of the Cocoa frameworks. You could get more information by using +[NSString stringWithContentsOfURL:encoding:error:] and looking at the NSError object, like so:
NSError *error = nil;
NSString *theData = [NSString stringWithContentsOfURL:aURL encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
NSLog(#"received error: %#", error);
}
A quick google search for "cocoa ftp" shows that there are several approaches to connecting to an FTP server from Objective-C.