Foundation has two classes that facilitate working with URLs: NSURL and NSURLHandle. NSURL represents a Uniform Resource Locator (URL). This class lets applications create, manipulate, and pick apart URLs. NSURLHandle accesses data and resources specified by an instance of NSURL. This class can access resources provided by HTTP, FTP, and file services.
 FTP support in NSURLHandle was added in Mac OS X 10.2 and is not available in earlier versions of Mac OS X.
NSURL represents a URLthe human-readable host names and paths that various network clients use to locate resources on the local filesystem or over the Internet. NSURL provides a number of methods and initializers that let you create instances in many different ways, as shown in Example 6-2.
// From a string... NSURL *url = [NSURL URLWithString:@"http//www.macdevcenter.com"]; url = [[NSURL alloc] initWithString: :@"http//www.macdevcenter.com"]; // From a file path... url = [NSURL fileURLWithPath:@"/Users/mike/Pictures/pic.tiff"]; url = [[NSURL alloc] initFileURLWithPath: :@"/Users/mike/Pictures/pic.tiff"]; // Access a URL with scheme, host, and path url = [[NSURL alloc] initWithScheme:@" FTP" host:@"localhost" path:@"/Some/Path"];
In Example 6-2, the last initializer, initWithScheme:host:path:, specifies the scheme used by the host the URL points to. In this case, an FTP address was specified; however, the backend to NSURL's data transfer functionality, NSURLHandle, supports HTTP and file URL schemes as well.
NSURL includes an assortment of methods that let you pick apart URLs to extract pieces of information from them, such as the URL path, the host name, the base URL, and the query string. Example 6-3 illustrates several NSURL methods.
NSURL *url = [NSURL URLWithString:@"http//www.google.com/ search?hl=en&ie=ISO-8859-1&q=NSURL&btnG=Google+Search"]; NSString *s; s = [url host]; // Returns "www.google.com" s = [url scheme]; // Returns "HTTP" s = [url path]; // Returns "/search" // Returns "//www.google.com/search?hl=en&ie=ISO-8859-1&q=NSURL&btnG=Google+Search" s = [url resourceSpecifier]; // Returns "hl=en&ie=ISO-8859-1&q=NSURL&btnG=Google+Search" s = [url query];
While NSURLHandle implements data transfer functionality, NSURL provides a handful of convenience methods that can transfer data without having to instantiate NSURLHandle. These methods, whose usage is shown in Example 6-4, include:
// Create an instance of NSURL from an NSString NSString *urlStr = @"http//host_address/image.jpg"; NSURL *url = [NSURL URLWithString:urlStr]; // Download data from the resource located by a URL NSData *data = [url resourceDataUsingCache:NO]; NSImage *img = [[NSImage alloc] initWithData:data]; // Write data to a resource located by a URL NSData *data = [img TIFFRepresentation]; [url setResourceData:data];
If YES is passed to the resourceDataUsingCache: method, NSURL attempts to load the resource from the cache if it was loaded previously. If the resource was not loaded, then the host will load it. Passing NO to this method tells NSURL to always fetch the data from the host, even if it has done so already.
NSURLHandle provides an interface for uploading and downloading data to and from a resource specified by an instance of NSURL. NSURLHandle actually offloads much of this work to subclasses that implement NSURLHandle's interface to work with various schemes. NSURLHandle's subclasses include NSFileURLHandle, NSFTPURLHandle, and NSHTTPURLHandle. These three subclasses are privateall interaction with them is through NSURLHandle's public interface, which creates the proper subclass based on the provided NSURL object's scheme. For most purposes, the interface provided by NSURL should be sufficient for resource access. NSURLHandle is most useful when you need to create a new subclass to support a URL scheme other than file, FTP, or HTTP.
NSURLHandle's subclasses are responsible for implementing the resource acquisition mechanics needed by a URL scheme. When created, that subclass needs to be registered with NSURLHandle using the class method registerURLHandleClass:. The registration process makes NSURLHandle aware of a subclass's availability to handle a new URL scheme.
To determine whether NSURLHandle handles a particular URL scheme, use the class method canInitWithURL:. Additionally, you can retrieve the actual class object used by NSURLHandle for a particular URL scheme by invoking the class method URLHandleClassForURL:.