Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 183 Vote(s) - 3.38 Average
  • 1
  • 2
  • 3
  • 4
  • 5
iOS9 sendSynchronousRequest deprecated

#1
> Warning:'sendSynchronousRequest(_:returningResponse:)' was deprecated
> in iOS 9.0: Use [NSURLSession dataTaskWithRequest:completionHandler:]
> (see NSURLSession)



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

Any idea on how to get rid of this warning? I just upgraded from Swift 1.2 to Swift 2

UPDATE: Fonix is marked as my best answer. If your trying to add a try statement, I modified his answer as followed:



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

#2
If you need to block the current thread (like Mike Keskinov's answer), best to use gdc semaphore instead of doing a [NSThread sleepForTimeInterval:0]. e.g.


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);


and Swift (tested on 5.0):

let semaphore = DispatchSemaphore(value:0)

URLSession.shared.dataTask(with: serverUrl) { (httpData, response, error) in
// handle response
semaphore.signal()
}.resume()

semaphore.wait()

Reply

#3
I wrote the following solution for the cases when you actually need for synchronous request which blocks the current thread execution. I use this code for migration from `NSURLConnection` to `NSURLSession` in the complex solution where it was **quite a hassle** to just change to async approach. With this solution the migration is just method name replacement.

*NOTE: If you have a simple case, please use the accepted answer instead.*


- (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.02];
}
if (response != nil)
*response = resp;
if (error != nil)
*error = err;
return data;
}

Usage (simple replace `NSURLConnection` to this method):

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

Reply

#4
Here is a complete version of mine with dispatch_semaphore_t and return response and error without block assign warning . Thank @Nick H247 and @Mike Keskinov.


- (NSData*)sendSynchronousRequest:NSURLRequest *urlRequest
returningResponse:(NSURLResponse **)outResponse
error:(NSError **)outError
{

NSError __block *err = NULL;
NSData __block *data;
BOOL __block reqProcessed = false;
NSURLResponse __block *resp;

// data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:response error:error];

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSession *session = _session;
[[session dataTaskWithRequest:urlRequest
completionHandler:^(NSData *_data,
NSURLResponse *_response,
NSError *_error) {
// handle response
data = _data;
resp = _response;
err = _error;

reqProcessed = true;

dispatch_semaphore_signal(semaphore);

}] resume];

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

if (reqProcessed) {
if(outResponse != NULL) {
*outResponse = resp;
}

if (outError != NULL) {
*outError = err;
}

}

return data;
}

Reply

#5
I have modified the code of Nilesh Patel a little bit, so you can use the old call, just by changing class name.

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error {
__block NSData *blockData = nil;
@try {

__block NSURLResponse *blockResponse = nil;
__block NSError *blockError = nil;

dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable subData, NSURLResponse * _Nullable subResponse, NSError * _Nullable subError) {

blockData = subData;
blockError = subError;
blockResponse = subResponse;

dispatch_group_leave(group);
}] resume];

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

*error = blockError;
*response = blockResponse;

} @catch (NSException *exception) {

NSLog(@"%@", exception.description);
} @finally {
return blockData;
}
}
Reply

#6
**Swift 4 / Xcode 9**

If you really want the request to be synchronous like in the deprecated semantics, you can block the main thread with an empty loop on a condition set true by the completion handler:

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")
...

**EDIT:** or if you prefer to use semaphores like in the Obj-C Nick H247 answer:

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")
...

Reply

#7
Use `NSURLSession` instead like below,

For Objective-C


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

}] resume];


For 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()

Reply

#8
you can hide that warning in your project by using following code write your method between input directives and your warning goes away.

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



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through