佳为好友

笔记:Http网络编程

/Files/walkklookk/Http网络编程.txt

日期:2010-04-01


[自:基本上介绍了全部的HTTP编程知识,包括简单同步获取网络信息;提供详细Error的同步获取网络信息;异步获取网络信息;使用Get和Post获取网络信息.
文章最后,给出了一个完整的使用Get和Post异步获取网络信息的例子,也可以直接使用.
尚有一个问题需要调查:文章使用的Get和Post数据的格式是UTF8,但是这可能不能完全适合URL编码.

邮件附件是本文的一个copy.
]

++++++++++++BEGIN+++++++++++++++++
笔记:More.iPhone.3.Development.Tackling.iPhone.SDK.3.Dec.2009 
-- Chapter 10 Working with Data from the Web

* Highlight, page 329
++Chapter 10 Working with Data from the Web

* Highlight, page 336
+++Retrieving Data Using Foundation Objects
To initialize an NSData instance from a file on the Web, for example, you could do this:
    NSString *theUrlString = @"http://domainname.com/filename"; 
    NSURL *url = [NSURL urlWithString:theUrlString]; 
    NSData *imageData = [NSData dataWithContentsOfURL:url]; 
To initialize an NSString instance from a file on the Web, it looks like this: 
    NSString *theUrlString = @"http://domainname.com/filename"; 
    NSURL *url = [NSURL urlWithString:theUrlString]; 
    NSString *string = [NSString stringWithContentsOfURL:url  
        encoding:NSUTF8StringEncoding error:nil]; 


* Highlight, page 337
2个弊端.第一,出错时只返回nil,而无其他信息.当然,有时会给出一个NSError值,但是这仍然只提供了很少的信息.
第二个弊端是:它们是同步的.
As a result, you should limit your use of these methods for retrieving data from the network to very small pieces of data, and even then, use them with caution.

* Highlight, page 339
+++Retrieving Data Synchronously
++++The URL Request
Here’s how we create such a request: 
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL:url];

* Highlight, page 340
如果需要同步获取数据,则不需要创建一个connection,我们只是需要一个NSURLConnection的函数来发送请求和获取数据即可,例如:

    NSHTTPURLResponse* response = nil;   
    NSError* error nil;   
    NSData *responseData = [NSURLConnection sendSynchronousRequest:req    
        returningResponse:&response    
        error:&error]; 

* Highlight, page 340
response对象返回了更多的信息.我们可以通过response得到服务器信息以及属性,通过函数的返回值得到返回的数据.可以通过下面的方法得到response code:
    NSInteger statusCode = [response statusCode]; 
    NSString *contentType = [[response allHeaderFields]  
        objectForKey:@"Content-Type"]; 


* Highlight, page 340
返回值的意义.As we said before, if the server couldn’t be reached at all, then response will be nil. If the server responded, but something went wrong, the response code will give us more information about the problem. If reponseData is nil, we might find out that the data wasn’t found (response code 404) or that it moved to a new location (301) or that we don’t have privileges to download it (401). Armed with the list of response codes, we can give our users a much better answer about why we weren’t able to get the file for them. We can also ensure that the data we’re receiving is the same type that we were expecting. Web servers will often forward requests, so responseData might contain, for example, the HTML for a 404 page, or a page full of ads rather than the file we were trying to retrieve.

