If you’ve been around Foundation for some time now, you’ve likely grown familiar with the way a URL will manifest itself: NSURL. With it, we are able to interact in a number of different ways using HTTP protocol.

let url = NSURL(string: “http://www.dreaminginbinary.co")

Like any protocol worth its salt, HTTP defines a structure and certain order of elements it expects to interact with. We can clearly see an example of this in its purest form from the URL above:

Scheme — http:

Host — www.dreaminginbinary.co

There are many components of a URL, and NSURL contains all of them specified in RCF 1808. So, as far as representing a valid and usable URL, NSURL does a fine job.

There comes a time, though, when a URL might need to be manipulated in some fashion. Say we decided not to visit www.dreaminginbinary.co, and instead opted for a quick visit to www.medium.com.

Not an issue, you say, and promptly code the following:

url.host = “www.medium.com”

Unfortunately, the previous code would produce a glorious compile time exception. If you were to visit the header file for NSURL or the docs, you’d quickly see why:



@property(readonly, copy) NSString *host //Objective-C var host: String ? { get } // Swift@property(readonly, copy) NSString *host //Objective-C

NSURL only exposes its components in a read-only capacity. NSURLComponents, on the other hand, was created specifically for situations like this. It’s members are exposed in a friendly, readwrite fashion.

You will have no learning curve in getting to know NSURLComponents if you’ve read this far. They can be created in the same fashion as an NSURL:

let components:NSURLComponents! = NSURLComponents(string: “http://www.dreaminginbinary.co")

And like NSURL, if the string supplied results in a malformed URL, nil will be responsibly set as the value.

Assuming our URL was valid, we are able to manipulate its components as needed:

components.host = “www.medium.com”

Its uses are manifested in situations where one could benefit from mutability. Suppose we had to create a URL dynamically, and all of the components needed are housed in a collection.

If we are to task NSURL with the responsiblity of creating such a URL, we’ll be left to several pieces of string concatenation — and before swift — string concatenation was slightly bloated and embarrassingly underpowered.

We’d be using the (not missed):

myURLSoFar = [myURLSoFar stringByAppendingString:theHost];

Or, the far less painful swift variant:

myURLSoFar += theHost

Turning to our new friend, however, yields a syntactically pleasant approach to solving the problem:

let components = NSURLComponents()

components.scheme = @"https";

components.user = @"jmorgan";

components.password = @"notapassword";

components.host = @"medium.com";

components.path = @"/stories/drafts.html";

components.fragment = @"paragraph4";

let url = components.url;

Here, one can set the logical properties on NSURLComponents. When you are finished, just ask it (nicely) for the valid URL. You’ll be promptly returned a spec compliant NSURL, complete with percent escaping and other conveniences.

NSURLComponents has everything to clearly and concisely express a URL. Let’s take a sneak peek at all the components left at your disposal:

//All typed as string, save for port - which is a NSNumber and queryItems, which is an Array containing NSURLQueryItems scheme //An invalid scheme results in an exception

user

password

host

port //Likewise, a negative port also hands out free exceptions.

path

query

fragment

queryItem

One new property added in iOS 8 is the queryItem collection, which contains useful tuples of all the items contained in the query string.

If we had initialized an instance of NSURLComponents like so:

let comp:NSURLComponents! = NSURLComponents(string: “https://www.dreaminginbinary.co/jordan?isTired=true")

Printing out components.queryItem would yield the following:

Optional([<NSURLQueryItem (Memory Address)> {name = isTired, value = true}])

And if you’re an especially astute reader — you’d notice that the query string conveys the message that I am indeed tired. No matter, though it be 2:00 am in Ozark, Missouri — our time with NSURLComponents is done for now.

Become a victim of randomly stumbling across helpful classes. NSURLComponents was a result of my curious snooping through header files a mere week ago. Who knows what other interesting secrets Foundation holds within its keep?

Until next week, friends.