In NSURLSession HTTPBody must be NSData? - ios

When I use AFNetworking to post parameters is NSMutableDictionary, this request is succeeded.
But when I used NSURLSession, the self.request!.HTTPBody must be NSData, so request failed.
How can I use NSURLSession to make request succeeded?
postDict[#"jgId"] = "1000000000";
[manager GET:SELECTDEPART parameters:postDict success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"-----%#", error);
}];
//use NSData
NSJSONSerialization.dataWithJSONObject(postDict, options: NSJSONWritingOptions.PrettyPrinted)
Please help me.

let params = ["jgId": "1000000000"]
let data = try? JSONSerialization.data(withJSONObject: params, options: [JSONSerialization.WritingOptions(rawValue: 0)])
var request = URLRequest(url: URL(string: "https://my-url.com")!, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 30)
request.httpMethod = "POST"
request.httpBody = data
request.allHTTPHeaderFields = [:]
URLSession.shared.dataTask(with: request) { (data, response, error) in
}

You are correct, for NSURLSession you need NSData.
But you can easily convert an NSDictionary to NSData by using NSKeyedArchiver.

You are using GET method to request data from server, so your parameters is not sent by request HTTPBody data. Your params is simple past via request URL.
In question You have SELECTDEPART as base URL of request and postDict as parameter. The following code use NSURLSession to make GET request with parameters
// get request URL from base URL and params
NSURLComponents *components = [NSURLComponents componentsWithString:#"http://stackoverflow.com"]; // some thing like SELECTDEPART in your question
NSDictionary *params = #{ #"q": #"ios", #"count": #"10" }; // params of request like your postDict
NSMutableArray *queryItems = [NSMutableArray array];
for (NSString *key in params.allKeys) {
[queryItems addObject:[NSURLQueryItem queryItemWithName:key value:params[key]]];
}
components.queryItems = queryItems;
NSURL *url = components.URL;
// create request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPMethod = #"GET";
// data task with NSURLSession
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
// parse your data here
} else {
// handle error here
}
}];
[task resume];

Related

Wait response for HTTP request using NSURLSession - Objective C

