mattermost-mobile/ios/Mattermost/MattermostManaged.m
Elias Nahum 30d4aa2a3e
Build Improvements (#4884)
* Use AppGroupId from Info.plists instead of hardcoded constant

* Update script, ci & Makefile

* Update Cocoapods to 1.9.3

* Split android builds using ABI filters

* Update Fastlane deps & build scripts

* Update CI to use latests scripts

* Display app version & build number in select server screen

* Make generate scripts compatible with node < 12

* Build scripts

* add build script to package.json

* Update to use bundler 2.1.4 and CI with Xcode 12

* Fix script name for build:ios-unsigned

* Fix RN iOS scripts

* Update CI pods-dependencies step

* Add pipefail to android executor

* Update Fastlane

* Fix type in postinstall script

* update android executor and set TERM

* Fix S3 bucket name variable

* Apply suggestions from code review

Co-authored-by: Miguel Alatzar <migbot@users.noreply.github.com>

* Fix master unit tests

* use requireActual in jest setup

* Jest setup to use react instead of React

Co-authored-by: Miguel Alatzar <migbot@users.noreply.github.com>
2020-10-15 22:09:36 -03:00

189 lines
5.7 KiB
Objective-C

//
// MattermostManaged.m
// Mattermost
//
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
//
#import "MattermostManaged.h"
#import <LocalAuthentication/LocalAuthentication.h>
#import <UploadAttachments/MMMConstants.h>
@implementation MattermostManaged {
bool hasListeners;
}
RCT_EXPORT_MODULE();
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
- (void)startObserving {
hasListeners = YES;
}
- (void)stopObserving {
hasListeners = NO;
}
- (BOOL)hasSafeAreaInsets {
UIView *rootView = nil;
UIApplication *sharedApplication = RCTSharedApplication();
if (sharedApplication) {
UIWindow *window = RCTSharedApplication().keyWindow;
if (window) {
UIViewController *rootViewController = window.rootViewController;
if (rootViewController) {
rootView = rootViewController.view;
}
}
}
UIEdgeInsets safeAreaInsets = [self safeAreaInsetsForView:rootView];
return safeAreaInsets.bottom > 0;
}
- (UIEdgeInsets)safeAreaInsetsForView:(UIView *)view {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
if (@available(iOS 11.0, *)) {
if (view) {
return view.safeAreaInsets;
}
}
#endif
UIEdgeInsets safeAreaInsets = UIEdgeInsetsMake(0, 0, 0, 0);
if (view) {
return safeAreaInsets;
}
return safeAreaInsets;
}
-(NSString *)appGroupId {
NSBundle *bundle = [NSBundle mainBundle];
NSString *appGroupId = [bundle objectForInfoDictionaryKey:@"AppGroupIdentifier"];
return appGroupId;
}
- (NSDictionary *)constantsToExport {
return @{
@"hasSafeAreaInsets": @([self hasSafeAreaInsets]),
@"appGroupIdentifier": [self appGroupId]
};
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:NSUserDefaultsDidChangeNotification];
}
- (NSArray<NSString *> *)supportedEvents
{
return @[@"managedConfigDidChange"];
}
- (instancetype)init {
self = [super init];
if (self) {
_sharedUserDefaults = [[NSUserDefaults alloc] initWithSuiteName:[self appGroupId]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedConfigDidChange:) name:@"managedConfigDidChange" object:nil];
[[NSNotificationCenter defaultCenter] addObserverForName:NSUserDefaultsDidChangeNotification
object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[self remoteConfigChanged];
}];
}
return self;
}
+ (void)sendConfigChangedEvent {
[[NSNotificationCenter defaultCenter] postNotificationName:@"managedConfigDidChange"
object:self
userInfo:nil];
}
// The Managed app configuration dictionary pushed down from an MDM server are stored in this key.
static NSString * const configurationKey = @"com.apple.configuration.managed";
// The dictionary that is sent back to the MDM server as feedback must be stored in this key.
static NSString * const feedbackKey = @"com.apple.feedback.managed";
- (void)managedConfigDidChange:(NSNotification *)notification
{
NSDictionary *response = [[NSUserDefaults standardUserDefaults] dictionaryForKey:configurationKey];
if (hasListeners) {
@try {
[self sendEventWithName:@"managedConfigDidChange" body:response];
} @catch (NSException *exception) {
NSLog(@"Error sending event managedConfigDidChange to JS details=%@", exception.reason);
}
}
}
- (void) remoteConfigChanged {
NSDictionary *response = [[NSUserDefaults standardUserDefaults] dictionaryForKey:configurationKey];
NSDictionary *group = [self.sharedUserDefaults dictionaryForKey:configurationKey];
if (response && ![response isEqualToDictionary:group]) {
// copies the managed configuration so it is accessible in the Extensions
[self.sharedUserDefaults setObject:response forKey:configurationKey];
}
if (hasListeners) {
@try {
[self sendEventWithName:@"managedConfigDidChange" body:response];
} @catch (NSException *exception) {
NSLog(@"Error sending event managedConfigDidChange to JS details=%@", exception.reason);
}
}
}
RCT_EXPORT_METHOD(getConfig:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSDictionary *response = [[NSUserDefaults standardUserDefaults] dictionaryForKey:configurationKey];
if (response) {
resolve(response);
}
else {
resolve(@{});
}
}
RCT_EXPORT_METHOD(isRunningInSplitView:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
BOOL isRunningInFullScreen = CGRectEqualToRect(
[UIApplication sharedApplication].delegate.window.frame,
[UIApplication sharedApplication].delegate.window.screen.bounds);
resolve(@{
@"isSplitView": @(!isRunningInFullScreen)
});
}
RCT_EXPORT_METHOD(quitApp)
{
exit(0);
}
RCT_EXPORT_METHOD(supportsFaceId:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
LAContext *context = [[LAContext alloc] init];
NSError *error;
// context.biometryType is initialized when canEvaluatePolicy, regardless of the error or return value
[context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error];
resolve(@{
@"supportsFaceId": @(context.biometryType == LABiometryTypeFaceID && @available(iOS 11.0, *))
});
}
@end