开源中国iOS客户端学习——(十二)用户登陆

上一篇博客开源中国iOS客户端学习——(十一)AES加密中提到将用户名和密码保存到了本地沙盒之中,在从本地读取用户名和密码,这是一个怎样的过程?

10年积累的成都网站建设、成都做网站经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站制作后付款的网站建设流程,更有施甸免费网站建设让你可以放心的选择与我们合作。

-(void)saveUserNameAndPwd:(NSString *)userName andPwd:(NSString *)pwd
{
    NSUserDefaults * settings = [NSUserDefaults standardUserDefaults];
    [settings removeObjectForKey:@"UserName"];
    [settings removeObjectForKey:@"Password"];
    [settings setObject:userName forKey:@"UserName"];
    pwd = [AESCrypt encrypt:pwd password:@"pwd"];
    [settings setObject:pwd forKey:@"Password"];
    [settings synchronize];
}

上面的方法使用了NSUserDefaults类,它也是以字典形式实现对数据功能,并将这些数据保存到本地应用程序沙盒之中,这种方法适合保存较小的数据,例如用户登陆配置信息;这段代码首先是定义了一个对象,进行初始化,移除键值为UseName和Password的对象,防止数据混乱造成干扰;然后就是重新设置键值信息; [settings synchronize];将键值信息同步道本地;

现在我们道沙盒中来看看这个用户配置信息

首先查看应用程序沙盒的路径 ,使用

    NSString *homeDirectory = NSHomeDirectory();    NSLog(@"path:%@", homeDirectory);

打印结果:   path:/Users/DolBy/Library/Application Support/iPhone Simulator/5.1/Applications/55C49712-AD95-49E0-B3B9-694DC7D26E94

但是在我的DolBy用户下并没有Library这个目录,这是因为系统隐藏了这些文件目录,现在需要显示这些隐藏的文件,打开终端输入 defaults write com.apple.finder AppleShowAllFiles -bool true  回车,然后重启Finder(不会?请看查看iOS沙盒(SanBox)文件),找到55C49712-AD95-49E0-B3B9-694DC7D26E94目录下的Library/Preferences下的 net.oschina.iosapp.plist文件,将其打开

开源中国iOS客户端学习——(十二)用户登陆

开源中国iOS客户端学习——(十二)用户登陆

从中不难看出保存在本地沙盒中用户的一些基本信息,以及一些配置信息,还记录一些上次获取数据时间等等;

登陆类在Setting目录下的loginView类,先看看loginView.xib吧,界面比较简陋,可能是缺美工吧;

开源中国iOS客户端学习——(十二)用户登陆

开源中国iOS客户端学习——(十二)用户登陆

从头文件中声明部分

#import 
#import "Tool.h"
#import "ProfileBase.h"
#import "MessageView.h"
#import "Config.h"
#import "MBProgressHUD.h"
#import "MyThread.h"
@interface LoginView : UIViewController
{
//    ASI类库,获取网络请求,进行登陆验证
    ASIFormDataRequest *request;
}
//接受用户名输入
@property (strong, nonatomic) IBOutlet UITextField *txt_Name;
//接受用户属于密码
@property (strong, nonatomic) IBOutlet UITextField *txt_Pwd;
//开关按钮,设置用户是否要记住用户名和密码
@property (strong, nonatomic) IBOutlet UISwitch *switch_Remember;
//标记作用,用于记录请求数据返回异常或错误时是否弹出一个警告
@property BOOL isPopupByNotice;
//webView,布局一个手机上的web网页,显示说明信息,在这个web页面有富文本使用,直接可以跳转到url上
@property (strong, nonatomic) IBOutlet UIWebView *webView;
//登陆处理
- (IBAction)click_Login:(id)sender;
//取消两个textFile的第一响应对象
- (IBAction)textEnd:(id)sender;
//取消键盘第一响应对象,点击页面推出键盘
- (IBAction)backgrondTouch:(id)sender;
//根据返回的数据保存用户名和用户ID到本地
- (void)analyseUserInfo:(NSString *)xml;
@end

在实现文件里,粘贴上主要方法代码

