4

我已经对 Web 服务进行了大量阅读和研究,并从 iOS 应用程序端使用它们。但是许多网站非常简短,并没有深入了解如何使用和解析数据。目前我正在阅读 raywenderlich 的教程http://www.raywenderlich.com/2965/how-to-write-an-ios-app-that-uses-a-web-service并阅读了一个 SO 线程 http://stackoverflow.com/questions/7364326/recommendations-for-net-web-service-format-protocol-for-android-iphone-etc-i,但我仍然不清楚我应该如何处理它。

据我所知,目前使用 Web 服务的几种方法是 REST 和 SOAP 协议。(我在 xcode 中的应用程序和在 VB 中完成的 web 服务(.asmx 文件))

我是那种通过教程而不是阅读文章等来学习更多和更快的人。有没有关于使用 .asmx(使用 VS 构建的 web 服务)而不是 php 的教程。就我个人而言,我更喜欢解析 JSON 的 REST 协议,因为很多人说它更容易使用,而且 Apple 已经为它提供了一个 lib/framework。

如果有人能指出我正确的方向,那就太好了,因为我觉得学习如何让 iOS 应用程序使用 Web 服务在未来的应用程序开发中非常重要。

编辑:通过 php webservice 阅读后,有一些我没有的东西。

功能兑换自http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app

// Put parameters into local variables
        $rw_app_id = $_POST["rw_app_id"];
        $code = $_POST["code"];
        $device_id = $_POST["device_id"]

如果我使用 asmx 文件,我是否还必须在我的每个 web 方法中声明这样的内容?

我的一种 webMethod 的 EG(基本 CRUD)

[网络方法]

        public string insertUser(string User, string Password, string Gender)
        {

               try
                {

                    string connectionString = ConfigurationManager.ConnectionStrings["mysql"].ToString();
                    MySqlCommand dCmd = new MySqlCommand();
                    using (MySqlConnection mysqlCon = new MySqlConnection(connectionString))
                    {

                        if (do_check_record(User) == false)
                            {

                                mysqlCon.Open();
                                dCmd.CommandText = "INSERT into tbl_login (username,password,gender) values (?username,?password,?gender)";
                                dCmd.CommandType = CommandType.Text;
                                dCmd.Parameters.Add(new MySqlParameter("?username", User));
                                dCmd.Parameters.Add(new MySqlParameter("?password", Password));
                                dCmd.Parameters.Add(new MySqlParameter("?gender", Gender));
                                dCmd.Connection = mysqlCon;
                                dCmd.ExecuteNonQuery();
                                mysqlCon.Close();

                            }
                            else

                            {
                                return string.Format( "User exists in data_base");
                            }

                    }

                    return string.Format("data_base insert");

                }
                catch (Exception ex)
                {
                    return string.Format(ex.Message);
                }

}

从应用程序端消费网络服务

本教程中给出的示例是

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSLog(@"Want to redeem: %@", textField.text);

    // Get device unique ID
    UIDevice *device = [UIDevice currentDevice];
    NSString *uniqueIdentifier = [device uniqueIdentifier];

    // Start request
    NSString *code = textField.text;
    NSURL *url = [NSURL URLWithString:@"http://www.wildfables.com/promos/"];
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
    [request setPostValue:@"1" forKey:@"rw_app_id"];
    [request setPostValue:code forKey:@"code"];
    [request setPostValue:uniqueIdentifier forKey:@"device_id"];
    [request setDelegate:self];
    [request startAsynchronous];

    // Hide keyword
    [textField resignFirstResponder];

    // Clear text field
    textView.text = @"";    

    return TRUE;
}

但它不应该是一个IBAction调用按钮而不是一个BOOL

- (void)requestFinished:(ASIHTTPRequest *)request
{    

    if (request.responseStatusCode == 400) {
        textView.text = @"Invalid code";        
    } else if (request.responseStatusCode == 403) {
        textView.text = @"Code already used";
    } else if (request.responseStatusCode == 200) {
        NSString *responseString = [request responseString];
        NSDictionary *responseDict = [responseString JSONValue];
        NSString *unlockCode = [responseDict objectForKey:@"unlock_code"];

        if ([unlockCode compare:@"com.razeware.test.unlock.cake"] == NSOrderedSame) {
            textView.text = @"The cake is a lie!";
        } else {        
            textView.text = [NSString stringWithFormat:@"Received unexpected unlock code: %@", unlockCode];
        }

    } else {
        textView.text = @"Unexpected error";
    }

}

- (void)requestFailed:(ASIHTTPRequest *)request
{    
    NSError *error = [request error];
    textView.text = error.localizedDescription;
}

如果我错了,请纠正我,但本- (void)requestFinished:(ASIHTTPRequest *)request教程中使用的这种方法是解析 JSON 的方法,对吧?如果是这样,对于我调用的每个网络方法,我都必须提出一个新的请求和一个新的- (void)requestFinished:(ASIHTTPRequest *)request

编辑:任何帮助将不胜感激......我是这方面的初学者,希望有经验的人可以指导我完成。

4

2 回答 2

2

我是否还必须在我的每个网络方法中声明这样的内容?

您在上面发布的代码是从 POST 中提取数据。asmx 文件应该已经为您完成了这项工作。您在 POST 中传递的参数将转换为传递给 MethodName 的参数(请参阅:访问 XML Web 服务)。


更新

因此,如果我理解正确,您的 Web 服务端点是http://xxx.yyy/zzz.asmx/insertUser. 然后,您将使用变量用户名、密码和性别发送帖子正文:

[request setPostValue:username forKey:@"User"];
[request setPostValue:password forKey:@"Password"];
[request setPostValue:gender forKey:@"Gender"];

但它不应该是一个 IBAction 按钮来调用而不是一个 BOOL 吗?

No.-textFieldShouldReturn:UITextField的委托方法。它不是 IBAction。

当用户触摸文本字段时,键盘将变为活动状态。当按下键盘上的返回按钮时,将向文本字段的委托发送-textFieldShouldReturn:消息。

结果是当在键盘上按下 return 或 done 时调用此方法。


为我错过的部分添加了更多信息

如果我错了,请纠正我,但本-requestFinished:教程中使用的这种方法是解析 JSON 的方法,对吧?如果是这样,对于我调用的每个网络方法,我都必须提出一个新的请求和一个新的-requestFinished:

-requestFinished:不,每个班级只有一个。您可以将您的客户端分成几个类:每个 Web 服务 URL 一个,或者您需要区分一个-requestFinished:.

- (void)requestFinished:(ASIHTTPRequest *)request
{
    if ([request.originalURL.absoluteString isEqualToString:@"http://xxx.yyy/zzz.asmx/methodName"]) {
        // handle methodName endpoint.
    }
}

如果您不喜欢委托的工作方式,您也可以使用-setCompletionBlock:and-setFailedBlock:代替。-setDelegate:更好的是,选择像 @Stew 建议的 AFNetworking 之类的东西。

于 2012-07-16T03:28:20.800 回答
1

我建议使用 AFNetworking 库(https://github.com/AFNetworking/AFNetworking)并使用内置的 AFJSONRequestOperation:https ://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFJSONRequestOperation.h

它没有实现“请求完成”回调,而是在请求完成时调用成功块,并将 JSON 对象作为参数传入。您可以将该对象解析为成功块中所需的任何内容。

在此答案中有一个如何使用它的示例https://stackoverflow.com/a/8920596/223558

于 2012-07-16T03:28:11.340 回答