上一篇博客開源中國iOS客戶端學(xué)習(xí)——(十一)AES加密中提到將用戶名和密碼保存到了本地沙盒之中,在從本地讀取用戶名和密碼,這是一個(gè)怎樣的過程?
10年積累的成都網(wǎng)站建設(shè)、成都做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有施甸免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
-(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類,它也是以字典形式實(shí)現(xiàn)對(duì)數(shù)據(jù)功能,并將這些數(shù)據(jù)保存到本地應(yīng)用程序沙盒之中,這種方法適合保存較小的數(shù)據(jù),例如用戶登陸配置信息;這段代碼首先是定義了一個(gè)對(duì)象,進(jìn)行初始化,移除鍵值為UseName和Password的對(duì)象,防止數(shù)據(jù)混亂造成干擾;然后就是重新設(shè)置鍵值信息; [settings synchronize];將鍵值信息同步道本地;
現(xiàn)在我們道沙盒中來看看這個(gè)用戶配置信息
首先查看應(yīng)用程序沙盒的路徑 ,使用
NSString *homeDirectory = NSHomeDirectory(); NSLog(@"path:%@", homeDirectory);
打印結(jié)果: path:/Users/DolBy/Library/Application Support/iPhone Simulator/5.1/Applications/55C49712-AD95-49E0-B3B9-694DC7D26E94
但是在我的DolBy用戶下并沒有Library這個(gè)目錄,這是因?yàn)橄到y(tǒng)隱藏了這些文件目錄,現(xiàn)在需要顯示這些隱藏的文件,打開終端輸入 defaults write com.apple.finder AppleShowAllFiles -bool true 回車,然后重啟Finder(不會(huì)?請(qǐng)看查看iOS沙盒(SanBox)文件),找到55C49712-AD95-49E0-B3B9-694DC7D26E94目錄下的Library/Preferences下的 net.oschina.iosapp.plist文件,將其打開
從中不難看出保存在本地沙盒中用戶的一些基本信息,以及一些配置信息,還記錄一些上次獲取數(shù)據(jù)時(shí)間等等;
登陸類在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> { // ASI類庫,獲取網(wǎng)絡(luò)請(qǐng)求,進(jìn)行登陸驗(yàn)證 ASIFormDataRequest *request; } //接受用戶名輸入 @property (strong, nonatomic) IBOutlet UITextField *txt_Name; //接受用戶屬于密碼 @property (strong, nonatomic) IBOutlet UITextField *txt_Pwd; //開關(guān)按鈕,設(shè)置用戶是否要記住用戶名和密碼 @property (strong, nonatomic) IBOutlet UISwitch *switch_Remember; //標(biāo)記作用,用于記錄請(qǐng)求數(shù)據(jù)返回異?;蝈e(cuò)誤時(shí)是否彈出一個(gè)警告 @property BOOL isPopupByNotice; //webView,布局一個(gè)手機(jī)上的web網(wǎng)頁,顯示說明信息,在這個(gè)web頁面有富文本使用,直接可以跳轉(zhuǎn)到url上 @property (strong, nonatomic) IBOutlet UIWebView *webView; //登陸處理 - (IBAction)click_Login:(id)sender; //取消兩個(gè)textFile的第一響應(yīng)對(duì)象 - (IBAction)textEnd:(id)sender; //取消鍵盤第一響應(yīng)對(duì)象,點(diǎn)擊頁面推出鍵盤 - (IBAction)backgrondTouch:(id)sender; //根據(jù)返回的數(shù)據(jù)保存用戶名和用戶ID到本地 - (void)analyseUserInfo:(NSString *)xml; @end
在實(shí)現(xiàn)文件里,粘貼上主要方法代碼
- (void)viewDidLoad { [super viewDidLoad]; [Tool clearWebViewBackground:webView]; [self.webView setDelegate:self]; self.navigationItem.title = @"登錄"; //決定是否顯示用戶名以及密碼 NSString *name = [Config Instance].getUserName; NSString *pwd = [Config Instance].getPwd; // 如果用戶名和密碼存在,且不為空,取出付給相應(yīng)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 = @"<body style='background-color:#EBEBF3'>1, 您可以在 <a >http://www.oschina.net</a> 上免費(fèi)注冊(cè)一個(gè)賬號(hào)用來登陸<p />2, 如果您的賬號(hào)是使用OpenID的方式注冊(cè)的,那么建議您在網(wǎng)頁上為賬號(hào)設(shè)置密碼<p />3, 您可以點(diǎn)擊 <a >這里</a> 了解更多關(guān)于手機(jī)客戶端登錄的問題</body>"; [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]; 滾動(dòng)上下滾動(dòng)是出現(xiàn)空隙,不美觀,為NO 時(shí)就不會(huì);
- (IBAction)click_Login:(id)sender { // 獲取用戶名和密碼 NSString *name = self.txt_Name.text; NSString *pwd = self.txt_Pwd.text; // 使用ASI類庫請(qǐng)求登陸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]; // 失敗調(diào)用 requestFailed: [request setDidFailSelector:@selector(requestFailed:)]; // 成功調(diào)用 equestLogin: [request setDidFinishSelector:@selector(requestLogin:)]; // 開始請(qǐng)求 [request startAsynchronous]; // 動(dòng)畫提示用戶等待 request.hud = [[MBProgressHUD alloc] initWithView:self.view]; [Tool showHUD:@"正在登錄" andView:self.view andHUD:request.hud]; } // 登陸失敗,隱藏顯示的動(dòng)畫 - (void)requestFailed:(ASIHTTPRequest *)request { if (request.hud) { [request.hud hide:YES]; } }
- (void)requestLogin:(ASIHTTPRequest *)request { if (request.hud) { [request.hud hide:YES]; } // 根據(jù)請(qǐng)求回來的xml進(jìn)行解析數(shù)據(jù),判斷是否登陸成功 [Tool getOSCNotice:request]; // 將請(qǐng)求回來的信息保存在客戶端 [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方法可知是一個(gè)定時(shí)器,每隔60s刷新一下用戶信息,是否有新的粉絲或幾條評(píng)論 [[MyThread Instance] startNotice]; } break; case 0: case -1: { // 返回 當(dāng)error.errorCode =0 || 1的時(shí)候,顯示相關(guān)錯(cuò)誤信息 [Tool ToastNotification:[NSString stringWithFormat:@"錯(cuò)誤 %@",error.errorMessage] andView:self.view andLoading:NO andIsBottom:NO]; } break; } }
ApiError 這個(gè)類看起來可能很迷惑人,它并不完全像字面意思那樣指的是錯(cuò)誤的api信息,而是根據(jù)請(qǐng)求返回來的數(shù)字進(jìn)行判斷。如果error.errorCode = 1表示成功返回了用戶的數(shù)據(jù),0,-1就可能由于服務(wù)器網(wǎng)絡(luò)等原因不能正確返回?cái)?shù)據(jù);
在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[新風(fēng)作浪]]></name> <followers>1</followers> <fans>0</fans> <score>1</score> <portrait>http://static.oschina.net/uploads/user/56/112617_100.jpg</portrait> </user> <notice> <atmeCount>0</atmeCount> <msgCount>0</msgCount> <reviewCount>0</reviewCount> <newFansCount>0</newFansCount> </notice> </oschina> <!-- Generated by OsChina.NET (init:3[ms],page:3[ms],ip:61.163.231.198) -->
在 [self analyseUserInfo:request.responseString]方法中, 根據(jù)請(qǐng)求成功返回的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方法,是一個(gè)定時(shí)器,每隔60s刷新一下用戶信息,是否有新的粉絲或幾條評(píng)論;
-(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請(qǐng)求獲取返回的信息(已經(jīng)登陸情開源中國社區(qū)網(wǎng)站的況下)
<oschina> <notice> <atmeCount>0</atmeCount> <msgCount>0</msgCount> <reviewCount>0</reviewCount> <newFansCount>0</newFansCount> </notice> </oschina> <!-- Generated by OsChina.NET (init:1[ms],page:1[ms],ip:61.163.231.198) -->
關(guān)于本文提到的幾個(gè)動(dòng)畫過渡顯示效果請(qǐng)看
[Tool showHUD:@"正在登錄" andView:self.view andHUD:request.hud]; MBProgressHUD特效
[Tool ToastNotification:[NSString stringWithFormat:@"錯(cuò)誤 %@",error.errorMessage] andView:self.view andLoading:NO andIsBottom:NO]; GCDiscreetNotificationView提示視圖
開源中國iOS客戶端×××地址:http://git.oschina.net/oschina/iphone-app
本文標(biāo)題:開源中國iOS客戶端學(xué)習(xí)——(十二)用戶登陸
網(wǎng)址分享:http://m.rwnh.cn/article12/pdidgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、全網(wǎng)營銷推廣、用戶體驗(yàn)、關(guān)鍵詞優(yōu)化、品牌網(wǎng)站設(shè)計(jì)、品牌網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)