2017-03-07 35 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