调用必须等待服务器响应的函数的问题

Issues with calling a function that has to wait for a server response

所以我的视图控制器中有以下代码可以完美运行。我发出 json 请求,服务器调用已发出,我得到的响应没有任何问题。单击按钮时调用我的函数:

@IBAction func buttonClick(sender: AnyObject) {

        var postsEndpoint = "http://test.com/test"
        let test = ["Blah":"test"]

        request(.POST, postsEndpoint, parameters: test as! [String : AnyObject]   , encoding: .JSON)
            .responseJSON { (request, response, data, error) in

                if let anError = error
                {
                    // got an error in getting the data, need to handle it
                    println("error calling POST on /posts")
                    println(error)
                }
                else if let data: AnyObject = data
                {

                    let post = JSON(data)
                    // now we have the results, let's just print them though a tableview would definitely be better UI:
                     println("The post is: " + post.description)
                }
        }
}

所以现在我想制作一个 class,我可以用它来调用我的所有服务。所以我在这个 class 中创建了一个函数,我正在使用我的视图控制器调用它 让调用 = WebServiceCall() 让 json请求 = invoke.InvokeService()

所以我的 class 和函数是

class WebServiceCall{


    var post:JSON = nil

    func InvokeService(type : String) ->JSON{

        var postsEndpoint = "http://test.com/test"
        let test = ["Blah":"test"]


        request(.POST, postsEndpoint, parameters: test as! [String : AnyObject]   , encoding: .JSON)
            .responseJSON { (request, response, data, error) in


                if let anError = error
                {
                    // got an error in getting the data, need to handle it
                    println("error calling POST on /posts")
                    println(error)
                }
                else if let data: AnyObject = data
                {

                    self.post = JSON(data)
                    // now we have the results, let's just print them though a tableview would definitely be better UI:
                     println("The post is: " + post.description)
                }
        }

        return self.post

    }

我认为我的问题是函数被调用了,但是因为没有完成处理程序来等待响应,所以我从来没有得到返回的数据。 我用谷歌搜索了完成处理程序,但我感到困惑。 任何帮助都会很棒thx

您不能从异步调用中 return JSON,因为 returning 是同步发生的。 JSON 不能保证在方法 return 时可用(很可能不可用)。

一个修复:

  • 从您的方法签名中删除 ->JSON 并从您的正文中删除 return self.post
  • 创建一个像 func parseJSON(JSON : JSON) 这样的新方法,用 JSON
  • 做任何你想做的事
  • 从完成处理程序中调用此方法

parseJSON(:_) 方法中,您可以将 JSON(或任何其他对象)传递回视图控制器。这通常是通过委托、完成处理程序(如评论中提到的 Gruntcakes)或 NSNotification.

完成的
var post:JSON = nil

func InvokeService(type : String) ->JSON{

var postsEndpoint = "http://test.com/test"
let test = ["Blah":"test"]


request(.POST, postsEndpoint, parameters: test as! [String : AnyObject]   , encoding: .JSON)
    .responseJSON { (request, response, data, error) in


        if let anError = error
        {
            // got an error in getting the data, need to handle it
            println("error calling POST on /posts")
            println(error)
        }
        else if let data: AnyObject = data
        {

            self.post = JSON(data)
            // now we have the results, let's just print them though a tableview would definitely be better UI:
             println("The post is: " + post.description)
        }
}

return self.post

}

将此更改为

var post:JSON = nil

func InvokeService(type : String, compHandler: (NSRequest, NSresponse, NSData, NSError) -> Void){

var postsEndpoint = "http://test.com/test"
let test = ["Blah":"test"]


request(.POST, postsEndpoint, parameters: test as! [String : AnyObject]   , encoding: .JSON)
    .responseJSON { (request, response, data, error) in
    compHandler(request, response, data, error)
}

}

然后就可以调用这个方法了

注意: 此代码尚未经过测试。所以也许你需要稍微改变一下。