我已经完成了很多关于webservice的阅读和研究,并从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和webservice中完成了VB(.asmx文件))
我是那种通过教程而不是阅读文章等而更多,更快地学习的人。是否有任何教程可以使用.asmx(使用VS构建的webservice)而不是php。就个人而言,我更喜欢解析JSON的REST协议,因为很多人说它更容易使用,并且Apple已经有了一个lib /框架。
如果有人能指出我正确的方向会很好,因为我觉得学习如何让iOS应用程序使用网络服务对于未来的应用程序开发非常重要。
编辑:通过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(基本CRUD)的E.G
[的WebMethod]
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
编辑:真的很感激任何帮助......我是初学者,希望有经验的人能指导我。
答案 0 :(得分:2)
我是否还必须在每个网络方法中声明这样的内容?
您上面发布的代码是从POST中提取数据。 asmx文件应该已经为您执行此操作。您在POST中传递的参数将转换为传递给MethodName的参数(请参阅:Accessing XML Web Services)。
<强>更新强>
因此,如果我理解正确,那么您的Web服务端点为http://xxx.yyy/zzz.asmx/insertUser
。然后,您将使用变量username,password和gender发送一个帖子正文:
[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这样的东西。
答案 1 :(得分:1)
我建议使用AFNetworking库(https://github.com/AFNetworking/AFNetworking)并使用内置的AFJSONRequestOperation:https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFJSONRequestOperation.h
它不是实现'request finished'回调,而是在请求完成时调用成功块,并将JSON对象作为参数传递。您可以将该对象解析为成功块中的任何内容。
中有一个如何使用它的示例