当前位置: 首页 > 知识库问答 >
问题:

快速可选完成处理程序

蒋高扬
2023-03-14

我正在尝试在我的Swift应用程序中创建一个服务对象,以便更轻松地处理请求。我已经把它连接起来了,但是我可能误解了完成处理器。

我有这个函数,它只是发布到我正在运行的本地APIendpoint。

func createList(name: String, completion: @escaping (Response) -> Void) {
        let parameters = ["name": name, "user_id": session.auth.currentUser!.uid]
        
        AF.request("\(url)/wishlist", method: .post, parameters: parameters, encoding: URLEncoding.default).responseDecodable(of: Response.self) { response in
                switch response.result {
                case .failure(let err):
                    print(err)
                case .success(let res):
                    completion(res)
            }
        }
    }

我需要做的就是把这个名字传给我在这里做的函数

barback.createList(name: name) -> after a button is tapped

但是,我现在收到此错误。

调用中缺少参数“completion”的参数

我的目标是返回< code>Response对象,这样我就可以访问它的属性,在UI中做一些事情。我不能在这里返回< code>res,因为,根据我的理解,这是一个异步请求,它实际上是从那个竞争处理程序返回的?(可能是屠杀)。我看到其他人这样做的方式是在参数中添加一个竞争处理程序,并添加一个转义。

我的最终目标是做一些像...

if barback.createList(name: name).status = 200
    (trigger some UI component)
else
    (display error toast)
end

我的功能在设计上有缺陷吗?我已经试着把我的比赛教练改成

完成:(@逃脱(响应)-

但是会遇到一些其他的错误。有什么指导吗?

共有3个答案

海典
2023-03-14

使用注释和答案中提到的完成处理程序。此外,当完成失败时,您应该包含一个完成,否则您将永远无法退出该函数。

我会重新构建您的代码,以应对可能发生的任何错误,就像这样:

func createList(name: String, completion: @escaping (Response?, Error?) -> Void) {
    let parameters = ["name": name, "user_id": session.auth.currentUser!.uid]

    AF.request("\(url)/wishlist", method: .post, parameters: parameters, encoding: URLEncoding.default).responseDecodable(of: Response.self) { response in
        switch response.result {
        case .failure(let err):
            print(err)
            completion(nil, err)   
        case .success(let res):
            completion(res, nil)
        }
    }
}

这样称呼它:

barback.createList(name: name) { (response, error) in
    if error != nil {
        
    } else {
        
    }
}

如果你不把一个完成(...)在你的案例中。失败”它永远不会离开那里。

穆劲
2023-03-14

调用 createList 看起来更像这样:

barback.createList(name: name) { response in
    if response.status == 200 {
        // OK
    } else {
        // Error
    }
}

这解决了这个问题,因为您现在正在运行这个完成闭包-{响应在...}-其中响应是您传入的值。在这种情况下,您传入res。请参阅有关使用完成处理程序的这篇文章。

如果您确实想要一个可选的完成处理程序,以便您不总是需要包含它,您可以将定义更改为以下内容(在}中添加={_,这意味着它默认为空闭包):

func createList(name: String, completion: @escaping (Response) -> Void = { _ in })

另一种方法实际上是使闭包成为可选的:

func createList(name: String, completion: ((Response) -> Void)? = nil)

然后在方法内部需要 当您调用完成时,因为它是可选的:

completion?(res)

潘涵煦
2023-03-14

完成处理程序类似于函数返回值,但不相同。例如,比较以下函数:

/// 1. With return value
func createList(name: String) -> Response { }
/// 2. With completion handler
func createList(name: String, completion: @escaping (Response) -> Void) { }

在第一个函数中,您将立即获得返回值。

let response = barback.createList(name: name)
if response.status = 200 {
    /// trigger some UI component
}

但是,如果您对第二个函数进行同样的尝试,您将会得到< code >调用中缺少参数' completion '的参数错误。那是因为,你定义了一个< code >完成:参数标签。然而,你没有提供它,正如马特评论的那样。

将完成处理程序视为将一段代码“传递”到函数中,作为参数。您需要提供那块代码。从那块代码中,您可以访问您的响应

                                           /// pass in chunk of code here
barback.createList(name: name, completion: { response in
    /// access `response` from within block of code
    if response.status = 200 {
        /// trigger some UI component
    }
})

请注意您刚才是如何说<code>barback的。createList,而不是让result=barback.createList。这是因为在第二个函数中,带有完成处理程序的函数没有返回值()-

Swift还有一个很好的特性,称为尾随闭包语法,它允许您省略参数标签<code>completion:

barback.createList(name: name) { response in
    /// access `response` from within block of code
    if response.status = 200 {
        /// trigger some UI component
    }
}

您还可以通过使用0美元(这是我在评论中所做的)来引用闭包的第一个参数响应。但是您是使用0美元还是提供像响应这样的自定义名称取决于您,有时0美元只是更容易键入。

barback.createList(name: name) {
    /// access $0 (`response`) from within block of code
    if $0.status = 200 {
        /// trigger some UI component
    }
}
 类似资料:
  • 我有一个函数,它将闭包作为完成处理程序。它反过来调用一个也接受一个的函数。完成时,我想从第一个完成闭包中获取返回值并调用第二个传递它们的函数。 此func引发异常: 致命错误:无法打开可选的。没有人 我做错了什么?我有记录,在这种情况下没有错误。我想它试图打开错误? 谢啦

  • 我基本上想有一个可选的完成处理器,没有参数被传递回来。这是我目前掌握的情况,但显然是错误的。 我不想在完成块中传递任何参数。我只想知道网络调用何时完成,以便刷新UI。我不想在这里刷新UI,因为我希望它充当刷新数据的通用函数。我之所以希望完成处理程序是可选的,是因为有时候刷新完成后我不需要做任何事情。 我也很困惑“逃离”是什么意思。当我做这样的事情时,我通常会有它,但任何清晰都会很好。我在网上做了一

  • 问题内容: 如何快速执行Firebase的完成侦听器?它说文档中有SetValue和UpdateValue的完成列表,但没有示例。 问题答案: setValue的完成在{}块(关闭)中处理。因此,一旦尝试设置setValue,该块中的代码就会执行。如果没有错误,错误将为nil,快照将是已写入的数据。 给出结果 并打印“完成”

  • 问题内容: 我正在尝试实现自动补全功能,但是找不到在Swift中可用的示例。下面,我打算转换Ray Wenderlich的自动完成教程 和2010年的示例代码。最后,代码进行了编译,但是没有显示包含可能完成的表格,而且我没有经验来了解为什么它未被隐藏shouldChangeCharactersInRange。 问题答案: 用下面的内容替换您的函数内容。希望对您有帮助。

  • 我的完成处理程序有问题。下面是一个带有完成处理程序的函数,位于一个实用程序文件中: 我在视图控制器中调用它 输出清楚地表明该函数在运行该块之前没有等待完成: 我如何解决这个问题?

  • 我有一个关于CompletableFuture方法的问题: JavaDoc的意思是: 返回一个新的完成阶段,当此阶段正常完成时,将使用此阶段的结果作为所提供函数的参数来执行该阶段。有关异常完成的规则,请参阅完成阶段文档。 穿线呢?这将在哪个线程中执行?如果未来由线程池来完成呢?