Three20 这系列的文章也好久没更新了,学习的路上是阻挡不了我们程序猿的,哇咔咔~~ 今天我们主要学习一下 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 这是入口类,应该没问题吧,这里我们写了两个页面 一个用来登录,一个显示登录结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#import "AppDelegate.h" @implementation AppDelegate @synthesize window = _window; - (void)dealloc { [_window release]; [super dealloc]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //创建导航条 TTNavigator* navigator = [TTNavigator navigator]; navigator.persistenceMode = TTNavigatorPersistenceModeAll; navigator.window = [[[UIWindow alloc] initWithFrame:TTScreenBounds()] autorelease]; //TTURLMap 非常重要的一个属性 //界面的点击切换完全取决与它的设定 TTURLMap* map = navigator.URLMap; //如果须要访问wab页面的话 就必需添加 [map from:@"*" toViewController:[TTWebController class]]; //拼一个url 意思是如果访问 "tt://Login" 会进入 MyViewController class [map from:@"tt://Login" toSharedViewController:[LoginViewController class]]; [map from:@"tt://Main" toViewController:[MainViewController class]]; if (![navigator restoreViewControllers]) { //打开上面设置的url [navigator openURLAction:[TTURLAction actionWithURLPath:@"tt://Login"]]; } return YES; } @end |
LoginViewController.h 首先是登录界面 这里将ASIHTTPRequest.h 与 JSON.h引入,登录页面是仿照FaceBook的在输入框中MOMO选择的是TabView。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#import <Three20/Three20.h> #import "ASIHTTPRequest.h" #import "ASIFormDataRequest.h" #import "JSON.h" @interface LoginViewController : TTTableViewController<UITextFieldDelegate> { //输入用户名 UITextField* userName; //输入密码 UITextField* passWord; //登录按钮 UIButton* keyDone; //登录时动画 UIActivityIndicatorView *activity; //登录半透明背景 UITextView *textView; } @end |
LoginViewController.m 大量的逻辑都在这里面,请大家仔细看这个类,MOMO已经添加了详细的注释噢。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
#import "LoginViewController.h" @implementation LoginViewController - (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query { if (self = [super init]) { //设置TabView的风格 self.tableViewStyle = UITableViewStyleGrouped; //设置背景图片 self.view.backgroundColor=[UIColor colorWithPatternImage:TTIMAGE(@"bundle://Default.png")]; //用户名输入框 userName = [[[UITextField alloc] init]autorelease]; //这里设置它的代理在本类中 userName.delegate = self; //默认灰色的文字,写入后会消失 userName.placeholder = @"请输入用户名"; //这里设置为true表示 //当IOS软键盘抬起后,输入框中若没有输入内容,右下角按钮将呈灰色状态 userName.enablesReturnKeyAutomatically = true; //在这里设置IOS软键盘右下角文字显示内容为完成,这里还有很多选项。 userName.returnKeyType= UIReturnKeyDone; //设置字体 userName.font = TTSTYLEVAR(font); //设置IOS软键盘抬起后首字母不大写 userName.autocapitalizationType = UITextAutocapitalizationTypeNone; //密码输入框 passWord = [[[UITextField alloc] init]autorelease]; //这里设置它的代理在本类中 passWord.delegate = self; //默认灰色的文字,写入后会消失 passWord.placeholder = @"请输入密码"; //在密码输入框中右侧添加整体清除按钮 passWord.clearButtonMode = UITextFieldViewModeWhileEditing; //在这里设置IOS软键盘右下角文字显示内容为完成,这里还有很多选项。 passWord.returnKeyType = UIReturnKeyDone; //设置字体 passWord.font = TTSTYLEVAR(font); //当IOS软键盘抬起后,输入框中若没有输入内容,右下角按钮将呈灰色状态 passWord.enablesReturnKeyAutomatically = true; //输入后字符串显示为*符号 passWord.secureTextEntry =YES; //在这里创建一个按钮,点击按钮后开始登录 keyDone = [UIButton buttonWithType:UIBarStyleBlack] ; keyDone.frame = CGRectMake(10, 150, 300, 40); [keyDone setTitle:@"登录" forState:UIControlStateNormal]; [keyDone addTarget:self action:@selector(ButtonPressed) forControlEvents:UIControlEventTouchUpInside]; //将按钮加入视图中 [self.view addSubview:keyDone]; //设置tableView的显示区域 self.tableView.frame = CGRectMake(0, 30, 320, 100); //TabView默认触摸时可以上下滑动 //这里禁止它上滑滑动 self.tableView.scrollEnabled = NO; //设置TableView背景颜色为透明状态 self.tableView.backgroundColor = [UIColor clearColor]; //将用户名与密码输入框加入视图中 self.dataSource = [TTListDataSource dataSourceWithObjects: userName, passWord, nil]; } return self; } //页面每次进入时都会调用这里的方法, -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //在这里将标题栏Navigation隐藏。 self.navigationController.navigationBarHidden=YES; } - (void)viewDidLoad { [super viewDidLoad]; } - (void)dealloc { [super dealloc]; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } - (BOOL)textFieldShouldReturn:(UITextField *)textField { //当用户点击IOS软键盘右下角完成按钮 此时关闭软键盘 [textField resignFirstResponder]; return YES; } //登陆时弹出窗口来显示loading动画 - (void)addLoading { //关闭软键盘 [userName resignFirstResponder]; [passWord resignFirstResponder]; //写入动画视图 textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 130, 130)]; //设置背景颜色为黑色 [textView setBackgroundColor:[UIColor blackColor]]; //正在登录 [textView setText:@"正在登录"]; //设置文字的颜色 [textView setTextColor:[UIColor whiteColor]]; //这里表示让文字居中显示 [textView setTextAlignment:UITextAlignmentCenter]; //字体大小 [textView setFont:[UIFont systemFontOfSize:15]]; //设置背景透明度 textView.alpha = 0.8f; //设置view整体居中显示 textView.center = self.view.center; //创建Loading动画视图动画有三个状态可供选择 activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; //设置动画视图的风格,这里设定它位白色 activity.activityIndicatorViewStyle=UIActivityIndicatorViewStyleWhiteLarge; //设置它显示的区域 这里设置为整个手机屏幕大小 //为了避免登录动画播放时用户还能点击动画后面的高级控件 activity.frame = self.view.frame; //动画居中显示 activity.center = self.view.center; //开始播放动画 [activity startAnimating]; //将动画于与文字视图添加在窗口中 [self.view addSubview:textView]; [self.view addSubview:activity]; //释放 [activity release]; [textView release]; } //关闭登录动画 -(void)removeLoading { //结束动画 [activity stopAnimating]; //删除动画视图 [activity removeFromSuperview]; //删除文字视图 [textView removeFromSuperview]; } //点击登录按钮时 - (void)ButtonPressed { //判断用户名与密码长度是否大于0 if(userName.text.length == 0 ¦¦passWord.text.length == 0) { //创建对话框 提示用户重新输入 UIAlertView * alert= [[UIAlertView alloc] initWithTitle:@"用户名或密码不能为空" message:nil delegate:self cancelButtonTitle:@"确定" otherButtonTitles: nil]; //将这个UIAlerView 显示出来 [alert show]; //释放 [alert release]; }else { //开始播放loading动画 [self addLoading]; //下面这里就需要使用ASI的东东啦。 //服务器 访问地址 NSString *Server_Host = @"http://192.168.1.1:3000"; //地址的后缀, 这里应当与服务器约定好 NSString *server_base = [NSString stringWithFormat:@"%@/abc.json", Server_Host]; //设置ASI向服务器请求 ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:server_base]]; //这是一个字典对象, 这里我把用户名与密码写入字典中 NSMutableDictionary *dictRequest = [NSMutableDictionary dictionaryWithObjectsAndKeys: userName.text,@"userName", passWord.text,@"password", nil]; //当用户登陆时禁止状态栏中出现动画 //ASI底层会默认在状态栏中加入动画 [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator: NO]; //这里就比较重要的 //[ dictRequest JSONFragment] 的意思是把字典对象变成一个string //还记得开始MOMO说的 客户端与服务器之间的交互就是字符串 //服务器拿到这个字符串在做解析 [request setPostValue:[ dictRequest JSONFragment] forKey:@"request"]; //设置在本类中代理 [request setDelegate : self]; //开始一个异步请求 [request startAsynchronous]; } } //请求失败 - (void)requestFailed:( ASIHTTPRequest *)request { NSError *error = [request error ]; NSLog ( @"%@" ,error. userInfo ); //因为这里的IP我乱写的所以肯定会失败, //在这里我直接让程序进入登录成功状态 [self LoginSuccess]; } - (void)requestFinished:( ASIHTTPRequest *)request { //如果请求成功,它就是服务器返回的字符串 //如果使用JSON 服务器应当是在这里返回一个json类型的字符串 NSString *responseString = [request responseString ]; //因为我们拿到的是字符串,所以我们通过JOSN 中的方法把字符串在变成字典对象 //这样在使用起来就方便很多噢。。 NSMutableDictionary *dictRequest = [responseString JSONValue]; //因为服务器请求的地址有误,所以请求不到任何东东 [self LoginSuccess]; } //登录成功 -(void) LoginSuccess { //删除登录动画 [self removeLoading]; //下面我们学习320页面之间切换数据的传递 //这里我取得当前用户在输入框中输入的用户名与密码 //将它们写入一个字典中 NSArray * key = [NSArray arrayWithObjects:@"userName",@"passWord", nil]; NSArray * obj = [NSArray arrayWithObjects:userName.text,passWord.text, nil]; //页面切换时 将字典对象传入下一个页面 TTURLAction *action = [[[TTURLAction actionWithURLPath:@"tt://Main"] applyQuery:[NSDictionary dictionaryWithObjects:obj forKeys:key]] applyAnimated:NO]; TTNavigator* navigator = [TTNavigator navigator]; //切换至登录成功页面 [navigator openURLAction:action]; } @end |
MainViewController.h 登录成功页面, 很简单 就是将用户在上个页面中输入的信息显示在这个页面中。
1 2 3 4 5 6 7 8 9 10 11 |
#import <Three20/Three20.h> @interface MainViewController : TTViewController { NSString* userName; NSString* userPassword; UIButton* reLogin; } @end |
MainViewController.m 这里应当比较好理解了吧?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#import "MainViewController.h" @implementation MainViewController //这个方法就比较重要的。 //默认320在页面切换时都会调用这个方法, //参数2 就是上个页面过来时附带的字典对象 //我们在这里把用户在上个页面中输入的信息取出来 - (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query { if ( self = [super init]) { NSLog(@"%@" , query); userName = [query objectForKey:@"userName"]; userPassword = [query objectForKey:@"passWord"]; } return self; } -(void)viewWillAppear:(BOOL)animated { //隐藏标题栏 [super viewWillAppear:animated]; self.navigationController.navigationBarHidden=NO; } - (void)viewDidLoad { [super viewDidLoad]; [self.navigationItem setHidesBackButton:YES]; self.title =@"登录成功"; UILabel* textName = [[UILabel alloc] initWithFrame:CGRectMake(180, 50, 100, 20)]; textName.text = [NSString stringWithFormat:@"%@%@",@"用户名:",userName]; UILabel* textPassword = [[UILabel alloc] initWithFrame:CGRectMake(180, 80, 100, 20)]; textPassword.text = [NSString stringWithFormat:@"%@%@",@"密码:",userPassword]; reLogin = [UIButton buttonWithType:UIBarStyleBlack] ; reLogin.frame = CGRectMake(10, 150, 300, 40); [reLogin setTitle:@"重新登录" forState:UIControlStateNormal]; [reLogin addTarget:self action:@selector(ButtonPressed) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:reLogin]; [self.view addSubview:textName]; [self.view addSubview:textPassword]; } -(void) ButtonPressed { //当用户点击按钮时重新登录 TTURLAction *action = [[TTURLAction actionWithURLPath:@"tt://Login"] applyAnimated:NO]; TTNavigator* navigator = [TTNavigator navigator]; [navigator openURLAction:action]; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end |
感觉本章的内容不是很难,所以我就不做过多的解释。唯一感觉比较恶心的就是搭建ASI的环境,最后雨松MOMO祝大家学习愉快、一起进步哇咔咔~~
下载地址:http://vdisk.weibo.com/s/ab-Id
大家下载以后是不能直接运行的,可以在工程中将红色的Three20相关的文件删除,然后重新直接一下搭建Three20环境的python语句即可。祝大家学习愉快,不早了晚安~~~
- 本文固定链接: https://www.xuanyusong.com/archives/1281
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
momo 啥时候写一片关于unity在ios中内置购买道具的例子啊?
等有时间了一定哈。。。 最近真心有点忙碌啊。。
楼主的队伍很强大
回头也得搭建一个才行,学习ing..加油。
其实博主说得也很有道理
Three20很强大…MOMO写了这样的文章可以在IOS群里告知下的,有N多人在学这个,说不会的…