New Value Is Only Available in Sendasynchronousrequest - Swift

New value is only available in sendAsynchronousRequest - Swift

sendAsynchronousRequest is, as the name suggests, asynchronous. So your final println runs before the request is complete. After the completion handler runs, the new data will be available for all readers (in or outside this handler).

NSURLConnection sendAsynchronousRequest can't get variable out of closure

This is calling asynchronous function that is using a completion handler block/closure. So, you need to employ the completion handler pattern in your own code. This consists of changing the method return type to Void and adding a new completionHandler closure that will be called when the asynchronous call is done:

func post(url: String, info: String, completionHandler: (NSString?, NSError?) -> ()) {
let URL = NSURL(string: url)!
let request = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
let bodyData = info
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { response, data, error in
guard data != nil else {
completionHandler(nil, error)
return
}

completionHandler(NSString(data: data!, encoding: NSUTF8StringEncoding), nil)
}
}

Or, since NSURLConnection is now formally deprecated, it might be better to use NSURLSession:

func post(url: String, info: String, completionHandler: (NSString?, NSError?) -> ()) -> NSURLSessionTask {
let URL = NSURL(string: url)!
let request = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
let bodyData = info
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
dispatch_async(dispatch_get_main_queue()) {
guard data != nil else {
completionHandler(nil, error)
return
}

completionHandler(NSString(data: data!, encoding: NSUTF8StringEncoding), nil)
}
}
task.resume()

return task
}

And you call it like so:

post(url, info: info) { responseString, error in
guard responseString != nil else {
print(error)
return
}

// use responseString here
}

// but don't try to use response string here ... the above closure will be called
// asynchronously (i.e. later)

Note, to keep this simple, I've employed the trailing closure syntax (see Trailing Closure section of The Swift Programming Language: Closures), but hopefully it illustrates the idea: You cannot immediately return the result of an asynchronous method, so provide a completion handler closure that will be called when the asynchronous method is done.

Cannot invoke 'sendAsynchronousRequest' in Swift 2 with an argument list

With Swift 1.2 and Xcode 6.3, the signature of sendAsynchronousRequest:queue:completionHandler: is:

class func sendAsynchronousRequest(request: NSURLRequest,
queue: NSOperationQueue!,
completionHandler handler: (NSURLResponse!, NSData!, NSError!) -> Void)

With Swift 2 and Xcode 7 beta, however, the signature of sendAsynchronousRequest:queue:completionHandler: has changed and is now:

// Note the non optionals, optionals and implicitly unwrapped optionals differences
class func sendAsynchronousRequest(request: NSURLRequest,
queue: NSOperationQueue,
completionHandler handler: (NSURLResponse?, NSData?, NSError?) -> Void)

As a consequence, turning to Swift 2 and Xcode 7 beta, you will have to change your completionHandler parameter implementation and ensure that your queue parameter is a non optional.

sendAsynchronousRequest was deprecated in iOS 9, How to alter code to fix

Use NSURLSession instead like below,

For Objective-C

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:"YOUR URL"]
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>

request.HTTPBody = try? NSJSONSerialization.dataWithJSONObject(params, options: [])

request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")

var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
print("Response: \(response)")})

task.resume()

For asynchronously query, from Apple docs

Like most networking APIs, the NSURLSession API is highly
asynchronous. It returns data in one of two ways, depending on the
methods you call:

To a completion handler block that returns data to your app when a
transfer finishes successfully or with an error.

By calling methods on your custom delegate as the data is received.

By calling methods on your custom delegate when download to a file is
complete.

Swift AsynchronousRequest response cannot be read

You are missing the do/catch block

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response, data, error) -> Void in
let res = response as! NSHTTPURLResponse
do {
if(res.statusCode >= 200 && res.statusCode < 300) {
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
}
} catch {

}
}

But easier and better way in swift is this networking library: Alamofire

Example:

Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization

if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}

how to use sendAsynchronousRequest:queue:completionHandler:

PArt 1:

NSURL *url = [NSURL URLWithString:urlString];

NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if ([data length] > 0 && error == nil)
[delegate receivedData:data];
else if ([data length] == 0 && error == nil)
[delegate emptyReply];
else if (error != nil && error.code == ERROR_CODE_TIMEOUT)
[delegate timedOut];
else if (error != nil)
[delegate downloadError:error];
}];

NSURLConnection sendAsynchronousRequest: How to check finished status code?

You have to implement 2 delegate methods:

  1. Status code: - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

  2. Received data: - (void)connection:(NSURLConnection *)connection
    didReceiveData:(NSData *)data

Example usage:

Declaration

@interface RequestHandler : NSObject <NSURLConnectionDelegate>
{
NSMutableData *receivedData;
}

Request

- (void)sendRequest:(NSString *)surveyorId withData:(NSData *)requestData
{

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

// Apply params in http body
if (requestData) {
[request setHTTPBody:requestData];
}

[request setURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
}

Delegates

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *responseCode = (NSHTTPURLResponse *)response;
if ([self.delegate respondsToSelector:@selector(didReceiveResponseCode:)]) {
[self.delegate didReceiveResponseCode:responseCode];
}
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
receivedData = [[NSMutableData alloc] initWithData:data];

if ([self.delegate respondsToSelector:@selector(connectionSucceedWithData:)]) {
[self.delegate connectionSucceedWithData:receivedData];
}
}


Related Topics



Leave a reply



Submit