DragFan目前的网络连接使用了ASIHTTPRequest这个第三方库。ASIHTTPRequest
是一个相对非常庞大的库,在心理上我总觉得用在DragFan里有点大材小用了。因此,我今天试着寻找了一下替代方案。很幸运,我找到了一个不错的替代方案,而且是利用现有的Cocoa API,而且在iOS下也是能使用的。
尽管印象中看到过文章说用Cocoa的网络API的性能没有用CoreFoundation的性能好,但是目前我在写的程序并没有特别的需要高性能,而且用Cocoa的API,程序的可读性和内存管理也更加直观,应该说,是一个比较好的方案。
废话了一通,下面来看看究竟是如何实现的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
| #define FANFOU_SEND_PHOTO_API @"http://api.fanfou.com/photos/upload.json"
- (IBAction)sendMessage:(id)sender {
// 创建Request对象
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:FANFOU_SEND_PHOTO_API]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// 定义boundary
NSString *boundary = @"----Boundary+WhateverYouLikeToPutInHere----datatata--done";
// 使用POST方法
[req setHTTPMethod:@"POST"];
// 设置Content-Type
[req setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary, nil] forHTTPHeaderField:@"Content-Type"];
// 把图片变成data。
NSImage *theImage = [self.imageView image];
NSBitmapImageRep *bitmap = [[theImage representations] objectAtIndex:0];
NSData *imageData = [bitmap representationUsingType:NSJPEGFileType properties: nil];
// 需要POST的键值对
NSDictionary *values = [NSDictionary dictionaryWithObjectsAndKeys:[messageField string], @"status", imageData, @"photo", nil];
// 初始化POST Data
NSMutableData *d = [NSMutableData data];
// 遍历键值对,将其转换成NSData
for (NSString *key in [values allKeys]) {
// Append一个Boundary
[d appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
id currentValue = [values objectForKey:key];
if( [currentValue isKindOfClass:[NSData class]] && [NSImageRep imageRepClassForData:currentValue] != nil ) {
// 如果是图片对象的处理方法。
// 设置Content-Disposition,这里设置图片对应的key的名字
[d appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.png\"\r\n", key]
dataUsingEncoding:NSUTF8StringEncoding]];
// 设置图片的Content-Type
[d appendData:[@"Content-Type: image/png\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
// 设置传输编码为二进制
[d appendData:[@"Content-Transfer-Encoding: binary\r\n\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
// Append图片
[d appendData:currentValue];
}
else {
// 字符串值的处理方法
// Append一个Boundary
[d appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// 设置字符串键
[d appendData:[@"Content-Disposition: form-data; name=\"status\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
// 设置字符串值
[d appendData:[[NSString stringWithFormat:@"%@", currentValue] dataUsingEncoding:NSUTF8StringEncoding]];
}
}
// 最后Append一个Boundary
[d appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// 设置数据为请求的Body
[req setHTTPBody:d];
// 建立一个连接,用来发送请求,并且设置delegate为self,这里主要用来处理BasicAuth
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:req delegate:self];
if (theConnection) {
// 处理连接成功
} else {
// 处理链接失败
}
[req release];
}
// NSURLConnection的Delegate方法,用来处理Basic Auth。
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential = [NSURLCredential credentialWithUser:@"YOUR_USER_NAME"
password:@"YOUR_PASSWORD"
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential
forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
// 处理认证失败
}
}
|
利用NSMutableURLRequest
应该也能够轻松的实现饭否Basic Auth API的Cocoa封装,配合其他的一些库,要实现OAuth的封装应该也没有什么问题的。我目前对NSMutableURLRequest
的理解还只是一知半解,所以继续研究文档去。。。下一版DragFan中,我会用NSMutableURLRequest
替代ASIHTTPRequest
,实现DragFan的图片发送功能。
(本文参考了这里和这里)
(全文完)