iOS开发之CFNetWork的简单使用

CFNetWork是苹果提供的位于 Core Foundation 中的一个基于C的底层框架,是对更底层OS层BSD socket的封装,著名的网络框架ASI网络请求方面就是对CFNetWork进行封装的

CFNetWork主要依赖俩个API,CFSocket 和 CFStream,CFSocket主要用于网络底层的通信,而CFStream包括CFReadStream 和 CFWriteStream,分别用于对Socket的读取和写入。

昨天下午小小研究了一ASIHttpRequest,顺带着看了看CFNetWork框架,试着写了一个小Demo,主要是用CFNetWork请求网上的一张图片,向新浪微博上传发送一张图片。

首先构造URL

[objc]  view plain  copy
  1. //url(度娘上的一张图片)  
  2. CFStringRef urlStr = CFSTR("http://c.hiphotos.baidu.com/image/w%3D310/sign=b8f7695888d4b31cf03c92bab7d6276f/4e4a20a4462309f76248df09710e0cf3d7cad682.jpg");  
  3.   
  4. //GET请求  
  5. CFStringRef method = CFSTR("GET");  
  6.   
  7. //构造URL  
  8. CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault, urlStr, NULL);  


然后通过 CFReadStream发送http请求

[objc]  view plain  copy
  1. //http请求  
  2. CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, method, url, kCFHTTPVersion1_1);  
  3.   
  4. //创建一个读取流 读取网络数据  
  5. CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);  
  6.   
  7. //设置流的context这里将self传入,用于以后的回调  
  8. CFStreamClientContext ctxt = {0, (__bridge voidvoid *)(self), NULLNULLNULL};  

设置回调事件,用于监听网络事件

[objc]  view plain  copy
  1.     //监听回调事件  
  2.       
  3. //  kCFStreamEventNone,(没有事件发生)  
  4. //      
  5. //  kCFStreamEventOpenCompleted,(流被成功打开)  
  6. //      
  7. //  kCFStreamEventHasBytesAvailable,(有数据可以读取)  
  8. //      
  9. //  kCFStreamEventCanAcceptBytes,(流可以接受写入数据(用于写入流))  
  10. //      
  11. //  kCFStreamEventErrorOccurred,(在流上有错误发生)  
  12. //      
  13. //  kCFStreamEventEndEncountered ,(到达了流的结束位置)  
  14.     CFOptionFlags event = kCFStreamEventHasBytesAvailable|kCFStreamEventEndEncountered;  
  15.       

传入回调函数,用于接收的流事件的回调

[objc]  view plain  copy
  1.     //设值回调函数myCallBack  
  2.       
  3. //    回调函数格式  
  4. //    void callBack(CFReadStreamRef stream,CFStreamEventType type,void *clientCallBackInfo)  
  5.       
  6.     CFReadStreamSetClient(readStream, event, myCallBack, &ctxt);  

将流加入到runloop中,并打开流

[objc]  view plain  copy
  1. //将流加入到runloop中  
  2. CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);  
  3.   
  4. //打开流  
  5. CFReadStreamOpen(readStream);  

回调函数的实现,接收请求到的数据

[objc]  view plain  copy
  1. void myCallBack (CFReadStreamRef stream,CFStreamEventType type,voidvoid *clientCallBackInfo){  
  2.       
  3.     if (type == kCFStreamEventHasBytesAvailable) {  
  4.           
  5.         //将流中的数据存入到数组中  
  6.         UInt8 buff [255];  
  7.         int length = CFReadStreamRead(stream, buff, 255);  
  8.           
  9.         if (!imageData) {  
  10.             imageData = [NSMutableData data];  
  11.         }  
  12.   
  13.         [imageData appendBytes:buff length:length];  
  14.           
  15.     }  
  16.     if (type == kCFStreamEventEndEncountered) {  
  17.           
  18.         //通知imageView显示图片  
  19.         [(__bridge ViewController *)clientCallBackInfo didRequestImage];  
  20.           
  21.         //关闭流  
  22.         CFReadStreamClose(stream);  
  23.         //将流从runloop中移除  
  24.         CFReadStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);  
  25.     }  
  26. }  

