1
2
3
4
5
6
7
8
9
10
<code>-(</code><code>void</code><code>)saveUserNameAndPwd:(NSString *)userName andPwd:(NSString *)pwd</code>
<code>{</code>
<code> </code><code>NSUserDefaults * settings = [NSUserDefaults standardUserDefaults];</code>
<code> </code><code>[settings removeObjectForKey:@</code><code>"UserName"</code><code>];</code>
<code> </code><code>[settings removeObjectForKey:@</code><code>"Password"</code><code>];</code>
<code> </code><code>[settings setObject:userName forKey:@</code><code>"UserName"</code><code>];</code>
<code> </code><code>pwd = [AESCrypt encrypt:pwd password:@</code><code>"pwd"</code><code>];</code>
<code> </code><code>[settings setObject:pwd forKey:@</code><code>"Password"</code><code>];</code>
<code> </code><code>[settings synchronize];</code>
<code>}</code>
上面的方法使用了NSUserDefaults類,它也是以字典形式實作對資料功能,并将這些資料儲存到本地應用程式沙盒之中,這種方法适合儲存較小的資料,例如使用者登陸配置資訊;這段代碼首先是定義了一個對象,進行初始化,移除鍵值為UseName和Password的對象,防止資料混亂造成幹擾;然後就是重新設定鍵值資訊; [settings synchronize];将鍵值資訊同步道本地;
現在我們道沙盒中來看看這個使用者配置資訊
首先檢視應用程式沙盒的路徑 ,使用
列印結果: path:/Users/DolBy/Library/Application Support/iPhone Simulator/5.1/Applications/55C49712-AD95-49E0-B3B9-694DC7D26E94
從中不難看出儲存在本地沙盒中使用者的一些基本資訊,以及一些配置資訊,還記錄一些上次擷取資料時間等等;
登陸類在Setting目錄下的loginView類,先看看loginView.xib吧,界面比較簡陋,可能是缺美工吧;
從頭檔案中聲明部分
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<code>#import <UIKit/UIKit.h></code>
<code>#import "Tool.h"</code>
<code>#import "ProfileBase.h"</code>
<code>#import "MessageView.h"</code>
<code>#import "Config.h"</code>
<code>#import "MBProgressHUD.h"</code>
<code>#import "MyThread.h"</code>
<code>@interface LoginView : UIViewController<UIWebViewDelegate></code>
<code>// ASI類庫,擷取網絡請求,進行登陸驗證</code>
<code> </code><code>ASIFormDataRequest *request;</code>
<code>//接受使用者名輸入</code>
<code>@property (strong, nonatomic) IBOutlet UITextField *txt_Name;</code>
<code>//接受使用者屬于密碼</code>
<code>@property (strong, nonatomic) IBOutlet UITextField *txt_Pwd;</code>
<code>//開關按鈕,設定使用者是否要記住使用者名和密碼</code>
<code>@property (strong, nonatomic) IBOutlet UISwitch *switch_Remember;</code>
<code>//标記作用,用于記錄請求資料傳回異常或錯誤時是否彈出一個警告</code>
<code>@property </code><code>BOOL</code> <code>isPopupByNotice;</code>
<code>//webView,布局一個手機上的web網頁,顯示說明資訊,在這個web頁面有富文本使用,直接可以跳轉到url上</code>
<code>@property (strong, nonatomic) IBOutlet UIWebView *webView;</code>
<code>//登陸處理</code>
<code>- (IBAction)click_Login:(id)sender;</code>
<code>//取消兩個textFile的第一響應對象</code>
<code>- (IBAction)textEnd:(id)sender;</code>
<code>//取消鍵盤第一響應對象,點選頁面推出鍵盤</code>
<code>- (IBAction)backgrondTouch:(id)sender;</code>
<code>//根據傳回的資料儲存使用者名和使用者ID到本地</code>
<code>- (</code><code>void</code><code>)analyseUserInfo:(NSString *)xml;</code>
<code>@end</code>
在實作檔案裡,粘貼上主要方法代碼
32
33
34
35
36
37
<code>- (</code><code>void</code><code>)viewDidLoad</code>
<code> </code><code>[super viewDidLoad];</code>
<code> </code><code>[Tool clearWebViewBackground:webView];</code>
<code> </code><code>[self.webView setDelegate:self];</code>
<code> </code>
<code> </code><code>self.navigationItem.title = @</code><code>"登入"</code><code>;</code>
<code> </code><code>//決定是否顯示使用者名以及密碼</code>
<code> </code><code>NSString *name = [Config Instance].getUserName;</code>
<code> </code><code>NSString *pwd = [Config Instance].getPwd;</code>
<code>// 如果使用者名和密碼存在,且不為空,取出付給相應text</code>
<code> </code><code>if</code> <code>(name && ![name isEqualToString:@</code><code>""</code><code>]) {</code>
<code> </code><code>self.txt_Name.text = name;</code>
<code> </code><code>}</code>
<code> </code><code>if</code> <code>(pwd && ![pwd isEqualToString:@</code><code>""</code><code>]) {</code>
<code> </code><code>self.txt_Pwd.text = pwd;</code>
<code> </code><code>UIBarButtonItem *btnLogin = [[UIBarButtonItem alloc] initWithTitle:@</code><code>"登入"</code> <code>style:UIBarButtonItemStyleBordered target:self action:@selector(click_Login:)];</code>
<code> </code><code>self.navigationItem.rightBarButtonItem = btnLogin;</code>
<code> </code><code>self.view.backgroundColor = [Tool getBackgroundColor];</code>
<code> </code><code>self.webView.backgroundColor = [Tool getBackgroundColor];</code>
<code>// web控件上資訊</code>
<code> </code><code>NSString *html = @</code><code>"<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>"</code><code>;</code>
<code> </code><code>[self.webView loadHTMLString:html baseURL:nil];</code>
<code> </code><code>self.webView.hidden = NO;</code>
<code> </code><code>在 [Tool clearWebViewBackground:webView];作用描述不好,直接看方法</code>
<code>+ (</code><code>void</code><code>)clearWebViewBackground:(UIWebView *)webView</code>
<code> </code><code>UIWebView *web = webView;</code>
<code> </code><code>for</code> <code>(id v in web.subviews) {</code>
<code> </code><code>if</code> <code>([v isKindOfClass:[UIScrollView </code><code>class</code><code>]]) {</code>
<code> </code><code>[v setBounces:NO];</code>
<code> </code><code>}</code>
[v setBounces:NO]; 如果[v setBounces:YES]; 滾動上下滾動是出現空隙,不美觀,為NO 時就不會;
<code>- (IBAction)click_Login:(id)sender</code>
<code>// 擷取使用者名和密碼</code>
<code> </code><code>NSString *name = self.txt_Name.text;</code>
<code> </code><code>NSString *pwd = self.txt_Pwd.text;</code>
<code>// 使用ASI類庫請求登陸API,</code>
<code> </code><code>request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:api_login_validate]];</code>
<code> </code><code>[request setUseCookiePersistence:YES];</code>
<code> </code><code>[request setPostValue:name forKey:@</code><code>"username"</code><code>];</code>
<code> </code><code>[request setPostValue:pwd forKey:@</code><code>"pwd"</code><code>];</code>
<code> </code><code>[request setPostValue:@</code><code>"1"</code> <code>forKey:@</code><code>"keep_login"</code><code>];</code>
<code> </code><code>[request setDelegate:self];</code>
<code>// 失敗調用 requestFailed:</code>
<code> </code><code>[request setDidFailSelector:@selector(requestFailed:)];</code>
<code>// 成功調用 equestLogin:</code>
<code> </code><code>[request setDidFinishSelector:@selector(requestLogin:)];</code>
<code>// 開始請求</code>
<code> </code><code>[request startAsynchronous];</code>
<code>// 動畫提示使用者等待</code>
<code> </code><code>request.hud = [[MBProgressHUD alloc] initWithView:self.view];</code>
<code> </code><code>[Tool showHUD:@</code><code>"正在登入"</code> <code>andView:self.view andHUD:request.hud];</code>
<code>// 登陸失敗,隐藏顯示的動畫</code>
<code>- (</code><code>void</code><code>)requestFailed:(ASIHTTPRequest *)request</code>
<code> </code><code>if</code> <code>(request.hud) {</code>
<code> </code><code>[request.hud hide:YES];</code>
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<code>- (</code><code>void</code><code>)requestLogin:(ASIHTTPRequest *)request</code>
<code>// 根據請求回來的xml進行解析資料,判斷是否登陸成功</code>
<code> </code><code>[Tool getOSCNotice:request];</code>
<code>// 将請求回來的資訊儲存在用戶端</code>
<code> </code><code>ApiError *error = [Tool getApiError:request];</code>
<code> </code>
<code> </code><code>if</code> <code>(error == nil) {</code>
<code> </code><code>[Tool ToastNotification:request.responseString andView:self.view andLoading:NO andIsBottom:NO];</code>
<code> </code><code>switch</code> <code>(error.errorCode) {</code>
<code> </code>
<code> </code><code>case</code> <code>1:</code>
<code> </code><code>{</code>
<code> </code><code>[[Config Instance] saveCookie:YES];</code>
<code> </code><code>if</code> <code>(isPopupByNotice == NO)</code>
<code> </code><code>{</code>
<code> </code><code>NSUserDefaults *d= [NSUserDefaults standardUserDefaults];</code>
<code> </code><code>[self.navigationController popViewControllerAnimated:YES];</code>
<code> </code><code>}</code>
<code> </code>
<code> </code><code>//處理是否記住使用者名或者密碼</code>
<code> </code><code>if</code> <code>(self.switch_Remember.isOn)</code>
<code> </code><code>[[Config Instance] saveUserNameAndPwd:self.txt_Name.text andPwd:self.txt_Pwd.text];</code>
<code> </code><code>//否則需要清空使用者名于密碼</code>
<code> </code><code>else</code>
<code> </code><code>[[Config Instance] saveUserNameAndPwd:@</code><code>""</code> <code>andPwd:@</code><code>""</code><code>];</code>
<code> </code><code>//傳回的處理</code>
<code> </code><code>if</code> <code>([Config Instance].viewBeforeLogin)</code>
<code> </code><code>if</code><code>([[Config Instance].viewNameBeforeLogin isEqualToString:@</code><code>"ProfileBase"</code><code>])</code>
<code> </code><code>{</code>
<code> </code><code>ProfileBase *_parent = (ProfileBase *)[Config Instance].viewBeforeLogin;</code>
<code> </code><code>_parent.isLoginJustNow = YES;</code>
<code> </code><code>}</code>
<code> </code><code>//開始分析 uid 等等資訊</code>
<code> </code><code>[self analyseUserInfo:request.responseString];</code>
<code> </code><code>//分析是否需要退回</code>
<code> </code><code>if</code> <code>(self.isPopupByNotice) {</code>
<code>// 檢視startNotice方法可知是一個定時器,每隔60s重新整理一下使用者資訊,是否有新的粉絲或幾條評論</code>
<code> </code><code>[[MyThread Instance] startNotice];</code>
<code> </code><code>break</code><code>;</code>
<code> </code><code>case</code> <code>0:</code>
<code> </code><code>case</code> <code>-1:</code>
<code>// 傳回 當error.errorCode =0 || 1的時候,顯示相關錯誤資訊</code>
<code> </code><code>[Tool ToastNotification:[NSString stringWithFormat:@</code><code>"錯誤 %@"</code><code>,error.errorMessage] andView:self.view andLoading:NO andIsBottom:NO];</code>
ApiError 這個類看起來可能很迷惑人,它并不完全像字面意思那樣指的是錯誤的api資訊,而是根據請求傳回來的數字進行判斷。如果error.errorCode = 1表示成功傳回了使用者的資料,0,-1就可能由于伺服器網絡等原因不能正确傳回資料;
在ApiError *error = [Tool getApiError:request];中,列印 request.responseString如下,
<code><?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code> <code>encoding</code><code>=</code><code>"UTF-8"</code><code>?></code>
<code><</code><code>oschina</code><code>></code>
<code> </code><code><</code><code>result</code><code>></code>
<code> </code><code><</code><code>errorCode</code><code>>1</</code><code>errorCode</code><code>></code>
<code> </code><code><</code><code>errorMessage</code><code>></code><code><![CDATA[登入成功]]></code><code></</code><code>errorMessage</code><code>></code>
<code> </code><code></</code><code>result</code><code>></code>
<code> </code><code><</code><code>user</code><code>></code>
<code> </code><code><</code><code>uid</code><code>>112617</</code><code>uid</code><code>></code>
<code> </code><code><</code><code>location</code><code>></code><code><![CDATA[河南 南陽]]></code><code></</code><code>location</code><code>></code>
<code> </code><code><</code><code>name</code><code>></code><code><![CDATA[新風作浪]]></code><code></</code><code>name</code><code>></code>
<code> </code><code><</code><code>followers</code><code>>1</</code><code>followers</code><code>></code>
<code> </code><code><</code><code>fans</code><code>>0</</code><code>fans</code><code>></code>
<code> </code><code><</code><code>score</code><code>>1</</code><code>score</code><code>></code>
<code> </code><code><</code><code>portrait</code><code>>http://static.oschina.net/uploads/user/56/112617_100.jpg?t=1350377690000</</code><code>portrait</code><code>></code>
<code> </code><code></</code><code>user</code><code>></code>
<code> </code><code><</code><code>notice</code><code>></code>
<code> </code><code><</code><code>atmeCount</code><code>>0</</code><code>atmeCount</code><code>></code>
<code> </code><code><</code><code>msgCount</code><code>>0</</code><code>msgCount</code><code>></code>
<code> </code><code><</code><code>reviewCount</code><code>>0</</code><code>reviewCount</code><code>></code>
<code> </code><code><</code><code>newFansCount</code><code>>0</</code><code>newFansCount</code><code>></code>
<code></</code><code>notice</code><code>></code>
<code></</code><code>oschina</code><code>></code>
<code><!-- Generated by OsChina.NET (init:3[ms],page:3[ms],ip:61.163.231.198) --></code>
在 [self analyseUserInfo:request.responseString]方法中, 根據請求成功傳回的xml,解析使用者名和UID,儲存使用者的UID
<code>- (</code><code>void</code><code>)analyseUserInfo:(NSString *)xml</code>
<code> </code><code>@</code><code>try</code> <code>{</code>
<code> </code><code>TBXML *_xml = [[TBXML alloc] initWithXMLString:xml error:nil];</code>
<code> </code><code>TBXMLElement *root = _xml.rootXMLElement;</code>
<code> </code><code>TBXMLElement *user = [TBXML childElementNamed:@</code><code>"user"</code> <code>parentElement:root];</code>
<code> </code><code>TBXMLElement *uid = [TBXML childElementNamed:@</code><code>"uid"</code> <code>parentElement:user];</code>
<code> </code><code>//擷取uid</code>
<code> </code><code>[[Config Instance] saveUID:[[TBXML textForElement:uid] intValue]];</code>
<code> </code><code>@</code><code>catch</code> <code>(NSException *exception) {</code>
<code> </code><code>[NdUncaughtExceptionHandler TakeException:exception];</code>
<code> </code><code>@finally {</code>
<code> </code>
<code> </code>
在後面也看到[[MyThread Instance] startNotice];看看startNotice方法,是一個定時器,每隔60s重新整理一下使用者資訊,是否有新的粉絲或幾條評論;
<code>-(</code><code>void</code><code>)startNotice</code>
<code> </code><code>if</code> <code>(isRunning) {</code>
<code> </code><code>return</code><code>;</code>
<code> </code><code>else</code> <code>{</code>
<code> </code><code>timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerUpdate) userInfo:nil repeats:YES];</code>
<code> </code><code>isRunning = YES;</code>
<code>-(</code><code>void</code><code>)timerUpdate</code>
<code> </code><code>NSString * url = [NSString stringWithFormat:@</code><code>"%@?uid=%d"</code><code>,api_user_notice,[Config Instance].getUID];</code>
<code> </code><code>[[AFOSCClient sharedClient]getPath:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {</code>
<code> </code>
<code> </code><code>[Tool getOSCNotice2:operation.responseString];</code>
<code> </code><code>} failure:^(AFHTTPRequestOperation *operation, NSError *error) {</code>
<code> </code><code>}];</code>
<code> </code>
url請求擷取傳回的資訊(已經登陸情開源中國社群網站的況下)
<code><</code><code>notice</code><code>></code>
<code><</code><code>atmeCount</code><code>>0</</code><code>atmeCount</code><code>></code>
<code><</code><code>msgCount</code><code>>0</</code><code>msgCount</code><code>></code>
<code><</code><code>reviewCount</code><code>>0</</code><code>reviewCount</code><code>></code>
<code><</code><code>newFansCount</code><code>>0</</code><code>newFansCount</code><code>></code>
<code><!--</code>
<code> </code><code>Generated by OsChina.NET (init:1[ms],page:1[ms],ip:61.163.231.198)</code>
<code>--></code>
關于本文提到的幾個動畫過渡顯示效果請看
本文轉自新風作浪 51CTO部落格,原文連結:http://blog.51cto.com/duxinfeng/1206850,如需轉載請自行聯系原作者