在此代码中,request.getStatusCode()
和request.getIsConnected()
都在执行task
块内的代码之前执行
即。 dataTask.resume()在执行任何后续代码之后才会执行,无论是相同函数,类还是单独类中的代码。
我已经尝试将函数调用放入主队列(串行),全局队列(并发),手动串行队列,手动并发队列和NSOperationQueue,所有后跟aa while循环等待关闭完成。
while isDoingSomething {
NSThread.sleepForTimeInterval(0.0)
}
环。
我已经从这段代码中删除了任何GCD或操作,以避免我尝试过的每个队列场景的混乱。
ViewController.swift
import Cocoa
class ViewController: NSViewController {
.
.
.
func login(username username: String, password: String) {
let url = "https://www.awebsite.com/login"
let URL = NSURL(string: url)
let method = "POST"
let params = "username=\(username)&password=\(password)"
vis = URLVisitor(URL: URL!, params: params, method: method, jsonParams: [:])
vis.execute()
cookies = vis.getCookies()
let contentsOfURL = vis.getContentsOfURL()
}
.
.
.
}
URLVisitor.swift
import Cocoa
let queue = NSOperationQueue
class URLVisitor: NSOperation {
.
.
.
func execute() {
let request = Request(URL: URL!, params: params, method: method, jsonParams: jsonParams)
if !self.cookies.isEmpty {
request._setCookies(self.cookies)
}
request._setAuthorizationHeader(self.authorizationHeader)
request.sendRequest()
self.statusCode = request.getStatusCode()
self.isConnected = request.getIsConnected()
}
.
.
.
}
Request.swift
import Cocoa
class Request: NSOperation {
.
.
.
func sendRequest() {
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: URL)
request.HTTPMethod = method
// send jsonParams or params
if jsonParams.count != 0 {
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(jsonParams, options: .PrettyPrinted)
request.setValue("aplication/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = jsonData
} catch {
}
} else {
request.HTTPBody = self.params.dataUsingEncoding(NSUTF8StringEncoding)
}
let task = session.dataTaskWithRequest(request) {
(data, response, error) in
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookies(self.cookies, forURL: self.URL, mainDocumentURL: nil)
if data != nil {
self.data = data!
do {
let responseHeaders = response as! NSHTTPURLResponse
self.statusCode = responseHeaders.statusCode
switch self.statusCode {
case 200:
print("200: OK. getting contentsOfURL and cookies")
self.contentsOfURL = try NSString(contentsOfURL: self.URL, encoding: NSUTF8StringEncoding)
self.cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookiesForURL(self.URL)!
case 400:
print("400: page not found on web")
case 404:
print("404: page not found on server")
case 407:
print("407: failed authenticate proxy credentials")
default:
print("unable to get statusCode")
}
} catch {
}
} else {
print("\(self.statusCode): unable to get response ")
}
NSThread.sleepForTimeInterval(1.0)
}
task.resume()
}
答案 0 :(得分:1)
执行此操作的正确方法是添加完成处理程序
func sendRequest(completion: () -> Void) {
// ...
let task = session.dataTaskWithRequest(request) {
// ...
completion()
}
task.resume()
}
用法:
let r = Request()
r.sendRequest {
// It's done, do something
}
如果你坚持阻止线程(我希望它不是主线程),请使用信号量。但请记住发信号通知请求是成功还是失败。我看到太多的代码忘记在请求失败时发出信号,因此应用程序只是挂断了。
func sendRequest() {
let semaphore = dispatch_semaphore_create(0)
let task = session.dataTaskWithRequest(request) {
// ...
dispatch_semaphore_signal(semaphore)
}
task.resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}