最后就非常简单了将接收到的数据转成图片,给UIImageView显示就行了.

[objc]  view plain  copy
  1. - (void)didRequestImage{  
  2.     UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0100320200)];  
  3.     UIImage *image = [UIImage imageWithData:imageData];  
  4.     imageView.image = image;  
  5.       
  6.     [self.view addSubview:imageView];  
  7. }  

上面是通过 CFNetWork请求数据,看起来挺简单的吧,下面是通过 CFNetWork向 新浪微博发送一张图片,上传的流程和上面的差不太多,主要是拼接数据麻烦一些,下面放上代码。

[objc]  view plain  copy
  1. //url  
  2. CFStringRef urlStr = CFSTR("https://upload.api.weibo.com/2/statuses/upload.json");  
  3.   
  4. //POST请求  
  5. CFStringRef method = CFSTR("POST");  
  6.   
  7. CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault, urlStr, NULL);  
  8.   
  9. CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, method, url, kCFHTTPVersion1_1);  

//设置请求头,和请求体,注意只有POST才需要设置请求体

[objc]  view plain  copy
  1. //设置请求头  
  2. //分割符,HTTP上传文件的固定格式  
  3. NSString *boundary = [NSString stringWithFormat:@"---------------------------14737809dasdasda2746641449"];  
  4. NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];  
  5.   
  6. //OC的字符串要做C框架中使用需要__bridge桥接  
  7. CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), (__bridge CFStringRef)(contentType));  

请求体

[objc]  view plain  copy
  1. //设置请求体  
  2. NSData *bodyData = [self getRequestData];  
  3. CFHTTPMessageSetBody(request, (__bridge CFDataRef)(bodyData));  

请求体的拼接

[objc]  view plain  copy
  1. //拼装请求体  
  2. - (NSData *)getRequestData{  
  3.       
  4.     //需要上传的图片  
  5.     UIImage *image = [UIImage imageNamed:@"cat.png"];  
  6.     NSData *imageData = UIImagePNGRepresentation(image);  
  7.       
  8.       
  9.     //分隔符,注意要与上面请求头中的一致  
  10.     NSString *boundary = [NSString stringWithFormat:@"---------------------------14737809dasdasda2746641449"];  
  11.       
  12.       
  13.     //定义可变Data;  
  14.     NSMutableData *body = [NSMutableData data];  
  15.       
  16.     //分隔符  
  17.     [body appendData:[[NSString stringWithFormat:@"\r\n\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];  
  18.       
  19.     //需要发送的文字内容  
  20.     [body appendData:[@"Content-Disposition: form-data; name=\"status\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];  
  21.     [body appendData:[@"需要发送的文字内容\r\n" dataUsingEncoding:NSUTF8StringEncoding]];  
  22.       
  23.     //分隔符  
  24.     [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];  
  25.       
  26.     //需要发送的图片内容  
  27.     [body appendData:[@"Content-Disposition: form-data; name=\"pic\"; filename=\"cat.png\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];  
  28.     [body appendData:[@"Content-Type: image/png\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];  
  29.     [body appendData:[NSData dataWithData:imageData]];  
  30.       
  31.     //分割符  
  32.     [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];  
  33.       
  34.     //access_token 向新浪微博发送内容,需要OAuth认证,这里必须带上access_token  
  35.     [body appendData:[@"Content-Disposition: form-data; name=\"access_token\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];  
  36.       
  37.     [body appendData:[@"2.00svaeojkrewe901dPLialB" dataUsingEncoding:NSUTF8StringEncoding]];  
  38.       
  39.     //结尾注意这里的分割符和前面不一样,--%@--后面多了两条--,如果少了会发送不成功哦  
  40.     [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];  
  41.       
  42.     return body;  
  43. }  

然后将流加入到runloop中,打开流就OK了,剩下的基本和第一个Demo相同,在此就不再啰嗦了。

Ok发送成功



转载:http://blog.csdn.net/u013341398/article/details/39754133


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值