- 浏览: 4064388 次
文章分类
最新评论
-
klxh:
Android如何一次安装多个apk -
kchiu:
废话啊啊啊
TCP,socket 心跳检测 -
追求幸福:
iOS: 当发生signal 9为 kill的时候,程序直接被 ...
android和iOS平台的崩溃捕获和收集 -
andsy2008:
给的地址,没豆子呢,能单独发一份给我吗,andsy2008@1 ...
点餐订餐系统应用android源码 -
王粤新:
[b][i][u]引用[list]
[*][flash=200 ...
百度地图SDK for Android【事件监听】
Three20研究院之搭建ASI与JSON环境制作简单的登录界面(七)
今天我们主要学习一下 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"
|
02
|
03
|
@implementation
AppDelegate
|
04
|
05
|
@synthesize
window = _window;
|
06
|
07
|
-
( void )dealloc
|
08
|
{
|
09
|
[_window
release];
|
10
|
[super
dealloc];
|
11
|
}
|
12
|
13
|
-
( BOOL )application:(UIApplication
*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
14
|
{
|
15
|
16
|
//创建导航条
|
17
|
TTNavigator*
navigator = [TTNavigator navigator];
|
18
|
navigator.persistenceMode
= TTNavigatorPersistenceModeAll;
|
19
|
navigator.window
= [[[UIWindow alloc] initWithFrame:TTScreenBounds()] autorelease];
|
20
|
21
|
//TTURLMap
非常重要的一个属性
|
22
|
//界面的点击切换完全取决与它的设定
|
23
|
TTURLMap*
map = navigator.URLMap;
|
24
|
25
|
//如果须要访问wab页面的话
就必需添加
|
26
|
[map
from:@ "*" toViewController:[TTWebController class ]];
|
27
|
28
|
//拼一个url
意思是如果访问 "tt://Login" 会进入 MyViewController class
|
29
|
30
|
[map
from:@ "tt://Login" toSharedViewController:[LoginViewController class ]];
|
31
|
32
|
[map
from:@ "tt://Main" toViewController:[MainViewController class ]];
|
33
|
34
|
if (![navigator
restoreViewControllers]) {
|
35
|
//打开上面设置的url
|
36
|
[navigator
openURLAction:[TTURLAction actionWithURLPath:@ "tt://Login" ]];
|
37
|
}
|
38
|
39
|
return YES;
|
40
|
}
|
41
|
42
|
@end
|
LoginViewController.h 首先是登录界面 这里将ASIHTTPRequest.h 与 JSON.h引入,登录页面是仿照FaceBook的在输入框中MOMO选择的是TabView。
01
|
#import
<Three20/Three20.h>
|
02
|
#import
"ASIHTTPRequest.h"
|
03
|
#import
"ASIFormDataRequest.h"
|
04
|
#import
"JSON.h"
|
05
|
06
|
@interface
LoginViewController : TTTableViewController<UITextFieldDelegate>
|
07
|
{
|
08
|
//输入用户名
|
09
|
UITextField*
userName;
|
10
|
//输入密码
|
11
|
UITextField*
passWord;
|
12
|
//登录按钮
|
13
|
UIButton*
keyDone;
|
14
|
//登录时动画
|
15
|
UIActivityIndicatorView
*activity;
|
16
|
//登录半透明背景
|
17
|
UITextView
*textView;
|
18
|
19
|
}
|
20
|
21
|
@end
|
LoginViewController.m 大量的逻辑都在这里面,请大家仔细看这个类,MOMO已经添加了详细的注释噢。。
001
|
#import
"LoginViewController.h"
|
002
|
003
|
@implementation
LoginViewController
|
004
|
005
|
-
(id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query {
|
006
|
if (self
= [super init]) {
|
007
|
008
|
//设置TabView的风格
|
009
|
self.tableViewStyle
= UITableViewStyleGrouped;
|
010
|
//设置背景图片
|
011
|
self.view.backgroundColor=[UIColor
colorWithPatternImage:TTIMAGE(@ "bundle://Default.png" )];
|
012
|
013
|
//用户名输入框
|
014
|
userName
= [[[UITextField alloc] init]autorelease];
|
015
|
//这里设置它的代理在本类中
|
016
|
userName.delegate
= self;
|
017
|
//默认灰色的文字,写入后会消失
|
018
|
userName.placeholder
= @ "请输入用户名" ;
|
019
|
020
|
//这里设置为true表示
|
021
|
//当IOS软键盘抬起后,输入框中若没有输入内容,右下角按钮将呈灰色状态
|
022
|
userName.enablesReturnKeyAutomatically
= true ;
|
023
|
//在这里设置IOS软键盘右下角文字显示内容为完成,这里还有很多选项。
|
024
|
userName.returnKeyType=
UIReturnKeyDone;
|
025
|
//设置字体
|
026
|
userName.font
= TTSTYLEVAR(font);
|
027
|
//设置IOS软键盘抬起后首字母不大写
|
028
|
userName.autocapitalizationType
= UITextAutocapitalizationTypeNone;
|
029
|
030
|
//密码输入框
|
031
|
passWord
= [[[UITextField alloc] init]autorelease];
|
032
|
//这里设置它的代理在本类中
|
033
|
passWord.delegate
= self;
|
034
|
//默认灰色的文字,写入后会消失
|
035
|
passWord.placeholder
= @ "请输入密码" ;
|
036
|
//在密码输入框中右侧添加整体清除按钮
|
037
|
passWord.clearButtonMode
= UITextFieldViewModeWhileEditing;
|
038
|
//在这里设置IOS软键盘右下角文字显示内容为完成,这里还有很多选项。
|
039
|
passWord.returnKeyType
= UIReturnKeyDone;
|
040
|
//设置字体
|
041
|
passWord.font
= TTSTYLEVAR(font);
|
042
|
//当IOS软键盘抬起后,输入框中若没有输入内容,右下角按钮将呈灰色状态
|
043
|
passWord.enablesReturnKeyAutomatically
= true ;
|
044
|
045
|
//输入后字符串显示为*符号
|
046
|
passWord.secureTextEntry
=YES;
|
047
|
048
|
//在这里创建一个按钮,点击按钮后开始登录
|
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];
|
053
|
054
|
//将按钮加入视图中
|
055
|
[self.view
addSubview:keyDone];
|
056
|
057
|
//设置tableView的显示区域
|
058
|
self.tableView.frame
= CGRectMake(0, 30, 320, 100);
|
059
|
//TabView默认触摸时可以上下滑动
|
060
|
//这里禁止它上滑滑动
|
061
|
self.tableView.scrollEnabled
= NO;
|
062
|
//设置TableView背景颜色为透明状态
|
063
|
self.tableView.backgroundColor
= [UIColor clearColor];
|
064
|
065
|
//将用户名与密码输入框加入视图中
|
066
|
self.dataSource
= [TTListDataSource dataSourceWithObjects:
|
067
|
userName,
|
068
|
passWord,
|
069
|
nil];
|
070
|
071
|
}
|
072
|
return self;
|
073
|
}
|
074
|
075
|
//页面每次进入时都会调用这里的方法,
|
076
|
-( void )viewWillAppear:( BOOL )animated
|
077
|
{
|
078
|
[super
viewWillAppear:animated];
|
079
|
//在这里将标题栏Navigation隐藏。
|
080
|
self.navigationController.navigationBarHidden=YES;
|
081
|
082
|
}
|
083
|
084
|
-
( void )viewDidLoad
|
085
|
{
|
086
|
[super
viewDidLoad];
|
087
|
088
|
}
|
089
|
090
|
-
( void )dealloc
|
091
|
{
|
092
|
093
|
[super
dealloc];
|
094
|
}
|
095
|
096
|
-
( void )viewDidUnload
|
097
|
{
|
098
|
[super
viewDidUnload];
|
099
|
//
Release any retained subviews of the main view.
|
100
|
}
|
101
|
102
|
-
( BOOL )shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
103
|
{
|
104
|
return (interfaceOrientation
== UIInterfaceOrientationPortrait);
|
105
|
}
|
106
|
107
|
-
( BOOL )textFieldShouldReturn:(UITextField
*)textField {
|
108
|
//当用户点击IOS软键盘右下角完成按钮
此时关闭软键盘
|
109
|
[textField
resignFirstResponder];
|
110
|
return YES;
|
111
|
}
|
112
|
113
|
//登陆时弹出窗口来显示loading动画
|
114
|
-
( void )addLoading
|
115
|
{
|
116
|
//关闭软键盘
|
117
|
[userName
resignFirstResponder];
|
118
|
[passWord
resignFirstResponder];
|
119
|
120
|
//写入动画视图
|
121
|
textView
= [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 130, 130)];
|
122
|
//设置背景颜色为黑色
|
123
|
[textView
setBackgroundColor:[UIColor blackColor]];
|
124
|
//正在登录
|
125
|
[textView
setText:@ "正在登录" ];
|
126
|
//设置文字的颜色
|
127
|
[textView
setTextColor:[UIColor whiteColor]];
|
128
|
129
|
//这里表示让文字居中显示
|
130
|
[textView
setTextAlignment:UITextAlignmentCenter];
|
131
|
132
|
//字体大小
|
133
|
[textView
setFont:[UIFont systemFontOfSize:15]];
|
134
|
//设置背景透明度
|
135
|
textView.alpha
= 0.8f;
|
136
|
137
|
//设置view整体居中显示
|
138
|
textView.center
= self.view.center;
|
139
|
140
|
//创建Loading动画视图动画有三个状态可供选择
|
141
|
activity
= [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
142
|
//设置动画视图的风格,这里设定它位白色
|
143
|
activity.activityIndicatorViewStyle=UIActivityIndicatorViewStyleWhiteLarge;
|
144
|
//设置它显示的区域
这里设置为整个手机屏幕大小
|
145
|
//为了避免登录动画播放时用户还能点击动画后面的高级控件
|
146
|
activity.frame
= self.view.frame;
|
147
|
//动画居中显示
|
148
|
activity.center
= self.view.center;
|
149
|
//开始播放动画
|
150
|
[activity
startAnimating];
|
151
|
152
|
//将动画于与文字视图添加在窗口中
|
153
|
[self.view
addSubview:textView];
|
154
|
[self.view
addSubview:activity];
|
155
|
156
|
//释放
|
157
|
[activity
release];
|
158
|
[textView
release];
|
159
|
}
|
160
|
161
|
//关闭登录动画
|
162
|
-( void )removeLoading
|
163
|
{
|
164
|
165
|
//结束动画
|
166
|
[activity
stopAnimating];
|
167
|
//删除动画视图
|
168
|
[activity
removeFromSuperview];
|
169
|
//删除文字视图
|
170
|
[textView
removeFromSuperview];
|
171
|
}
|
172
|
173
|
//点击登录按钮时
|
174
|
-
( void )ButtonPressed
|
175
|
{
|
176
|
177
|
//判断用户名与密码长度是否大于0
|
178
|
if (userName.text.length
== 0 ¦¦passWord.text.length == 0)
|
179
|
{
|
180
|
181
|
//创建对话框
提示用户重新输入
|
182
|
UIAlertView
* alert= [[UIAlertView alloc] initWithTitle:@ "用户名或密码不能为空" message:nil
delegate:self cancelButtonTitle:@ "确定" otherButtonTitles:
nil];
|
183
|
//将这个UIAlerView
显示出来
|
184
|
[alert
show];
|
185
|
//释放
|
186
|
[alert
release];
|
187
|
188
|
} else
|
189
|
{
|
190
|
191
|
//开始播放loading动画
|
192
|
[self
addLoading];
|
193
|
194
|
//下面这里就需要使用ASI的东东啦。
|
195
|
196
|
//服务器
访问地址
|
197
|
NSString
*Server_Host = @ "http://192.168.1.1:3000" ;
|
198
|
199
|
//地址的后缀,
这里应当与服务器约定好
|
200
|
NSString
*server_base = [NSString stringWithFormat:@ "%@/abc.json" ,
Server_Host];
|
201
|
202
|
//设置ASI向服务器请求
|
203
|
ASIFormDataRequest
*request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:server_base]];
|
204
|
205
|
//这是一个字典对象,
这里我把用户名与密码写入字典中
|
206
|
NSMutableDictionary
*dictRequest = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
207
|
userName.text,@ "userName" ,
|
208
|
passWord.text,@ "password" ,
|
209
|
nil];
|
210
|
211
|
//当用户登陆时禁止状态栏中出现动画
|
212
|
//ASI底层会默认在状态栏中加入动画
|
213
|
[ASIHTTPRequest
setShouldUpdateNetworkActivityIndicator: NO];
|
214
|
215
|
//这里就比较重要的
|
216
|
//[
dictRequest JSONFragment] 的意思是把字典对象变成一个string
|
217
|
//还记得开始MOMO说的
客户端与服务器之间的交互就是字符串
|
218
|
//服务器拿到这个字符串在做解析
|
219
|
[request
setPostValue:[ dictRequest JSONFragment] forKey:@ "request" ];
|
220
|
//设置在本类中代理
|
221
|
[request
setDelegate : self];
|
222
|
223
|
//开始一个异步请求
|
224
|
[request
startAsynchronous];
|
225
|
226
|
}
|
227
|
}
|
228
|
229
|
//请求失败
|
230
|
-
( void )requestFailed:(
ASIHTTPRequest *)request
|
231
|
{
|
232
|
NSError
*error = [request error ];
|
233
|
234
|
NSLog
( @ "%@" ,error.
userInfo );
|
235
|
236
|
//因为这里的IP我乱写的所以肯定会失败,
|
237
|
//在这里我直接让程序进入登录成功状态
|
238
|
[self
LoginSuccess];
|
239
|
}
|
240
|
241
|
-
( void )requestFinished:(
ASIHTTPRequest *)request
|
242
|
{
|
243
|
//如果请求成功,它就是服务器返回的字符串
|
244
|
//如果使用JSON
服务器应当是在这里返回一个json类型的字符串
|
245
|
NSString
*responseString = [request responseString ];
|
246
|
247
|
//因为我们拿到的是字符串,所以我们通过JOSN
中的方法把字符串在变成字典对象
|
248
|
//这样在使用起来就方便很多噢。。
|
249
|
NSMutableDictionary
*dictRequest = [responseString JSONValue];
|
250
|
251
|
//因为服务器请求的地址有误,所以请求不到任何东东
|
252
|
253
|
[self
LoginSuccess];
|
254
|
255
|
}
|
256
|
257
|
//登录成功
|
258
|
-( void )
LoginSuccess
|
259
|
{
|
260
|
//删除登录动画
|
261
|
[self
removeLoading];
|
262
|
//下面我们学习320页面之间切换数据的传递
|
263
|
//这里我取得当前用户在输入框中输入的用户名与密码
|
264
|
//将它们写入一个字典中
|
265
|
NSArray
* key = [NSArray arrayWithObjects:@ "userName" ,@ "passWord" ,
nil];
|
266
|
NSArray
* obj = [NSArray arrayWithObjects:userName.text,passWord.text, nil];
|
267
|
268
|
//页面切换时
将字典对象传入下一个页面
|
269
|
TTURLAction
*action = [[[TTURLAction actionWithURLPath:@ "tt://Main" ]
|
270
|
applyQuery:[NSDictionary
dictionaryWithObjects:obj forKeys:key]]
|
271
|
applyAnimated:NO];
|
272
|
273
|
TTNavigator*
navigator = [TTNavigator navigator];
|
274
|
//切换至登录成功页面
|
275
|
[navigator
openURLAction:action];
|
276
|
277
|
}
|
278
|
279
|
@end
|
MainViewController.h 登录成功页面, 很简单 就是将用户在上个页面中输入的信息显示在这个页面中。
1
|
#import
<Three20/Three20.h>
|
2
|
3
|
@interface
MainViewController : TTViewController
|
4
|
{
|
5
|
NSString*
userName;
|
6
|
NSString*
userPassword;
|
7
|
UIButton*
reLogin;
|
8
|
}
|
9
|
@end
|
MainViewController.m 这里应当比较好理解了吧?
01
|
#import
"MainViewController.h"
|
02
|
03
|
@implementation
MainViewController
|
04
|
05
|
//这个方法就比较重要的。
|
06
|
//默认320在页面切换时都会调用这个方法,
|
07
|
//参数2
就是上个页面过来时附带的字典对象
|
08
|
//我们在这里把用户在上个页面中输入的信息取出来
|
09
|
-
(id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query
|
10
|
{
|
11
|
if (
self = [super init])
|
12
|
{
|
13
|
NSLog(@ "%@" ,
query);
|
14
|
userName
= [query objectForKey:@ "userName" ];
|
15
|
userPassword
= [query objectForKey:@ "passWord" ];
|
16
|
}
|
17
|
return self;
|
18
|
}
|
19
|
20
|
-( void )viewWillAppear:( BOOL )animated
|
21
|
{
|
22
|
//隐藏标题栏
|
23
|
[super
viewWillAppear:animated];
|
24
|
self.navigationController.navigationBarHidden=NO;
|
25
|
26
|
}
|
27
|
28
|
-
( void )viewDidLoad
|
29
|
{
|
30
|
[super
viewDidLoad];
|
31
|
[self.navigationItem
setHidesBackButton:YES];
|
32
|
self.title
=@ "登录成功" ;
|
33
|
34
|
UILabel*
textName = [[UILabel alloc] initWithFrame:CGRectMake(180, 50, 100, 20)];
|
35
|
36
|
textName.text
= [NSString stringWithFormat:@ "%@%@" ,@ "用户名:" ,userName];
|
37
|
38
|
UILabel*
textPassword = [[UILabel alloc] initWithFrame:CGRectMake(180, 80, 100, 20)];
|
39
|
40
|
textPassword.text
= [NSString stringWithFormat:@ "%@%@" ,@ "密码:" ,userPassword];
|
41
|
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];
|
46
|
47
|
[self.view
addSubview:reLogin];
|
48
|
[self.view
addSubview:textName];
|
49
|
[self.view
addSubview:textPassword];
|
50
|
}
|
51
|
52
|
-( void )
ButtonPressed
|
53
|
{
|
54
|
55
|
//当用户点击按钮时重新登录
|
56
|
TTURLAction
*action = [[TTURLAction actionWithURLPath:@ "tt://Login" ]
|
57
|
applyAnimated:NO];
|
58
|
59
|
TTNavigator*
navigator = [TTNavigator navigator];
|
60
|
[navigator
openURLAction:action];
|
61
|
62
|
}
|
63
|
64
|
-
( void )viewDidUnload
|
65
|
{
|
66
|
[super
viewDidUnload];
|
67
|
//
Release any retained subviews of the main view.
|
68
|
}
|
69
|
70
|
-
( BOOL )shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
71
|
{
|
72
|
return (interfaceOrientation
== UIInterfaceOrientationPortrait);
|
73
|
}
|
74
|
75
|
@end
|
感觉本章的内容不是很难,所以我就不做过多的解释。唯一感觉比较恶心的就是搭建ASI的环境,最后雨松MOMO祝大家学习愉快、一起进步哇咔咔~~
下载地址:http://vdisk.weibo.com/s/ab-Id
相关推荐
ASI-GSD,用于识别ASI元件,在编程软件界面下可以看到
ASI和SDI的区别 广电领域传输。介绍这2种线的区别。串行传输和异步传输
ASi现场总线使用手册pdf,ASi现场总线使用手册
(1)ASI原理基础知识、规划设计注意事项(文档资料) (2)倍加福、必威、西门子ASI ET200模块等多种产品ASI网关通信程序案例 (3)ASI常见问题、资料手册
在目前的DVB-C广播电视系统的传输接口中,有两种MPEG-2视频传输接口标准:异步串行接口标准 ASI和同步并行接口SPI。SPI一共有11位有用信号,每位信号差分成两个信号用来提高传输抗干扰性,在物理链接上用DB25传输,...
美国ASI温度记录仪 ASI-L1500B 记录软件 常用型号:ASI-1200 ASI 1100 / 1200 ASI-L1500 ASI-L1508B ASI-L1516B ASI-L1524B ASI-L1532B ASI-L1500B ASI-2900 ASI-L1501B
ASI教程,异步,block,同步,下载,session,验证,登陆
ASI网关手册 很不容易下载的有关ASI的手册,很值得拥有
ASI总线系统内部培训
ASI共振主图 副图 选股通达信指标公式源码.doc
完整的ALTERA的ASI 188或204格式的接收、发送代码。包括应用举例等等。做技术开发的人员值得参考哈,同时对工程涉及到此类的开发,特别是FPGA的应用有很大的帮助。
asi-http-request源码 asi-http-request-master.zip
西门子Asi Safe与G120F 安全功能应用指南
ASI现场级通讯pdf,ASI现场级通讯
mt4平台的asi指标,非常实用,可以预知行情的涨幅,和能都到达的位置
ASIHTTPRequest对CFNetwork API进行了封装,并且使用起来非常简单,用Objective-C编写,可以很好的应用在Mac OS X系统和iOS平台的应用程序中。ASIHTTPRequest适用于基本的HTTP请求,和基于REST的服务之间的交互。 ...
Dahua大华DH-ASI1201A门禁一体主机使用说明书.pdf
基于MbpsAlteraASIIPFPGA核的ASI发送MPEGFIFOTs卡实现。硬件FPGA开发参考。
在使用asi或者NSURLConnection之后 将得到的数据进行json解析得到里面的可用数据