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. Qt之国际化(系统文本-QMessageBox按钮、QLineEdit右键菜单等)

    简介 使用Qt的时候,经常会遇到英文问题,例如:QMessageBox中的按钮.QLineEdit.QSpinBox.QScrollBar中的右键菜单等.通常情况下,我们软件都不会是纯英文的,那么如何 ...

  2. Qt之国际化

    简介 Qt国际化属于Qt高级中的一部分,本想着放到后面来说,上节刚好介绍了Qt Linguist,趁热打铁就一起了解下. 对于绝大多数的应用程序,在刚启动时,需要加载默认的语言(或最后一次设置的语言) ...

  3. Remember-Me功能

    Remember-Me功能 目录 1.1概述 1.2基于简单加密token的方法 1.3基于持久化token的方法 1.4Remember-Me相关接口和实现类 1.4.1TokenBasedReme ...

  4. (六)6.12 Neurons Networks from self-taught learning to deep network

    self-taught learning 在特征提取方面完全是用的无监督的方法,对于有标记的数据,可以结合有监督学习来对上述方法得到的参数进行微调,从而得到一个更加准确的参数a. 在self-taug ...

  5. windows7操作系统64位安装ArcSDE10.1和Oracle11g

    安装环境如下: Oracle11g R2 64位服务端Oracle11g R2 32位客户端(管理员,第二项)ArcSDE10.1 for Oracle11g SDE数据库可由其它机器安装Arcata ...

  6. Apache PHP 安装问题 (SUSE Linux)

    1. SUSE Linux配置命令如下: './configure' '--with-apxs2=/usr/local/apache2/bin/apxs' '--with-mysql' 2. 接下来 ...

  7. 编辑时snapping的添加

    原文 编辑时snapping的添加 注意需要在编辑模式下进行snapping的添加(也即先需要使用IEngineEditor进入编辑状态): IMapControl3 mMap = (IMapCont ...

  8. JQuery实现分页程序代码,源码下载

    Web开发,分页在所难免的,微软GridView.AspPager等设置分页数据可以自动分页,但是这里浏览器会闪动,用户体验不是很友好,在此我整理了JQuery实现分页,并且使用 JQuery模板显示 ...

  9. ajax轮询

    oa.comet = function (id) {    if (oa.id == 0) oa.id = id;    $.ajax({        url: '/comet.asy?id=' + ...

  10. stl 中List vector deque区别

    stl提供了三个最基本的容器:vector,list,deque.         vector和built-in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此     它能非常好的支持随 ...