首页 > 代码库 > Chapter 21 WebServices and UIWebView
Chapter 21 WebServices and UIWebView
Chapter 21 WebServices and UIWebView
1. Usually, fetch data from a web server using four handy classes: NSURL, NSURLRequest, NSURLSessionTask, and NSURLSession. Each of these classes has an important role in communicating with a web server:
An NSURL instance contains the location of a web application in URL format. For many web services, the URL will be composed of the base address, the web application you are communicating with, and any arguments that are being passed.
An NSURLRequest instance holds all the data necessary to communicate with a web server. This includes an NSURL object as well as a caching policy, a limit on how long you will give the web server to respond, and additional data passed through the HTTP protocol. (NSMutableURLRequest is the mutable subclass of NSURLRequest.)
An NSURLSessionTask instance encapsulates the lifetime of a single request. It tracks the state of the request and has methods to cancel, suspend, and resume the request. Tasks will always be subclasses of NSURLSessionTask, specifically NSURLSessionDataTask, NSURLSessionUploadTask, or NSURLSessionDownloadTask.
An NSURLSession instance acts as a factory for data transfer tasks. It is a configurable container that can set common properties on the tasks it creates. Some examples include header fields that all requests should have or whether requests work over cellular connections. NSURLSession also has a rich delegate model that can provide information on the status of a given task and handle authentication challenges, for example.
2. The purpose of the NSURLSession is a bit hazier. NSURLSession’s job is to create tasks of a similar nature. For example, if your application had a set of requests that all required the same header fields, you could configure the NSURLSession with these additional header fields. Similarly, if a set of requests should not connect over cellular networks, then an NSURLSession could be configured to not allow cellular access. These shared behaviors and attributes are then configured on the tasks that the session creates. Tasks are always created in the suspended state, so calling resume on the task will start the web service request.
#import <UIKit/UIKit.h>#import "BNRWebViewController.h"@interface BNRCoursesViewController : UITableViewController@property (nonatomic) BNRWebViewController *webViewController;@end
#import "BNRCoursesViewController.h"#import "TableViewCell.h"@interface BNRCoursesViewController ()<NSURLSessionDataDelegate>@property (nonatomic) NSURLSession *session;@property (nonatomic, copy) NSArray *courses;@end@implementation BNRCoursesViewController#pragma mark - Life cycle-(instancetype)initWithStyle:(UITableViewStyle)style{ self = [super initWithStyle:style]; if(self) { self.navigationItem.title = @"BNR Courses"; NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil]; [self fetchFeed]; } return self;}-(void)viewDidLoad{ [super viewDidLoad]; // [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"]; UINib *nib = [UINib nibWithNibName:@"TableViewCell" bundle:nil]; [self.tableView registerNib:nib forCellReuseIdentifier:@"TableViewCell"];}#pragma mark - UITableViewDataSource-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.courses.count;}-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableViewCell" forIndexPath:indexPath]; NSDictionary *course = self.courses[indexPath.row]; cell.courseTitleLabel.text = course[@"title"]; NSArray *upcoming = course[@"upcoming"]; if(upcoming) { NSString *startDate = [upcoming firstObject][@"start_date"]; NSString *instructors = [upcoming firstObject][@"instructors"]; cell.upcomingLabel.text = [NSString stringWithFormat:@"%@ %@", startDate, instructors]; } return cell;}-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSDictionary *course = self.courses[indexPath.row]; NSURL *url = [NSURL URLWithString:course[@"url"]]; self.webViewController.url = url; self.webViewController.title = course[@"title"]; [self.navigationController pushViewController:self.webViewController animated:YES];}#pragma mark - Request to server-(void)fetchFeed{ NSString *requestString = @"https://bookapi.bignerdranch.com/private/courses.json"; NSURL *url = [NSURL URLWithString:requestString]; NSURLRequest *req = [NSURLRequest requestWithURL:url]; NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; self.courses = jsonObject[@"courses"]; dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; }); }]; [dataTask resume];}#pragma mark - NSURLSessionDataDelegate-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler{ NSURLCredential *cred = [NSURLCredential credentialWithUser:@"BigNerdRanch" password:@"AchieveNerdvana" persistence:NSURLCredentialPersistenceForSession]; completionHandler(NSURLSessionAuthChallengeUseCredential, cred);}@end
Chapter 21 WebServices and UIWebView