zoukankan      html  css  js  c++  java
  • IOS网络编程:HTTP

    IOS网络编程:HTTP

    HTTP定义了一种在服务器和客户端之间传递数据的途径。

    URL定义了一种唯一标示资源在网络中位置的途径。

    REQUESTS 和 RESPONSES:

    客户端先建立一个TCP连接,然后发送一个请求。服务器受到请求处理后发送一个响应向客户端传递数据。然后客户端可以继续发送请求或者关闭这个TCP连接。

    HTTPS:
    在TCP连接建立后,发送请求之前,需要建立一个一个SSL会话。

    request方法和它们的用途

    iOS的NSURLRequest和它的子类NSMutableURLRequest提供了建立HTTP请求的方法。

    NSURLResponse 和 它的子类NSHTTPURLResponse 处理返回的数据。

    URL:

     

    Protocol包括HTTP、FTP和file。

    URL编码:

    NSString *urlString = @"http://myhost.com?query=This is a question"; 
    NSString *encoded = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    NSURL用来管理URL。

     

    IOS HTTP APIS:

    涉及到下面一些类:

    NSURL, NSURLRequest, NSURLConnection, 和 NSURLResponse.

    1、NSURL

    NSURL可以定义本地文件和网络文件

    NSURL *url = [NSURL urlWithString:@"http://www.google.com"]; 
    NSData *data = [NSData dataWithContentsOfURL:url];

    NSURL定义了很多访问器:

    复制代码
    if (url.port == nil) { 
      NSLog(@"Port is nil"); } else {   NSLog(@"Port is not nil"); }
    复制代码

    2、NSURLRequest

    创建了NSURL后,就可以用NSURLRequest建立请求了:

    复制代码
    复制代码
    NSURL *url = [NSURL URLWithString: @"https://gdata.youtube.com/feeds/api/standardfeeds/top_rated"];
    if (url == nil) {
         NSLog(@"Invalid URL"); 

       return; } NSURLRequest *request = [NSURLRequest requestWithURL:url];

    if (request == nil) {   NSLog(@"Invalid Request"); return; }
    复制代码
    复制代码

    NSMutableURLRequest是NSURLRequest 的子类,提供了改变请求的属性的方法:

    NSURL *url = [NSURL urlWithString@"http://server.com/postme"]; 
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    [req setHTTPMethod:@"POST"]; [req setHTTPBody:[@"Post body" dataUsingEncoding:NSUTF8StringEncoding]];

    如果你要发送一个图片或者视频,那么用需要用NSInputStream,它没有把数据全部加在到内存。

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    NSInputStream *inStream = [NSInputStream inputStreamWithFileAtPath:srcFilePath];
    [request setHTTPBodyStream:inStream];
    [request setHTTPMethod:@"POST"];

    3、NSURLConnection

    提供了初始化、开始、和取消一个连接。

    4、NSURLResponse

    发送同步请求:

    复制代码
    复制代码
    - (NSArray *) doSyncRequest:(NSString *)urlString {
        // make the NSURL object from the string
        NSURL *url = [NSURL URLWithString:urlString];
        
        // Create the request object with a 30 second timeout and a cache policy to always retrieve the
        // feed regardless of cachability.
        NSURLRequest *request = 
           [NSURLRequest requestWithURL:url 
                            cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData 
                        timeoutInterval:30.0];
        
        // Send the request and wait for a response
        NSHTTPURLResponse   *response;
        NSError             *error;
        NSData *data = [NSURLConnection sendSynchronousRequest:request 
                                             returningResponse:&response 
                                                         error:&error];
        // check for an error
        if (error != nil) {
            NSLog(@"Error on load = %@", [error localizedDescription]);
            return nil;
        }
        
        // check the HTTP status
        if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            if (httpResponse.statusCode != 200) {
                return nil;
            }
            NSLog(@"Headers: %@", [httpResponse allHeaderFields]);
        }
        
        // Parse the data returned into an NSDictionary
        NSDictionary *dictionary = 
            [XMLReader dictionaryForXMLData:data 
                                      error:&error];
        // Dump the dictionary to the log file
        NSLog(@"feed = %@", dictionary);
        
        NSArray *entries =[self getEntriesArray:dictionary];
        
        // return the list if items from the feed.
        return entries;
    
    }
    复制代码
    复制代码

     

    Queued Asynchronous Requests:

    复制代码
    复制代码
    - (void) doQueuedRequest:(NSString *)urlString  delegate:(id)delegate {
        // make the NSURL object
        NSURL *url = [NSURL URLWithString:urlString];
        
        // create the request object with a no cache policy and a 30 second timeout.
        NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30.0];
        
        // If the queue doesn't exist, create one.
        if (queue == nil) {
            queue = [[NSOperationQueue alloc] init];
        }
        
        // send the request and specify the code to execute when the request completes or fails.
        [NSURLConnection sendAsynchronousRequest:request 
                                           queue:queue 
                               completionHandler:^(NSURLResponse *response, 
                                                   NSData *data, 
                                                   NSError *error) {
                                   
                if (error != nil) {
                   NSLog(@"Error on load = %@", [error localizedDescription]);
                } else {
                    
                    // check the HTTP status
                    if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
                        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                        if (httpResponse.statusCode != 200) {
                            return;
                        }
                        NSLog(@"Headers: %@", [httpResponse allHeaderFields]);
                    }
                                   
                    // parse the results and make a dictionary
                    NSDictionary *dictionary = 
                       [XMLReader dictionaryForXMLData:data 
                                                 error:&error];
                    NSLog(@"feed = %@", dictionary);
    
                    // get the dictionary entries.
                    NSArray *entries =[self getEntriesArray:dictionary];
    
                    // call the delegate
                    if ([delegate respondsToSelector:@selector(setVideos:)]) {
                        [delegate performSelectorOnMainThread:@selector(setVideos:) 
                                                   withObject:entries 
                                                waitUntilDone:YES];
                    }
                }
        }];
    }
    复制代码
    复制代码

    Asynchronous Requests:

    复制代码
    复制代码
    #import <Foundation/Foundation.h>
    
    #define kDownloadComplete   @"downloadComplete"
    
    @class DownloadProgressView;
    
    @interface AsyncDownloader : NSObject <NSURLConnectionDelegate> {
        // The number of bytes that need to be downloaded
        long long   downloadSize;
        // the total amount downloaded thus far
        long long   totalDownloaded;
    }
    // A reference to the progress view to show the user how things are progressing
    @property (assign) DownloadProgressView *progressView;
    // The target MP4 file
    @property (strong) NSString *targetFile;
    // The original URL to download.  Due to redirects the actual content may come from another URL
    @property (strong) NSString *srcURL;
    // The open file to which the content is written
    @property (strong) NSFileHandle *outputHandle;
    // The name of the temp file to which the content is streamed. This file is moved to the target file when
    // the download is complete
    @property (strong) NSString *tempFile;
    @property (strong) NSURLConnection *conn;
    
    // instructs the class to start the download.
    - (void) start;
    @end
    复制代码
    复制代码
    复制代码
    复制代码
    //
    //  AsyncDownloader.m
    //  VideoDownloader
    //
    //  Created by Jack Cox on 4/7/12.
    //   
    //
    
    #import "AsyncDownloader.h"
    #import "DownloadProgressView.h"
    
    @implementation AsyncDownloader
    
    @synthesize targetFile;
    @synthesize srcURL;
    @synthesize outputHandle;
    @synthesize tempFile;
    @synthesize progressView;
    @synthesize conn;
    
    - (void) start {
        NSLog(@"Starting to download %@", srcURL);
        
        // create the URL
        NSURL *url = [NSURL URLWithString:srcURL];
        
        // Create the request
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        // create the connection with the target request and this class as the delegate
        self.conn = 
             [NSURLConnection connectionWithRequest:request 
                                           delegate:self];
        
        // start the connection
        [self.conn start];
    }
    
    /**
     * Creates a UUID to use as the temporary file name during the download
     */
    - (NSString *)createUUID
    {
        CFUUIDRef uuidRef = CFUUIDCreate(NULL);
        CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);
        CFRelease(uuidRef);
        NSString *uuid = [NSString stringWithString:(__bridge NSString *)
                          uuidStringRef];
        CFRelease(uuidStringRef);
        return uuid;
    }
    #pragma mark NSURLConnectionDelegate methods
    /**
     * This delegate method is called when the NSURLConnection gets a 300 series response that indicates
     * that the request needs to be redirected.  It is implemented here to display any redirects that might
     * occur. This method is optional.  If omitted the client will follow all redirects.
     **/
    - (NSURLRequest *)connection:(NSURLConnection *)connection 
                 willSendRequest:(NSURLRequest *)request 
                redirectResponse:(NSURLResponse *)redirectResponse {
        
        // Dump debugging information
        NSLog(@"Redirect request for %@ redirecting to %@", srcURL, request.URL);
        NSLog(@"All headers = %@", 
              [(NSHTTPURLResponse*) redirectResponse allHeaderFields]);
        
        // Follow the redirect
        return request;
    }
    
    /**
     * This delegate method is called when the NSURLConnection connects to the server.  It contains the 
     * NSURLResponse object with the headers returned by the server.  This method may be called multiple times.
     * Therefore, it is important to reset the data on each call.  Do not assume that it is the first call
     * of this method.
     **/
    - (void) connection:(NSURLConnection *)connection 
     didReceiveResponse:(NSURLResponse *)response {
        NSLog(@"Received response from request to url %@", srcURL);
        
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        NSLog(@"All headers = %@", [httpResponse allHeaderFields]);
        
        if (httpResponse.statusCode != 200) {// something went wrong, abort the whole thing
            // reset the download counts
            if (downloadSize != 0L) {
                [progressView addAmountToDownload:-downloadSize];
                [progressView addAmountDownloaded:-totalDownloaded];
            }
            [connection cancel];
            return;
        }
        
        
        NSFileManager *fm = [NSFileManager defaultManager];
        
        // If we have a temp file already, close it and delete it
        if (self.tempFile != nil) {
            [self.outputHandle closeFile];
            
            NSError *error;
            [fm removeItemAtPath:self.tempFile error:&error];
        }
    
        // remove any pre-existing target file
        NSError *error;
        [fm removeItemAtPath:targetFile error:&error];
        
        // get the temporary directory name and make a temp file name
        NSString *tempDir = NSTemporaryDirectory();
        self.tempFile = [tempDir stringByAppendingPathComponent:[self createUUID]];
        NSLog(@"Writing content to %@", self.tempFile);
        
        // create and open the temporary file
        [fm createFileAtPath:self.tempFile contents:nil attributes:nil];
        self.outputHandle = [NSFileHandle fileHandleForWritingAtPath:self.tempFile];
        
        // prime the download progress view
        NSString *contentLengthString = [[httpResponse allHeaderFields] objectForKey:@"Content-length"];
        // reset the download counts
        if (downloadSize != 0L) {
            [progressView addAmountToDownload:-downloadSize];
            [progressView addAmountDownloaded:-totalDownloaded];
        }
        downloadSize = [contentLengthString longLongValue];
        totalDownloaded = 0L;
        
        [progressView addAmountToDownload:downloadSize];
    }
    /**
     * This delegate method is called for each chunk of data received from the server.  The chunk size
     * is dependent on the network type and the server configuration.  
     */
    - (void)connection:(NSURLConnection *)connection 
        didReceiveData:(NSData *)data {
        // figure out how many bytes in this chunk
        totalDownloaded+=[data length];
        
        // Uncomment if you want a packet by packet log of the bytes received.  
        NSLog(@"Received %lld of %lld (%f%%) bytes of data for URL %@", 
              totalDownloaded, 
              downloadSize, 
              ((double)totalDownloaded/(double)downloadSize)*100.0,
              srcURL);
        
        // inform the progress view that data is downloaded
        [progressView addAmountDownloaded:[data length]];
        
        // save the bytes received
        [self.outputHandle writeData:data];
    }
    
    /**
     * This delegate methodis called if the connection cannot be established to the server.  
     * The error object will have a description of the error
     **/
    - (void)connection:(NSURLConnection *)connection 
      didFailWithError:(NSError *)error {
        NSLog(@"Load failed with error %@", 
              [error localizedDescription]);
        
        NSFileManager *fm = [NSFileManager defaultManager];
        
        // If we have a temp file already, close it and delete it
        if (self.tempFile != nil) {
            [self.outputHandle closeFile];
            
            NSError *error;
            [fm removeItemAtPath:self.tempFile error:&error];
        }
        
        // reset the progress view
        if (downloadSize != 0L) {
            [progressView addAmountToDownload:-downloadSize];
            [progressView addAmountDownloaded:-totalDownloaded];
        }
    }
    
    /**
     * This delegate method is called when the data load is complete.  The delegate will be released 
     * following this call
     **/
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
        // close the file
        [self.outputHandle closeFile];
        
        // Move the file to the target location
        NSFileManager *fm = [NSFileManager defaultManager];
        NSError *error;
        [fm moveItemAtPath:self.tempFile 
                    toPath:self.targetFile 
                     error:&error];
        
        // Notify any concerned classes that the download is complete
        [[NSNotificationCenter defaultCenter] 
         postNotificationName:kDownloadComplete 
         object:nil 
         userInfo:nil];
    }
    @end
  • 相关阅读:
    CDH5.15.1 hive 连接mongodb配置及增删改查
    一些hue的参考网址
    CDH hue下定时执行hive脚步
    流式分析系统实现 之二
    流式分析系统实现 之一
    Spark升级--在CDH-5.15.1中添加spark2
    Spark 基础之SQL 快速上手
    CDH Spark-shell启动报错
    Spark SQL例子
    azkaban 配置邮件
  • 原文地址:https://www.cnblogs.com/iOS-mt/p/4114871.html
Copyright © 2011-2022 走看看