iOS开发之CFNetWork的简单使用
来源:互联网 发布:浙商控股集团 知乎 编辑:程序博客网 时间:2024/04/29 02:33
CFNetWork是苹果提供的位于 Core Foundation 中的一个基于C的底层框架,是对更底层OS层BSD socket的封装,著名的网络框架ASI网络请求方面就是对CFNetWork进行封装的。
CFNetWork主要依赖俩个API,CFSocket 和 CFStream,CFSocket主要用于网络底层的通信,而CFStream包括CFReadStream 和 CFWriteStream,分别用于对Socket的读取和写入。
昨天下午小小研究了一ASIHttpRequest,顺带着看了看CFNetWork框架,试着写了一个小Demo,主要是用CFNetWork请求网上的一张图片,向新浪微博上传发送一张图片。
首先构造URL
//url(度娘上的一张图片) CFStringRef urlStr = CFSTR("http://c.hiphotos.baidu.com/image/w%3D310/sign=b8f7695888d4b31cf03c92bab7d6276f/4e4a20a4462309f76248df09710e0cf3d7cad682.jpg"); //GET请求 CFStringRef method = CFSTR("GET"); //构造URL CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault, urlStr, NULL);
//http请求 CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, method, url, kCFHTTPVersion1_1); //创建一个读取流 读取网络数据 CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request); //设置流的context这里将self传入,用于以后的回调 CFStreamClientContext ctxt = {0, (__bridge void *)(self), NULL, NULL, NULL};
设置回调事件,用于监听网络事件
//监听回调事件 // kCFStreamEventNone,(没有事件发生)// //kCFStreamEventOpenCompleted,(流被成功打开)// //kCFStreamEventHasBytesAvailable,(有数据可以读取)// //kCFStreamEventCanAcceptBytes,(流可以接受写入数据(用于写入流))// //kCFStreamEventErrorOccurred,(在流上有错误发生)// //kCFStreamEventEndEncountered ,(到达了流的结束位置) CFOptionFlags event = kCFStreamEventHasBytesAvailable|kCFStreamEventEndEncountered;
传入回调函数,用于接收的流事件的回调
//设值回调函数myCallBack // 回调函数格式// void callBack(CFReadStreamRef stream,CFStreamEventType type,void *clientCallBackInfo) CFReadStreamSetClient(readStream, event, myCallBack, &ctxt);
将流加入到runloop中,并打开流
//将流加入到runloop中 CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); //打开流 CFReadStreamOpen(readStream);
回调函数的实现,接收请求到的数据
void myCallBack (CFReadStreamRef stream,CFStreamEventType type,void *clientCallBackInfo){ if (type == kCFStreamEventHasBytesAvailable) { //将流中的数据存入到数组中 UInt8 buff [255]; int length = CFReadStreamRead(stream, buff, 255); if (!imageData) { imageData = [NSMutableData data]; } [imageData appendBytes:buff length:length]; } if (type == kCFStreamEventEndEncountered) { //通知imageView显示图片 [(__bridge ViewController *)clientCallBackInfo didRequestImage]; //关闭流 CFReadStreamClose(stream); //将流从runloop中移除 CFReadStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); }}
最后就非常简单了将接收到的数据转成图片,给UIImageView显示就行了.
- (void)didRequestImage{ UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 100, 320, 200)]; UIImage *image = [UIImage imageWithData:imageData]; imageView.image = image; [self.view addSubview:imageView];}
上面是通过CFNetWork请求数据,看起来挺简单的吧,下面是通过CFNetWork向 新浪微博发送一张图片,上传的流程和上面的差不太多,主要是拼接数据麻烦一些,下面放上代码。
//url CFStringRef urlStr = CFSTR("https://upload.api.weibo.com/2/statuses/upload.json"); //POST请求 CFStringRef method = CFSTR("POST"); CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault, urlStr, NULL); CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, method, url, kCFHTTPVersion1_1);
//设置请求头,和请求体,注意只有POST才需要设置请求体
//设置请求头 //分割符,HTTP上传文件的固定格式 NSString *boundary = [NSString stringWithFormat:@"---------------------------14737809dasdasda2746641449"]; NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; //OC的字符串要做C框架中使用需要__bridge桥接 CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), (__bridge CFStringRef)(contentType));
请求体
//设置请求体 NSData *bodyData = [self getRequestData]; CFHTTPMessageSetBody(request, (__bridge CFDataRef)(bodyData));
请求体的拼接
//拼装请求体- (NSData *)getRequestData{ //需要上传的图片 UIImage *image = [UIImage imageNamed:@"cat.png"]; NSData *imageData = UIImagePNGRepresentation(image); //分隔符,注意要与上面请求头中的一致 NSString *boundary = [NSString stringWithFormat:@"---------------------------14737809dasdasda2746641449"]; //定义可变Data; NSMutableData *body = [NSMutableData data]; //分隔符 [body appendData:[[NSString stringWithFormat:@"\r\n\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; //需要发送的文字内容 [body appendData:[@"Content-Disposition: form-data; name=\"status\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"需要发送的文字内容\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; //分隔符 [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; //需要发送的图片内容 [body appendData:[@"Content-Disposition: form-data; name=\"pic\"; filename=\"cat.png\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"Content-Type: image/png\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[NSData dataWithData:imageData]]; //分割符 [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; //access_token 向新浪微博发送内容,需要OAuth认证,这里必须带上access_token [body appendData:[@"Content-Disposition: form-data; name=\"access_token\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"2.00svaeojkrewe901dPLialB" dataUsingEncoding:NSUTF8StringEncoding]]; //结尾注意这里的分割符和前面不一样,--%@--后面多了两条--,如果少了会发送不成功哦 [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; return body;}
然后将流加入到runloop中,打开流就OK了,剩下的基本和第一个Demo相同,在此就不再啰嗦了。
Ok发送成功
0 0
- iOS开发之CFNetWork的简单使用
- iOS开发之CFNetWork的简单使用
- iOS开发之CFNetWork的简单使用
- iOS网络编程之CFNetwork
- iOS网络编程之CFNetwork
- iOS网络编程之CFNetwork
- iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- [深入浅出Cocoa]iOS网络编程之CFNetwork
- JS基础——函数的创建和使用
- Cocos2d-X中的字体
- 大数求余(java高精度)
- hdu 1398 Square Coins (母函数)
- 继承、派生
- iOS开发之CFNetWork的简单使用
- 流对象
- Mac下同时安装多个版本的JDK
- 关于Windows7 下面安装memcached和php的memcache扩展
- Android 利用fastjson进行json解析
- 回调函数
- 使用存储过程操作数据表
- hdu1715(高精度····JAVA版)
- static inline