Spa*_*Dog 17 iphone ios ios9 swift2
我从这里有这个代码在Swift 2上做一个URL的同步请求.
func send(url: String, f: (String)-> ()) {
var request = NSURLRequest(URL: NSURL(string: url)!)
var response: NSURLResponse?
var error: NSErrorPointer = nil
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: error)
var reply = NSString(data: data, encoding: NSUTF8StringEncoding)
f(reply)
}
Run Code Online (Sandbox Code Playgroud)
但该函数NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: error)
已被弃用,我不知道如何在Swift上执行同步请求,因为替代方法是异步的.Apple显然不赞成同步执行此功能的唯一功能.
我怎样才能做到这一点?
fpg*_*503 39
如果你真的想同步这样做,你总是可以使用信号量:
func send(url: String, f: (String) -> Void) {
var request = NSURLRequest(URL: NSURL(string: url)!)
var error: NSErrorPointer = nil
var data: NSData
var semaphore = dispatch_semaphore_create(0)
try! NSURLSession.sharedSession().dataTaskWithRequest(request) { (responseData, _, _) -> Void in
data = responseData! //treat optionals properly
dispatch_semaphore_signal(semaphore)
}.resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
var reply = NSString(data: data, encoding: NSUTF8StringEncoding)
f(reply)
}
Run Code Online (Sandbox Code Playgroud)
编辑:添加一些hackish!所以代码工作,不要在生产代码中这样做
func send(url: String, f: (String) -> Void) {
guard let url = URL(string: url) else {
print("Error! Invalid URL!") //Do something else
return
}
let request = URLRequest(url: url)
let semaphore = DispatchSemaphore(value: 0)
var data: Data? = nil
URLSession.shared.dataTask(with: request) { (responseData, _, _) -> Void in
data = responseData
semaphore.signal()
}.resume()
semaphore.wait(timeout: .distantFuture)
let reply = data.flatMap { String(data: $0, encoding: .utf8) } ?? ""
f(reply)
}
Run Code Online (Sandbox Code Playgroud)
Jir*_*cak 10
弃用背后有一个原因 - 它没有用处.您应该避免同步网络请求作为瘟疫.它有两个主要问题,只有一个优点(易于使用..但同样不是异步?):
而不是这个,只需使用异步请求:
NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
// Handle incoming data like you would in synchronous request
var reply = NSString(data: data, encoding: NSUTF8StringEncoding)
f(reply)
})
Run Code Online (Sandbox Code Playgroud)
iOS9弃用
由于在iOS9中这个方法已被弃用,我建议你改用NSURLSession:
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request) { (data, response, error) -> Void in
// Handle incoming data like you would in synchronous request
var reply = NSString(data: data, encoding: NSUTF8StringEncoding)
f(reply)
}
Run Code Online (Sandbox Code Playgroud)
同步请求有时在后台线程上很好.有时你有一个复杂的,不可能改变的代码库充满了异步请求等.然后有一个小的请求,不能作为异步折叠到当前系统.如果同步失败,那么您将得不到任何数据.简单.它模仿文件系统的工作方式.
当然它并没有涵盖各种各样的可能性,但是同样存在许多不可能的事件.
根据@ fpg1503的答案,我在Swift 3中做了一个简单的扩展:
extension URLSession {
func synchronousDataTask(with request: URLRequest) throws -> (data: Data?, response: HTTPURLResponse?) {
let semaphore = DispatchSemaphore(value: 0)
var responseData: Data?
var theResponse: URLResponse?
var theError: Error?
dataTask(with: request) { (data, response, error) -> Void in
responseData = data
theResponse = response
theError = error
semaphore.signal()
}.resume()
_ = semaphore.wait(timeout: .distantFuture)
if let error = theError {
throw error
}
return (data: responseData, response: theResponse as! HTTPURLResponse?)
}
}
Run Code Online (Sandbox Code Playgroud)
然后你只需致电:
let (data, response) = try URLSession.shared.synchronousDataTask(with: request)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
25324 次 |
最近记录: |