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