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

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

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

    github: https://github.com/hellovoidworld/HVWWeibo   A.封装微博业务 1.需求 把微博相关业务(读取.写微博) 界面控制器不需要知道微博操作细节( ...

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

    A.概念      OAUTH协议为用户资源的授权提供了一个安全的.开放而又简易的标准.与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用 ...

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

    github: https://github.com/hellovoidworld/HVWWeibo   A.封装网络请求 1.需求 为了避免代码冗余和对于AFN框架的多处使用导致耦合性太强,所以把网 ...

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

    github: https://github.com/hellovoidworld/HVWWeibo   A.发送授权请求 1.使用UIWebView加载请求页面 自定义一个继承UIViewContr ...

  5. [iOS微博项目 - 3.4] - 获取用户信息

    github: https://github.com/hellovoidworld/HVWWeibo   A.获取用户信息 1.需求 获取用户信息并储存 把用户昵称显示在“首页”界面导航栏的标题上   ...

  6. [iOS微博项目 - 2.4] - 重新安排app启动步骤

    github: https://github.com/hellovoidworld/HVWWeibo   A.app启动步骤 1.加入了授权步骤之后,最先要判断app内是否已经登陆了账号 2.在程序启 ...

  7. [iOS微博项目 - 4.3] - 设置每条微博边框样式

    github: https://github.com/hellovoidworld/HVWWeibo A.设置每条微博边框样式 1.需求 不需要分割线 每个微博之间留有一定的间隙   2.思路 直接设 ...

  8. 【Python项目】爬取新浪微博个人用户信息页

    微博用户信息爬虫 项目链接:https://github.com/RealIvyWong/WeiboCrawler/tree/master/WeiboUserInfoCrawler 1 实现功能 这个 ...

  9. php微信网页授权获取用户信息

    配置回调域名: 1. 引导用户进入授权页面同意授权,获取code 2. 通过code换取网页授权access_token(与基础支持中的access_token不同) 3. 如果需要,开发者可以刷新网 ...

随机推荐

  1. jQuery中filter(),not(),split()的用法

    filter(),not(): <script type="text/javascript"> $(document).ready(function() { //输出 ...

  2. HDU 4023 (博弈 贪心 模拟) Game

    如果硬要说这算是博弈题目的话,那这个博弈是不公平博弈(partizan games),因为双方面对同一个局面做出来的决策是不一样的. 我们平时做的博弈都是公平博弈(impartial games),所 ...

  3. ubuntu下实现openerp 7使用nginx反正代理及绑定域名

    这里要记录一个nginx upstream实现反向代理的配置过程. 连接vps的ssh. 先安装nginx sudo apt-get install nginx 修改/etc/nginx/nginx. ...

  4. jq的post传递数组

    a = new Object();            b = new Object();            a['你好[眼见]'] = "y";            a[ ...

  5. Android 高仿豌豆荚 一键安装app 功能 实现

    以往我们那些应用市场 帮我们安装app的时候  我们都得点确定,当然你如果 root 以后 不用点确定 也能自动安装了,后来豌豆荚 推出了一个功能 非root的手机也能不点确定 直接帮你安装好.(如果 ...

  6. Android 一步步教你从ActionBar迁移到ToolBar

    谷歌的材料设计也发布了有一段时间了,包括官方的support库 相信大家也熟悉了不少,今天就把actionbar 迁移到toolbar的 经验发出来. 这个地方要注意 我用的图标都是studio里的一 ...

  7. PHP String函数分类

    1.查找字符位置函数: strpos  ($str,search,[int]):    查找search在$str中的第一次位置从int开始: stripos ($str,search,[int]): ...

  8. X86调用约定

    cdecl      C语言默认的调用约定,从右往左压栈,由调用者负责清栈,所以参数个数可以不固定: stdcall    windows默认调用方式,从右往左压栈,由被调用者负责栈操作. pasca ...

  9. 【转】loadrunner检查点设置

    转自:http://www.cnblogs.com/fnng/archive/2013/03/10/2953257.html 判断脚本是否执行成功是根据服务器返回的状态来确定的,如果服务器返回的HTT ...

  10. oracle导入导出数据库和创建表空间和用户

    直入主题: 首先在本地创建2个文件,D:\oradata\jgszz\temp.dbf和 D:\oradata\jgszz\data.dbf. 然后执行下面的SQL. /*创建临时表空间 */ cre ...