* Highlight, page 341
replace the existing stub implementation of getImageSynchronously with the following version: 
- (IBAction)getImageSynchronously { 
    textView.hidden = YES; 
    imageView.hidden = NO; 
    NSURL *url = [[NSURL alloc] initWithString:kImageURL]; 
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL:url]; 
     
    NSHTTPURLResponse* response = nil;   
    NSError* error = nil;  
    NSData *responseData = [NSURLConnection sendSynchronousRequest:req    
                                                 returningResponse:&response    
                                                             error:&error];   
    if (response == nil) { 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error!"  
            message:@"Unable to contact server." 
            delegate:nil  
            cancelButtonTitle:@"Bummer" 
            otherButtonTitles:nil]; 
        [alert show]; 
        [alert release]; 
    } 
 
    NSInteger statusCode = [response statusCode]; 
    NSString *contentType = [[response allHeaderFields]  
        objectForKey:@"Content-Type"]; 
     
    if (statusCode >= 200 && statusCode < 300 && [contentType hasPrefix:@"image"]) { 
        imageView.image = [UIImage imageWithData:responseData]; 
    } 
    else { 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error!"  
            message:[NSString stringWithFormat: 
                @"Encountered %d error while loading", statusCode] 
            delegate:nil  
            cancelButtonTitle:@"Bummer" 
            otherButtonTitles:nil]; 
        [alert show]; 
        [alert release]; 
    } 
     
    [url release]; 
    [req release]; 
    [self performSelector:@selector(clear) withObject:nil afterDelay:5.0]; 



* Highlight, page 342
Now, find the getTextSynchronously stub and replace it with this version: 
- (IBAction)getTextSynchronously { 
    textView.hidden = NO; 
    imageView.hidden = YES; 
    NSURL *url = [[NSURL alloc] initWithString:kTextURL]; 
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL:url]; 
     
    NSHTTPURLResponse* response = nil;   
    NSError* error = nil;  
    NSData *responseData = [NSURLConnection sendSynchronousRequest:req    
                                                 returningResponse:&response    
                                                             error:&error];   
    if (response == nil) { 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error!"  
            message:@"Unable to contact server." 
            delegate:nil  
            cancelButtonTitle:@"Bummer" 
            otherButtonTitles:nil]; 
        [alert show]; 
        [alert release]; 
        return; 
    } 
 
    NSInteger statusCode = [response statusCode]; 
    NSString *contentType = [[response allHeaderFields]  
        objectForKey:@"Content-Type"]; 
     
    if (statusCode >= 200 && statusCode < 300 && [contentType hasPrefix:@"text"]) { 
        NSString *payloadAsString = [[NSString alloc] initWithData:responseData      
            encoding:NSUTF8StringEncoding]
        textView.text = payloadAsString; 
        [payloadAsString release]; 
    } 
    else { 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error!"  
            message:[NSString stringWithFormat: 
                @"Encountered %d error while loading", statusCode] 
            delegate:nil  
            cancelButtonTitle:@"Bummer" 
            otherButtonTitles:nil]; 
        [alert show]; 
        [alert release]; 
        return; 
    } 
 
    [url release]; 
    [req release]; 
    [self performSelector:@selector(clear) withObject:nil afterDelay:5.0]; 

 

* Highlight, page 344
+++Retrieving Data Asynchronously
* Highlight, page 346
Find the stub implementation of getImageAsynchronously and replace it with this version:
- (IBAction)getImageAsynchronously { 
    [spinner startAnimating]; 
     
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL: 
        [NSURL URLWithString:kImageURL]]; 
    NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:req  
                                                          delegate:self]; 
    if (con) { 
        NSMutableData *data = [[NSMutableData alloc] init]; 
        self.receivedData = data; 
        [data release]; 
        requestType = kRequestTypeImage; 
    }  
    else { 
        UIAlertView *alert = [[UIAlertView alloc]  
            initWithTitle:@"Error" 
            message:@"Error connecting to remote server" 
            delegate:self  
            cancelButtonTitle:@"Bummer" 
            otherButtonTitles:nil]; 
        [alert show]; 
        [alert release]; 
    }    
    [req release]; 



