NSURL path vs absoluteString
Question 1:
What is the actual difference between these methods?
Let's analyze this writing 6 lines of code - 3 for a local and 3 for http URL - and playing around with them a little bit.
Let's create an NSURL
using the file://
scheme. If you ask yourself why there are 3 /
after file:
you should remember that a complete URL exists of a scheme (file://
and absolute or relative path (you can find more information on creating URLs in RFC 1808 on page 3). We use an absolute path which starts with a /
so that we end up with ///
.
NSURL *aLocalURL = [NSURL URLWithString:@"file:///Users/dennis/Desktop/"];
NSLog(@"absolute string: %@", aLocalURL.absoluteString);
NSLog(@"path: %@", aLocalURL.path);
Output:
absolute string: file:///Users/dennis/Desktop/
path: /Users/dennis/Desktop
So we see that absoluteString
still knows its scheme whereas path
doesn't have this information anymore.
Note: path
is a file (directory) URL and as the docs state, the trailing slash it is stripped.
Now let's take a look at remote URLs. With these type of URLs most people are more familiar. We create it using the same procedure as for local URLs. Our scheme is now http://
and our path
is www.apple.com/
.
NSURL *anHTTPURL = [NSURL URLWithString:@"http://www.apple.com/"];
NSLog(@"absolute string: %@", anHTTPURL.absoluteString);
NSLog(@"path: %@", anHTTPURL.path);
Output:
absolute string: http://www.apple.com/
path: /
Again, we see that the absolute string still knows its scheme but path
is now /
. So path
seems to be not an appropriate way when working with remote URLs.
However, when we have an URL
like http://www.apple.com/index.html
we get
absolute string: http://www.apple.com/index.html
path: /index.html
Reading the docs helps here, too:
Per RFC 3986, the leading slash after the authority (host name and port) portion is treated as part of the path.
So the path
is everything beginning (and including) at the slash after the authority
which is www.apple.com
in our case.
Question 2
Is there a time when one should be used over the other?
From the docs: (method: path
)
If this URL object contains a file URL (as determined with isFileURL), the return value of this method is suitable for input into methods of NSFileManager or NSPathUtilities.
In my opinion that sentence states clearly that you should use path
when you work with NSFileManager
or NSPathUtilities
.
Conclusion:
When you work with remote URLs you (generally) use absoluteString
, otherwise the result is not what you (generally) want.
When you work with local URLs use path
.
Sources:
http://www.ietf.org/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc3986.txt
NSURL Class Reference
NSURL fileURLWithPath where NSString has a space
Try this:
NSString *fnam = [@"Localizable" stringByAppendingPathExtension:@"strings"];
NSArray *parts = [NSArray arrayWithPathComponents:@"~", @"SP BB", fnam, (void *)nil];
NSString *path = [[NSString pathWithComponents:parts] stringByStandardizingPath];
NSURL *furl = [NSURL fileURLWithPath:path];
Foundation has a host of platform-independent, path-related methods. Prefer those over hard-coding path extension separators (often ".") and path component separators (often "/" or "\").
What’s the correct way to create an NSURL from an NSString?
A path is not a valid URL by itself. You have to use this:
NSURL *pathURL = [NSURL fileURLWithPath:filePath];
And read the documentation. (And don’t overuse / abuse format strings.)
NSString to NSurl
When making URL
from NSString
, don't forget to encode it first, so try this:
NSString *urlString = [NSString stringWithFormat:@"%@", item.image];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
For IOS ≥ 9.0 use
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
Check if NSString is Local File
After trying all kinds of URL example, I think the NSURL class may not the final way for this to check the local file path. Now I use the following function.
BOOL IsLocalFilePath(NSString *path)
{
NSString *fullpath = path.stringByExpandingTildeInPath;
return [fullpath hasPrefix:@"/"] || [fullpath hasPrefix:@"file:/"];
}
It covers the local file paths like /path/to/foo
, file:///path/to/foo
, ~/path/to/foo
, ../path/to/foo
.
It works great for Unix-like path so far, punch me there are some exceptions.
Related Topics
React Native Xcode Project Product Archive Fails with Duplicate Symbols for Architecture Arm64
How to Create Different User Groups in Firebase
Avspeechsynthesizer in Background Mode
Present a Modal View Controller with Transparent Background
Is It Ok to Place Most Logic and Models in the Appdelegate
Receive Accelerometer Updates in Background Using Coremotion Framework
Uitableviewcell Auto Height Based on Amount of Uilabel Text
How to Get a Crash Log Due to Expiration of Provisioning Profile
User Set Time for Notification in Swift
How to Completely Hide the Status Bar in iOS Using Cordova
Create Singleton of a Viewcontroller in Swift 3
Pass in a Type to a Generic Swift Extension, or Ideally Infer It
iPhone Storage in Tmp Directory
Intercepting Phone Call - iPhone (Correct Method to Hook in Coretelephony)
Get User Profile Details (Especially Email Address) from Twitter in iOS