Запустите фоновый таймер в родном модуле iOS с Objective C - React Native - PullRequest
0 голосов
/ 08 июня 2019

Мое приложение требует непрерывной работы таймера в фоновом режиме, когда приложение находится в фоновом режиме, и оно должно остановиться, когда приложение выходит на передний план.

Приложение построено с использованием React Native, а не имеет соответствующего модуля для работы в фоновом режиме.Поэтому я создал мост между React Native Javascript и Native iOS.

Я предоставляю собственный модуль ios, который может сигнализировать события в JavaScript без непосредственного вызова и передавать событие в собственный код для вызова изjavascript.

TestManager.h

//
//  TestManager.h
//
//  Created by Asbar Ali on 6/7/19.
//  Copyright © 2019 Facebook. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

NS_ASSUME_NONNULL_BEGIN

@interface TestManager : RCTEventEmitter <RCTBridgeModule>

@end

NS_ASSUME_NONNULL_END

TestManager.m

//
//  TestManager.m
//  CrockfitMobile
//
//  Created by Asbar Ali on 6/7/19.
//  Copyright © 2019 Facebook. All rights reserved.
//

#import "TestManager.h"

@implementation TestManager
{
  bool hasListeners;
}

RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents
{
  return @[@"EventReminder"];
}

// Will be called when this module's first listener is added.
-(void)startObserving {
  hasListeners = YES;
  NSLog(@"Listener added");
}

// Will be called when this module's last listener is removed, or on dealloc.
-(void)stopObserving {
  hasListeners = NO;
    NSLog(@"Listner Removed");
}

- (void)TestEventReminderReceived:(NSNotification *)notification
{
  NSString *eventName = notification.userInfo[@"name"];
  if (hasListeners) { // Only send events if anyone is listening
    [self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
  }
}

RCT_EXPORT_METHOD(timerStart:(NSString *)name location:(NSString *)location)
{
  NSLog(@"invoked by javaScript");
}

@end


следующий метод в TestManager.mвызывается из React Native (JavaScript)

RCT_EXPORT_METHOD(timerStart:(NSString *)name location:(NSString *)location)
{
  NSLog(@"invoked by javaScript");
}

Когда я добавляю следующий код в вышеупомянутый метод, NSTimer не запускается.

ПРИМЕЧАНИЕ: Это будет отлично работать в ViewControllers

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
                                       selector:@selector(updateModel:) userInfo:str repeats:YES];

Я нашел несколько ответов на это. Ответ1 Ответ2

Тогда я понимаю, что это может быть проблема с многопоточностью, и мне нужно вызвать ее в главном потоке.

  1. Как запустить таймер в подклассе RCTEventEmitter, когда приложение попадает в фоновый режим?(TestManager.m)

  2. Если мы не можем сделать это в этом модуле, как мы можем это сделать?

...