草庐IT

ios - 来自 ViewController 外部的 Alamofire 请求

coder 2023-09-12 原文

有什么方法可以从 ViewController (UITableViewController) 外部通过 alamofire 调用请求,然后用响应中的数据填充 tablewView?现在我在 Controller 中创建了一个函数,在获取数据后调用 tablewView 的 reloadData()。但是有没有办法创建这样的方法:

class InsuranceServices {

    class func getContracts(table : UITableView) -> [Contract] {
        var contracts = [Contract]()
        let headers : HTTPHeaders = [
            "Content-Type":"application/json"
        ]
        let params : Parameters = [String:Any]()

        Alamofire.request("http://test:9090/testService/getContracts", method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).validate().responseJSON(completionHandler: {response -> Void in

            switch response.result {
            case .success(let value):
                let json = JSON(value)
                for data in json["data"].arrayValue {
                    let contract = Contract(json: data)
                    print(contract.fullName!)
                    contracts.append(contract)
                }
            case .failure(let error):
                print(error)
            }
            table.reloadData()
        })
        return contracts
    }

}

这个方法对我不起作用。也许还有另一种方法?我认为在 Controller 内部创建服务方法是不正确的。

最佳答案

您的 ViewControllerAlamofire 应该有明显的区别。 一种实现方法类似于您编写的方法,但您的函数不应采用 UITableView 本身,而应采用接收 [Contract] 的完成 block 。

它看起来像这样:

class func getContracts(completion: @escaping ([Contract])→Void) { 
    //...
    Alamofire.request(...).responseJSON(completionHandler: {response -> Void in

        switch response.result {

        case .success(let value):
            let json = JSON(value)
            var contracts = [Contract]()
            for data in json["data"].arrayValue {
                let contract = Contract(json: data)
                contracts.append(contract)                    
            }
            completion(contracts)

        case .failure(let error):
            print(error)
            completion([])
        }
    })
}

另一件事是你不能在函数的返回值中返回请求的结果(在你的例子中是 Contract 的数组)。由于 Alamofire 异步调用请求,它会比函数返回晚得多结束。这就是为什么如您所见,我编写的函数签名不返回任何内容。相反,它会在请求准备好且数据可用时调用 completion 闭包。

请注意,即使在失败时,您也必须调用completion 闭包!否则调用者(在您的情况下是您的 View Controller )将永远等待请求而不知道它失败了....

然后您可以像这样调用该函数,确保您不会因 self 导致内存泄漏:

InsuranceServices.getContracts(completionHandler: { [weak self] data in 
    self?.contracts = data
    self?.tableView.reloadData() 
})

关于ios - 来自 ViewController 外部的 Alamofire 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41351484/

有关ios - 来自 ViewController 外部的 Alamofire 请求的更多相关文章

  1. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  4. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  5. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  6. ruby - 从外部访问类的实例变量 - 2

    我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内

  7. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  8. ruby - HTTP 请求中的用户代理,Ruby - 2

    我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)

  9. ruby - 可以正常中断的来自 Rake 的长时间运行的 shell 命令? - 2

    在几个项目中,我希望有一个类似rakeserver的rake任务,它将通过任何需要的方式开始为该应用程序提供服务。这是一个示例:task:serverdo%x{bundleexecrackup-p1234}end这行得通,但是当我准备停止它时,按Ctrl+c并没有正常关闭;它中断了Rake任务本身,它说rakeaborted!并给出堆栈跟踪。在某些情况下,我必须执行Ctrl+c两次。我可能可以用Signal.trap写一些东西来更优雅地中断它。有没有更简单的方法? 最佳答案 trap('SIGINT'){puts"Yourmessa

  10. ruby-on-rails - 获取并发布相同匹配项的请求 - 2

    在我的路线文件中我有:match'graphs/(:id(/:action))'=>'graphs#(:action)'如果是GET请求(工作)或POST请求(不工作),我想匹配它我知道我可以使用以下方法在资源中声明POST请求:post'/'=>:show,:on=>:member但是我怎样才能为比赛做到这一点呢?谢谢。 最佳答案 如果你同时想要POST和GETmatch'graphs/(:id(/:action))'=>'graphs#(:action)',:via=>[:get,:post]编辑默认值可以设置如下match'g

随机推荐