Reputation: 1289
In swift 2 When I'm communicating with a web-service and when I write these codes in button action it works fine.
let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: .Alert)
let ok = UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in })
alert.addAction(ok);
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.myaddress.com/web-service/iostest.aspx")!)
request.HTTPMethod = "POST"
var postString = String();
postString = "uid=1";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else {
alert.title="Error"
alert.message = "Connection error"
dispatch_async(dispatch_get_main_queue()){
self.presentViewController(alert, animated: true, completion: nil)
}
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
alert.title="Error"
alert.message = "Server error"
dispatch_async(dispatch_get_main_queue()){
self.presentViewController(alert, animated: true, completion: nil)
}
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
alert.title="Info"
alert.message = responseString as? String
dispatch_async(dispatch_get_main_queue()){
self.presentViewController(alert, animated: true, completion: nil)
}
}
task.resume()
As I said this works fine but as I want to do this from different ViewControls as well I have created a swift file which contains a struct and a static func in that struct that returns the the "responseString" so I could alert it in the view control. Something like this:
struct globalClass {
static func sendInfo(url: String, data: String) -> (answer: String, errorCode: Int32) {
var res = String();
var err = Int32();
err = 0;
let request = NSMutableURLRequest(URL: NSURL(string: url)!);
request.HTTPMethod = "POST";
let postString: String = data;
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else {
err = 1;
return;
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
err = 2;
return;
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding);
res = (responseString as? String)!;
}
task.resume();
return (res, err);
}
But now when I call this func from my button it shows me an empty alert very fast that it seems like it didn't get anything from web-service and didn't even try too.
I put these in the button action:
@IBAction func btnData(sender: AnyObject) {
let y: String = "uid=1";
let res = globalClass.sendInfo("http://www.myaddress.com/web-service/iostest.aspx", data: y);
let alert = UIAlertController(title: "", message: "", preferredStyle: .Alert);
let OK = UIAlertAction(title: "OK", style: .Default, handler: nil);
alert.addAction(OK);
if (res.errorCode==0) {
alert.title = "Info";
alert.message = res.answer;
} else if (res.errorCode==1) {
alert.title = "Error";
alert.message = "Error connecting to server";
} else {
alert.title = "Error";
alert.message = "Server returned an error";
}
dispatch_async(dispatch_get_main_queue()){
self.presentViewController(alert, animated: true, completion: nil);
};
}
Thanks for the help,
Afshin Mobayen Khiabani
Upvotes: 0
Views: 99
Reputation: 3878
static func sendInfo(url: String, data: String, completion: (answer: String, errorCode: Int32) -> ()){
//Your code..
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding);
res = (responseString as? String)!;
completion(answer: res, errorCode: err)
}
task.resume()
}
Then when you call the sendInfo
, call like so:
sendInfo(url: "your url", data: "your data") { (result, error) in
//you use your result and error values as u want.
}
Upvotes: 1
Reputation: 1017
globalClass.sendInfo
uses async call - dataTaskWithRequest
. The result of the request will be delivered in completion of this method. But you don't wait for that result, instead you try to use sendInfo
like a sync function.
To be able to deliver the result from dataTaskWithRequest
's completion, put your own completion into sendInfo
and invoke this completion (closure) when the result is delivered. An example
struct GlobalClass {
static func sendInfo(url: String, data: String, completion: (answer: String?, errorCode: Int32?) -> Void) {
// you code here which prepares request
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
// you parse the result here
// you deliver the result using closure
completion(string, error)
}
task.resume();
}
}
And an example of usage:
func usage() {
GlobalClass.sendInfo("url", data: "data") { (answer, errorCode) in
// your answer and errorCode here
// handle the result
}
}
Upvotes: 1