2012-06-21 55 views
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,但我仍不清楚應該如何處理它。ios app消費webservice

從我所知道的到目前爲止,使用webservice的幾種方法是REST和SOAP協議。 (我有我的應用程序在xcode和web服務在VB(.asmx文件)完成)

我是那種通過教程而不是閱讀文章等手段更多,更快地學習的人。是否有任何教程可以使用.asmx(使用VS構建webservice)而不是php。就個人而言,我更喜歡REST協議,它解析JSON,因爲許多人認爲它更易於使用,並且Apple已經有了它的lib /框架。

如果任何人都可以指出我的方向是正確的,我覺得學習如何讓iOS應用程序使用Web服務對於將來的應用程序開發非常重要。

編輯:在通過php webservice閱讀後,有一些我沒有在我的東西。如果我使用ASMX文件,我也要申報這樣的事情在我的每一個Web方法的

功能從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"] 

贖回?

EG我WEBMETHOD之一的(基本CRUD)

[的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); 
       } 

} 

在消耗web服務從應用側

在教程中給出的例子是

- (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解析的一個,對不對?如果是這樣,我打電話給每個webmethod,我必須提出一個新的請求和一個新的- (void)requestFinished:(ASIHTTPRequest *)request

編輯:任何幫助真的會被讚賞...我是一個初學者,並希望有經驗的人可以指導我通過。

回答

2

我也要申報這樣的事情在我的每一個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:UITextField一個delegate方法。這不是一個IBAction。

當用戶觸摸文本字段時,鍵盤變爲活動狀態。當鍵盤上的返回鍵被按下時,文本字段的代表被髮送-textFieldShouldReturn:消息。

結果是當在鍵盤上按下返回或完成時調用此方法。


增加了一部分,我錯過了

糾正我,如果我錯了更多的信息,但在本教程中使用這種方法-requestFinished:是JSON解析的一個,對不對?如果是這樣,對於每一個我稱之爲的WebMethod,我必須做出一個新的要求和新的-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。

+0

編輯該問題。該代碼是從他的webMethod redeemFunction中提取的,他在那裏首次構建它。我從來沒有嘗試過PHP,所以他們構造它的方式和它們的語法對我來說都是陌生的。我還把webMethod的樣本放在那裏。 –

+0

@YangJieDomodomo我增加了一些關於inserUser端點的信息。 –

+0

抱歉,我的意思是在網絡服務方面存在混淆。 '[請求setPostValue:用戶名forKey:@「User」];'將在應用程序端完成是不是? php部分'$ rw_app_id = $ _POST [「rw_app_id」];' 是否等價於我的'dCmd.Parameters.Add(new MySqlParameter(「?username」,User));'? –

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