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