Right now I am developing I little class that has a method for sending a POST request. This method is intended for returning a ResponseModel (which basically has two ivars: code, message), this model is going to be map from response.
I am using dataTaskWithRequest:urlRequest completionHandler: method. Like this:
+ (void)sendPOSTRequest1:(id)data withResponse:(void (^) (ResponseModel * data) )taskResponse {
NSError *error = nil;
NSMutableURLRequest * urlRequest = [self getRequestObject];
[urlRequest setHTTPMethod:#"POST"];
NSData * requestData = [self encodeAndEncrypt:data];
[urlRequest setHTTPBody:requestData];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session
dataTaskWithRequest:urlRequest
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
ResponseModel * responseModel = [NSKeyedUnarchiver
unarchivedObjectOfClass:[ResponseModel class]
fromData:data
error:&error];
taskResponse(responseModel);
}];
[dataTask resume];
}
And call the method this way:
DummyModel * dummy = [[DummyModel alloc] init];
__block ResponseModel * result = [[ResponseModel alloc] init];
[HTTPRequest sendPOSTRequest1:dummy withResponse:^(ResponseModel *data) {
result = data;
NSLog(#"data %#",data);
}];
// It`s not sure that the asyncronous request has already finished by this point
NSLog(#"POST result : %#",result);
My problem is that I do not want to execute a code in call back block because I need to wait for the response in order to return a ResponseModel and whoever is implementing this can receive the Model and make other stuff.
I been researching for using NSURLConnection because it has a method for executing Synchronous request, but now It´s deprecated, so I been wondering: is It a way I can wait for a response using what I have in the code ?
You can use GCD to implement synchronous request like this:
swift code
public static func requestSynchronousData(request: URLRequest) -> Data? {
var data: Data? = nil
let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: {
taskData, _, error -> () in
data = taskData
if data == nil, let error = error {print(error)}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: .distantFuture)
return data
}
Objective-C code
+ (NSData *)requestSynchronousData:(NSURLRequest *)request {
__block NSData * data = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable taskData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(#"%#", error);
}
data = taskData;
dispatch_semaphore_signal(semaphore);
}];
[task resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return data;
}
You can use dispatch_async to handle UI interaction inside the block
DummyModel * dummy = [[DummyModel alloc] init];
__block ResponseModel * result = [[ResponseModel alloc] init];
[HTTPRequest sendPOSTRequest1:dummy withResponse:^(ResponseModel *data) {
result = data;
dispatch_async(dispatch_get_main_queue(), ^{
// handle some ui interaction
});
NSLog(#"data %#",data);
}];

How to get the PayPal refresh token through API call in iOS

I have successfully implemented profile sharing option with PayPal iOS Sdk.
I am getting proper code once user logged in to paypal account in the app.
I have tried to get the user information with curl command I got success.
Now I want to implement 2nd and 3rd step through api call.
Below is what I have implemented for getting refresh token from PayPal server.
func getTheRefreshToken(authToken:NSString) {
print("Token \(authToken)")
let urlPath: String = "https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice"
let url: NSURL = NSURL(string: urlPath)!
let request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
let basicAuthCredentials: String = "AXvaZH_Bs9**CLIENTID**0RbhP0G8Miw-y:ED_xgio**SECRET**YFwMOWLfcVGs"
let plainData = (basicAuthCredentials as NSString).dataUsingEncoding(NSUTF8StringEncoding)
let base64String = "Basic \(plainData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)))"
request.HTTPMethod = "POST"
let params = ["grant_type":"authorization_code","redirect_uri":"urn:ietf:wg:oauth:2.0:oob", "authorization_code":authToken as String] as Dictionary<String, String>
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue(base64String, forHTTPHeaderField: "Authorization")
request.timeoutInterval = 60
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(params, options: [])
request.HTTPShouldHandleCookies=false
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in
let refreshResponse = NSString(data: data!, encoding: NSISOLatin1StringEncoding)
print("Response \(refreshResponse!)")
}
}
Every time I am getting the error with grant_type as null.
Error
Response {"error_description":"Grant type is null","error":"invalid_grant","correlation_id":"e5d4cc9c47d21","information_link":"https://developer.paypal.com/docs/api/#errors"}
A couple things here...
1. You should never have your client Secret stored on the client side for security reasons.
2. Can you attempt the call from your server using the curl commands outline here and let me know the result?
The only thing I can see from our internal logs is the same as the error or grant_type missing. Running the test from your server, using the authorization code in the response, should let us know if it's just something in your code that's getting discombobulated.
Using this code you can refresh or got new Access token on PayPal.
NSString *clientID = #"YOUR_CLIENT_ID";
NSString *secret = #"YOUR_SECRET";
NSString *authString = [NSString stringWithFormat:#"%#:%#", clientID, secret];
NSData * authData = [authString dataUsingEncoding:NSUTF8StringEncoding];
NSString *credentials = [NSString stringWithFormat:#"Basic %#", [authData base64EncodedStringWithOptions:0]];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
[configuration setHTTPAdditionalHeaders:#{ #"Accept": #"application/json", #"Accept-Language": #"en_US", #"Content-Type": #"application/x-www-form-urlencoded", #"Authorization": credentials }];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://api.sandbox.paypal.com/v1/oauth2/token"]];
request.HTTPMethod = #"POST";
NSString *dataString = #"grant_type=client_credentials";
NSData *theData = [dataString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:theData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSLog(#"data = %#", [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]);
}
}];
[task resume];
This will give this Response.
data = {
"access_token" = "A101.S6WF1CZIz9TcamYexl6k1mBsXhxEL1OWtotHq37UVHDrK7roty_4DweKXMhObfCP.7hNTzK62FqlDn3K9bqCjUIFmsVy";
"app_id" = "APP-80W284485P519543T";
"expires_in" = 32042;
nonce = "2016-12-26T10:24:12Z8qEQBxdSGdAbNMg2ivVmUNTUJfyFuSL30OI_W9UCgGA";
scope = "https://uri.paypal.com/services/subscriptions https://api.paypal.com/v1/payments/.* https://api.paypal.com/v1/vault/credit-card https://uri.paypal.com/services/applications/webhooks openid https://uri.paypal.com/payments/payouts https://api.paypal.com/v1/vault/credit-card/.*";
"token_type" = Bearer;
}

Get external player URL from Vimeo api for tvOS

I want to use vimeo to host videos for a AppleTV app. I realise I will need a pro account to do exactly what I want, but at the moment just trying to do a POC.
What I need to achieve is to retrieve a url of my private video that expires after 1 hour, and I want the app to be authenticated with my credentials, not having the user have to sign in (as if the have the app, then they can view the videos).
Code that I am using is below, the constants set are:
kVimeoToken is an access token I created on vimeo for the app, and I have imported the vimeo api into my project.
-(NSString*) getVimeoUrls2 {
VIMClient *client = [[VIMClient alloc] initWithDefaultBaseURL];
AFJSONRequestSerializer *serializer= [AFJSONRequestSerializer serializer];
NSString *token = kVimeoToken;
//[serializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[serializer setValue:#"application/vnd.vimeo.*+json; version=3.2" forHTTPHeaderField:#"Accept"];
[serializer setValue:[NSString stringWithFormat:#"Bearer %#", token] forHTTPHeaderField:#"Authorization"];
client.requestSerializer = serializer;
__block NSString *str= nil;
[client requestURI:#"/me" completionBlock:^(VIMServerResponse *response, NSError *error)
{
id JSONObject = response.result;
NSLog(#"JSONObject: %#", JSONObject);
NSLog(#"Error: %#", [error localizedDescription]);
str = [[NSString alloc] initWithData:JSONObject encoding:NSUTF8StringEncoding];
}];
return str;
}
All I get back is an empty string, any idea what I am doing wrong?
If I change the access token so it is incorrect then I get back an error message {"error":"You must provide a valid authenticated access token."}, so it appears that I get authenticated ok. I have also tried some other endpoints but all of them end up with an empty string.
I have tried two separate approaches, both with the same result...i.e none, or an empty string.
I posted the question on the vimeo forums and got provided these two links:
developer.vimeo.com/api/authentication#single-user
github.com/vimeo/VIMNetworking#lightweight-use
The is the output from the log for the above code is below:
2016-01-09 08:13:26.091 tvOSShortGame[68357:91090409] server start (/me/watched/videos)
2016-01-09 08:13:26.461 tvOSShortGame[68357:91090448] server success 0.370109 sec (/me/watched/videos)
..and if I change the endpoint to /xxx (to force an error)
2016-01-09 08:07:28.826 tvOSShortGame[67829:91039056] server start (/xxx)
2016-01-09 08:07:29.003 tvOSShortGame[67829:91039045] server failure 0.177531 sec (/xxx)
2016-01-09 08:07:29.003 tvOSShortGame[67829:91039460] JSONObject: (null)
2016-01-09 08:07:29.003 tvOSShortGame[67829:91039460] Error: Request failed: not found (404)
Other endpoints get the same result, reports success but there is no JSON object returned.
Any help appreciated.
I finally got this working by using Postman which I saw on one of the Vimeo forums. It produces the correct code in multiple languages, and shows the resulting JSON so you can validate your endpoints.
Hope someone finds it useful.
//Obj C version
NSDictionary *headers = #{ #"authorization": #"Bearer MY_VIMEO_TOKEN",
#"cache-control": #"no-cache",
#"postman-token": #"MY_POSTMAN_TOKEN" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://api.vimeo.com/videos/116999999"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:#"GET"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"%#", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(#"%#", httpResponse);
}
}];
[dataTask resume];
//Swift version
let headers = [
"authorization": "Bearer MY_VIMEO_TOKEN",
"cache-control": "no-cache",
]
var request = NSMutableURLRequest(URL: NSURL(string: "https://api.vimeo.com/videos/116999999")!,
cachePolicy: .UseProtocolCachePolicy,
timeoutInterval: 10.0)
request.HTTPMethod = "GET"
request.allHTTPHeaderFields = headers
var str = ""
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? NSHTTPURLResponse
str = self.parseJSON(data!)
}
})
dataTask.resume()

Post request with raw body using NSURLSession

I have stuck here. Below is my code for Post request with raw body using NSURLSession. I got response = NULL and no error.
NSString* stringRequest = #"https://chocudan.com/api/shops/by_ids";
NSURL* urlRequest = [NSURL URLWithString:stringRequest];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:urlRequest];
request.HTTPMethod = #"POST";
NSString* bodyRequest = #"563c268b84ba489c4729f149";
//I have to tried a base64 convert here but still not work.
//request.HTTPBody = [NSData base64DataFromString:bodyRequest];
request.HTTPBody = [bodyRequest dataUsingEncoding:NSUTF8StringEncoding];
NSURLSessionConfiguration* configureSession = [NSURLSessionConfiguration defaultSessionConfiguration];
configureSession.HTTPAdditionalHeaders = #{#"Content-Type" : #"application/json charset=utf-8",
#"Content-Lenght" : #"180"};
NSURLSession* session = [NSURLSession sessionWithConfiguration:configureSession];
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSHTTPURLResponse* respHttp = (NSHTTPURLResponse*) response;
if (!error && respHttp.statusCode == 200) {
NSDictionary* respondData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSLog(#"%#", respondData);
}else{
NSLog(#"%#", error);
}
}];
[dataTask resume];
I have to try with postman and everything work fine. This is pictures.
Thank in advance.
Try changing it too
NSArray* bodyArray = #[#"563c268b84ba489c4729f149"]
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:bodyArray
options:NSJSONWritingPrettyPrinted error:&error];
request.HTTPBody = jsonData;
My raw data was like :
{
"email":"test#gmail.com",
"password":"12345678"
}
and what I did is :
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:#"test#gmail.com" forKey:#"email"];
[dict setValue:#"12345678" forKey:#"password"];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
options:NSJSONWritingPrettyPrinted error:&error];
request.HTTPBody = jsonData;
This fixed it for me:
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = ["Content-Type" : "text/plain"]
I guess that it was not data that was null but respondData was null?
That is because your service sends an Array with exactly one Object. JSONSerialisation creates an NSArray from that with one NSDictionary in it. The dictionary has the keys _id, contact and so on.
So it is
NSArray* respondData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
BTW
NSHTTPURLResponse* respHttp = (NSHTTPURLResponse*) response;
does not make much of a sense but does not harm either.
With respect to the body of your request, see mihir's answer. He is just right.
It may help you understanding mihir's point when you do this:
NSString* bodyRequest = #"[563c268b84ba489c4729f149]";
However, this is rather quick & dirty but may help you understanding the principles. Once understood you will certainly follow mihir's suggestion.
If you want to post raw, and param is a format of NSString, you only need to do this:
NSData *param_data = [encry_str dataUsingEncoding:NSUTF8StringEncoding];
murequest.HTTPBody = param_data;
If we can’t get anything from that response, notice that the response serializer is correct. Any additional settings, please deal it with server.

iOS9 sendSynchronousRequest deprecated

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#>)
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()
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];
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()
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;
}
}
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")
...
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;
}
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

Resources