ios 应用程序使用 web 服务
Posted
技术标签:
【中文标题】ios 应用程序使用 web 服务【英文标题】:ios app consuming webservice 【发布时间】:2012-06-21 09:59:58 【问题描述】:我对 Web 服务进行了大量阅读和研究,并从 ios 应用程序端使用它们。但是许多网站非常简短,并没有深入了解如何使用和解析数据。目前我正在阅读 raywenderlich http://www.raywenderlich.com/2965/how-to-write-an-ios-app-that-uses-a-web-service
的教程并阅读了一个 SO 线程 http://***.com/questions/7364326/recommendations-for-net-web-service-format-protocol-for-android-iphone-etc-i
但我仍然不清楚我应该如何处理它。
据我目前所知,使用 Web 服务的几种方法是 REST 和 SOAP 协议。 (我在 xcode 中的应用程序和在 VB 中完成的 webservice (.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 的 E.G(基本 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
编辑:任何帮助将不胜感激...我是这方面的初学者,希望有经验的人可以指导我。
【问题讨论】:
【参考方案1】:我是否也必须在我的每个 web 方法中声明类似的内容?
您在上面发布的代码是从 POST 中提取数据。 asmx 文件应该已经为您完成了这项工作。在 POST 中传递给你的参数将变成传递给 MethodName 的参数(参见:Accessing XML Web Services)。
更新
因此,如果我理解正确,您的 Web 服务端点是 http://xxx.yyy/zzz.asmx/insertUser
。然后,您将使用变量用户名、密码和性别发送帖子正文:
[request setPostValue:username forKey:@"User"];
[request setPostValue:password forKey:@"Password"];
[request setPostValue:gender forKey:@"Gender"];
但它不应该是一个 IBAction 按钮来调用而不是一个 BOOL 吗?
没有。 -textFieldShouldReturn:
是 delegate 的 UITextField 方法。这不是 IBAction。
当用户触摸文本字段时,键盘将变为活动状态。当按下键盘上的返回按钮时,文本字段的委托会发送-textFieldShouldReturn:
消息。
结果是当在键盘上按下 return 或 done 时调用此方法。
为我错过的部分添加了更多信息
如果我错了,请纠正我,但是教程中使用的这种方法
-requestFinished:
是解析 JSON 的方法,对吧?如果是这样,对于我调用的每个网络方法,我都必须发出一个新请求和一个新的-requestFinished:
不,每个班级只有一个-requestFinished:
。您可以将您的客户端分为几个类:每个 Web 服务 URL 一个,或者您需要区分一个 -requestFinished:
中的不同 URL。
- (void)requestFinished:(ASIHTTPRequest *)request
if ([request.originalURL.absoluteString isEqualToString:@"http://xxx.yyy/zzz.asmx/methodName"])
// handle methodName endpoint.
如果您不喜欢委托的工作方式,也可以使用-setCompletionBlock:
和-setFailedBlock:
代替-setDelegate:
。更好的是,选择像 @Stew 建议的 AFNetworking 之类的东西。
【讨论】:
编辑了问题。代码是从他的 webMethodredeemFunction 中提取的,他第一次构建它的地方。我以前从未尝试过 PHP,所以他们的结构方式和语法对我来说是陌生的。我还在上面放了一个我的 webMethod 示例。 @YangJieDomodomo 我添加了更多关于您的 inserUser 端点的信息。 对不起,我的意思是网络服务方面的混乱。[request setPostValue:username forKey:@"User"];
将在应用程序端完成,不是吗? php 部分`$rw_app_id = $_POST["rw_app_id"];` 是否等同于我的dCmd.Parameters.Add(new MySqlParameter("?username", User));
?
@YangJieDomodomo No.(string User, string Password, string Gender)
在public string insertUser(string User, string Password, string Gender)
的末尾相当于php部分。 asmx 方法会自动从请求中提取 POST 值,您不必手动进行。
@YangJieDomodomo 作为补充说明:dCmd.Parameters.Add(new MySqlParameter("?username", User))
是数据库命令。这是与后端数据库通信的 Web 服务。【参考方案2】:
我建议使用 AFNetworking 库 (https://github.com/AFNetworking/AFNetworking) 并使用内置的 AFJSONRequestOperation:https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFJSONRequestOperation.h
它没有实现“请求完成”回调,而是在请求完成时调用成功块,并将 JSON 对象作为参数传入。您可以将该对象解析为成功块中所需的任何内容。
在这个答案https://***.com/a/8920596/223558中有一个如何使用它的例子
【讨论】:
以上是关于ios 应用程序使用 web 服务的主要内容,如果未能解决你的问题,请参考以下文章
iOS 应用程序的 WCF 或 Web 服务 (.asmx)?
如何使用IOS中的参数调用应用程序中的Web服务? [关闭]