* Highlight, page 347
Now find the stub implementation of getTextAsynchronously and replace it with this 
version: 
- (IBAction)getTextAsynchronously { 
    [spinner startAnimating]; 
     
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL: 
        [NSURL URLWithString:kTextURL]]; 
    NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:req  
                                                          delegate:self]; 
    if (con) { 
        NSMutableData *data = [[NSMutableData alloc] init]; 
        self.receivedData = data; 
        [data release]; 
        requestType = kRequestTypeText; 
    }  
    else { 
        UIAlertView *alert = [[UIAlertView alloc]  
            initWithTitle:@"Error" 
            message:@"Error connecting to remote server" 
            delegate:self  
            cancelButtonTitle:@"Bummer" 
            otherButtonTitles:nil]; 
        [alert show]; 
        [alert release]; 
    }    
    [req release]; 



* Highlight, page 348
#pragma mark - 
#pragma mark NSURLConnection Callbacks 
- (void)connection:(NSURLConnection *)connection  
        didReceiveResponse:(NSURLResponse *)response { 
    [receivedData setLength:0]; 

 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [receivedData appendData:data]; 

 
- (void)connection:(NSURLConnection *)connection 
  didFailWithError:(NSError *)error { 
    [connection release]; 
    self.receivedData = nil;  
     
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" 
        message:[NSString stringWithFormat: 
            @"Connection failed! Error - %@ (URL: %@)",  
            [error localizedDescription],[[error userInfo]    
            objectForKey:NSErrorFailingURLStringKey]]  
        delegate:self 
        cancelButtonTitle:@"Bummer" 
        otherButtonTitles:nil]; 
    [alert show]; 
    [alert release]; 
    [spinner stopAnimating]; 

 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    if (requestType == kRequestTypeImage) { 
        imageView.hidden = NO; 
        textView.hidden = YES; 
        imageView.image = [UIImage imageWithData:receivedData]; 
    } 
    else { 
        imageView.hidden = YES; 
        textView.hidden = NO; 
        NSString *payloadAsString = [[NSString alloc] initWithData:receivedData  
            encoding:NSUTF8StringEncoding]
        textView.text = payloadAsString; 
        [payloadAsString release]; 
    } 
     
    [connection release]; 
    self.receivedData = nil; 
    [spinner stopAnimating]; 
    [self performSelector:@selector(clear) withObject:nil afterDelay:5.0]; 



* Highlight, page 350
+++Request Types and Form Parameters
[各种HTTP的命令.]The HTTP protocol actually defines multipe types of requests. In addition to the standard GET request that we’ve been using, there’s also something called a POST request, which is used by most web forms. There’s also the lesser-used PUT, which is used to add or replace an existing resource with a new one, and DELETE which is used to remove a resource or make it unavailable.

* Highlight, page 352
++++GET Parameters
Get消息类似于:
http://www.foobar.org/picture?id=1001&size=200x200
程序中如何设定Get消息:
    NSString *url = [NSString stringWithFormat:@"http://www.foo.bar/action?%@=%@",  
        paramName, paramValue]; 


* Highlight, page 352
++++POST Parameters
    NSString *paramDataString = [NSString stringWithFormat:@"%@=%@", paramName,  
        paramValue]; 
    NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding]; 
    [req setHTTPBody: paramData]; 

++++Building the RequestTypes Application 
* Highlight, page 353
RequestTypesViewController.h and replace the contents with this version: 

#import <UIKit/UIKit.h> 
#define kFormURL @"http://iphonedevbook.com/more/10/echo.php
 
@interface RequestTypesViewController : UIViewController { 
    UIWebView       *webView; 
    UITextField     *paramName; 
    UITextField     *paramValue; 
 
