zoukankan      html  css  js  c++  java
  • 登陆功能

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

    [cpp] view plaincopy
     
    1. -(void)saveUserNameAndPwd:(NSString *)userName andPwd:(NSString *)pwd  
    2. {  
    3.     NSUserDefaults * settings = [NSUserDefaults standardUserDefaults];  
    4.     [settings removeObjectForKey:@"UserName"];  
    5.     [settings removeObjectForKey:@"Password"];  
    6.     [settings setObject:userName forKey:@"UserName"];  
    7.       
    8.     pwd = [AESCrypt encrypt:pwd password:@"pwd"];  
    9.       
    10.     [settings setObject:pwd forKey:@"Password"];  
    11.     [settings synchronize];  
    12. }  


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

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

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

    [cpp] view plaincopy
     
    1.   
    [cpp] view plaincopy
     
    1. <span style="font-family:Comic Sans MS;font-size:18px;">    NSString *homeDirectory = NSHomeDirectory();  
    2.     NSLog(@"path:%@", homeDirectory);</span>  

    打印结果:   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文件,将其打开


     


     

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

     

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


    从头文件中声明部分

    [cpp] view plaincopy
     
    1. #import <UIKit/UIKit.h>  
    2. #import "Tool.h"  
    3. #import "ProfileBase.h"  
    4. #import "MessageView.h"  
    5. #import "Config.h"  
    6. #import "MBProgressHUD.h"  
    7. #import "MyThread.h"  
    8.   
    9. @interface LoginView : UIViewController<UIWebViewDelegate>   
    10. {  
    11. //    ASI类库,获取网络请求,进行登陆验证  
    12.     ASIFormDataRequest *request;  
    13. }  
    14. //接受用户名输入  
    15. @property (strong, nonatomic) IBOutlet UITextField *txt_Name;  
    16. //接受用户属于密码  
    17. @property (strong, nonatomic) IBOutlet UITextField *txt_Pwd;  
    18. //开关按钮,设置用户是否要记住用户名和密码  
    19. @property (strong, nonatomic) IBOutlet UISwitch *switch_Remember;  
    20. //标记作用,用于记录请求数据返回异常或错误时是否弹出一个警告  
    21. @property BOOL isPopupByNotice;  
    22. //webView,布局一个手机上的web网页,显示说明信息,在这个web页面有富文本使用,直接可以跳转到url上  
    23. @property (strong, nonatomic) IBOutlet UIWebView *webView;  
    24.   
    25. //登陆处理  
    26. - (IBAction)click_Login:(id)sender;  
    27. //取消两个textFile的第一响应对象  
    28. - (IBAction)textEnd:(id)sender;  
    29. //取消键盘第一响应对象,点击页面推出键盘  
    30. - (IBAction)backgrondTouch:(id)sender;  
    31. //根据返回的数据保存用户名和用户ID到本地  
    32. - (void)analyseUserInfo:(NSString *)xml;  
    33.   
    34. @end  


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

    [cpp] view plaincopy
     
    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.   
    5.     [Tool clearWebViewBackground:webView];  
    6.     [self.webView setDelegate:self];  
    7.       
    8.     self.navigationItem.title = @"登录";  
    9.     //决定是否显示用户名以及密码  
    10.     NSString *name = [Config Instance].getUserName;  
    11.     NSString *pwd = [Config Instance].getPwd;  
    12. //    如果用户名和密码存在,且不为空,取出付给相应text  
    13.     if (name && ![name isEqualToString:@""]) {  
    14.         self.txt_Name.text = name;  
    15.     }  
    16.     if (pwd && ![pwd isEqualToString:@""]) {  
    17.         self.txt_Pwd.text = pwd;  
    18.     }  
    19.       
    20.     UIBarButtonItem *btnLogin = [[UIBarButtonItem alloc] initWithTitle:@"登录" style:UIBarButtonItemStyleBordered target:self action:@selector(click_Login:)];  
    21.     self.navigationItem.rightBarButtonItem = btnLogin;  
    22.     self.view.backgroundColor = [Tool getBackgroundColor];  
    23.     self.webView.backgroundColor = [Tool getBackgroundColor];  
    24. //    web控件上信息  
    25.     NSString *html = @"<body style='background-color:#EBEBF3'>1, 您可以在 <a href='http://www.oschina.net'>http://www.oschina.net</a> 上免费注册一个账号用来登陆<p />2, 如果您的账号是使用OpenID的方式注册的,那么建议您在网页上为账号设置密码<p />3, 您可以点击 <a href='http://www.oschina.net/question/12_52232'>这里</a> 了解更多关于手机客户端登录的问题</body>";  
    26.     [self.webView loadHTMLString:html baseURL:nil];  
    27.     self.webView.hidden = NO;  
    28. }   

     在 [ToolclearWebViewBackground:webView];作用描述不好,直接看方法

     

    [cpp] view plaincopy
     
    1. + (void)clearWebViewBackground:(UIWebView *)webView  
    2. {  
    3.     UIWebView *web = webView;  
    4.     for (id v in web.subviews) {  
    5.         if ([v isKindOfClass:[UIScrollView class]]) {  
    6.             [v setBounces:NO];  
    7.         }  
    8.     }  
    9. }  

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

      

     

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

     

    [cpp] view plaincopy
     
    1. - (void)requestLogin:(ASIHTTPRequest *)request  
    2. {  
    3.     if (request.hud) {  
    4.         [request.hud hide:YES];  
    5.     }  
    6. //    根据请求回来的xml进行解析数据,判断是否登陆成功  
    7.     [Tool getOSCNotice:request];  
    8. //    将请求回来的信息保存在客户端  
    9.     [request setUseCookiePersistence:YES];  
    10.     ApiError *error = [Tool getApiError:request];  
    11.      
    12.     if (error == nil) {  
    13.         [Tool ToastNotification:request.responseString andView:self.view andLoading:NO andIsBottom:NO];  
    14.     }  
    15.     switch (error.errorCode) {  
    16.           
    17.         case 1:  
    18.         {  
    19.             [[Config Instance] saveCookie:YES];  
    20.             if (isPopupByNotice == NO)   
    21.             {  
    22.                 NSUserDefaults  *d= [NSUserDefaults standardUserDefaults];  
    23.                 [self.navigationController popViewControllerAnimated:YES];  
    24.             }  
    25.               
    26.             //处理是否记住用户名或者密码  
    27.             if (self.switch_Remember.isOn)   
    28.             {  
    29.                 [[Config Instance] saveUserNameAndPwd:self.txt_Name.text andPwd:self.txt_Pwd.text];  
    30.             }  
    31.             //否则需要清空用户名于密码  
    32.             else  
    33.             {  
    34.                 [[Config Instance] saveUserNameAndPwd:@"" andPwd:@""];  
    35.             }  
    36.             //返回的处理  
    37.   
    38.             if ([Config Instance].viewBeforeLogin)   
    39.             {  
    40.                 if([[Config Instance].viewNameBeforeLogin isEqualToString:@"ProfileBase"])  
    41.                 {  
    42.                     ProfileBase *_parent = (ProfileBase *)[Config Instance].viewBeforeLogin;  
    43.                     _parent.isLoginJustNow = YES;  
    44.                 }  
    45.             }  
    46.               
    47.             //开始分析 uid 等等信息  
    48.             [self analyseUserInfo:request.responseString];  
    49.             //分析是否需要退回  
    50.             if (self.isPopupByNotice) {  
    51.                 [self.navigationController popViewControllerAnimated:YES];  
    52.             }  
    53. //            查看startNotice方法可知是一个定时器,每隔60s刷新一下用户信息,是否有新的粉丝或几条评论  
    54.             [[MyThread Instance] startNotice];  
    55.         }  
    56.             break;  
    57.         case 0:  
    58.         case -1:  
    59.         {  
    60. //            返回 当error.errorCode =0 || 1的时候,显示相关错误信息  
    61.             [Tool ToastNotification:[NSString stringWithFormat:@"错误 %@",error.errorMessage] andView:self.view andLoading:NO andIsBottom:NO];  
    62.         }  
    63.             break;  
    64.     }  
    65. }  



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

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

     

    [html] view plaincopy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2.   
    3.   
    4. <oschina>  
    5.   <result>  
    6.     <errorCode>1</errorCode>  
    7.     <errorMessage><![CDATA[登录成功]]></errorMessage>  
    8.   </result>  
    9.     <user>  
    10.     <uid>112617</uid>  
    11.     <location><![CDATA[河南 南阳]]></location>  
    12.     <name><![CDATA[新风作浪]]></name>  
    13.     <followers>1</followers>  
    14.     <fans>0</fans>  
    15.     <score>1</score>  
    16.     <portrait>http://static.oschina.net/uploads/user/56/112617_100.jpg?t=1350377690000</portrait>  
    17.   </user>  
    18.   <notice>  
    19.     <atmeCount>0</atmeCount>  
    20.     <msgCount>0</msgCount>  
    21.     <reviewCount>0</reviewCount>  
    22.     <newFansCount>0</newFansCount>  
    23. </notice>  
    24. </oschina>  
    25. <!-- Generated by OsChina.NET (init:3[ms],page:3[ms],ip:61.163.231.198) -->  



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

    [cpp] view plaincopy
     
    1. - (void)analyseUserInfo:(NSString *)xml  
    2. {  
    3.     @try {  
    4.         TBXML *_xml = [[TBXML alloc] initWithXMLString:xml error:nil];  
    5.         TBXMLElement *root = _xml.rootXMLElement;      
    6.         TBXMLElement *user = [TBXML childElementNamed:@"user" parentElement:root];  
    7.         TBXMLElement *uid = [TBXML childElementNamed:@"uid" parentElement:user];  
    8.         //获取uid  
    9.         [[Config Instance] saveUID:[[TBXML textForElement:uid] intValue]];  
    10.     }  
    11.     @catch (NSException *exception) {  
    12.         [NdUncaughtExceptionHandler TakeException:exception];  
    13.     }  
    14.     @finally {  
    15.           
    16.     }  
    17.       
    18. }  
     

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

     

    [cpp] view plaincopy
     
    1. -(void)startNotice  
    2. {  
    3.     if (isRunning) {  
    4.         return;  
    5.     }  
    6.     else {  
    7.         timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerUpdate) userInfo:nil repeats:YES];  
    8.         isRunning = YES;  
    9.     }  
    10. }  
    [cpp] view plaincopy
     
    1. -(void)timerUpdate  
    2. {  
    3.     NSString * url = [NSString stringWithFormat:@"%@?uid=%d",api_user_notice,[Config Instance].getUID];  
    4.     [[AFOSCClient sharedClient]getPath:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {  
    5.           
    6.         [Tool getOSCNotice2:operation.responseString];  
    7.           
    8.     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
    9.           
    10.     }];  
    11.       
    12. }  

     

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

    [html] view plaincopy
     
    1. <oschina>  
    2. <notice>  
    3. <atmeCount>0</atmeCount>  
    4. <msgCount>0</msgCount>  
    5. <reviewCount>0</reviewCount>  
    6. <newFansCount>0</newFansCount>  
    7. </notice>  
    8. </oschina>  
    9. <!-- 
    10.  Generated by OsChina.NET (init:1[ms],page:1[ms],ip:61.163.231.198)  
    11. -->  

     

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

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

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

     

  • 相关阅读:
    OC基础框架
    协议代理
    内存管理
    重写init或自定义init方法
    iOS输入框UITextField输入限制
    iOS 打包FrameWork
    iOS 持续往文件写入数据。
    ld: library not found for -lxxx 问题的解决办法
    iOS 侧滑返回过程中导航栏的黑色问题解决办法
    iOS 蓝牙分包发送数据
  • 原文地址:https://www.cnblogs.com/yulang314/p/3587039.html
Copyright © 2011-2022 走看看