zoukankan      html  css  js  c++  java
  • IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践

    到ios的应用开发,我们不能不提到web server服务端,如果没有服务端的支持,ios应用开发就没有多大意义了,因为从事过手机开发的朋友都知道(Android也一样),大量复杂业务的处理和数据库的处理,其实大部分都是在服务端来完成的,因为iphone客户端的资源是非常有限的,象内存,多线程处理等。我们更多的是把Iphone/ipad等作为一个终端和载体,虽然Iphone客户端也会有自己的数据库,象SQLITE3等,但是也只是非常少量的客户端的数据库存储操作而也。所以我们与其说iphone应用的强大,不与说是iphone坚强后盾服务端功能的强大。但是,要想让服务端来处理客户端的一些业务请求,这里首先需要解决客户端和服务端之间交互的问题。下面,阿堂就重点讲解开源库 ASIHTTPREQUEST 的用法了,这是目前IOS 开发中比较主流的一种通讯方式(实现iphone客户端和web server的通讯),实际就是对IOS自带的通讯交互方式作了一些更好的封装。

    下面,网络时空(阿堂)就以下图示中的demo来说明整个流程

    IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践

    IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践



    当我们点登录时,就会由IPHONE 发通讯请求到web server端,WEB SERVER 端收到请求后,会对请求进行分析处理后,封装相应的业务数据反馈给IPHONE 客户端,客户端得到反馈的信息后,若正常就会跳到如下正常的业务界面,进行后续的操作了;若不正常,则会弹出相应的信息窗口显示显示给当前操作者。(不正常的弹出信息窗口,我这里不截图说明了)

    iphone客户端和服务端交互一般来说,有三种方式可以实现。

    一. 方式1. 是ios自带的api中的通讯方式

    定义一个请求:

    NSMutableURLRequest* urlRequest = [[NSMutableURLRequestalloc]initWithURL:url

    cachePolicy:NSURLRequestReloadIgnoringCacheData

    timeoutInterval:NETWORK_TIMEOUT];

    url参数就是一个http地址

    NSMutableURLRequest有诸如setHTTPMethod、setValue、setHTTPBody之类的方法

     

    发送一个请求:

    NSURLConnection* connection = [[NSURLConnection alloc]initWithRequest:urlRequest

    delegate:self];

    [connection start];

     

    connection的delegate负责服务器端返回数据的接收,这个delegate(NSURLConnectionDataDelegate)实现如下一些方法:

    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

    -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data;

    -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError*)error;

    以上方法的使用,比较简单,阿堂就不再特别说明了,看看下面的ASIHTTPREQUEST 的实现方式就很好理解了,也可以从XCODE 的帮助文档中去查看

    二. 方式2 和方式3(采用 ASIHTTPREQUEST 的方式

    要想使用 asihttprequest的开源库,前提是要导入如下的开源库文件和对应的 lib文件,如下

    IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践

    图,其中红线标明的是必须要导入的lib,否则使用asihttprequest时会报错的

    IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践

    方式2:采用 get方式

    /* Get 提交方式
    NSString *urlString = [NSString stringWithFormat:@"http://www.isn.com/zzgame/ProcesLogin?param=%@&userName=%@&passWord=%@",@"login",userName,passWord];
    // 向应用服务器发出请求验正 用户名,密码,是否正确
    NSURL *url = [NSURL URLWithString:urlString];
    m_Request = [ASIHTTPRequest requestWithURL:url];
    // 设置请求超时时,设置重试的次数
    [m_Request setTimeOutSeconds:60];
    [m_Request setNumberOfTimesToRetryOnTimeout:3];
    [m_Request addRequestHeader:@"User-Agent" value:@"[AH:6753048720{-}0{-}1{-}1{-}iphone3G{-}iphone{-}320x480]"];
    [m_Request setDelegate:self];
    [m_Request startAsynchronous]; //异步方式

    方式3:采用post方式(这是阿堂推荐的一种最好方式)

    以下重要信息,根据实际情况,要进行加密后处理,为了不增加说明的复杂性,阿堂下面就没有相应处理了,这不是今天讨论的重点,请网友在使用时自行处理了。(可采用base64等方式去加密和解密)

    // Post提交方式
    NSURL *url = [NSURL URLWithString:@"http://www.isn.com/zzgame/ProcesLogin"];
    m_Request = [[ASIFormDataRequest alloc] initWithURL:url];
    NSMutableDictionary *postData = [[NSMutableDictionary alloc] initWithCapacity:2];
    NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithCapacity:5];
    [data setObject:@"login" forKey:@"param"];
    [data setObject:userName1 forKey:@"userName"];
    [data setObject:passWord1 forKey:@"passWord"];
    [postData setValue:data forKey:@"data"];
    NSString *jsonString = [postData JSONRepresentation];
    [m_Request setDelegate:self];
    [m_Request setPostValue:jsonString forKey:@"p_data"];
    [m_Request setTimeOutSeconds:120];
    [m_Request startAsynchronous]; //异步执行
    交互时步骤如下
    1.请先定义如下两个变量
    NSMutableData *recData;
    ASIFormDataRequest *m_Request;
    2.实现如下协议
    @interface LoginViewController : UIViewController
    <ASIHTTPRequestDelegate>
    3.实现如下四个代理方法
    - (void)requestStarted:(ASIHTTPRequest *)request{
    self.recData.length = 0;
    }
    - (void)requestFinished:(ASIHTTPRequest *)request{
    NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF8);
    NSString *aString = [[NSString alloc]initWithData:self.recData encoding:enc];
    if ([aString isEqualToString:@"YES"]) {
    //这里写上自己实际的代码
    }else{
    //弹出错误信息的弹出窗口
    }
    }
    - (void)requestFailed:(ASIHTTPRequest *)request{
    NSError *error =[request error];
    NSDictionary * userInfoDirectionary = error.userInfo;
    NSString *content = [userInfoDirectionary objectForKey:@"NSLocalizedDescription"];
    if ([content isEqualToString:@"The request timed out"]) {
    //写上自己的实际代码
    }else if([content isEqualToString:@"Unable to create request (bad url?)"]){
    //写上自己的实际代码
    }
    else{
    //写上自己的实际代码
    }
    }
    - (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data{
    [self.recData appendData:data];
    }
     
    文中,阿堂给出Iphone客户端的详细讲解,想必网友们应该对Iphone如何与web server服务端交互有了全面的了解。下面阿堂就准备开始继续揭开web server服务端的神秘面纱了,相信网友看完这篇文章后,应该对iphone客户端与服务端交互就会有一个比较全面的,完整的了解了,如果稍加改装的话,就可以马上应用到ios的开发项目中去了,这样阿堂就会觉得很欣慰了,因为帮助了别人,也就快乐了自己!
    实际上,上篇文章中的调用方式后,我们会在服务端收到的数据是 {"data":{"userName":"test","passWord":"123456","param":"login"}}也就是说通过 String p_data = request.getParameter("p_data"); 方式后,最终得到的p_data 的值为 {"data":{"userName":"test","passWord":"123456","param":"login"}},哈哈,知道是这样的内容后,阿堂在下面作了一些处理后,就完成了正常的web server 服务端的正常交互了!
    -------------------------------------------------------------------------
    String param = "";
    String userName ="";
    String passWord ="";

    PrintWriter out = response.getWriter();
    String p_data = request.getParameter("p_data");
    //服务端获得iphone端传来的最终json数据 {"data":{"userName":"test","passWord":"123456","param":"login"}}
    JSONObject firstJSON = JSONObject.fromObject(p_data);
    JSONObject secondJSON= JSONObject.fromObject(firstJSON.get("data"));
    Iterator iter = secondJSON.keySet().iterator();
    while(iter.hasNext()) {
    String key = iter.next().toString();
    if(key.equals("userName")){
    userName = secondJSON.getString("userName");
    }else if(key.equals("passWord")){
    passWord = secondJSON.getString("passWord");
    }else if(key.equals("param")){
    param = secondJSON.getString("param");
    }else{
    }
    }

    //获取web容器
    ServletContext servletContext = this.getServletContext();
    ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
    //获取springIOC容器中的业务组件
    iphoneAndIPadService = (IPhoneAndIPadService) ctx.getBean("iphoneAndIPadService");


    String result = iphoneAndIPadService.judgeLoginIsVlidateOrNot(param , userName, passWord);
    if(result.equals("YES")){
    out.print("YES");
    }else{
    out.print("NO");
    }
    out.flush();

    -------------------------------------------------------------------------

    补充说明

    以上红色部分,请网友根据自己web server服务端的实际情况,将网络时空(阿堂)上面的代码换成相应的替代代码。

  • 相关阅读:
    八数码难题 (codevs 1225)题解
    小木棍 (codevs 3498)题解
    sliding windows (poj 2823) 题解
    集合删数 (vijos 1545) 题解
    合并果子 (codevs 1063) 题解
    等价表达式 (codevs 1107)题解
    生理周期 (poj 1006) 题解
    区间 (vijos 1439) 题解
    区间覆盖问题 题解
    种树 (codevs 1653) 题解
  • 原文地址:https://www.cnblogs.com/lhj588/p/3143410.html
Copyright © 2011-2022 走看看