seba_sencha
seba_sencha

Reputation: 205

How to pass callback method as parameter in IOS

I will explain the need based on below example

This is the method that need to be called after an async operation

    -(void) myCallbackMethodOne: (NSString *)response
    {
        //method to be called
    }

    -(void) myCallbackMethodTwo: (NSString *)response
    {
        //method to be called
    }



    -(void) getDataFromServerWithCallback: (NSString *)requestString _Callback(CallbackMethod *) methodName
    {
        //logic to send request and 
        //to set callback method something similar to
        [setCallbackMethod  methodName]; 
    }

    -(void) onDataRecievedFromServerWithResponse: (NSString *) response //this method gets called as part of framework
    {
        [callTheCallbackMethod: response]; 
    }

A place to call the method to demonstrate the requirement

    -int main()
    {
        [getDataFromFromServerWithCallback: @"getTopNews" _Callback:myCallbackMethodOne];  //this is the requirement; I should be able to pass myCallbackMethod as argument

        [getDataFromFromServerWithCallback: @"getBusinessNews" _Callback:myCallbackMethodTwo];  //this is the requirement; I should be able to pass myCallbackMethod as argument

    }

Upvotes: 0

Views: 7889

Answers (3)

seba_sencha
seba_sencha

Reputation: 205

I got my requirement working by using selectors

-(void) myCallbackMethodOne: (NSString *)response

{

    //method to be called

}


-(void) myCallbackMethodTwo: (NSString *)response
{
    //method to be called
}



-(void) getDataFromServerWithCallback: (NSString *)requestString _Callback:(SEL) methodName _Caller(id):callingClass
{
    //write the logic here to store methodname and caller to reference variables
    //so that it will be accessible in onDataRecievedFromServerWithResponse
    //and to send the request

}

-(void) onDataRecievedFromServerWithResponse: (NSString *) response //this method gets called as part of framework
{
    [callingClass performSelector:methodName withObject:response];
}


 -int main()
{

    SEL methodOneSelctor =@selector(myCallbackMethodOne:);
    [getDataFromFromServerWithCallback: @"getTopNews" _Callback:methodOneSelctor _MethodCaller:self];  //I should be able to pass myCallbackMethod as argument

    SEL methodTwoSelctor =@selector(myCallbackMethodTwo:);
   [getDataFromFromServerWithCallback: @"getBusinessNews" _Callback:methodTwoSelctor _MethodCaller:self];  //I should be able to pass myCallbackMethod as argument

}

Upvotes: 0

trojanfoe
trojanfoe

Reputation: 122381

There are two well established patterns for this type of functionality:

1) Delegate:

@protocol ResponseDelegate
- (void)handleResponse:(NSString *)response;
@end

@interface CommsClass : NSObject
@property (weak) id<ResponseDelegate> delegate;
- (void)sendRequest:(NSString *)request;
@end

@interface CallingClass : NSObject <ResponseDelegate>
{
    CommsClass _commsClass;
}

- (void)callingCode;
@end

@interface CallingCode

- (void)callingCode
{
    _commsClass = [CommsClass new];
    _commsClass.delegate = self;
    [_commsClass sendRequest:@"Blah"];
}

- (void)handleResponse:(NSString *)response
{
    NSLog(@"Whoot: %@", response);
}

@end

2) Blocks.

typedef (^HandleResponseBlock)(NSString *response);

@interface CommsClass : NSObject
- (void)sendRequest:(NSString *)request
withCompletionBlock:(HandleResponseBlock)block;
@end

Upvotes: 1

billyklh
billyklh

Reputation: 49

For objective C, I believe you have to pass the callback using block. But for Swift, since methods are also first class citizens, we can do something like this:

func buttonDidTapped(sender: AnyObject!) {
    doSomethingWithCallback(callbackFunc: myCallback)
}

func doSomethingWithCallback(callbackFunc: (NSDictionary)->()) {
    //do something
    callbackFunc(["param": "pass any param by dynamic dictionary"])
}


func myCallback(infoDict: NSDictionary) {
    //callback implementation
}

We can define the callback and as any functions and pass it like any parameters.

For more information on using objective-c and swift in the same project, please refer to Apple document: https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/MixandMatch.html

Hope that it helps.

Upvotes: 0

Related Questions