上一篇博客 开源中国iOS客户端学习——(十一)AES加密 中提到将用户名和密码保存到了本地沙盒之中,在从本地读取用户名和密码,这是一个怎样的过程?
- -(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];将键值信息同步道本地;
现在我们道沙盒中来看看这个用户配置信息
首先查看应用程序沙盒的路径 ,使用
- <span style="font-family:Comic Sans MS;font-size:18px;"> NSString *homeDirectory = NSHomeDirectory();
- 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吧,界面比较简陋,可能是缺美工吧;
从头文件中声明部分
- #import <UIKit/UIKit.h>
- #import "Tool.h"
- #import "ProfileBase.h"
- #import "MessageView.h"
- #import "Config.h"
- #import "MBProgressHUD.h"
- #import "MyThread.h"
-
- @interface LoginView : UIViewController<UIWebViewDelegate>
- {
-
- 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;
-
- @property (strong, nonatomic) IBOutlet UIWebView *webView;
-
-
- - (IBAction)click_Login:(id)sender;
-
- - (IBAction)textEnd:(id)sender;
-
- - (IBAction)backgrondTouch:(id)sender;
-
- - (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;
-
- 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];
-
- 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>";
- [self.webView loadHTMLString:html baseURL:nil];
- self.webView.hidden = NO;
- }
在 [ToolclearWebViewBackground:webView];作用描述不好,直接看方法
- + (void)clearWebViewBackground:(UIWebView *)webView
- {
- UIWebView *web = webView;
- for (id v in web.subviews) {
- if ([v isKindOfClass:[UIScrollView class]]) {
- [v setBounces:NO];
- }
- }
- }
[v setBounces:NO]; 如果[v setBounces:YES]; 滚动上下滚动是出现空隙,不美观,为NO 时就不会;
- - (IBAction)click_Login:(id)sender
- {
-
- NSString *name = self.txt_Name.text;
- NSString *pwd = self.txt_Pwd.text;
-
- 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];
-
- [request setDidFailSelector:@selector(requestFailed:)];
-
- [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];
- }
-
- [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;
- }
- }
-
-
- [self analyseUserInfo:request.responseString];
-
- if (self.isPopupByNotice) {
- [self.navigationController popViewControllerAnimated:YES];
- }
-
- [[MyThread Instance] startNotice];
- }
- break;
- case 0:
- case -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如下,
- <?xml version="1.0" encoding="UTF-8"?>
-
-
- <oschina>
- <result>
- <errorCode>1</errorCode>
- <errorMessage><![CDATA[登录成功]]></errorMessage>
- </result>
- <user>
- <uid>112617</uid>
- <location><![CDATA[河南 南阳]]></location>
- <name><![CDATA[新风作浪]]></name>
- <followers>1</followers>
- <fans>0</fans>
- <score>1</score>
- <portrait>http://static.oschina.net/uploads/user/56/112617_100.jpg?t=1350377690000</portrait>
- </user>
- <notice>
- <atmeCount>0</atmeCount>
- <msgCount>0</msgCount>
- <reviewCount>0</reviewCount>
- <newFansCount>0</newFansCount>
- </notice>
- </oschina>
-
在 [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];
-
- [[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请求获取的返回的信息(已经登陆情开源中国社区网站的况下)
- <oschina>
- <notice>
- <atmeCount>0</atmeCount>
- <msgCount>0</msgCount>
- <reviewCount>0</reviewCount>
- <newFansCount>0</newFansCount>
- </notice>
- </oschina>
-
-
-
关于本文提到的几个动画过渡显示效果请看
[Tool showHUD:@"正在登录" andView:self.view andHUD:request.hud]; MBProgressHUD特效
[Tool ToastNotification:[NSString stringWithFormat:@"错误 %@",error.errorMessage] andView:self.view andLoading:NO andIsBottom:NO]; GCDiscreetNotificationView提示视图
原创博客欢迎转载分享,请注明出处 http://blog.csdn.net/duxinfeng2010