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

Posted

技术标签:

【中文标题】调用必须等待服务器响应的函数的问题【英文标题】:Issues with calling a function that has to wait for a server response 【发布时间】:2015-05-27 22:22:31 【问题描述】:

所以我的视图控制器中有以下代码可以完美运行。我发出 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)
                
        

所以现在我想创建一个可以用来调用我所有服务的类。所以我在这个类中创建了一个函数,我从我的视图控制器调用 让调用 = WebServiceCall() 让 jsonrequest = invoke.InvokeService()

所以我的类和功能是

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

    

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

【问题讨论】:

您可以做几件事。一种可能是将完成处理程序作为参数添加到 InvokeService。然后,您的视图控制器将完成处理程序传递给 InvokeService,这样当 jason 可用时,您的视图控制器的完成处理程序就会被调用。 【参考方案1】:
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)



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

注意: 此代码未经测试。所以也许你需要改变一点。

【讨论】:

请原谅我的无知,但是我该如何调用该服务,因为 compHandler 让我感到困惑,它没有构建,因为它说 compHandler 中的 NSRequest 是“使用未声明的类型 NSrequest”?感谢您的快速回复:) 将 NSRequest 更改为正确的类型。当你调用 request(.POST, postsEndpoint, parameters: test as! [String : AnyObject] , encoding: .JSON) .responseJSON (request, response, data, error) 中的请求、响应数据和错误有哪些类型? 所以我已经设置了参数,但我仍然不确定现在如何调用调用服务函数以及如何返回我的 json 对象? @Jack Swift 会帮助你。创建类 WebServiceCall 的新对象,然后调用该对象的方法。输入第一个参数。然后按tab,然后按enter,然后按tab,然后按enter。希望很清楚。因为我没有你正在使用的库,所以我无法编写你的代码。 所以我这样调用我的函数 let jsonResponse = invoke.InvokeService("authentication", compHandler: (NSURLRequest, NSHTTPURLResponse, AnyObject, NSError) -> Void in) 函数被调用但又好像它没有等待响应。已经调试过,它只是通过功能,但没有等待响应。我正在使用 Alamofire,谢谢您的输入@Omar Al-Shammary【参考方案2】:

您不能从异步调用中返回 JSON,因为返回是同步发生的。当从该方法返回时,不能保证 JSON 可用(并且可能不可用)。

一个修复:

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

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

【讨论】:

但这并没有解决他如何让 jason 回到调用视图控制器,或者 vc 如何知道 jason 何时可用,我认为这是他想要做的。跨度> 当然可以。他可以在parseJSON 方法中完成所有这些操作。 是的,但他不知道该怎么做,这实际上是他的问题的重点。他的问题的更大图景,而不是狭隘的焦点,是如何将他的调用从他的视图控制器迁移到一个专用的类中。你的答案是完全正确的,但错过了这种联系的一个重要部分,他不知道该怎么做,因为他正在与块和异步作斗争。 好的,我添加了更多信息。 (也可以发布您自己的答案。) 你先到这里了,不想打败你的答案 ;-)

以上是关于调用必须等待服务器响应的函数的问题的主要内容,如果未能解决你的问题,请参考以下文章

ios - 如何使用 Alamofire 等待 api 响应

等待ajax响应时如何防止用户交互?

Ajax+PHP打造等待进度条效果

Spring整合JMS(消息中间件)

如何在调用 Apollo Graphql Query 之前等待服务器响应?

Swift:如何对服务进行 API 调用但不等待响应