A.封装授权业务
1.把app的授权信息移动到HVWWeibo-Prefix.pch中作为公共宏
1 // 授权信息 2 #define HVWAppKey @"3942775926"; 3 #define HVWAppSecret @"cc577953b2aa3aa8ea220fd15775ea35" 4 #define HVWGrantType @"authorization_code" 5 #define HVWRedirecgURI @"http://www.cnblogs.com/hellovoidworld/"
2.封装一个用来处理app启动时rootViewController的类
1 // 2 // HVWControllerTool.m 3 // HVWWeibo 4 // 5 // Created by hellovoidworld on 15/2/5. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWControllerTool.h" 10 #import "HVWOAuthViewController.h" 11 #import "HVWTabBarViewController.h" 12 #import "HVWNewFeatureViewController.h" 13 14 @implementation HVWControllerTool 15 16 + (void) chooseRootViewController { 17 // 获得主窗口 18 UIWindow *window = [UIApplication sharedApplication].keyWindow; 19 20 // 检查是否已有登陆账号 21 NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 22 NSString *filePath = [docPath stringByAppendingPathComponent:@"accountInfo.plist"]; 23 NSDictionary *accountInfo = [NSDictionary dictionaryWithContentsOfFile:filePath]; 24 25 if (!accountInfo) { // 如果不存在登陆账号,要先进行授权 26 window.rootViewController = [[HVWOAuthViewController alloc] init]; 27 } else { 28 /** 新版本特性 */ 29 // app现在的版本 30 // 由于使用的时Core Foundation的东西,需要桥接 31 NSString *versionKey = (__bridge NSString*) kCFBundleVersionKey; 32 NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; 33 NSString *currentVersion = [infoDic objectForKey:versionKey]; 34 35 // 上次使用的版本 36 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 37 NSString *lastVersion = [defaults stringForKey:versionKey]; 38 39 // 如果版本变动了,存储新的版本号并启动新版本特性图 40 if (![lastVersion isEqualToString:currentVersion]) { 41 42 // 存储 43 [defaults setObject:currentVersion forKey:versionKey]; 44 [defaults synchronize]; 45 46 // 开启app显示新特性 47 HVWNewFeatureViewController *newFeatureVC = [[HVWNewFeatureViewController alloc] init]; 48 window.rootViewController = newFeatureVC; 49 } else { 50 // 创建根控制器 51 HVWTabBarViewController *tabVC = [[HVWTabBarViewController alloc] init]; 52 window.rootViewController = tabVC; 53 } 54 } 55 } 56 57 @end
这样在AppDelegate和授权控制器都能直接调用这个工具类的方法来选择主窗口根控制器了
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 [self.window makeKeyAndVisible]; 12 13 // 设置根控制器 14 [HVWControllerTool chooseRootViewController]; 15 16 return YES; 17 }
HVWOAuthViewController:
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"] = HVWAppKey; 9 param[@"client_secret"] = HVWAppSecret; 10 param[@"grant_type"] = HVWGrantType; 11 param[@"code"] = accessCode; 12 param[@"redirect_uri"] = HVWRedirecgURI; 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 // 存储用户信息,包括access_token到沙盒中 20 NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 21 NSString *filePath = [docPath stringByAppendingPathComponent:@"accountInfo.plist"]; 22 [accountInfo writeToFile:filePath atomically:YES]; 23 24 // 设置根控制器 25 [HVWControllerTool chooseRootViewController]; 26 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 27 [MBProgressHUD hideHUD]; 28 HVWLog(@"请求access_token失败 ----> %@", error); 29 }]; 30 31 }
B.封装用户信息
1.封装一个“用户信息”模型
- 封装应有属性
- 处理服务器发来的json数据的初始化方法
- 用来存储用户信息到文件的归档重写方法
1 // 2 // HVWAccountInfo.h 3 // HVWWeibo 4 // 5 // Created by hellovoidworld on 15/2/5. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 // 注意遵守NSCoding协议 12 @interface HVWAccountInfo : NSObject <NSCoding> 13 14 /** 访问令牌 */ 15 @property(nonatomic, strong) NSString *access_token; 16 17 /** access_token的有效期,单位:秒 */ 18 @property(nonatomic, copy) NSString *expires_in; 19 20 /** 过期时间,自己计算存储 */ 21 @property(nonatomic, strong) NSDate *expires_time; 22 23 /** 当前授权用户的UID */ 24 @property(nonatomic, copy) NSString *uid; 25 26 /** 自定义初始化方法,这里是用来初始化服务器发来的json数据的 */ 27 + (instancetype) accountInfoWithDictionary:(NSDictionary *) dict; 28 29 @end
1 // 2 // HVWAccountInfo.m 3 // HVWWeibo 4 // 5 // Created by hellovoidworld on 15/2/5. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWAccountInfo.h" 10 11 @implementation HVWAccountInfo 12 13 /** 自定义初始化方法,这里是用来初始化服务器发来的json数据的 */ 14 + (instancetype) accountInfoWithDictionary:(NSDictionary *) dict { 15 HVWAccountInfo *accountInfo = [[self alloc] init]; 16 17 accountInfo.access_token = dict[@"access_token"]; 18 accountInfo.expires_in = dict[@"expires_in"]; 19 20 NSDate *now = [NSDate date]; 21 accountInfo.expires_time = [now dateByAddingTimeInterval:accountInfo.expires_in.doubleValue]; 22 23 accountInfo.uid = dict[@"uid"]; 24 25 return accountInfo; 26 } 27 28 #pragma mark - NSCoding 29 /** 从文件解析对象调用 */ 30 - (id)initWithCoder:(NSCoder *)aDecoder { 31 if (self = [super init]) { 32 self.access_token = [aDecoder decodeObjectForKey:@"access_token"]; 33 self.expires_in = [aDecoder decodeObjectForKey:@"expires_in"]; 34 self.expires_time = [aDecoder decodeObjectForKey:@"expires_time"]; 35 self.uid = [aDecoder decodeObjectForKey:@"uid"]; 36 } 37 38 return self; 39 } 40 41 /** 把对象写入文件调用 */ 42 - (void)encodeWithCoder:(NSCoder *)aCoder { 43 [aCoder encodeObject:self.access_token forKey:@"access_token"]; 44 [aCoder encodeObject:self.expires_in forKey:@"expires_in"]; 45 [aCoder encodeObject:self.expires_time forKey:@"expires_time"]; 46 [aCoder encodeObject:self.uid forKey:@"uid"]; 47 } 48 49 @end
2.封装一个用来处理用户信息的工具类
(1)使用 归档器/反归档器 快速读写文件
如果用户信息已经过期,返回nil,让系统重新申请
注意
- 存储文件名:accountInfo.data,不是之前的accountInfo.plist
- 日期比较千万不要搞错
1 // 2 // HVWAccountInfoTool.m 3 // HVWWeibo 4 // 5 // Created by hellovoidworld on 15/2/5. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWAccountInfoTool.h" 10 11 #define accountInfoPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"accountInfo.data"] 12 13 @implementation HVWAccountInfoTool 14 15 /** 从文件获取accountInfo */ 16 + (HVWAccountInfo *) accountInfo { 17 HVWAccountInfo *accountInfo = [NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfFile:accountInfoPath]]; 18 19 // 需要判断是否过期 20 NSDate *now = [NSDate date]; 21 if ([now compare:accountInfo.expires_time] != NSOrderedAscending) { // now->expires_data 非升序, 已经过期 22 accountInfo = nil; 23 } 24 25 return accountInfo; 26 } 27 28 /** 存储accountInfo到文件 */ 29 + (void) saveAccountInfo:(HVWAccountInfo *) accountInfo { 30 [NSKeyedArchiver archiveRootObject:accountInfo toFile:accountInfoPath]; 31 } 32 33 @end
(2)这样在授权控制器就可以直接调用工具类来存储用户信息了
1 // HVWOAuthViewController.m 2 /** 根据access_code获取access_token */ 3 - (void) accessTokenWithAccessCode:(NSString *) accessCode { 4 // 创建AFN的http操作请求管理者 5 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 6 7 // 参数设置 8 NSMutableDictionary *param = [NSMutableDictionary dictionary]; 9 param[@"client_id"] = HVWAppKey; 10 param[@"client_secret"] = HVWAppSecret; 11 param[@"grant_type"] = HVWGrantType; 12 param[@"code"] = accessCode; 13 param[@"redirect_uri"] = HVWRedirecgURI; 14 15 // 发送请求 16 [manager POST:@"https://api.weibo.com/oauth2/access_token" parameters:param success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) { 17 [MBProgressHUD hideHUD]; 18 19 // 返回的是用户信息字典 20 // 存储用户信息,包括access_token到沙盒中 21 HVWAccountInfo *accountInfo = [HVWAccountInfo accountInfoWithDictionary:responseObject]; 22 [HVWAccountInfoTool saveAccountInfo:accountInfo]; 23 24 // 设置根控制器 25 [HVWControllerTool chooseRootViewController]; 26 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 27 [MBProgressHUD hideHUD]; 28 HVWLog(@"请求access_token失败 ----> %@", error); 29 }]; 30 31 }
(3)控制器选择器也可以调用此工具类来读取用户信息文件
1 + (void) chooseRootViewController { 2 // 获得主窗口 3 UIWindow *window = [UIApplication sharedApplication].keyWindow; 4 5 // 检查是否已有登陆账号 6 HVWAccountInfo *accountInfo = [HVWAccountInfoTool accountInfo]; 7 8 if (!accountInfo) { // 如果不存在登陆账号,要先进行授权 9 window.rootViewController = [[HVWOAuthViewController alloc] init]; 10 } else { 11 /** 新版本特性 */ 12 // app现在的版本 13 // 由于使用的时Core Foundation的东西,需要桥接 14 NSString *versionKey = (__bridge NSString*) kCFBundleVersionKey; 15 NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; 16 NSString *currentVersion = [infoDic objectForKey:versionKey]; 17 18 // 上次使用的版本 19 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 20 NSString *lastVersion = [defaults stringForKey:versionKey]; 21 22 // 如果版本变动了,存储新的版本号并启动新版本特性图 23 if (![lastVersion isEqualToString:currentVersion]) { 24 25 // 存储 26 [defaults setObject:currentVersion forKey:versionKey]; 27 [defaults synchronize]; 28 29 // 开启app显示新特性 30 HVWNewFeatureViewController *newFeatureVC = [[HVWNewFeatureViewController alloc] init]; 31 window.rootViewController = newFeatureVC; 32 } else { 33 // 创建根控制器 34 HVWTabBarViewController *tabVC = [[HVWTabBarViewController alloc] init]; 35 window.rootViewController = tabVC; 36 } 37 } 38 }