您好,登錄后才能下訂單哦!
上一篇博客 開源中國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];將鍵值信息同步道本地;
現在我們道沙盒中來看看這個用戶配置信息
首先查看應用程序沙盒的路徑 ,使用
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文件,將其打開
從中不難看出保存在本地沙盒中用戶的一些基本信息,以及一些配置信息,還記錄一些上次獲取數據時間等等;
登陸類在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類庫,獲取網絡請求,進行登陸驗證 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 = @"<body style='background-color:#EBEBF3'>1, 您可以在 <a >http://www.oschina.net</a> 上免費注冊一個賬號用來登陸<p />2, 如果您的賬號是使用OpenID的方式注冊的,那么建議您在網頁上為賬號設置密碼<p />3, 您可以點擊 <a >這里</a> 了解更多關于手機客戶端登錄的問題</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]; } } }
[v setBounces:NO]; 如果[v setBounces:YES]; 滾動上下滾動是出現空隙,不美觀,為NO 時就不會;
- (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如下,
<?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> <!-- Generated by OsChina.NET (init:3[ms],page:3[ms],ip:61.163.231.198) -->
在 [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請求獲取返回的信息(已經登陸情開源中國社區網站的況下)
<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) -->
關于本文提到的幾個動畫過渡顯示效果請看
[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
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。