简体   繁体   English

如何在swift中使用块/闭包

[英]How to use block/closure in swift

In one of my app I have used block for webservice calling and getting response. 在我的一个应用程序中,我使用了块进行Web服务调用并获得响应。 Now I want to write this app in swift, but I am getting trouble to use blocks/Closure in Swift. 现在我想在swift中编写这个应用程序,但是我在Swift中使用blocks / Closure时遇到了麻烦。 Here is my objective C code which I want to migrate in swift: 这是我想要在swift中迁移的客观C代码:

calling a class method of Communicator 调用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
}];

in communicator class 在传播者课堂上

-(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);
   }
}

For Swift. 对于斯威夫特。 Use AnyObject for id objc type. 对id id objc类型使用AnyObject。

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)
    }
}

UPDATE: An example when you want call web service . 更新:您需要调用web service的示例。 See code below 见下面的代码

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
}

Your code might look like this: 您的代码可能如下所示:

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) {

}

I replaced NSDictionary with [String : AnyObject] . 我用[String : AnyObject]替换了NSDictionary If you can replace any of the uses of AnyObject with more specific types, your code will be cleaner and more stable. 如果您可以使用更具体的类型替换AnyObject任何用法, AnyObject您的代码将更清晰,更稳定。

For Swift Closures we have to use ( ) -> ( ) 对于Swift Closures,我们必须使用( ) -> ( )

For example: 例如:

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

}

You can call it as: 您可以将其命名为:

yourFunction({(response) -> Void in
    // Success
}) { (error) -> Void in
    // Handle Errors
}

Hope it will help you to create Closures with your requirements. 希望它能帮助您根据自己的要求创建Closures。

In the communicator class the method that cals the webservice would be defined something like this depending on the type of object you want to return 在communicator类中,根据您要返回的对象类型,将定义类似于此的Web服务的方法

func performRequest(serviceName: NSString, methodName: NSString,paramaters:NSDictionary, successblock: (String)->(), failureBlock: () -> ()) {
    if(callSuccess) {
        successblock("Success")
    } else {
       failureBlock() 
}

We define the success and failure blocks types as by their function signatures in the case above success is defined as a method that takes a string as an input parameter and returns nothing so we can then call successBlock passing in a string. 我们定义成功和失败块类型,因为它们的函数签名在上面的情况下成功被定义为一个方法,它将一个字符串作为输入参数并且不返回任何内容,因此我们可以调用successBlock传入一个字符串。 The failure block is defined above as a block that takes no parameters and returns nothing. 上面将故障块定义为不带参数且不返回任何参数的块。

To call this method 要调用此方法

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)
}

Finally to call this 最后打电话给这个

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

})

For the completion block we define a variable returnedString to allow us to manipulate that input parameter (in the above example it would be the string "Success"). 对于完成块,我们定义一个变量returnedString,以允许我们操作该输入参数(在上面的例子中,它将是字符串“Success”)。 I assume your data is not just returning a string though so you will probably need to play around with they type depending on what your service returns. 我假设你的数据不仅仅是返回一个字符串,所以你可能需要根据你的服务返回来输入它们。

Also here I tried to match your method signatures by using NSString and NSDictionary though depending on your needs the Swift equivalents String and [String: AnyObject] could be more appropriate. 此外,我尝试使用NSString和NSDictionary匹配您的方法签名,但根据您的需要,Swift等效String和[String:AnyObject]可能更合适。

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)")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM