1// Copyright 2015-present 650 Industries. All rights reserved.
2
3#import "EXAppState.h"
4#import "EXScopedModuleRegistry.h"
5
6#import <UMCore/UMAppLifecycleService.h>
7#import <UMReactNativeAdapter/UMModuleRegistryHolderReactModule.h>
8#import <React/RCTAssert.h>
9#import <React/RCTBridge.h>
10#import <React/RCTEventDispatcher.h>
11#import <React/RCTUtils.h>
12
13@interface EXAppState ()
14
15@property (nonatomic, assign) BOOL isObserving;
16
17@end
18
19@implementation EXAppState
20
21+ (NSString *)moduleName { return @"RCTAppState"; }
22
23- (instancetype)init
24{
25  if (self = [super init]) {
26    _lastKnownState = @"active";
27  }
28  return self;
29}
30
31+ (BOOL)requiresMainQueueSetup
32{
33  return YES;
34}
35
36- (dispatch_queue_t)methodQueue
37{
38  return dispatch_get_main_queue();
39}
40
41- (NSDictionary *)constantsToExport
42{
43  return @{@"initialAppState": @"active"};
44}
45
46#pragma mark - Lifecycle
47
48- (NSArray<NSString *> *)supportedEvents
49{
50  return @[@"appStateDidChange", @"memoryWarning"];
51}
52
53- (void)startObserving
54{
55  _isObserving = YES;
56  [[NSNotificationCenter defaultCenter] addObserver:self
57                                           selector:@selector(handleMemoryWarning)
58                                               name:UIApplicationDidReceiveMemoryWarningNotification
59                                             object:nil];
60}
61
62- (void)stopObserving
63{
64  _isObserving = NO;
65  [[NSNotificationCenter defaultCenter] removeObserver:self];
66}
67
68#pragma mark - App Notification Methods
69
70- (void)handleMemoryWarning
71{
72  [self sendEventWithName:@"memoryWarning" body:nil];
73}
74
75- (void)setState:(NSString *)state
76{
77  if (![state isEqualToString:_lastKnownState]) {
78    _lastKnownState = state;
79    if (_isObserving) {
80      [self sendEventWithName:@"appStateDidChange"
81                         body:@{@"app_state": _lastKnownState}];
82    }
83
84    // change state on universal modules
85    // TODO: just make EXAppState a universal module implementing UMAppLifecycleService
86    id<UMAppLifecycleService> lifeCycleManager = [[[self.bridge moduleForClass:[UMModuleRegistryHolderReactModule class]] umModuleRegistry] getModuleImplementingProtocol:@protocol(UMAppLifecycleService)];
87    if ([state isEqualToString:@"background"]) {
88      [lifeCycleManager setAppStateToBackground];
89    } else if ([state isEqualToString:@"active"]) {
90      [lifeCycleManager setAppStateToForeground];
91    }
92  }
93}
94
95RCT_EXPORT_METHOD(getCurrentAppState:(RCTResponseSenderBlock)callback
96                  error:(__unused RCTResponseSenderBlock)error)
97{
98  callback(@[@{@"app_state": _lastKnownState}]);
99}
100
101@end
102