感谢borluse, 原文出处: http://blog.sina.com.cn/s/blog_52e8bd020100o012.html
今晚照往常一样继续我的sina微博Mac下客户端的开发, 结果死活也打不开sina的API网站. 难道法国连接国内的电缆又出问题了? 既然如此, 那就把我这两天的开发心得记录下来.
这篇文章的目的是想详细说下如何用oob模式连接sina微博. 内容应该说非常基本. 老鸟可以无视. 如果你是和我一样的新手, 刚刚学会cocoa和objc, 那这篇文章应该能帮助到你.
一. 准备工作
sina微博采用了和twitter基本一样的认证过程, 即OAuth认证模式. (吐槽一下, 不光是OAuth, 如果你仔细看过twitter的API, 你会发现, sina微博就是twitter的克隆. 连API文档基本也都是照搬过来) 如果你对OAuth认证模式不是太熟悉, 那最好找一下文章大概了解了解.
为了在mac下连接sina微博,我们可以使用几个已经实现OAuth协议的framework. sina官方的OAuth页面的最下面给了推荐的几个. 这里我选的是OAuthConsumer.
OAuthConsumer的地址在这里: http://code.google.com/p/oauthconsumer/
英文版的使用方法在这里: http://code.google.com/p/oauthconsumer/wiki/UsingOAuthConsumer
下载OAuthConsumer的方法: 在你的终端里, 输入如下命令 :
需要注意的是, 这个OAuthConsumer还是个老版本, 只支持到OAuth1.0. 新浪微博使用的是OAuth1.0a. 所以下载后,我们要进行一点点的修改.
1, 打开oauth的目录下的OAuthConsumer.xcodeproj
2, 打开classes/OAMutableURLRequest.m, 找到函数 -(NSString*) _signatureBaseString
3, 在NSArray *sortedPairs = [parameterPairs sortedArrayUsingSelector:@selector(compare:)];之前加入如下这段代码:
//Begin custom
for (NSString *parameterName in [[extraOAuthParameters allKeys] sortedArrayUsingSelector:@selector(compare:)]) {
[parameterPairs addObject:[[OARequestParameter requestParameterWithName:parameterName value:[extraOAuthParameters objectForKey:parameterName]] URLEncodedNameValuePair]];
}
//end custom
4, 保存. 选择编译目标(Active target)为:OAuthConsumer. 这样我们的framework就可以使用了.
5, 从products中将OAuthConsumer.framework拖到你的project中, 使用copy模式.
6, 在你的project的主要目标中添加一个copy files build phase, 从你的project中将OAuthConsumer.framework托拽到这个新的copy files build phase里.
7, 至此, OAuthConsumer已经可以使用了.
要使用OAuthConsumer, 需要引用头文件 #import <OAuthConsumer/OAuthConsumer.h>
二, OAuthConsumer的使用方法:
1. 是用你的新浪注册开发时提供的appkey和appsecret创建一个consumer:
OAConsumer *consumer = [[OAConsumer alloc] initWithKey:@"mykey"
secret:@"mysecret"];
2. 创建一个request:
NSURL *url = [NSURL URLWithString:@"http://example.com/get_request_token"];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer //上面创建的consumer
token:aToken //一个密钥对, 后面会详细说
realm:nil //貌似没什么用,使用nil就好
signatureProvider:nil]; //默认为HMAC-SHA1.我们传nil就行
3. 设置HTTP方法
[request setHTTPMethod:@"POST"];
4. 设置额外的参数
[request setOAuthParameterName:@"oauth_callback" withValue:@"oob"];
5. 创建fetcher对象
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:@selector(requestTokenTicket:didFinishWithData:)
didFailSelector:@selector(requestTokenTicket:didFailWithError:)];
didFinishSelector后的代理方法名称可以不同. 比如说对应requesttoken可一有个requestTokenTicket:didfinishWithData. 对应accessToken,这个可以是accessTokenTicket:didFinishWithData. 对于didFailSelector也是一样的.
6. 创建代理方法.
- (void)requestTokenTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data {
if (ticket.didSucceed) {
NSString *responseBody = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
requestToken = [[OAToken alloc] initWithHTTPResponseBody:responseBody];
}
}
以上是OAConsumer的基本使用方法. 下面将具体介绍连接sina微博的步骤.
PS: requestToken是一个外面定义好的OAToken对象. 定义为:
OAToken *requestToken;
后面还会用到accessToken, 同requestToken的定义一样.
三, 连接sina微博.
是用OAuth连接sina微博可分为以下几步:
1. 获取requestToken.
2. 重定向用户到认证页面. 用户会获取一个PIN码.
3. 使用这个PIN码来获取accessToken
这几步在sina的api中都有详细的说明, 这里大概贴一下我的代码. 与上一部分写的一样. 这里只贴下request的创建过程.
1. 获取requestToken.
获取requestToken时, 我们还没有token可以使用, 所以创建request如下:
NSURL * url = [NSURL URLWithString:@"http://api.t.sina.com.cn/oauth/request_token"] ;
OAMutableURLRequest * request = [[OAMutableURLRequest alloc] initWithURL: url
consumer:consumer
token:nil realm:nil signatureProvider:nil];
[request setHTTPMethod:@"POST"]; //Post方法传参
[request setOAuthParameterName:@"oauth_callback" withValue:@"oob"]; //加入参数 oauth_callback=oob
服务器会返回一个requestToken. 保存好. 这里假定保存到requestToken这个对象中
2. 重定向用户到认证页面.
可以用这个方法:
NSURL *url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/oauth/authorize?auth_token=%@", requestToken.key];
[[NSWorkspace sharedWorkspace] openURL:url];
3. 获取accessToken
这里需要用到用户获得的PIN码. 代码如下:
NSURL *url = [NSURL URLWithString:@"http://api.t.sina.com.cn/oauth/access_token"]
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer
token:requestToken realm:NULL
gnatureProvider:nil];
[request setOAuthParameterName:@"oauth_callback" withValue:@"oob"];
[request setOAuthParameterName:@"oauth_verifier" withValue:pin];
当获取了accessToken, 我们就可以用这个token来调用sina其他的API了.