    NSMutableData           *receivedData; 

 
@property (nonatomic, retain) IBOutlet UIWebView *webView; 
@property (nonatomic, retain) IBOutlet UITextField *paramName; 
@property (nonatomic, retain) IBOutlet UITextField *paramValue; 
 
@property (nonatomic, retain) NSMutableData *receivedData; 
 
- (IBAction)doGetRequest; 
- (IBAction)doPostRequest; 
@end 


* Highlight, page 354
Single-click RequestTypesViewController.m and replace the contents with this version: 

#import "RequestTypesViewController.h" 
 
@implementation RequestTypesViewController 
@synthesize webView; 
@synthesize paramName; 
@synthesize paramValue; 
@synthesize receivedData; 
 
- (IBAction)doGetRequest { 
     
    NSMutableString *urlWithParameters = [NSMutableString  
        stringWithString:kFormURL]; 
 
    [urlWithParameters appendFormat:@"?%@=%@", paramName.text, paramValue.text]; 
     
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL:[NSURL  
        URLWithString:urlWithParameters]]; 
     
   NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:req  
        delegate:self]; 
    if (theConnection) { 
        NSMutableData *data = [[NSMutableData alloc] init]; 
        self.receivedData = data; 
        [data release]; 
    }  
    else { 
        [webView loadHTMLString:@"Unable to make connection!"  
            baseURL:[NSURL URLWithString:kFormURL]] ; 
    }     
    [paramName resignFirstResponder]; 
    [paramValue resignFirstResponder]; 
    [req release]; 

 
- (IBAction)doPostRequest {  
 NSURL *url = [[NSURL alloc] initWithString:kFormURL]; 
 NSMutableURLRequest *req = [[NSMutableURLRequest alloc]  
                                initWithURL:url]; 
 [req setHTTPMethod:@"POST"]; 
 
  
    NSString *paramDataString = [NSString stringWithFormat:@"%@=%@", paramName.text,  
        paramValue.text]; 
     
    NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding]; 
    [req setHTTPBody: paramData];  
     
    NSURLConnection *theConnection = [[NSURLConnection alloc] 
                                    initWithRequest:req  
                                    delegate:self]; 
    if (theConnection) { 
        NSMutableData *data = [[NSMutableData alloc] init]; 
        self.receivedData = data; 
        [data release]; 
    }  
    else { 
        [webView loadHTMLString:@"Unable to make connection!" baseURL:[NSURL  
            URLWithString:kFormURL]] ; 
    }   
 
    [url release]; 
    [req release]; 
    [paramName resignFirstResponder]; 
    [paramValue resignFirstResponder]; 

 
- (void)viewDidUnload { 
    self.webView = nil; 
    self.paramName = nil; 
    self.paramValue = nil; 

 
- (void)dealloc { 
    [webView release]; 
    [paramName release]; 
    [paramValue release]; 
    [receivedData release]; 
    [super dealloc]; 

#pragma mark - 
#pragma mark NSURLConnection Callbacks 
- (void)connection:(NSURLConnection *)connection  
didReceiveResponse:(NSURLResponse *)response { 
    [receivedData setLength:0]; 

 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [receivedData appendData:data]; 

 
- (void)connection:(NSURLConnection *)connection 
  didFailWithError:(NSError *)error { 
    [connection release]; 
    self.receivedData = nil;  
     
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" 
        message:[NSString stringWithFormat: 
            @"Connection failed! Error - %@ (URL: %@)",  
            [error localizedDescription], [[error userInfo]  
            objectForKey:NSErrorFailingURLStringKey]]  
        delegate:self 
        cancelButtonTitle:@"Bummer"  
        otherButtonTitles:nil]; 
    [alert show]; 
    [alert release]; 

 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
     
    webView.hidden = NO; 
    NSString *payloadAsString = [[NSString alloc] initWithData:receivedData  
        encoding:NSUTF8StringEncoding]
    [webView loadHTMLString:payloadAsString baseURL:[NSURL URLWithString:kFormURL]]; 
    [payloadAsString release]; 
     
    [connection release]; 
    self.receivedData = nil; 

 
@end

++++++++++++++END++++++++++++++++++

+++++

posted on 2012-12-26 10:16 佳为好友 阅读(299) 评论(0)  编辑 收藏 引用 所属分类: 非UI


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2012年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

留言簿(1)

随笔分类

搜索

最新评论

评论排行榜