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 [email protected]"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
时间: 2024-10-21 11:34:09

IOS网络编程:HTTP的相关文章

iOS网络编程笔记——Socket编程

一.什么是Socket通信: Socket是网络上的两个程序,通过一个双向的通信连接,实现数据的交换.这个双向连路的一端称为socket.socket通常用来实现客户方和服务方的连接.socket是TCP/IP协议的一个十分流行的编程接口.一个socket由一个IP地址和一个端口号唯一确定.TCP/IP协议的传输层又有两种协议:TCP(传输控制协议)和UDP(用户数据报协议).TCP是基于连接的,而UDP是无连接的:TCP对系统资源的要求较多,而UDP少:TCP保证数据的正确性而UDP可能丢包:

iOS网络编程(六) NSURLSession详解

昨夜浏览Demo的时候,看到别人请求网络数据用的是NSURLSession,当时就在想这里什么,怎么没有用过,引起了我的好奇心,遂去百度-谷歌-官方文档一一查看,有了一定的了解,原来NSURLSession是iOS7中新的网络接口,它与咱们熟悉的NSURLConnection是并列的. 查找资料,写了一个小Demo,大家可以看看,有什么不足的地方,可以留言帮我指出来. // // HMTRootViewController.m // // // Created by HMT on 14-6-7.

iOS网络编程开发GET请求和POST请求

iOS网络编程开发GET请求和POST请求 一.GET请求和POST请求简单说明 创建GET请求 // 1.设置请求路径 NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text]; NSURL *url=[NSURL URLWithString:urlStr]

iOS网络编程(三) 异步加载及缓存图片----&gt;SDWebImage

@SDWebImage提供一个UIImageView的类别以支持加载来自网络的远程图片.具有缓存管理.异步下载.同一个URL下载次数控制和优化等特征. @SDWebImage的导入1.https://github.com/rs/SDWebImage 下载SDWebImage开源包2.将类包拖入工程,再导入MapKit.framework.ImageIO.framework两个框架3.SDWebImage是支持ARC的,在MRC的工程中要注意,可参考MRC工程配置ARC4.注意:SDWebImag

iOS网络编程开发—JSON和XML数据解析

iOS网络编程开发—JSON解析 一.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) JSON的格式很像OC中的字典和数组 {"name" : "jack", "age" : 10} {"names" : ["jack", "rose", "jim"]} 标准JSON格式的

iOS网络编程--NSConnection的同步连接与异步连接

1 // 2 // ZFViewController.m 3 // 0628-表单验证 4 // 5 // Created by zfan on 14-6-28. 6 // Copyright (c) 2014年 zfan. All rights reserved. 7 // 8 9 #import "ZFViewController.h" 10 #import "MBProgressHUD+MJ.h" 11 12 @interface ZFViewControll

iOS网络编程(7) 第三方开源库-----&gt;AFNetworking

AFNetworking是一个为 iOS 和 Mac OSX 制作的令人愉快的网络库,它建立在URL 装载系统框架的顶层,内置在Cocoa里,扩展了强有力的高级网络抽象.它的模块架构被良好的设计,拥有丰富的功能,因此,使用起来,必定赏心悦目. @原文链接https://github.com/AFNetworking/AFNetworking,我在此基础上了点配置修改 @介绍 1.支持HTTP请求和基于REST的网络服务(包括GET.POST. PUT.DELETE等) 2.支持ARC 3.要求i

IOS网络编程——第三方类库

IOS网络编程——第三方类库 目录 概述 ASIHttpRequest AFNetworking 其他 概述 ASIHttpRequest AFNetworking 其他

iOS网络编程开发—HTTP协议

iOS网络编程开发—HTTP协议 说明:apache tomcat服务器必须占用8080端口 一.URL 1.基本介绍 URL的全称是Uniform Resource Locator(统一资源定位符) 通过1个URL,能找到互联网上唯一的1个资源 URL就是资源的地址.位置,互联网上的每个资源都有一个唯一的URL 2.URL中常见的协议 (1)HTTP 超文本传输协议,访问的是远程的网络资源,格式是http:// http协议是在网络开发中最常用的协议 (2)file 访问的是本地计算机上的资源