2017-03-07 37 views
-1

我在我目前正在使用的項目中遇到大問題。我在做什麼錯Swift 3 http請求和響應

我一直在閱讀關於URLSession的各個地方,但他們都似乎過時了,並指NSURLSession我認爲他們會相當相似,他們可能是但像一個像我這樣的新手我迷路了。我所做的是不工作,我不喜歡我找到的解決方案,因爲他們都在控制器上工作。

http://swiftdeveloperblog.com/image-upload-with-progress-bar-example-in-swift/ 這個例子。我正在使用PHP腳本,但想要創建一個可以隨意調用和使用的網絡層。但是我從哪裏可以瞭解如何使用這個API,我缺乏一個很好的資源。

我發現的每個地方都類似於以上或更舊的鏈接。少數新手似乎也沒有真正解釋如何使用這個API。

同時我是委託模式的新手,事實上我只知道這是在這個Api中大量使用的東西,但我沒有IDEA的方式或原因。 基本上我需要幫助找到我的方式來解決這個問題就在這裏:

我一直試圖做這樣的事情:

public class NetworkPostRequestor:NSObject,NetworkPostRequestingProtocol,URLSessionTaskDelegate,URLSessionDataDelegate 
{ 
    public var _response:HTTPURLResponse 
    public override init() 
    { 
     _response = HTTPURLResponse() 
    } 
    public func post(data: Data, url: URL) 
    { 
     var request = URLRequest(url: url) 
     request.httpMethod = "POST" 
     request.setValue("Keep-Alive", forHTTPHeaderField: "Connection") 
     let configuration = URLSessionConfiguration.default 
     let session = URLSession(configuration: configuration,delegate: self, delegateQueue: OperationQueue.main) 
     let task = session.uploadTask(with: request, from: data) 
     task.resume() 

    } 
    public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) 
    { 
     _response = response as! HTTPURLResponse 
    } 
} 

但是我從來沒有打到PHPserver。服務器打到時會在終端上這樣說:

[Tue Mar 7 11:43:20 2017] 192.168.250.100:64265 [200]:/
    [Tue Mar 7 11:43:20 2017] 192.168.250.100:64266 [404]: /favicon.ico - No such file or directory 

那麼就是當我用瀏覽器打開它並且沒有圖像時。但至少我知道它會寫入終端的東西,如果它擊中它。什麼都沒有發生如果沒有資源教我這個API,恐怕我永遠不會學會如何解決這個問題,或者即使我正在做一些完全錯誤的事情。

我用斯威夫特3的Xcode 8.2.1

編輯:

我已經添加了此方法的類,我發現我打它每一次。

public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) 
{ 
    _error = error.debugDescription 
} 

調試說明有這個字符串「一些」

+0

想知道爲什麼有人給我一個減號?有什麼方法可以改變我的帖子,以糾正我得到負面投票的原因嗎? – Helbo

+0

我的帖子絕對沒有錯。這個問題是有效的,你已經添加了對你所嘗試過的內容的解釋並描述了你的結果。片段被添加,問題被很好地格式化... –

+0

@AshleyMills試圖刪除您指出的部分。感謝您告知我我的錯誤 – Helbo

回答

1

我從來沒有使用過這個確切的程序與任務,而是使用的方法與回調。我不知道在背景中是否應該有很大的區別。

因此,生成會話(似乎很接近你):

let configuration = URLSessionConfiguration.default 
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main) 

然後我產生哪些愚蠢足夠需要在構造函數中的URL請求:

var request = URLRequest(url: URL(string: "www.nil.com")!) // can't initialize without url 
request.url = nil 

添加網址查詢參數(你可以在你的案例中設置URL,我有一個工具來處理幾個案例):

fileprivate func injectQueryParameters(request: inout URLRequest) { 
     if let query = queryParameters.urlEncodedString { 
      let toReturn = endpoint.url + "?" + query 
      if let url = URL(string: toReturn) { 
       request.url = url 
      } else { 
       print("Cannot prepare url: \(toReturn)") 
      } 
     } else { 
      let toReturn = endpoint.url 
      if let url = URL(string: toReturn) { 
       request.url = url 
      } else { 
       print("Cannot prepare url: \(toReturn)") 
      } 
     } 
    } 

然後是表單參數。我們主要是使用JSON但任何事情都會發生在這裏:

fileprivate func injectFormParameters(request: inout URLRequest) { 
     if let data = rawFormData { 
      request.httpBody = data 
     } else if let data = formParameters.urlEncodedString?.data(using: .utf8) { 
      request.httpBody = data 
     } 
    } 

和頭:

fileprivate func injectHeaders(request: inout URLRequest) { 
     headers._parameters.forEach { (key, value) in 
      if let stringValue = value as? String { 
       request.setValue(stringValue, forHTTPHeaderField: key) 
      } 
     } 
    } 

所以最後整個調用看起來是這樣的:

class func performRequest(request: URLRequest, callback: (([String: Any]?, NSError?) -> Void)?) { 
     let configuration = URLSessionConfiguration.default 
     let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main) 

     let task = session.dataTask(with: request) { data, response, error in 
      // Response is sent here 
      if let data = data { 
       callback?((try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as [String: Any]?, error) 
      } else { 
       callback?(nil, error) 
      } 
     } 
     task.resume() 
    } 

我希望這讓你在正確的軌道上。一般情況下,您確實有一些您可能感興趣的開源庫.Alamofire可能仍然在大多數情況下使用。

+0

我能否監控上傳進度?我需要能夠在上傳過程中提取進度條。 但目前只是發送數據是一個問題XD – Helbo

+0

那麼URLSessionTaskDelegate應該能夠接收這些。嘗試使用那個作爲代表自我。但是,您可能先從成功上傳開始,然後擴展功能以獲得進度。另外請注意,如果你連接到一個不安全的服務器(http),你將需要在plist中包含一個域以允許任意加載。 –

+0

所以如果我不使用委託發送,我仍然可以在不同的地方接收個別文件的進度更新。 ?只需調用URLSessionTaskDelegate? 是啊我已經這樣做:)我選擇http over https的原因是,這個應用程序無論如何都會在受保護的泡泡中運行。 – Helbo