不推荐使用iOS9的sendSynchronousRequest

警告:在iOS 9.0中不推荐使用“sendSynchronousRequest(_:returningResponse :)”:使用[NSURLSession dataTaskWithRequest:completionHandler:](请参阅NSURLSession)

urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response) 

任何想法如何摆脱这个警告? 我刚刚从Swift 1.2升级到Swift 2

更新:Fonix被标记为我最好的答案。 如果你试图添加一个try语句,我修改他的答案如下:

 urlData = try NSURLSession.dataTaskWithRequest(<#request: NSURLRequest#>, completionHandler: <#((NSData!, NSURLResponse!, NSError!) -> Void)?##(NSData!, NSURLResponse!, NSError!) -> Void#>) 

像下面这样使用NSURLSession

对于Objective-C

 NSURLSession *session = [NSURLSession sharedSession]; [[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // handle response }] resume]; 

对于Swift来说,

 var request = NSMutableURLRequest(URL: NSURL(string: "YOUR URL")) var session = NSURLSession.sharedSession() request.HTTPMethod = "POST" var params = ["username":"username", "password":"password"] as Dictionary<String, String> var err: NSError? request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err) request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Accept") var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in println("Response: \(response)")}) task.resume() 

我为实际需要阻止当前线程执行的同步请求的情况编写了以下解决scheme。 我使用这个代码从复杂的解决scheme中NSURLConnection迁移到NSURLSession在这种情况下,转换为asynchronous方法是一件很麻烦的事情。 有了这个解决scheme,迁移只是方法名称的替代。

注意:如果您有一个简单的案例,请使用接受的答案。

 - (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error { NSError __block *err = NULL; NSData __block *data; BOOL __block reqProcessed = false; NSURLResponse __block *resp; [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable _data, NSURLResponse * _Nullable _response, NSError * _Nullable _error) { resp = _response; err = _error; data = _data; reqProcessed = true; }] resume]; while (!reqProcessed) { [NSThread sleepForTimeInterval:0]; } *response = resp; *error = err; return data; } 

用法(简单地将NSURLConnectionreplace为此方法):

 //NSData *data = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&resp error:&err]; NSData *data = [self sendSynchronousRequest:theRequest returningResponse:&resp error:&err]; 

如果您需要阻止当前线程(如Mike Keskinov的答案),最好使用gdc信号量而不是执行[NSThread sleepForTimeInterval:0]。 例如

 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); NSURLSession *session = [NSURLSession sharedSession]; [[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // handle response dispatch_semaphore_signal(semaphore); }] resume]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

可以通过使用build议的方法摆脱警告[NSURLSession dataTaskWithRequest:completionHandler:]NSURLSession是你现在应该使用,而不是NSURLConnection

例如

 var session = NSURLSession(); session.dataTaskWithRequest(<#request: NSURLRequest#>, completionHandler: <#((NSData!, NSURLResponse!, NSError!) -> Void)?##(NSData!, NSURLResponse!, NSError!) -> Void#>) 

您可以通过使用以下代码在您的项目中隐藏该警告在input指令之间编写您的方法,并且您的警告消失。

 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - (void)yourMethodToCallNSURLConnection { //use deprecated stuff } #pragma GCC diagnostic pop 

Swift 4 / Xcode 9

如果你真的希望这个请求像在废弃的语义中一样是同步的,那么你可以在完成处理程序设置为true的情况下用空循环阻塞主线程:

 let request = URLRequest(url: URL(string: "YOUR_URL")!) let session = URLSession.shared var gotResp = false let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in // do my thing... gotResp = true }) task.resume() // block thread until completion handler is called while !gotResp { // wait } print("Got response in main thread") ... 

编辑:或者如果你喜欢使用信号量在Obj-C尼克H247答案:

 let request = URLRequest(url: URL(string: "YOUR_URL")!) let session = URLSession.shared let ds = DispatchSemaphore( value: 0 ) let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in // do my thing..., then unblock main thread ds.signal() }) task.resume() // block thread until semaphore is signaled ds.wait() print("Got response in main thread") ...