Extract all folders from NSUrl - objective-c

I have following NSURL, and would need to split it into its various components:
The FTP-Url,
Each of the folders in order to be able to iterate through them.
What is the best way to do this? I know i can use componentsSeparatedByCharactersInSet: but i would like to be sure that it is the BEST way to do it and that there isnt already a function provided to do just that. (like for example to extract the filename from the NSURL)
NSURL *url;
url = [NSURL URLWithString:urlText]; //urlText is ftp.somesite.com/folder1/folder2/folder3

There is a built in way to access it, using the pathComponents property:
NSURL *url = [NSURL URLWithString:#"ftp://ftp.somesite.com/folder1/folder2/folder3"];
NSArray *pathComponents = url.pathComponents;
NSLog(#"%#", pathComponents); // ( #"folder1", #"folder2", #"folder3" )
This is definitely the best approach, since it will handle URL escaping and all that for you.

Related

confused by substring result of stringByDeletingLastPathComponent

my code
NSMutableString *s= (NSMutableString *)[#"http://www.yahoo.com/index.html" stringByDeletingLastPathComponent];
what I expected result of s is
http://www.yahoo.com
but the code above show s is:
http:/www.yahoo.com
Your comment welcome
You should use NSURL, not NSString:
NSURL *url = [[NSURL URLWithString:#"http://www.yahoo.com/index.html"] URLByDeletingLastPathComponent];
Yielding:
http://www.yahoo.com/
If you absolutely need a string from this, you can then do:
NSString *urlString = url.absoluteString;
Or, if you really needed a mutable string, don’t cast it to NSMutableString, but do create a mutable copy:
NSMutableString *urlString = [url.absoluteString mutableCopy];
But, in general, where possible, you should stay with NSURL when dealing with URLs. And when tempted to use file paths, use file URLs instead.
The annotation for this method is explained as follows。
Apple Document: Note that this method only works with the file paths (not, for example, the string representations of URLs).
But you string is clearly a full URL address, does not belong to the file path, so we will assemble them into a URL, using URL classification URLByDeletingLastPathComponent to intercept
NSString *urlString = #"http://www.yahoo.com/index.html";
NSURL* URL = [NSURL URLWithString: urlString];
NSURL* lastPathUrl = [URL URLByDeletingLastPathComponent];
NSString* lastPathString = lastPathUrl.absoluteString;
NSLog(#"---%#---", lastPathString);

Managing a list of URLs

I'm pretty new to Objective-c and I'm still not familiar with some basic concepts. As of my question, I want to manage a list of urls'. When a new url is being add I want to add it iff it is not already in the list. The trivial way for me to implement this will be:
NSMutableSet<NSURL*>* setOfURLs = /* some set of urls*/;
NSURL* url = [NSURL URLWithString:#"some string"];
[setOfUrls addObject:url];
This approach won't work (will it?) because the set is holding an object instances of NSURL. And it is possible that two different objects will have the same url path.
Another approach would be to hold a set of strings but I think maybe there is other / more convenient way to implement this. Any tips/tricks will be appreciated.
The addObject method adds an object to a set only if the set does not already contain it (see Apple documentation).
So, the following code
NSMutableSet<NSURL*>* setOfURLs = [NSMutableSet setWithArray:#[[NSURL URLWithString:#"http://www.first.com"], [NSURL URLWithString:#"http://www.second.com"]]];
NSURL* url = [NSURL URLWithString:#"http://www.third.com"];
[setOfURLs addObject:url];
NSURL* url2 = [NSURL URLWithString:#"http://www.first.com"];
[setOfURLs addObject:url2];
NSLog(#"%#", setOfURLs);
Produces the following output:
{(
http://www.first.com,
http://www.second.com,
http://www.third.com
)}
The result is that http://www.first.com isn't added a second time, because it is already contained in the NSMutableSet

NSURL baseURL returns nil. Any other way to get the actual base URL

I think I don't understand the concept of "baseURL". This:
NSLog(#"BASE URL: %# %#", [NSURL URLWithString:#"http://www.google.es"], [[NSURL URLWithString:#"http://www.google.es"] baseURL]);
Prints this:
BASE URL: http://www.google.es (null)
And of course, in the Apple docs I read this:
Return Value
The base URL of the receiver. If the receiver is an absolute URL, returns nil.
I'd like to get from this example URL:
https://www.google.es/search?q=uiviewcontroller&aq=f&oq=uiviewcontroller&sourceid=chrome&ie=UTF-8
This base URL
https://www.google.es
My question is simple. Is there any cleaner way of getting the actual base URL without concatenating the scheme and the hostname? I mean, what's the purpose of base URL then?
-baseURL is a concept purely of NSURL/CFURL rather than URLs in general. If you did this:
[NSURL URLWithString:#"search?q=uiviewcontroller"
relativeToURL:[NSURL URLWithString:#"https://www.google.es/"]];
then baseURL would be https://www.google.es/. In short, baseURL is only populated if the NSURL is created using a method that explicitly passes in a base URL. The main purpose of this feature is to handle relative URL strings such as might be found in the source of a typical web page.
What you're after instead, is to take an arbitrary URL and strip it back to just the host portion. The easiest way I know to do this is a little cunning:
NSURL *aURL = [NSURL URLWithString:#"https://www.google.es/search?q=uiviewcontroller"];
NSURL *hostURL = [[NSURL URLWithString:#"/" relativeToURL:aURL] absoluteURL];
This will give a hostURL of https://www.google.es/
I have such a method published as -[NSURL ks_hostURL] as part of KSFileUtilities (scroll down the readme to find it documented)
If you want purely the host and not anything like scheme/port etc. then -[NSURL host] is your method.
Docs for BaseURL.
baseURL
Returns the base URL of the receiver.
- (NSURL *)baseURL
Return Value
The base URL of the receiver. If the receiver is an absolute URL, returns nil.
Availability
Available in iOS 2.0 and later.
Declared In
NSURL.h
Seems it only works for relative URLs.
You could possibly use ...
NSArray *pathComponents = [url pathComponents]
and then take the bits you want.
Or try...
NSString *host = [url host];
you can use host method
NSURL *url = [[NSURL alloc] initWithString:#"http://www.hello.com"];
NSLog(#"Host:%#", url.host);
result:
Host:www.hello.com
It might be just me, but when I think further about the double-URL solution, it sounds like something that could stop working between OS updates. So I decided to share yet another solution, definitely not beautiful either, but I find it more readable by the general public since it doesn't rely on any hidden specificity of the framework.
if let path = URL(string: resourceURI)?.path {
let baseURL = URL(string: resourceURI.replacingOccurrences(of: path, with: ""))
...
}
Here's a quick, easy, and safe way to fetch the base URL:
NSError *regexError = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"http://.*/" options:NSRegularExpressionCaseInsensitive error:&regexError];
if (regexError) {
NSLog(#"regexError: %#", regexError);
return nil;
}
NSTextCheckingResult *match = [regex firstMatchInString:url.absoluteString options:0 range:NSMakeRange(0, url.absoluteString.length)];
NSString *baseURL = [url.absoluteString substringWithRange:match.range];

Declare an NSString With Format Specifiers and use it as a URL to open in UIWebview

I have an int containing a number. I am wanting to declare an NSString so I can use use format specifiers when assigning a value to it.
I thought it might be something like this:
NSString[NSString stringWithFormat] myString;
myString = [#"http://myurl.com/%d",myInt];
I gather this is not the case, so question one is: How do I declare an NSString that can handle format specifiers and then assign it a value using format specifiers? The purpose of this NSString is to hold a URL, exactly like the second line above.
Question two is, How do I then use this string as a URL to open in a UIWebView?
I assume I use something like this:
[webView loadRequest:
Sadly, this is as far as my knowledge stretches. Is there a way I can tell my UIWebView (webView above) to use the NSString with the URL I mentioned earlier?
I intend on having the NSString as a global variable, as it will be assigned it's value inside a C function. And 'webView' will use it inside a (what I think is a) method. All of this code is in the same file, the Delegate.m file. It is all executed on launch of the application.
Your string should look like this:
NSString *myString = [NSString stringWithFormat:#"http://myurl.com/%d", myInt];
What you missed: adding the * to indicate a pointer, and thinking that you had to/could first state that the string would have a format and then later state the format. It all happens at once, creating the string with the specified format.
Edited to add NSURL
To create a url you're creating an object of class NSURL, like this:
NSURL *myURL = [[NSURL alloc] initWithString:myString];
And then you create the url request:
NSURLRequest *request = [NSURLRequest requestWithURL:myURL];
And finally, tell your webView to load the request:
[webView loadRequest:request];
For your first part:
NSString *myString = [NSString stringWithFormat:#"http://myurl.com/%d", myInt];
Then, based on a tutorial from iphonesdkarticles.com:
//Create a URL object.
NSURL *url = [NSURL URLWithString:myString];
//URL Request Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[webView loadRequest:requestObj];

NSURL fileURLWithPath where NSString has a space

I've looked at quite a few of the related questions and cannot find a similar problem or a solution so my apologies if there is a duplicate out there somewhere.
Anyway, I'm trying to generate a file's NSURL to use with an NSXMLDocument. I have the following components:
const NSString * PROJECT_DIR = #"~/SP\\ BB/";
const NSString * STRINGS_FILE = #"Localizable.strings";
and construct the URL like so:
NSURL * stringsURL = [NSURL fileURLWithPath:[[NSString stringWithFormat:#"%#%#",PROJECT_DIR,STRINGS_FILE] stringByExpandingTildeInPath]];
however, the resulting path in the NSURL is:
file://localhost/Users/timothyborrowdale/SP2B/Localizable.strings
I have tried changing the PROJECT_DIR to
#"~/SP BB/"
#"~/SP\\\\ BB/" (changes to SP엀2B)
#"~/SP%20BB/"
#"~/SP\%20BB/"
with the same problem. I also tried typing out the file url completely and using [NSURL URLWithString:]
I have also tried using stringByAddingPercentEscapesUsingEncoding with both NSUTF8Encoding and NSASCCIEncoding and these have the same issue.
The NSString displays properly before being passed to NSURL or stringByAddingPercentEscapesUsingEncoding but has the problem once outputted from either.
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 "\").
Try abandoning stringWithFormat: (never the right answer for stapling paths together) and stringByExpandingTildeInPath and using NSHomeDirectory() and stringByAppendingPathComponent: instead.
#"~/SP\\ BB/" (changes to SP엀2B)
How did you arrive at that conclusion?