【问题标题】:Calling a func in other swift file which works with web-service returns nothing在其他与 web 服务一起使用的 swift 文件中调用 func 不会返回任何内容
【发布时间】:2016-07-02 23:04:50
【问题描述】:

在 swift 2 中,当我与 Web 服务通信并在按钮操作中编写这些代码时,它工作正常。

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

正如我所说,这工作正常,但我也想从不同的 ViewControls 执行此操作,我创建了一个 swift 文件,其中包含一个结构和一个静态函数,该结构返回“responseString”,所以我可以提醒它在视图控件中。像这样的:

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

但是现在当我从我的按钮调用这个函数时,它会非常快地向我显示一个空警报,它似乎没有从网络服务中得到任何东西,甚至没有尝试过。

我把这些放在按钮动作中:

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

}

感谢您的帮助,

Afshin Mobayen Khiabani

【问题讨论】:

  • globalClass.sendInfo 使用异步调用,但用作同步方法。尝试使用闭包而不是 sendInfo 的 ret 值来传递结果
  • 谢谢你,但如何:D 我会试着找到如何,但你能详细说明一下

标签: ios swift web-services


【解决方案1】:

globalClass.sendInfo 使用异步调用 - dataTaskWithRequest。请求的结果将在此方法完成时交付。但是您不必等待该结果,而是尝试像同步功能一样使用sendInfo

为了能够从dataTaskWithRequest 的完成中传递结果,请将您自己的完成放入sendInfo 并在传递结果时调用此完成(闭包)。一个例子

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

还有一个用法示例:

func usage() {
    GlobalClass.sendInfo("url", data: "data") { (answer, errorCode) in
        // your answer and errorCode here
        // handle the result
    }
}

【讨论】:

    【解决方案2】:
    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()
    
    
    
    }
    

    那么当你调用sendInfo时,调用如下:

    sendInfo(url: "your url", data: "your data") { (result, error) in
    
    //you use your result and error values as u want.
    }
    

    【讨论】:

    • 谢谢,但是completion(answer: res, errorCode: err) 应该写在 ask.resume() 之前
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 2017-05-10
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    相关资源
    最近更新 更多