=。=第一次在CSDN上写博客,有点紧张。
最近用XCODE做了一个小项目,就是新浪微博,现在想写一篇关于新浪微博的总结。
首先先来讲讲我的架构吧,大致是这个样子,我把所有的MVC都分好类,一些小处理关于到整个程序的写到Commons里,然后把所有用到的API放到头文件中。
那么这样,整个程序的脉络就显得很清晰了。
现在进入正题,为了实现新浪微博,首先你必须得调用到新浪中的数据,要调用新浪的数据,必须实现的一步就是OAuth2.0认证,这在新浪的API文档里面有详细的解释,我这就不再赘述。
为了方便,我把API头文件里的内容放在此处:
OAuth2.0认证,你需要先使用一个UIWebView来打开认证的页面,认证页面如图:
打开页面的代码如下:
写在实现认证的controller的viewDidLoad里面。
上面的getCodeAddress是一个拿到Authentication code的url地址,保存在API里面。
使用新浪API的时候,有一点困扰了我很久的就是,怎么通过URL传参数过去,比如到时要取得AccessToken的时候,需要传code过去,其实非常简单,新浪的文档里也有说,他给你的API接口后面加一个问号?参数1=参数值1&参数2=参数值2就可以了。
回到正题,从上述的办法中你可以输入你的微博账号和密码了,然后输入没错之后,就可以得到Authentication code,那么如何拿到这个code呢?
很简单,你只需要实现一个实例方法
就可以了,这是UIWebView中的一个实例方法,request中包含了一个返回回来的url。code也被包含在这个url中,
用这两行代码,获得返回回来的URL并将其变成字符串类型。
然后如何将藏在返回的URL中的code剥离出来呢,我用了以下办法,我在我的commons中的OAuthOp类中定义了一个操作,用来取code的,
就是这个方法,在获得返回的urlString后,直接传到这个方法中来,用range把@”code=“后面的code值弄出来,然后将它返回出去,然后直接用于AccessToken的获取。
以下是我获取到AccessToken的办法,
这里有一个变量,getData,其实它是一个我定义的一个类的实例,这个类是GetJSONData,其中定义了两个实例方法,一种是向指定网页请求数据并且可以自己决定请求方式是Get还是Post,该方法的代码如下:
从上面我们可以看到,返回来包含AccessToken的数据是NSData类型,这时候,我们需要用一个XCODE中很强大的类——
NSJSONSerialization,其中有一个类方法
可以将你得到的NSData二进制数字串序列化成为一个id类型。
而返回的装有AccessToken的数据实际上是一个字典。
于是要对数据进行如下操作:
上面又使用了一个OAuthOp中的一个实例方法,实际上OAuthOp中定义了几个属性,用来装AccessToken和AccessToken的生命周期和uid。实际后两者在本次项目中没什么用=。=。其实上面说的那个init......的那个实例方法就类似于一个setter函数而已。
做到这里,你已经可以成功拿到AccessToken了。
你甚至可以Debug到OAuthOp中的那个init..............的那个方法中看AccessToken的值。
然后,就是将AccessToken进行保存的问题,为了方便,不用每次登陆都要经过OAuth的验证。我用的办法是使用NSUserDefault。当然你也可以用plist和bundle来储存。
所以我的用于OAuth的view controller的viewDidLoad方法和获取web返回数据的方法的完整代码是这样的:
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view.
NSString *urlString = getCodeAddress;
if ([[NSUserDefaultsstandardUserDefaults]objectForKey:@"access_token"]==nil) {
NSURLRequest *request = [[NSURLRequestalloc] initWithURL:[NSURLURLWithString:urlString]];
[self.myWebViewsetDelegate:self];
[self.myWebViewloadRequest:request];
}
else {
self.oauthOp=[[OAuthOpalloc]initWithAccessToken:[[NSUserDefaultsstandardUserDefaults]objectForKey:@"access_token"]andExpiresIn:[[NSUserDefaultsstandardUserDefaults]objectForKey:@"expires_in"]andUID:[[NSUserDefaultsstandardUserDefaults]objectForKey:@"uid"]];
[selfperformSegueWithIdentifier:@"Segue_WB"sender:self];
}
self.title=@"Oauth认证";
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *BackURL=[request URL];
NSString *BackURLString=[BackURL absoluteString];
GetJSONData *getData=[[GetJSONDataalloc]init];
if ([BackURLString hasPrefix:myBackURL]) {
NSLog(@"BackURLString is:%@",BackURLString);
self.oauthOp=[[OAuthOpalloc]init];
NSString *codeString=[self.oauthOpgetAuthorCodeWithURLString:BackURLString];
NSLog(@"code=%@",codeString);
NSData *data=[getData JSONData:authorizeAddress byAppendingString:codeStringwithHTTPMethod:@"POST"];
NSError *error=nil;
NSDictionary *dataDic=[NSJSONSerializationJSONObjectWithData:data options:kNilOptionserror:&error];
self.oauthOp=[self.oauthOpinitWithAccessToken:[dataDic valueForKey:@"access_token"]andExpiresIn:[dataDic valueForKey:@"expires_in"]andUID:[dataDic valueForKey:@"uid"]];
[[NSUserDefaultsstandardUserDefaults]setObject:self.oauthOp.access_tokenforKey:@"access_token"];
[[NSUserDefaultsstandardUserDefaults]synchronize];
[[NSUserDefaultsstandardUserDefaults]setObject:self.oauthOp.expires_inforKey:@"expires_in"];
[[NSUserDefaultsstandardUserDefaults]synchronize];
[[NSUserDefaultsstandardUserDefaults]setObject:self.oauthOp.uidforKey:@"uid"];
[[NSUserDefaultsstandardUserDefaults]synchronize];
[selfperformSegueWithIdentifier:@"Segue_WB"sender:self];
}
return YES;
}
当然,还有一个用来传参数给segue目标控制器的方法:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
WeiboTableViewController *v=[seguedestinationViewController];
v.oauthOption=self.oauthOp;
}
本章到此。