6

In one of my app I have used block for webservice calling and getting response. Now I want to write this app in swift, but I am getting trouble to use blocks/Closure in Swift. Here is my objective C code which I want to migrate in swift:

calling a class method of 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);
   }
}

5 Answers 5

4

For Swift. Use AnyObject for id objc type.

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. 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
}
Sign up to request clarification or add additional context in comments.

4 Comments

Great +1 For complete answer
@ Ashish Kakkad. Thanks
@longpham can you please help me in calling callWebservice method from my viewcontroller ? I am getting trouble in setting parameter with closure in swift. Thanks in advance.
@Mayank Jain. Take a tutorial with closure here: goshdarnclosuresyntax.com . And I just update my answer for your request.
3

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]. If you can replace any of the uses of AnyObject with more specific types, your code will be cleaner and more stable.

Comments

2

For Swift Closures we have to use ( ) -> ( )

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.

2 Comments

I guess there is some syntax error in calling function.
@MayankJain Oh!. Updated answer. hope it will work for you
1

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

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

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.