ios开发小项目——新浪微博(一)——OAuth认证

来源:互联网 发布:网络棋牌代理犯法吗? 编辑:程序博客网 时间:2024/05/17 23:38

=。=第一次在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:dataoptions:kNilOptionserror:&error];

        self.oauthOp=[self.oauthOpinitWithAccessToken:[dataDicvalueForKey:@"access_token"]andExpiresIn:[dataDicvalueForKey:@"expires_in"]andUID:[dataDicvalueForKey:@"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;

}


本章到此。






0 0
原创粉丝点击