Resolve real path in NSString, without ".." (previous directory references) - objective-c

OK, let me explain...
I have an NSString and a path stored in it, like this (as weird as it may look) :
/A/B/C/../D/../E/F
which is practically the same as :
/A/B/E/F
What I want is to convert the first path format (with the ..s in it) the the second format.
Is there any built-in Cocoa function for something like that?
Any ideas?

Just found it! :-)
-(NSString *)stringByStandardizingPath;
Returns a new string made by removing extraneous path components from
the receiver.
NSString class reference.

Related

Define global constant with username in Obj-C

I want to define a constant file path that includes whoever's username (e.g. /Users/username/Desktop...in my specific case it's a directory I create at /var/spool/FolderICreate/username).
What's the best way of declaring this constant so my other classes can recognize it? I currently have a globals.h file to include for the classes that need to see the globals, but I'm not sure how to set the value. #define obviously needs a hardcoded string literal, and I'm not sure if I can or how I would set the string using extern const NSString*. I feel like this shouldn't be hard, but I'm at a loss.
-- EDIT --
As people have rightly pointed out, my code was unnecessary because I can get the username with NSUserName, etc, so I've removed it. But I think people are missing the point of my question. I can see there are multiple ways to get the pathname I want--how do I declare that as a constant?
To your revised question, as Kaelin notes, you don't want a constant. A constant in C is something defined at compile time, and you don't know what the value is at compile time.
You don't want a variable for this problem. You want a static function. Foundation provides many that do things similar to what you want. If you want something else, make your own static function MYDirectoryForStuff().
Do not create non-constant global variables. That way lies madness. You then have to verify that they get initialized before they are used, which leads to all kinds of subtle bugs. If you use a static function, then it can easily be self-initializing.
Have a look at NSPathUtilities before you re-implement a bunch of functionality that's already provided in Foundation framework. You'll find a bunch of methods there specifically for what you're trying to do.
To answer the question you actually asked, there's no straightforward way to declare a variable as a constant and then change its value at runtime... That sort of defeats the purpose of telling the compiler it's constant. Simply declare the variable in a header file as an extern NSString * and only set it once. :-)
You should never make any assumptions about where the user's home folder might be.
The correct way to retrieve the path to the current user's home folder is
NSHomeDirectory()
If you wish to access one of the standard subfolders of the user's home folder, don't make any assumption about their location either, but use
NSSearchPathForDirectoriesInDomain()
to retrieve them. For example, to get the documents folder:
NSArray *searchPaths = NSSearchPathForDirectoriesInDomain(
NSDocumentDirectory,
NSUserDomainMask,
YES
);
NSLog(#"The documents folder is at %#", [searchPaths objectAtIndex:0]);
The Foundation framework has a function for this: NSUserName().

NSBundle returning NULL

I have been using pathForResource for a while but suddenly its giving up on me.
I have added an additional file to my resources called untitled.obj and untitled.mtl.
And following two lines of code:
NSString *path = [[NSBundle mainBundle] pathForResource:#"untitled" ofType:#"obj"];
NSLog(#"thePath = %#", path);
All other *.obj files work fine, except untitled.obj.
The output from NSLog is nothing when i use that file, so i assume its unable to find it for some reason.
The resource is also located in the temp. simulation library:
Delete the app from your device and reset contents and settings in the simulator. Also delete Derived Data of the project. After you do that, test again and it should work.
Everything looks correct to me. Have you checked that you haven't accidentally named the file with a trailing space or other invisible character? Try naming it something entirely different (including changing the extension) and then renaming it back.
I think you need the .plist file. There you have the Bundle name and identifier.

Get text after certain point using NSString

I am getting a url of a file when a user opens one from an NSOpenPanel for example like so:
/Users/Name/Documents/MyFile.png
So I just want this bit:
MyFile.png
However the user could have a file name of any length so how can I say, only get the string after the last forward slash (/)? I just want to get the file name.
NSString *fileName = [someStringContainingAPath lastPathComponent];
More general advice: spend a little time reading through the reference pages for NSString and NSString(UIStringDrawing). There are a lot of useful methods in there that you might not otherwise know to look for. In addition to -lastPathComponent demonstrated above, there's -pathComponents, -componentsSeparatedByString:, and many other handy tools.

What is the proper way to declare a function for use, from a 3rd party class?

I'm trying to utilize a class from the Google Toolbox for Mac libraries, for unescaping HTML text. Specifically, I'm using GTMNSString+HTML.h and GTMNSString+HTML.m.
Where I'm trying to escape the text, I'm doing this:
NSString *escaped = [ gtm_stringByEscapingForHTML:_item.body ];
But when I try to compile I'm getting an error:
'gtm_stringByEscapingForHTML' undeclared (first use in this function)
I understand that this means I need to declare something earlier in my file, but I'm not sure where, and beyond that what the syntax would be.
Any help is greatly appreciated, thank you.
First, make sure you're including GTMNString+HTML.h in your implementation file.
#include "GTMNSString+HTML.h"
Second, that file defines a category on NSString, so it's methods become methods of NSString objects. You would invoke it like this:
// Assuming body is of type NSString *
NSString *escaped = [_item.body gtm_stringByEscapingForHTML];
You can learn more about categories here: https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCategories.html.

Objective-C: Extract filename from path string

When I have NSString with /Users/user/Projects/thefile.ext I want to extract thefile with Objective-C methods.
What is the easiest way to do that?
Taken from the NSString reference, you can use :
NSString *theFileName = [[string lastPathComponent] stringByDeletingPathExtension];
The lastPathComponent call will return thefile.ext, and the stringByDeletingPathExtension will remove the extension suffix from the end.
If you're displaying a user-readable file name, you do not want to use lastPathComponent. Instead, pass the full path to NSFileManager's displayNameAtPath: method. This basically does does the same thing, only it correctly localizes the file name and removes the extension based on the user's preferences.
At the risk of being years late and off topic - and notwithstanding #Marc's excellent insight, in Swift it looks like:
let basename = NSURL(string: "path/to/file.ext")?.URLByDeletingPathExtension?.lastPathComponent