ios URLLoading System ---from apple document

The URL loading system is a set of classes and protocols that provide the underlying capability for an application to access the data specified by a URL. html

These classes fall into five categories: URL loading, cache management, authentication and credentials, cookie storage, and protocol support. cookie

The NSURLConnection and NSURLDownload classes provide the interface to make a connection specified by an NSURLRequest object and download the contents. An NSURLConnection object provides data to the delegate as it is received from the originating source, whereas an NSURLDownload object writes the request data directly to disk. Both classes provide extensive delegate support for responding to redirects, authentication challenges, and error conditions. app

The NSURLConnection class provides a delegate method that allows an application to control the caching of a response on a per-request basis. Downloads initiated by an NSURLDownload instance are not cached. ide

Cache Management flex

The URL loading system provides a composite on-disk and in-memory cache allowing an application to reduce its dependence on a network connection and provide faster turnaround for previously cached responses. The cache is stored on a per-application basis. ui

The cache is queried by NSURLConnection according to the cache policy specified by the initiating NSURLRequest. this


The NSURLCache class provides methods to configure the cache size and its location on disk. It also provides methods to manage the collection of NSCachedURLResponse objects that contain the cached responses. rest


An NSCachedURLResponse object encapsulates the NSURLResponse and the URL content data. code

NSCachedURLResponse also provides a user info dictionary that can be used by an application to cache any custom data. orm


Not all protocol implementations support response caching. Currently only http and https requests are cached, and https requests are never cached to disk.

An NSURLConnection can control whether a response is cached and whether the response should be cached only in memory by implementing the connection:willCacheResponse: delegate method.

 

Using NSURLConnection

NSURLConnection provides the most flexible method of downloading the contents of a URL. It provides a simple interface for creating and canceling a connection, and supports a collection of delegate methods that provide feedback and control of many aspects of the connection. These classes fall into five categories: URL loading, cache management, authentication and credentials, cookie storage, and protocol support.

Creating a Connection

In order to download the contents of a URL, an application needs to provide a delegate object that, at a minimum, implements the following delegate methods: connection:didReceiveResponse:,connection:didReceiveData:, connection:didFailWithError: and connectionDidFinishLoading:.

Controlling Response Caching

By default the data for a connection is cached according to the support provided by the NSURLProtocol subclass that handles the request. An NSURLConnection delegate can further refine that behavior by implementing connection:willCacheResponse:.

The example in Listing 6 prevents the caching of https responses. It also adds the current date to the user info dictionary for responses that are cached.

 

-(NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
NSCachedURLResponse *newCachedResponse = cachedResponse;
if ([[[[cachedResponse response] URL] scheme] isEqual:@"https"]) {
newCachedResponse = nil;
} else {
NSDictionary *newUserInfo;
newUserInfo = [NSDictionary dictionaryWithObject:[NSCalendarDate date]
forKey:@"Cached Date"];
newCachedResponse = [[[NSCachedURLResponse alloc]
initWithResponse:[cachedResponse response]
data:[cachedResponse data]
userInfo:newUserInfo
storagePolicy:[cachedResponse storagePolicy]]
autorelease];
}
return newCachedResponse;
}

Estimating Upload Progress

You can estimate the progress of an HTTP POST upload with the connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: delegate method.
Note that this is not an exact measurement of upload progress, because the connection may fail or the connection may encounter an authentication challenge.

 

 

Using NSURLDownload

NSURLDownload provides an application the ability to download the contents of a URL directly to disk. It provides an interface similar to NSURLConnection, adding an additional method for specifying the destination of the file. NSURLDownload can also decode commonly used encoding schemes such as MacBinary, BinHex and gzip. Unlike NSURLConnection, data downloaded using NSURLDownload is not stored in the cache system.


If your application is not restricted to using Foundation classes, the WebKit framework includes WebDownload, a subclass of NSURLDownload that provides a user interface for authentication.

 

Downloading to a Predetermined Destination

One usage pattern for NSURLDownload is downloading a file to a predetermined filename on disk. If the application knows the destination of the download, it can set it explicitly using
setDestination:allowOverwrite:. Multiple setDestination:allowOverwrite: messages to an
NSURLDownload instance are ignored.


The download starts immediately upon receiving the initWithRequest:delegate: message. It can be canceled any time before the delegate receives a downloadDidFinish: or download:didFailWithError: message by sending the download a cancel message.


The example in Listing 1 sets the destination, and thus requires the delegate only implement the download:didFailWithError: and downloadDidFinish: methods.

 

