• 新浪微博客户端(15)-保存用户名和密码


    检测本地是否保存有用户的密码。如果有,则下次自动登录;如果没有,则提示用户登录。

    DJAccount.h

    #import <Foundation/Foundation.h>
    
    @interface DJAccount : NSObject
    
    
    /** 访问token */
    @property (nonatomic,copy) NSString *access_token;
    /** 过期时间,单位是秒 */
    @property (nonatomic,copy) NSNumber *expires_in;
    /** 当前user id */
    @property (nonatomic,copy) NSString *uid;
    /** 当前帐号创建时间 */
    @property (nonatomic,strong) NSDate *create_time;
    
    + (instancetype)accountWithDictionary:(NSDictionary *)dict;
    
    
    @end

    DJAccount.m

    #import "DJAccount.h"
    
    
    @interface DJAccount() <NSCoding>
    
    @end
    
    @implementation DJAccount
    
    
    
    + (instancetype)accountWithDictionary:(NSDictionary *)dict {
    
        DJAccount *account = [[DJAccount alloc] init];
        
        account.access_token = dict[@"access_token"];
        account.expires_in = dict[@"expires_in"];
        account.uid = dict[@"uid"];
        account.create_time = [NSDate date];
        
        return account;
    }
    
    
    
    - (void)encodeWithCoder:(NSCoder *)encoder {
    
        [encoder encodeObject:self.access_token forKey:@"access_token"];
        [encoder encodeObject:self.expires_in forKey:@"expires_in"];
        [encoder encodeObject:self.uid forKey:@"uid"];
        [encoder encodeObject:self.create_time forKey:@"create_time"];
        
    }
    
    - (instancetype)initWithCoder:(NSCoder *)decoder {
    
        if (self = [super init]) {
            self.access_token = [decoder decodeObjectForKey:@"access_token"];
            self.expires_in = [decoder decodeObjectForKey:@"expires_in"];
            self.uid = [decoder decodeObjectForKey:@"uid"];
            self.create_time = [decoder decodeObjectForKey:@"create_time"];
        }
        return self;
    
    }
    
    
    @end

    DJAccountTool.h

    #import <Foundation/Foundation.h>
    
    @class DJAccount;
    
    @interface DJAccountTool : NSObject
    
    
    + (void)saveAccount:(DJAccount *)account;
    
    + (DJAccount *)account;
    
    
    @end

    DJAccountTool.m

    #import "DJAccountTool.h"
    #import "DJAccount.h"
    
    #define DJAccountPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.archiver"]
    
    
    @implementation DJAccountTool
    
    
    
    + (void)saveAccount:(DJAccount *)account {
    
        [NSKeyedArchiver archiveRootObject:account toFile:DJAccountPath];
        
    }
    
    
    
    + (DJAccount *)account {
        
        
        DJAccount *account = [NSKeyedUnarchiver unarchiveObjectWithFile:DJAccountPath];
        // 判断当前帐号是否过期
        long long expires_in = [account.expires_in longLongValue];
        // 获得过期时间
        NSDate *expires_time = [account.create_time dateByAddingTimeInterval:expires_in];
        // 获得当前时间
        NSDate *now_time = [NSDate date];
        // 如果now大于expires_time,则代表过期
        NSComparisonResult result = [expires_time compare:now_time];
        if (result != NSOrderedDescending) {
            return nil;
        }
        return account;
    }
    
    
    @end

    UIWindow+Extension.m

    #import "UIWindow+Extension.h"
    #import "DJMainViewController.h"
    #import "DJNewFeatureViewController.h"
    
    @implementation UIWindow (Extension)
    
    + (void)switchRootViewController {
    
        // 获取当前主窗口
        UIWindow *window = [UIApplication sharedApplication].keyWindow;
     
        NSString *versionKey = @"CFBundleVersion";
        // 从Info.plist中读取当前软件版本号
        NSString *currentVersion = [NSBundle mainBundle].infoDictionary[versionKey];
        // 从沙盒中读取保存的历史版本号
        NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:versionKey];
        
        // 判断当前软件版本号是否与沙盒中保存的一致
        if ([currentVersion isEqualToString:lastVersion]) { // 版本号一致
            DJMainViewController *mainVc = [[DJMainViewController alloc] init];
            window.rootViewController = mainVc;
        } else { // 版本号不一致,显示新特性,并将当前软件版本号保存到沙盒
            /* 1.显示新特性 */
            DJNewFeatureViewController *newVc = [[DJNewFeatureViewController alloc] init];
            window.rootViewController = newVc;
            /* 2.将当前版本号写入到沙盒 */
            [[NSUserDefaults standardUserDefaults] setValue:currentVersion forKey:versionKey];
            // 立即将内存中的数据同步到沙盒
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
    
    }
    
    @end

    AppDelegate.m

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        
        
        // 1. 创建窗口
        self.window = [[UIWindow alloc] init];
        self.window.frame = [UIScreen mainScreen].bounds;
        
        // 2. 显示窗口
        [self.window makeKeyAndVisible];
    
        // 3. 判断当前帐户是否已经被授权来决定根控制器显示
        DJAccount *account = [DJAccountTool account];
        if (account) { // 之前已经成功授权
            [UIWindow switchRootViewController];
        } else { // 尚未成功授权
           self.window.rootViewController = [[DJOAuthViewController alloc] init];
        }
        
        return YES;
    }

    DJOAuthViewController.m

    #import "DJOAuthViewController.h"
    #import "AFNetworking.h"
    #import "DJAccount.h"
    #import "DJAccountTool.h"
    #import "MBProgressHUD+MJ.h"
    
    
    @interface DJOAuthViewController () <UIWebViewDelegate>
    
    @end
    
    @implementation DJOAuthViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        /* client_id&redirect_uri */
        NSString *client_id = @"249054863";
        NSString *redirect_uri = @"https://www.baidu.com";
        
        UIWebView *webView = [[UIWebView alloc] init];
        webView.frame = self.view.bounds;
        webView.delegate = self;
        
        [self.view addSubview:webView];
        
        NSString *urlString = [NSString stringWithFormat:@"https://api.weibo.com/oauth2/authorize?client_id=%@&redirect_uri=%@",client_id,redirect_uri];
        
        NSURL *url = [NSURL URLWithString:urlString];
        NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
        
        [webView loadRequest:urlRequest];
    
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    #pragma mark - webView 代理方法
    
    - (void)webViewDidStartLoad:(UIWebView *)webView {
        [MBProgressHUD showMessage:@"加载中..."];
    
    }
    
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        [MBProgressHUD hideHUD];
    }
    
    
    /** 此方法可用于拦截http请求 */
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
        NSString *urlString = request.URL.absoluteString;
        DJLog(@"current access url str : %@",urlString);
    
        // 1. 判断当前地址是否是回调地址(https://www.baidu.com/?code=27a3d9fb9bbc5d3c20be9ae8e4331b02)
        NSRange range= [urlString rangeOfString:@"code="];
        if (range.length != 0) { // 是回调地址
            // 2.截取code=后面的参数值
            NSUInteger fromIndex = range.location + range.length;
            NSString *code = [urlString substringFromIndex:fromIndex]; // code 就是授权成功的请求标记
            // 3.使用授权成功的请求标记(code)来换取accessToken
            [self getAccessTokenWithCode:code];
            // 4.禁止加载回调地址
            return NO;
        }
        
        
        
        return YES;
    }
    
    
    
    
    - (void)getAccessTokenWithCode:(NSString *)code {
    
        // 1. 创建请求管理者
        AFHTTPSessionManager *requestManager = [AFHTTPSessionManager manager];
        
        // 2. 配置请求参数
        NSString *urlString = @"https://api.weibo.com/oauth2/access_token"; // 请求授权的access_token URL
        NSMutableDictionary *params = [NSMutableDictionary dictionary];
        params[@"client_id"] = @"249054863";
        params[@"client_secret"] = @"71d5b761bac9f377af3b938f6d89ba85";
        params[@"grant_type"] = @"authorization_code";
        params[@"code"] = code;
        params[@"redirect_uri"] = @"https://www.baidu.com";
        
        // 3. 发送请求
        [requestManager POST:urlString parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary *  _Nullable dict) {
            
            [MBProgressHUD hideHUD];
            // 1. 将返回的字典转换为模型
            DJAccount *account = [DJAccount accountWithDictionary:dict];
            // 2. 存储当前帐号信息
            [DJAccountTool saveAccount:account];
            // 3. 切换根控制器到DJMainViewController
            [UIWindow switchRootViewController];
            
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [MBProgressHUD showError:@"授权失败"];
             DJLog(@"failure responseObject: %@",error);
        }];
        
    }
    
    
    
    @end

    最终效果:

     

  • 相关阅读:
    C# git .gitignore文件
    Python常用库
    STM32移植LWIP之客户端与服务端的数据传输
    linux_cam_test文件
    DEBUG调试文件
    Linux多线程总结
    Git add命令
    Git使用总结
    C语言中可变参数的使用
    Hi3518EV300编译U-Boot和内核报错:loadlocale.c:130: _nl_intern_locale_data: Assertion `cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' failed. Aborted (core dumped)
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/6005673.html
Copyright © 2020-2023  润新知