如何在Swift中使用块/闭包

6

我使用块来调用webservice并获取响应的方式开发了一个应用。现在我想用Swift编写这个应用,但是我无法在Swift中使用块/闭包。以下是我要将其迁移到Swift的Objective-C代码:

调用Communicator的类方法

[[Communicator sharedInstance]callWebService:WS_LOGIN withMethod:POST_METHOD andParams:params showLoader:YES completionBlockSuccess:^(id obj) {
   //Do play with data
}completionBlockFailiure:^(id obj) {
   //Show alert with error
}];

在通信类中

-(void)callWebService:(NSString *)serviceName withMethod:(NSString *)methodName andParams:(NSDictionary *)params showLoader:(BOOL)showLoader completionBlockSuccess:(void (^)(id))aBlock completionBlockFailiure:(void (^)(id))aFailBlock
{
   if (showLoader) {
   // show loader
   }
   [self performRequestWithServiceName:serviceName method:methodName andParams:params successblock:aBlock failureblock:aFailBlock];
}

- (void)performRequestWithServiceName:(NSString *)serviceName method:(NSString*)methodName andParams:(NSDictionary*)params
                 successblock:(void (^)(id obj))successBlock
                 failureblock:(void (^)(id obj))failBlock {
   if(callSuceess){
      successBlock(@"Success");
   }else{
      successBlock(nil);
   }
}
5个回答

4

对于Swift语言, 使用AnyObject类型来代替id objc类型。

func callWebservice (serviceName: String, withMethod method: String, andParams params: NSDictionary, showLoader loader: Bool, completionBlockSuccess aBlock: ((AnyObject) -> Void), andFailureBlock failBlock: ((AnyObject) -> Void)) {
    if loader {
        // Show loader
    }

    performRequestWithServiceName(serviceName, method: method, andParams: params, success: aBlock, failure: failBlock)
}

func performRequestWithServiceName(serviceName: String, method methodName: String, andParams params: NSDictionary, success successBlock: ((AnyObject) -> Void), failure failureBlock: ((AnyObject) -> Void)) {
    if callSuceess {
        successBlock("Success")
    }else {
        successBlock(nil)
    }
}

更新:当您需要调用web服务时的示例。请参见下面的代码。
callWebservice("your-service-name", withMethod: "your-method", andParams: ["your-dic-key": "your dict value"], showLoader: true/*or false*/, completionBlockSuccess: { (success) -> Void in
    // your successful handle
}) { (failure) -> Void in
    // your failure handle
}

1
很好 +1 完整回答。 - Ashish Kakkad
1
@ Ashish Kakkad。谢谢 - Long Pham
@longpham,你能帮我在视图控制器中调用callWebservice方法吗?我在Swift中设置闭包参数时遇到了麻烦。提前致谢。 - Mayank Jain
1
@Mayank Jain。在这里使用闭包进行教程:http://goshdarnclosuresyntax.com/。我刚刚更新了你的请求的答案。 - Long Pham

3
您的代码可能如下所示:
func callWebService(serviceName: String, method: String, params: [String : AnyObject], showLoader: Bool, success: (responseObject: AnyObject) -> Void, failure: (responseObject: AnyObject) -> Void) {
    if showLoader {
        // show loader
    }

    performRequest(serviceName, method: method, params: params, success: success, failure: failure)
}

func performRequest(serviceName: String, method: String, params: [String : AnyObject], success: (responseObject: AnyObject) -> Void, failure: (responseObject: AnyObject) -> Void) {

}

我把NSDictionary替换成了[String : AnyObject]。如果你能用更具体的类型替换AnyObject的任何用法,你的代码将更加清晰和稳定。


2

对于Swift 闭包,我们需要使用( ) -> ( )

例如:

func yourFunction(success: (response: AnyObject!) -> Void, failure: (error: NSError?) -> Void) {

}

你可以称之为:
yourFunction({(response) -> Void in
    // Success
}) { (error) -> Void in
    // Handle Errors
}

希望这能帮助你按照需求创建闭包。

我猜在调用函数时有一些语法错误。 - Mayank Jain
@MayankJain 哦!已更新答案。希望对你有用。 - Ashish Kakkad

1
在通讯器类中,调用webservice的方法会根据你想要返回的对象类型定义如下。
func performRequest(serviceName: NSString, methodName: NSString,paramaters:NSDictionary, successblock: (String)->(), failureBlock: () -> ()) {
    if(callSuccess) {
        successblock("Success")
    } else {
       failureBlock() 
}

我们根据它们在上述情况中的函数签名定义成功和失败块类型。在上述情况中,成功被定义为一个接受字符串作为输入参数并返回空值的方法,因此我们可以调用successBlock并传入一个字符串。失败块在上面被定义为一个不带参数且返回空值的块。
要调用这个方法:
func callWebService(serviceName: NSString, method: NSString and parameters: NSDictionary, showLoader: Bool, completionBlockSuccess:(String) -> (), completionBlockFailiure:() -> ()) {
    if (showLoader) {
    // show loader
    }
    performRequest(serviceName: serviceName, methodName: method, parameters, successBlock:completionBlockSuccess, failureBlock: completionBlockFailiure)
}

最终调用此函数。
Communicator.sharedInstance().callWebService(serviceName: WS_LOGIN , method: POST_METHOD and parameters: params, showLoader: true, completionBlockSuccess:{ returnedString in

     //Do play with data

}, completionBlockFailiure:{ 

    //Show alert with error

})

对于完成块,我们定义了一个名为returnedString的变量,以便我们可以操纵输入参数(在上面的示例中,它将是字符串“Success”)。但我假设您的数据不仅返回一个字符串,因此您可能需要根据服务返回的内容类型进行调整。
此外,在这里我尝试通过使用NSString和NSDictionary来匹配您的方法签名,但根据您的需求,Swift等效的String和[String:AnyObject]可能更合适。

0
func processingWithAnyObject(input: String, completion: @escaping (_ result: AnyObject) -> Void) {
    ...
    completion(response.result.value! as AnyObject)
}

processingWithAnyObject("inputString") {
    (result: AnyObject) in
    print("back to caller: \(result)")
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接