- (void)startDownloadingURL:sender
{
// Create the request.
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL
URLWithString:@"http://www.apple.com"]

cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// Create the connection with the request and start loading the data.
NSURLDownload *theDownload = [[NSURLDownload alloc] initWithRequest:theRequest
delegate:self];
if (theDownload) {
// Set the destination file.
[theDownload setDestination:@"/tmp" allowOverwrite:YES];
} else {
// inform the user that the download failed.
}
}
- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error
{
// Release the connection.
[download release];
// Inform the user.
NSLog(@"Download failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)downloadDidFinish:(NSURLDownload *)download
{
// Release the connection.
[download release];
// Do something with the data.
NSLog(@"%@",@"downloadDidFinish");
}

 

Downloading a File Using the Suggested Filename

Sometimes the application must derive the destination filename from the downloaded data itself. This requires you to implement the delegate method download:decideDestinationWithSuggestedFilename: and
call setDestination:allowOverwrite: with the suggested filename. The example in Listing 2 saves the downloaded file to the desktop using the suggested filename.

- (void)startDownloadingURL:sender
{
// Create the request.
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL
URLWithString:@"http://www.apple.com/index.html"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// Create the download with the request and start loading the data.
NSURLDownload *theDownload = [[NSURLDownload alloc] initWithRequest:theRequest
delegate:self];
if (!theDownload) {
// Inform the user that the download failed.
}
}
- (void)download:(NSURLDownload *)download
decideDestinationWithSuggestedFilename:(NSString *)filename
{
NSString *destinationFilename;
NSString *homeDirectory = NSHomeDirectory();
destinationFilename = [[homeDirectory stringByAppendingPathComponent:@"Desktop"]
stringByAppendingPathComponent:filename];

[download setDestination:destinationFilename allowOverwrite:NO];
}
- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error
{
// Release the download.
[download release];
// Inform the user.
NSLog(@"Download failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)downloadDidFinish:(NSURLDownload *)download
{
// Release the download.
[download release];
// Do something with the data.
NSLog(@"%@",@"downloadDidFinish");
}

The downloaded file is stored on the user's desktop with the name index.html, which was derived from the downloaded content. Passing NO to setDestination:allowOverwrite: prevents an existing file from being overwritten by the download. Instead a unique filename is created by inserting a sequential number after the filename, for example, index-1.html.


The delegate is informed when a file is created on disk if it implements the download:didCreateDestination: method. This method also gives the application the opportunity to determine the finalized filename with which the download is saved.

The example in Listing 3 logs the finalized filename.

-(void)download:(NSURLDownload *)download didCreateDestination:(NSString *)path
{
// path now contains the destination path
// of the download, taking into account any
// unique naming caused by -setDestination:allowOverwrite:
NSLog(@"Final file destination: %@",path);
}

This message is sent to the delegate after it has been given an opportunity to respond to the
download:shouldDecodeSourceDataOfMIMEType: and download:decideDestinationWithSuggestedFilename: messages.

Displaying Download Progress

The progress of the download can be determined by implementing the delegate methods
download:didReceiveResponse: and download:didReceiveDataOfLength:.
The download:didReceiveResponse: method provides the delegate an opportunity to determine the expected content length from the NSURLResponse. The delegate should reset the progress each time this message is received.
The example implementation in Listing 4 demonstrates using these methods to provide progress feedback to the user.

- (void)setDownloadResponse:(NSURLResponse *)aDownloadResponse
{
[aDownloadResponse retain];
// downloadResponse is an instance variable defined elsewhere.
[downloadResponse release];
downloadResponse = aDownloadResponse;
}

- (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response { // Reset the progress, this might be called multiple times. // bytesReceived is an instance variable defined elsewhere. bytesReceived = 0; // Retain the response to use later. [self setDownloadResponse:response]; } - (void)download:(NSURLDownload *)download didReceiveDataOfLength:(unsigned)length { long long expectedLength = [[self downloadResponse] expectedContentLength]; bytesReceived = bytesReceived + length; if (expectedLength != NSURLResponseUnknownLength) { // If the expected content length is // available, display percent complete. float percentComplete = (bytesReceived/(float)expectedLength)*100.0; NSLog(@"Percent complete - %f",percentComplete); } else { // If the expected content length is // unknown, just log the progress. NSLog(@"Bytes received - %d",bytesReceived); } }

相關文章
相關標籤/搜索