Declare String then open string from Path with Cocoa - cocoa

I've Declared a string Like so
NSString* fileName = [files objectAtIndex:i];
NSLog(fileName);
NSImage* imageFromBundle = [[NSImage alloc] initWithContentsOfFile:fileName];
and want to use that filename to open a file in a different directory.
I came up with this
NSImage* imageFromBundle2;
imageFromBundle2 = [[NSImage alloc] initWithContentsOfFile:#"/Users/rhaynes/Documents/works4/" filename ];
Any help would be appreciated

I'll assume that your fileName string is actually a file name, like "myImage.png". A lot of the Objective-C docs refer to a file name when they really mean file path - so sometimes it's confusing.
What you want to do is create an NSString that represents the complete path to the file you want to load. For instance, you could say:
NSString * path = [NSString stringWithFormat: #"/Users/rhaynes/Documents/works4/%#", fileName];
That line creates a new NSString using the format string and parameters provided (the %# in the format string indicates that the string value of fileName should be inserted there.) StringWithFormat is a really powerful function, so you should definitely check it out in the docs.
Then you could call initWithContentsOfFile:path, and it should give you the image you want.

NSString* fileName = [files objectAtIndex:i]; NSLog(fileName);
Don't pass non-hard-coded strings as format-string arguments. If they contain format specifiers, you'll get garbage or a crash. (Try this with fileName = #"foo%sbar", for example. Then try it with fileName = #"foo%fbar" for even more fun.)
Your NSLog statement should be:
NSLog(#"%#", fileName);
[I] want to use that filename to open a file in a different directory. I came up with this
NSImage* imageFromBundle2; imageFromBundle2 = [[NSImage alloc] initWithContentsOfFile:#"/Users/rhaynes/Documents/works4/" filename ];
You can only concatenate string literals this way; as you've no doubt seen for yourself, this is a syntax error when one of the strings isn't a literal.
First off, if fileName is actually a pathname, you'll need to use lastPathComponent to get the actual filename. So:
NSString *path = [files objectAtIndex:i];
NSString *filename = [path lastPathComponent];
Then, use stringByAppendingPathComponent: to tack this onto the new superpath.
NSString *desiredFilenamePath = [directoryPath stringByAppendingPathComponent:filename];
Now you have the pathname you wanted to pass to NSImage's initializer.

Related

Log File to NSString

I am using this to get the log files data:
NSFileHandle *file;
file = [NSFileHandle fileHandleForReadingAtPath:#"~/Library/Application Support/RepoManager/*.log"];
NSData *filedata;
filedata = [file readDataToEndOfFile];
NSString *logC;
logC = [[NSString alloc] initWithData:filedata encoding:NSASCIIStringEncoding];
And than write them using this:
NSString *formatString = #"Log: %#";
return [NSString stringWithFormat:formatString, *logC.stringValue];
But it says logC does not contain a string value
NSString does not define a .stringValue property, and even if it did, *logC.stringValue would have no useful meaning in Objective-C. logC itself is what you want to be using as your format parameter. (It's the string containing the contents of the log file.)

Reading a plist

I'm trying to read ~/Library/Preferences/com.apple.mail.plist (on Snow Leopard) to get the email address and other information to enter into the about dialog. I'm using the following code, which is obviously wrong:
NSBundle* bundle;
bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:#"~/Library/Preferences/com.apple.mail.plist" ofType:#"plist"];
NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSString *item = [plistData valueForKeyPath:#"MailAccounts.Item 2.AccountName"];
NSLog(#"Result = %#", item);
Moreover, the value I need to read is MailAcounts -> Item 2 -> AccountName and I am not sure I am doing this correctly (due to the space in the Item 2 key).
I tried reading Apple's developer guide to plist files but no help there.
How can I read a plist and extract the values as an NSString?
Thanks.
The first level is an array, so you need to use "MailAccounts.AccountName" and treat it as NSArray*:
NSString *plistPath = [#"~/Library/Preferences/com.apple.mail.plist" stringByExpandingTildeInPath];
NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSArray *item = [plistData valueForKeyPath:#"MailAccounts.AccountName"];
NSLog(#"Account: %#", [item objectAtIndex:2]);
Alternatively you can go by keys and pull the array from "MailAccounts" first using valueForKey: (which will yield NSArray*) and then objectAtIndex: to get the dictionary of that particular account (useful if you need more than the name).
Two things:
You don't want or need to use NSBundle to get the path to the file. The file lies outside of the app bundle. So you should just have
NSString *plistPath = #"~/Library/Preferences/com.apple.mail.plist";
You have to expand the tilde in the path to the user directory. NSString has a method for this. Use something like
NSString *plistPath = [#"~/Library/Preferences/com.apple.mail.plist" stringByExpandingTildeInPath];

cocoa format NSURL string for gmail atom feed

I'm trying to format a url string to retrieve a gmail atom feed but I'm having problems with it. Here's my code:
NSString *urlstring = [NSString stringWithFormat:#"https://%#:%##gmail.google.com/­gmail/­feed/atom", username, userpass];
NSString *encodedString = [urlstring stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:encodedString];
Here's what's in my log.
https://••••••••#gmail.com:•••••••••#gmail.google.com/%C2%ADgmail/%C2%ADfeed/atom
This-->%C2%AD seems to be the problem. It should just be a slash. Any idea how to clean that up? Thanks.
Short answer:
Your urlstring contains soft hyphens.
Comprehensive answer:
In the following code withSoftHyphens and withoutSoftHyphens look equal:
NSString *withSoftHyphens = #"example/­example/­example";
NSString *withoutSoftHyphens = #"example/example/example";
NSLog(#"%#",[withSoftHyphens stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]);
NSLog(#"%#",[withoutSoftHyphens stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]);
The output is however different:
(checkout yourself by copying and executing the code above)
"example/%C2%ADexample/%C2%ADexample"
"example/example/example"
The soft hyphens are basically represented by %C2%AD after encoding the string.
Quote from Wikipedia:
Soft hyphen is a type of hyphen used to specify a place in text where
a hyphenated break is allowed without forcing a line break in an
inconvenient place if the text is re-flowed.
In other words, your urlstring contains soft hyphens.
Simply remove /­g and /­f using the backspace key and type them again.
Notice you actually need THREE backspaces to only remove two characters (/­g).
- The first backspace removes the g.
- The second backspace removes the invisible soft hyphen.
- The third backspace removes the /.
In conclusion, your code works just fine after removing the soft hyphens:
NSString *username = #"Anne";
NSString *userpass = #"Password";
NSString *urlstring = [NSString stringWithFormat:#"https://%#:%##gmail.google.com/mail/feed/atom", username, userpass];
NSString *encodedString = [urlstring stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:encodedString];
NSLog(#"%#", url);
Output:
https://Anne:Password#gmail.google.com/mail/feed/atom

Separate filename from file extension Cocoa?

I am using the writeToFile:atomically: method to write some encrypted data to a text file. The problem is, the file it needs to be saved as must be the file the user encrypts, with the extension I choose. Here is what I have so far:
[encryptedData writeToFile:[[NSHomeDirectory() stringByAppendingPathComponent:#"Desktop"]
stringByAppendingPathComponent:#"encryptedfile.txt.kry"] atomically:YES];
^//fileName here
As you can see, the encrypted filename is hardcoded as encryptedfile.txt.kry. But say the user selects the file "test.avi" to encrypt, the encrypted file that is written to the desktop should be named test.avi.kry. So there should be ofType:, like in NSBundle. I know there are some NSString methods here that I can use, but have forgotten.
Thanks!
Can't you just append the .kry onto the filename?
If you have the path, and just want the filename, you can use - (NSString *)lastPathComponent:
NSString *filename = [filePath lastPathComponent];
[encryptedData writeToFile:[[NSHomeDirectory() stringByAppendingPathComponent:#"Desktop"]
stringByAppendingPathComponent:[filename stringByAppendingString:#".kry"] atomically:YES];
If you want the filename without the extension you can use - (NSString *)stringByDeletingPathExtension:
NSString *filename = [[filePath lastPathComponent] stringByDeletingPathExtension];

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