[iOS微博项目 - 2.2] - 在app中获取授权
A.发送授权请求
1.使用UIWebView加载请求页面
自定义一个继承UIViewController的HVWOAuthViewController
1 // 2 // HVWOAuthViewController.m 3 // HVWWeibo 4 // 5 // Created by hellovoidworld on 15/2/4. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWOAuthViewController.h" 10 11 @interface HVWOAuthViewController () 12 13 @end 14 15 @implementation HVWOAuthViewController 16 17 - (void)viewDidLoad { 18 [super viewDidLoad]; 19 // Do any additional setup after loading the view. 20 21 // 创建UIWebView 22 UIWebView *webView = [[UIWebView alloc] init]; 23 webView.frame = self.view.bounds; 24 25 // 添加到主界面 26 [self.view addSubview:webView]; 27 28 // 加载请求页面 29 NSURL *url = [NSURL URLWithString:@"https://api.weibo.com/oauth2/authorize?client_id=3942775926&redirect_uri=http://www.cnblogs.com/hellovoidworld/"]; 30 NSURLRequest *request = [NSURLRequest requestWithURL:url]; 31 [webView loadRequest:request]; 32 } 33 34 35 @end
把这个控制器作为window的根控制器运行测试:
AppDelegate:
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 2 // Override point for customization after application launch. 3 4 // 启动后显示状态栏 5 UIApplication *app = [UIApplication sharedApplication]; 6 app.statusBarHidden = NO; 7 8 // 设置window 9 self.window = [[UIWindow alloc] init]; 10 self.window.frame = [UIScreen mainScreen].bounds; 11 12 self.window.rootViewController = [[HVWOAuthViewController alloc] init]; 13 [self.window makeKeyAndVisible]; 14 15 return YES; 16 }
2.使用UIWebView代理拦截发送url动作,发送授权请求之后发送的url就带有access_code
1 /** 截取web发送请求 */ 2 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { 3 4 NSString *urlStr = request.URL.absoluteString; 5 NSRange range = [urlStr rangeOfString:@"http://www.cnblogs.com/hellovoidworld/?code="]; 6 if (range.length > 0) { // 如果是匹配的url,即发送的是带access_code的url 7 // 截取access_code 8 NSUInteger accessCodeLocation = range.length + range.location; 9 NSString *accessCode = [urlStr substringFromIndex:accessCodeLocation]; 10 11 HVWLog(@"%@", accessCode); 12 13 return NO; // 阻止发送,不需要跳转到重定向页面 14 } 15 16 return YES; // 其他情况照常发送 17 }
Output:
5bef5308ba902cc52d9f2dc34bbfdd1c
注意这个access_code每次都不一样的
3.获取access_token
(1)获取access_token的请求API,发送POST请求
(2)使用AFN框架来发送post请求
1 /** 根据access_code获取access_token */ 2 - (void) accessTokenWithAccessCode:(NSString *) accessCode { 3 // 创建AFN的http操作请求管理者 4 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 5 6 // 参数设置 7 NSMutableDictionary *param = [NSMutableDictionary dictionary]; 8 param[@"client_id"] = @"3942775926"; 9 param[@"client_secret"] = @"cc577953b2aa3aa8ea220fd15775ea35"; 10 param[@"grant_type"] = @"authorization_code"; 11 param[@"code"] = accessCode; 12 param[@"redirect_uri"] = @"http://www.cnblogs.com/hellovoidworld/"; 13 14 // 发送请求 15 [manager POST:@"https://api.weibo.com/oauth2/access_token" parameters:param success:^(AFHTTPRequestOperation *operation, NSDictionary *accountInfo) { 16 [MBProgressHUD hideHUD]; 17 18 // 返回的是用户信息字典 19 HVWLog(@"%@", accountInfo); 20 21 22 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 23 [MBProgressHUD hideHUD]; 24 25 HVWLog(@"请求access_token失败 ----> %@", error); 26 }]; 27 28 }
(3)由于新浪返回的json数据Content-Type是 text/plain,但是AFNetworking框架默认的json序列化器不能识别,所以要修改一下json序列化器的acceptableContentType
1 - (instancetype)init { 2 self = [super init]; 3 if (!self) { 4 return nil; 5 } 6 7 self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/plain", nil]; 8 9 return self; 10 }
Output:
{
"access_token" = "2.00A5GpAGGIUpSEff44478fe90yykBw";
"expires_in" = 181897;
"remind_in" = 181897;
uid = 5508976272;
"access_token" = "2.00A5GpAGGIUpSEff44478fe90yykBw";
"expires_in" = 181897;
"remind_in" = 181897;
uid = 5508976272;
}
(4)保存返回的用户信息到沙盒
// 返回的是用户信息字典
// 存储用户信息,包括access_token到沙盒中
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [docPath stringByAppendingPathComponent:@"accountInfo.plist"];
// 存储用户信息,包括access_token到沙盒中
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [docPath stringByAppendingPathComponent:@"accountInfo.plist"];
[accountInfo writeToFile:filePath atomically:YES];