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