2017-01-01 65 views
2

我在我的項目中使用了swiftyJSON,當我使用php創建的API時,它在項目中工作正常,但是當我在項目中使用C#創建的API時,它會給出null作爲響應。 我在網上搜索,我得到你可以在你的項目中使用它。如何在Swift中使用.net(C#創建的API)。我可以使用它嗎?

這裏是代碼

let url: NSURL = NSURL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx?Mobile_Number=8523697888&Password=123")! // Enter URL Here 

     let request:NSMutableURLRequest = NSMutableURLRequest(url:url as URL) 
     //let bodyData = "employeeVerify & employeeID=\(empID)"// Pass parameter Form Here. 
     // print(bodyData) 
     request.httpMethod = "GET" 
     //request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding); 

     print(request) 
     let task = URLSession.shared.dataTask(with: request as URLRequest) 
     { 

      data, response, error in 

      if error != nil 
      { 

       print("error=\(error)") 
       return 
      } 
      // You can print out response object 
      print("response = \(response)") 


      do { 
       let json = JSON(data: data!) 

       print(json) 

      } 
       } 

     task.resume() 

究竟是什麼解決方案?我可以使用它嗎?

回答

1

回答你的問題,是的,你可以從Swift調用你的C#,ASP.NET web服務。這就是Web服務的美妙之處,只要請求和響應格式正確,客戶端和服務器代碼中使用的相應技術就完全相互獨立。

話雖如此,有幾個問題在這裏:

  1. 如果response(該)爲nil,則error不會nil。看看錯誤是什麼,並採取相應的行動。

    例如,如果您未更新Info.plist接受不安全的請求(即沒有0​​的請求),則會發生錯誤。但是你可以將以下條目添加到您的plist:

    https://www.dropbox.com/s/2q0r8nhx8lxr6dm/Screenshot%202017-01-01%2017.45.37.png?dl=0

  2. 說了這麼多,我懷疑是網絡響應可能沒有失敗(即response的對象,本身不是nil) ,而是JSON解析失敗,但是您沒有捕獲JSON解析錯誤。

    對於名爲SwiftyJSON的庫來說,具有諷刺意味的是,它捕獲錯誤的方式是獨一無二的。要捕獲錯誤,您必須致電JSON()初始化程序,並提供error參數。因此,在SwiftyJSON的當前版本,你會做這樣的事情:

    func performGetRequest(completionHandler: @escaping (JSON?, Error?) -> Void) { 
        let url = URL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx?Mobile_Number=8523697888&Password=123")! 
    
        var request = URLRequest(url: url) 
        request.httpMethod = "GET" 
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") 
        request.setValue("application/json", forHTTPHeaderField: "Accept") 
    
        let task = URLSession.shared.dataTask(with: request) { data, response, error in 
         guard let data = data, error == nil else { 
          completionHandler(nil, error) 
          return 
         } 
    
         var error: NSError? 
         let json = JSON(data: data, options: [], error: &error) 
         completionHandler(json, error) 
        } 
    
        task.resume() 
    } 
    

    ,然後調用它像這樣:

    performGetRequest() { json, error in 
        guard let json = json, error == nil else { 
         print("error = \(error)") 
         return 
        } 
    
        print("\(json)") 
    } 
    

    如果你這樣做,你會看到它報告:

    誤差=可選(錯誤域= NSCocoaErrorDomain代碼= 3840 「垃圾在端。」 的UserInfo = {在端NSDebugDescription =垃圾。})

    看着由Web服務返回的data的內容,問題是顯而易見的:

    [{"success":"1","Id":"5","FirstName":"admin","LastName":"admin","Email":"[email protected]","Password":"123","Mobile_Number":"8523697888"}] 
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    
    <html xmlns="http://www.w3.org/1999/xhtml"> 
    <head><title> 
    
    </title></head> 
    <body> 
        <form method="post" action="./login.aspx" id="form1"> 
    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="dLzeSuX8RwkzsXsmp+fPMkjIu69T9SDFeB24ER3qTQYwmIJB0b8hk32gWHwKrHiE2deVYOcUhwor5igxXXPwUh/uQ+FoE26gCWjolkMFgpg=" /> 
    
    <input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="45AB9188" /> 
        <div> 
    
        </div> 
        </form> 
    </body> 
    </html> 
    

    正如你所看到的,您的Web服務正在恢復不僅JSON,但HTML,太。您需要修復您的Web服務才能返回JSON。


說到所有這一切,有幾個,在很大程度上不相關的意見:

  • 如上我的例子所示,一個公形成的請求通常會指定某些標題,即Content-Type(告訴Web服務如何構建您的請求)和Accept(以期望響應正文的形式告知Web服務)。這些在技術上並不需要,但(a)這是最佳做法;和(b)取決於你如何編寫你的Web服務,它可能需要它。在這種情況下不是這樣,但是在編寫C#ASP.NET Web API時,它通常可以默認發送XML響應,除非客戶端請求明確請求Accept標頭中的JSON。

  • 另請注意,在我上面的示例中,我沒有使用NSURLNSURLRequestNSMutableURLRequest。我直接使用URLURLRequest

  • 請注意,在URL中發送密碼並不是一個好習慣。這並不像人們想象的那樣安全。你想把它放在請求的主體中,而不是URL。因此,你可能想使用POST請求(然後改變你的服務器使用https,而不是http):

    func performPostRequest(completionHandler: @escaping (JSON?, Error?) -> Void) { 
        let url = URL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx")! // Enter URL Here 
    
        var request = URLRequest(url: url) 
        request.httpMethod = "POST" 
        request.httpBody = "Mobile_Number=8523697888&Password=123".data(using: .utf8) 
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") 
        request.setValue("application/json", forHTTPHeaderField: "Accept") 
    
        let task = URLSession.shared.dataTask(with: request) { data, response, error in 
         guard let data = data, error == nil else { 
          completionHandler(nil, error) 
          return 
         } 
    
         var error: NSError? 
         let json = JSON(data: data, options: [], error: &error) 
         completionHandler(json, error) 
        } 
    
        task.resume() 
    } 
    
  • 另外值得一提的是,雖然我沒有做過上面,準備這些時請求,如果它們包含任何保留字符,則實際上應該百分比轉義這些字段值。一個例子見https://stackoverflow.com/a/41092318/1271826

    另外,在您註釋掉的httpBody中,有空格,但在正確的x-www-form-urlencoded請求中,您應該沒有空格。

  • 正如您所看到的,除了服務器代碼問題之外,還有與您的客戶端代碼相關的問題。要做好所有這些並不難,你可能會考慮使用像Alamofire這樣的庫,這樣做會更容易一些。

    +0

    所以基本上我的API給了我錯誤的答案。所以,我必須建議我的API創建者。 @Rob –

    +1

    @DhruvKhatri - 是的,API給你錯誤的答案,但你也寫了代碼,無法檢測/處理錯誤。告訴API創建者,響應不僅發送預期的JSON,而且之後還發送HTML。只要向任何有經驗的Web服務開發人員展示了響應的樣子(上面第2點結尾處的JSON/HTML),他們可能會感到震驚,並立即知道如何解決它。 – Rob

    +0

    非常感謝@ Rob –

    相關問題