bsorrentino / cordova-broadcaster

Cordova Plugin to allow message exchange between javascript and native (and viceversa)
MIT License
113 stars 53 forks source link

addEventListner does not get called back in ios #21

Closed Prabuganesan closed 6 years ago

Prabuganesan commented 6 years ago

This is my code in ionic.

constructor(public navCtrl: NavController,public broadcaster: Broadcaster,private platform: Platform) 
{
   this.platform.ready().then(() => {
     console.log('Ready')
     this.broadcaster.addEventListener('postevent')
       .subscribe((Event) => console.log('After post ionic'));

      this.broadcaster.fireNativeEvent('eventName', {}).then(() => console.log('After fire ionic'));
   });

And i have add following code in native side. In MainViewController

 (void)viewDidLoad
{
    [super viewDidLoad];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(navigateFromPlugin) name:@"eventName" object:nil];
    // Do any additional setup after loading the view from its nib.
}
-(void)navigateFromPlugin
{
    NSLog(@"Print Native **************");

    [[NSNotificationCenter defaultCenter] postNotificationName:@"postevent" object:self];

}

This code not working. 'After post ionic' log not printed.

bsorrentino commented 6 years ago

Hi

  1. Are you using last version 2.2.1 ?
  2. you don't see log 'After post ionic', but do you see "Print Native **" ?
Prabuganesan commented 6 years ago

Hi, Ya I used latest version. I see Print Native **. But not 'After post ionic' in log.

If I change my code like this, it will work. But why?

- (void)viewDidLoad
{
    [super viewDidLoad];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(navigateFromPlugin) name:@"eventName" object:nil];

    // Do any additional setup after loading the view from its nib.
}
-(void)targetMethod
{
    NSLog(@"Timer called");

    [[NSNotificationCenter defaultCenter] postNotificationName:@"postevent" object:self];

}
-(void)navigateFromPlugin
{
    NSLog(@"Print Native **************");

    [NSTimer scheduledTimerWithTimeInterval:1.0
                                     target:self
                                   selector:@selector(targetMethod)
                                   userInfo:nil
                                    repeats:NO];

}
bsorrentino commented 6 years ago

Seems a problem related to workflow synchronization.

Probably the navigateFromPlugin is called before plugin register the native listener.

Let me know if it is possible

Prabuganesan commented 6 years ago

Approximately how much time taken for plugin register the native listener. Because I change the timer interval to 0, that time also work.

bsorrentino commented 6 years ago

I think that is a problem due the Gand Central Dispatch (GCD)

Try this:

 dispatch_async(dispatch_get_main_queue(), ^{ 
   [[NSNotificationCenter defaultCenter] postNotificationName:@"postevent" object:self];
 });

and let me know

Prabuganesan commented 6 years ago

Already I tried this. But not working.

bsorrentino commented 6 years ago

the question is ... what NSTimer do ?

I've to investigate

Prabuganesan commented 6 years ago

ok..

bsorrentino commented 6 years ago

Is it possible share the code in order I could replicate the problem ?

Prabuganesan commented 6 years ago

Here I attache my project. Please check this. ionic-native-listioner.zip

bsorrentino commented 6 years ago

thx for sharing

Prabuganesan commented 6 years ago

Thanks for your response. Please fix this bug ASAP.

bsorrentino commented 6 years ago

I've understood the problem

The javascript method this.broadcaster.addEventListener is asynchronous (i.e. add listener after cordova exec success) so the subsequent call to this.broadcaster.fireNativeEvent is performed while the listener is not subscribed yet

To remove this condition I have to rethink the API and, due that your use case is not the most common one, I'll suggest you to use the simple work around below

   this.platform.ready().then(() => {
       console.log('Ready');

       this.broadcaster.addEventListener('postevent')
        .subscribe( (event) => console.log('After post ionic') );

        setTimeout( ()=> {
          this.broadcaster.fireNativeEvent('eventName', {})
                  .then(() => console.log('After fire ionic'));
        },0);

    });
Prabuganesan commented 6 years ago

ok thanks @bsorrentino

bsorrentino commented 6 years ago

Thanks you for feedbacks

Hope this issue don't discourage you to use plugin