[iOS微博项目 - 2.5] - 封装授权和用户信息读写业务

github: https://github.com/hellovoidworld/HVWWeibo

 

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, strong) NSString *expires_in;
19
20 /** 过期时间,自己计算存储 */
21 @property(nonatomic, strong) NSDate *expires_time;
22
23 /**  当前授权用户的UID */
24 @property(nonatomic, strong) 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 }
时间: 2024-10-05 22:28:31

[iOS微博项目 - 2.5] - 封装授权和用户信息读写业务的相关文章

[iOS微博项目 - 3.5] - 封装业务

github: https://github.com/hellovoidworld/HVWWeibo   A.封装微博业务 1.需求 把微博相关业务(读取.写微博) 界面控制器不需要知道微博操作细节(例如选择从网络读取还是缓存读取) 2.实现 把微博操作封装成一个工具类 把微博网络请求的参数和返回结果也封装成一个类 3.实现 (1)基础参数类 由于多数请求都需要access_token,所以封装一个参数父类 1 // 2 // HVWBaseParam.h 3 // HVWWeibo 4 //

[iOS微博项目 - 2.0] - OAuth授权3步

A.概念 OAUTH协议为用户资源的授权提供了一个安全的.开放而又简易的标准.与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的.oAuth是Open Authorization的简写. B.使用3步骤 OAUTH认证授权就三个步骤,三句话可以概括: 1. 获取未授权的Request Token 2. 获取用户授权的Request Token 3. 用授权的Requ

[iOS微博项目 - 3.3] - 封装网络请求

github: https://github.com/hellovoidworld/HVWWeibo A.封装网络请求 1.需求 为了避免代码冗余和对于AFN框架的多处使用导致耦合性太强,所以把网络请求封装成自己的工具类,以后便于更换网络框架. 2.思路 创建一个自定义工具类,提供类方法来实现网络请求 3.实现 1 // 2 // HVWNetworkTool.h 3 // HVWWeibo 4 // 5 // Created by hellovoidworld on 15/2/9. 6 //

iOS开发项目篇—36封装微博业务

iOS开发项目篇—36封装微博业务 一.简单说明 1.请求参数面向模型 2.请求结果面向模型 3.对控制器来说应该屏蔽业务细节.不让控制器关心(知道)业务细节,它只需要知道自己在做某个业务 @通过一个专门的业务处理类:处理微博业务细节 说明: 业务:加载新的微博首页数据 实现:给新浪服务器发送一个GET请求 业务:加载更多的首页微博数据 实现1:给新浪服务器发送一个GET请求 实现2:去沙盒中加载以前离线缓存的微博数据  二.实现 1.新建一个微博业务处理类,继承自NSObject 微博业务处理

iOS开发项目篇—37封装其他业务

iOS开发项目篇—37封装其他业务 一.简单说明 项目分层的步骤: (1)新建一个模型类封装请求参数 (2)新建一个模型类封装请求结果(返回结果) (3)新建一个业务类封装专一的业务 二.获得用户信息业务的封装 (1)新建一个模型类封装请求参数 查看新浪官方获取用户信息需要哪些请求参数: 封装请求参数的类的代码设计: YYUserInfoParam.h文件 1 // 2 // YYUserInfoParam.h 3 // 4 5 #import <Foundation/Foundation.h>

iOS开发项目篇—35封装网络请求

iOS开发项目篇—35封装网络请求 一.简单说明 1.分析项目对网路请求(AFN框架)的依赖 项目中,多个控制器都使用了AFN框架发送网络请求,如果AFN2.0存在重大BUg,或者是升级至3.0版本,那么对于整个项目都是及其危险的,所有用到AFN的地方都需要做出相应的修改. 另外,如果现在要求不再使用AFN框架,而是使用一个新的框架,那么有关AFN的依赖所关联的所有代码都需要重新来过. 如果把afn这个第三方框架从项目中删除的话,那么项目就相当于作废了,这就是项目对第三方框架的强依赖的体现. 说

iOS开发项目篇—19获取授权过的访问标记

iOS开发项目篇—19获取授权过的访问标记 一.简单说明 1.获取授权 2.简单说明 说明: (1)只能使用post请求 (2)post请求的参数有5个,且五个参数都是必须的. (3)新浪会返回一个JSON,转成OC对象为字典,可以通过Key取出ACCESS_TOKEN. 二.实现 1.导入第三方框架 2.使用字典封装请求参数,五个参数都是必须的,就算少一个都是非法请求. 封装代码 1 //2.封装请求参数 2 /* 3 url:https://api.weibo.com/oauth2/acce

iOS开发项目篇—18截取授权成功的请求标记

iOS开发项目篇—18截取授权成功的请求标记 一.步骤和说明 新建一个授权分组,创建一个自定义的授权控制器. 把window的根控制器设置为授权控制器,以测试. 自定义控制器代码: 1 // 2 // YYOAuthViewController.m 3 // 4 5 #import "YYOAuthViewController.h" 6 7 @interface YYOAuthViewController () 8 9 @end 10 11 @implementation YYOAut

[iOS微博项目 - 2.2] - 在app中获取授权

github: https://github.com/hellovoidworld/HVWWeibo   A.发送授权请求 1.使用UIWebView加载请求页面 自定义一个继承UIViewController的HVWOAuthViewController 1 // 2 // HVWOAuthViewController.m 3 // HVWWeibo 4 // 5 // Created by hellovoidworld on 15/2/4. 6 // Copyright (c) 2015年