- (void)viewDidLoad
{
    [super viewDidLoad];
    [Tool clearWebViewBackground:webView];
    [self.webView setDelegate:self];
                                                                                                                                                      
    self.navigationItem.title = @"登录";
    //决定是否显示用户名以及密码
    NSString *name = [Config Instance].getUserName;
    NSString *pwd = [Config Instance].getPwd;
//    如果用户名和密码存在,且不为空,取出付给相应text
    if (name && ![name isEqualToString:@""]) {
        self.txt_Name.text = name;
    }
    if (pwd && ![pwd isEqualToString:@""]) {
        self.txt_Pwd.text = pwd;
    }
                                                                                                                                                      
    UIBarButtonItem *btnLogin = [[UIBarButtonItem alloc] initWithTitle:@"登录" style:UIBarButtonItemStyleBordered target:self action:@selector(click_Login:)];
    self.navigationItem.rightBarButtonItem = btnLogin;
    self.view.backgroundColor = [Tool getBackgroundColor];
    self.webView.backgroundColor = [Tool getBackgroundColor];
//    web控件上信息
    NSString *html = @"1, 您可以在 http://www.oschina.net 上免费注册一个账号用来登陆

2, 如果您的账号是使用OpenID的方式注册的,那么建议您在网页上为账号设置密码

3, 您可以点击 这里 了解更多关于手机客户端登录的问题"; [self.webView loadHTMLString:html baseURL:nil]; self.webView.hidden = NO; } 在 [Tool clearWebViewBackground:webView];作用描述不好,直接看方法 + (void)clearWebViewBackground:(UIWebView *)webView { UIWebView *web = webView; for (id v in web.subviews) { if ([v isKindOfClass:[UIScrollView class]]) { [v setBounces:NO]; } } }

[vsetBounces:NO];  如果[v setBounces:YES]; 滚动上下滚动是出现空隙,不美观,为NO  时就不会;

开源中国iOS客户端学习——(十二)用户登陆

开源中国iOS客户端学习——(十二)用户登陆

- (IBAction)click_Login:(id)sender
{
//    获取用户名和密码
    NSString *name = self.txt_Name.text;
    NSString *pwd = self.txt_Pwd.text;
//    使用ASI类库请求登陆API,
    request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:api_login_validate]];
    [request setUseCookiePersistence:YES];
    [request setPostValue:name forKey:@"username"];
    [request setPostValue:pwd forKey:@"pwd"];
    [request setPostValue:@"1" forKey:@"keep_login"];
    [request setDelegate:self];
//    失败调用 requestFailed:
    [request setDidFailSelector:@selector(requestFailed:)];
//    成功调用 equestLogin:
    [request setDidFinishSelector:@selector(requestLogin:)];
//    开始请求
    [request startAsynchronous];
//    动画提示用户等待
    request.hud = [[MBProgressHUD alloc] initWithView:self.view];
    [Tool showHUD:@"正在登录" andView:self.view andHUD:request.hud];
}
//  登陆失败,隐藏显示的动画
- (void)requestFailed:(ASIHTTPRequest *)request
{
    if (request.hud) {
        [request.hud hide:YES];
    }
}

