今天我们主要学习一下 ASI 与 JSON 针对向服务端请求数据的知识。以前MOMO就给大伙说过没事多去GitHub去看看老外写的东西,这个网站真的特别好玩。今天说的AIS 与JSON都是GitHub上老外写的开源库。本文开始我在罗嗦一下,使用Three20开发时我的建议是 Three20 + FMDB + ASI + JSON 。 FMDB是数据库操作的类库,ASI全称是ASIHTTPRequest,可与服务器进行数据的交互 或者是2进制文件的交互包括断点续传等等非常强大的一个类库, 客户端与服务器都是以字符串的形式在做交互,以前在使用XML的时候开发者需要对大量的节点之间做解析,即使网上有现成的解析库但是MOMO觉得还是不好用。还是觉得JSON比较好用!~!! JSON就好比在本地维持一个字典对象,向服务器请求时将字典对象转换成字符串发给服务器,当服务器返回时在将字符串转换成字典对象,通过键值对的形式 对数据进行操作真的非常好用。然而这一切的一切JSON库都帮我们完成了。
首先我们学习在Three20之上构建ASI环境,ASI的下载地址是 https://github.com/pokeb/asi-http-request 。下载完毕后解压,在你的工程中将Class文件全部导入进来。如下图所示引入相应的类库,这里大家请和MOMO的保持一致。
下面就是最重要的一部,也是非常蛋疼的一部。当初学的时候就因为没加上这个导致我半个多小时才吧环境搭上,MOMO请大家一定要淡定!!如下图所示,在Header Search Paths中一定要加入 /usr/include/libxml2 切记!切记! 不然有一个错找不到头文件。。
OK 这一步你的ASI环境就配置OK啦。然后我们开始配置JSON,下载地址:https://github.com/stig/json-framework 和ASI一样,下载完后请把Classes文件夹中的文件拷贝至工程当中,为了区分开大家可为它们换个名称,下一步我们开始编写代码。
AppDelegate.m 这是入口类,应该没问题吧,这里我们写了两个页面 一个用来登录,一个显示登录结果。
01 | #import "AppDelegate.h" |
03 | @implementation AppDelegate |
05 | @synthesize window = _window; |
13 | - ( BOOL )application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions |
17 | TTNavigator* navigator = [TTNavigator navigator]; |
18 | navigator.persistenceMode = TTNavigatorPersistenceModeAll; |
19 | navigator.window = [[[UIWindow alloc] initWithFrame:TTScreenBounds()] autorelease]; |
23 | TTURLMap* map = navigator.URLMap; |
26 | [map from:@ "*" toViewController:[TTWebController class ]]; |
30 | [map from:@ "tt://Login" toSharedViewController:[LoginViewController class ]]; |
32 | [map from:@ "tt://Main" toViewController:[MainViewController class ]]; |
34 | if (![navigator restoreViewControllers]) { |
36 | [navigator openURLAction:[TTURLAction actionWithURLPath:@ "tt://Login" ]]; |
LoginViewController.h 首先是登录界面 这里将ASIHTTPRequest.h 与 JSON.h引入,登录页面是仿照FaceBook的在输入框中MOMO选择的是TabView。
01 | #import <Three20/Three20.h> |
02 | #import "ASIHTTPRequest.h" |
03 | #import "ASIFormDataRequest.h" |
06 | @interface LoginViewController : TTTableViewController<UITextFieldDelegate> |
09 | UITextField* userName; |
11 | UITextField* passWord; |
15 | UIActivityIndicatorView *activity; |
LoginViewController.m 大量的逻辑都在这里面,请大家仔细看这个类,MOMO已经添加了详细的注释噢。。
001 | #import "LoginViewController.h" |
003 | @implementation LoginViewController |
005 | - (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query { |
006 | if (self = [super init]) { |
009 | self.tableViewStyle = UITableViewStyleGrouped; |
014 | userName = [[[UITextField alloc] init]autorelease]; |
016 | userName.delegate = self; |
018 | userName.placeholder = @ "请输入用户名" ; |
022 | userName.enablesReturnKeyAutomatically = true ; |
024 | userName.returnKeyType= UIReturnKeyDone; |
026 | userName.font = TTSTYLEVAR(font); |
028 | userName.autocapitalizationType = UITextAutocapitalizationTypeNone; |
031 | passWord = [[[UITextField alloc] init]autorelease]; |
033 | passWord.delegate = self; |
035 | passWord.placeholder = @ "请输入密码" ; |
037 | passWord.clearButtonMode = UITextFieldViewModeWhileEditing; |
039 | passWord.returnKeyType = UIReturnKeyDone; |
041 | passWord.font = TTSTYLEVAR(font); |
043 | passWord.enablesReturnKeyAutomatically = true ; |
046 | passWord.secureTextEntry =YES; |
049 | keyDone = [UIButton buttonWithType:UIBarStyleBlack] ; |
050 | keyDone.frame = CGRectMake(10, 150, 300, 40); |
051 | [keyDone setTitle:@ "登录" forState:UIControlStateNormal]; |
052 | [keyDone addTarget:self action:@selector(ButtonPressed) forControlEvents:UIControlEventTouchUpInside]; |
055 | [self.view addSubview:keyDone]; |
058 | self.tableView.frame = CGRectMake(0, 30, 320, 100); |
061 | self.tableView.scrollEnabled = NO; |
063 | self.tableView.backgroundColor = [UIColor clearColor]; |
066 | self.dataSource = [TTListDataSource dataSourceWithObjects: |
076 | -( void )viewWillAppear:( BOOL )animated |
078 | [super viewWillAppear:animated]; |
080 | self.navigationController.navigationBarHidden=YES; |
096 | - ( void )viewDidUnload |
098 | [super viewDidUnload]; |
102 | - ( BOOL )shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation |
104 | return (interfaceOrientation == UIInterfaceOrientationPortrait); |
107 | - ( BOOL )textFieldShouldReturn:(UITextField *)textField { |
109 | [textField resignFirstResponder]; |
117 | [userName resignFirstResponder]; |
118 | [passWord resignFirstResponder]; |
121 | textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 130, 130)]; |
123 | [textView setBackgroundColor:[UIColor blackColor]]; |
125 | [textView setText:@ "正在登录" ]; |
127 | [textView setTextColor:[UIColor whiteColor]]; |
130 | [textView setTextAlignment:UITextAlignmentCenter]; |
133 | [textView setFont:[UIFont systemFontOfSize:15]]; |
135 | textView.alpha = 0.8f; |
138 | textView.center = self.view.center; |
141 | activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; |
143 | activity.activityIndicatorViewStyle=UIActivityIndicatorViewStyleWhiteLarge; |
146 | activity.frame = self.view.frame; |
148 | activity.center = self.view.center; |
150 | [activity startAnimating]; |
153 | [self.view addSubview:textView]; |
154 | [self.view addSubview:activity]; |
166 | [activity stopAnimating]; |
168 | [activity removeFromSuperview]; |
170 | [textView removeFromSuperview]; |
174 | - ( void )ButtonPressed |
178 | if (userName.text.length == 0 ¦¦passWord.text.length == 0) |
182 | UIAlertView * alert= [[UIAlertView alloc] initWithTitle:@ "用户名或密码不能为空" message:nil delegate:self cancelButtonTitle:@ "确定" otherButtonTitles: nil]; |
200 | NSString *server_base = [NSString stringWithFormat:@ "%@/abc.json" , Server_Host]; |
203 | ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:server_base]]; |
206 | NSMutableDictionary *dictRequest = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
207 | userName.text,@ "userName" , |
208 | passWord.text,@ "password" , |
213 | [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator: NO]; |
219 | [request setPostValue:[ dictRequest JSONFragment] forKey:@ "request" ]; |
221 | [request setDelegate : self]; |
224 | [request startAsynchronous]; |
230 | - ( void )requestFailed:( ASIHTTPRequest *)request |
232 | NSError *error = [request error ]; |
234 | NSLog ( @ "%@" ,error. userInfo ); |
241 | - ( void )requestFinished:( ASIHTTPRequest *)request |
245 | NSString *responseString = [request responseString ]; |
249 | NSMutableDictionary *dictRequest = [responseString JSONValue]; |
261 | [self removeLoading]; |
265 | NSArray * key = [NSArray arrayWithObjects:@ "userName" ,@ "passWord" , nil]; |
266 | NSArray * obj = [NSArray arrayWithObjects:userName.text,passWord.text, nil]; |
269 | TTURLAction *action = [[[TTURLAction actionWithURLPath:@ "tt://Main" ] |
270 | applyQuery:[NSDictionary dictionaryWithObjects:obj forKeys:key]] |
273 | TTNavigator* navigator = [TTNavigator navigator]; |
275 | [navigator openURLAction:action]; |
MainViewController.h 登录成功页面, 很简单 就是将用户在上个页面中输入的信息显示在这个页面中。
1 | #import <Three20/Three20.h> |
3 | @interface MainViewController : TTViewController |
6 | NSString* userPassword; |
MainViewController.m 这里应当比较好理解了吧?
01 | #import "MainViewController.h" |
03 | @implementation MainViewController |
09 | - (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query |
11 | if ( self = [super init]) |
14 | userName = [query objectForKey:@ "userName" ]; |
15 | userPassword = [query objectForKey:@ "passWord" ]; |
20 | -( void )viewWillAppear:( BOOL )animated |
23 | [super viewWillAppear:animated]; |
24 | self.navigationController.navigationBarHidden=NO; |
31 | [self.navigationItem setHidesBackButton:YES]; |
34 | UILabel* textName = [[UILabel alloc] initWithFrame:CGRectMake(180, 50, 100, 20)]; |
36 | textName.text = [NSString stringWithFormat:@ "%@%@" ,@ "用户名:" ,userName]; |
38 | UILabel* textPassword = [[UILabel alloc] initWithFrame:CGRectMake(180, 80, 100, 20)]; |
40 | textPassword.text = [NSString stringWithFormat:@ "%@%@" ,@ "密码:" ,userPassword]; |
42 | reLogin = [UIButton buttonWithType:UIBarStyleBlack] ; |
43 | reLogin.frame = CGRectMake(10, 150, 300, 40); |
44 | [reLogin setTitle:@ "重新登录" forState:UIControlStateNormal]; |
45 | [reLogin addTarget:self action:@selector(ButtonPressed) forControlEvents:UIControlEventTouchUpInside]; |
47 | [self.view addSubview:reLogin]; |
48 | [self.view addSubview:textName]; |
49 | [self.view addSubview:textPassword]; |
56 | TTURLAction *action = [[TTURLAction actionWithURLPath:@ "tt://Login" ] |
59 | TTNavigator* navigator = [TTNavigator navigator]; |
60 | [navigator openURLAction:action]; |
66 | [super viewDidUnload]; |
70 | - ( BOOL )shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation |
72 | return (interfaceOrientation == UIInterfaceOrientationPortrait); |
感觉本章的内容不是很难,所以我就不做过多的解释。唯一感觉比较恶心的就是搭建ASI的环境,最后雨松MOMO祝大家学习愉快、一起进步哇咔咔~~
下载地址:http://vdisk.weibo.com/s/ab-Id