- (void)requestLogin:(ASIHTTPRequest *)request
{
    if (request.hud) {
        [request.hud hide:YES];
    }
//    根据请求回来的xml进行解析数据,判断是否登陆成功
    [Tool getOSCNotice:request];
//    将请求回来的信息保存在客户端
    [request setUseCookiePersistence:YES];
    ApiError *error = [Tool getApiError:request];
                                                                                                                              
    if (error == nil) {
        [Tool ToastNotification:request.responseString andView:self.view andLoading:NO andIsBottom:NO];
    }
    switch (error.errorCode) {
                                                                                                                                   
        case 1:
        {
            [[Config Instance] saveCookie:YES];
            if (isPopupByNotice == NO)
            {
                NSUserDefaults  *d= [NSUserDefaults standardUserDefaults];
                [self.navigationController popViewControllerAnimated:YES];
            }
                                                                                                                                       
            //处理是否记住用户名或者密码
            if (self.switch_Remember.isOn)
            {
                [[Config Instance] saveUserNameAndPwd:self.txt_Name.text andPwd:self.txt_Pwd.text];
            }
            //否则需要清空用户名于密码
            else
            {
                [[Config Instance] saveUserNameAndPwd:@"" andPwd:@""];
            }
            //返回的处理
            if ([Config Instance].viewBeforeLogin)
            {
                if([[Config Instance].viewNameBeforeLogin isEqualToString:@"ProfileBase"])
                {
                    ProfileBase *_parent = (ProfileBase *)[Config Instance].viewBeforeLogin;
                    _parent.isLoginJustNow = YES;
                }
            }
                                                                                                                                       
            //开始分析 uid 等等信息
            [self analyseUserInfo:request.responseString];
            //分析是否需要退回
            if (self.isPopupByNotice) {
                [self.navigationController popViewControllerAnimated:YES];
            }
//            查看startNotice方法可知是一个定时器,每隔60s刷新一下用户信息,是否有新的粉丝或几条评论
            [[MyThread Instance] startNotice];
        }
            break;
        case 0:
        case -1:
        {
//            返回 当error.errorCode =0 || 1的时候,显示相关错误信息
            [Tool ToastNotification:[NSString stringWithFormat:@"错误 %@",error.errorMessage] andView:self.view andLoading:NO andIsBottom:NO];
        }
            break;
    }
}

ApiError 这个类看起来可能很迷惑人,它并不完全像字面意思那样指的是错误的api信息,而是根据请求返回来的数字进行判断。如果error.errorCode = 1表示成功返回了用户的数据,0,-1就可能由于服务器网络等原因不能正确返回数据;

在ApiError *error = [Tool getApiError:request];中,打印 request.responseString如下,



  
    1
    
  
    
    112617
    
    
    1
    0
    1
    http://static.oschina.net/uploads/user/56/112617_100.jpg
  
  
    0
    0
    0
    0


在 [self analyseUserInfo:request.responseString]方法中, 根据请求成功返回的xml,解析用户名和UID,保存用户的UID

- (void)analyseUserInfo:(NSString *)xml
{
    @try {
        TBXML *_xml = [[TBXML alloc] initWithXMLString:xml error:nil];
        TBXMLElement *root = _xml.rootXMLElement;
        TBXMLElement *user = [TBXML childElementNamed:@"user" parentElement:root];
        TBXMLElement *uid = [TBXML childElementNamed:@"uid" parentElement:user];
        //获取uid
        [[Config Instance] saveUID:[[TBXML textForElement:uid] intValue]];
    }
    @catch (NSException *exception) {
        [NdUncaughtExceptionHandler TakeException:exception];
    }
    @finally {
                                                                                                              
    }
                                                                                                          
}

在后面也看到[[MyThread Instance] startNotice];看看startNotice方法,是一个定时器,每隔60s刷新一下用户信息,是否有新的粉丝或几条评论;

-(void)startNotice
{
    if (isRunning) {
        return;
    }
    else {
        timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerUpdate) userInfo:nil repeats:YES];
        isRunning = YES;
    }
}

-(void)timerUpdate
{
    NSString * url = [NSString stringWithFormat:@"%@?uid=%d",api_user_notice,[Config Instance].getUID];
    [[AFOSCClient sharedClient]getPath:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
                                                                                                     
        [Tool getOSCNotice2:operation.responseString];
                                                                                                     
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                                                                                     
    }];
                                                                                                 
}

   url请求获取返回的信息(已经登陆情开源中国社区网站的况下)



0
0
0
0



关于本文提到的几个动画过渡显示效果请看

[Tool showHUD:@"正在登录" andView:self.view andHUD:request.hud];    MBProgressHUD特效

[Tool ToastNotification:[NSString stringWithFormat:@"错误 %@",error.errorMessage] andView:self.view andLoading:NO andIsBottom:NO];      GCDiscreetNotificationView提示视图

开源中国iOS客户端×××地址:http://git.oschina.net/oschina/iphone-app


当前标题:开源中国iOS客户端学习——(十二)用户登陆
转载注明:http://scyanting.com/article/pdidgc.html