yeet
This commit is contained in:
16
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncher.h
generated
vendored
Normal file
16
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncher.h
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright © 2019 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXUpdates/EXUpdatesUpdate.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol EXUpdatesAppLauncher
|
||||
|
||||
@property (nullable, nonatomic, strong, readonly) EXUpdatesUpdate *launchedUpdate;
|
||||
@property (nullable, nonatomic, strong, readonly) NSURL *launchAssetUrl;
|
||||
@property (nullable, nonatomic, strong, readonly) NSDictionary *assetFilesMap;
|
||||
@property (nonatomic, assign, readonly) BOOL isUsingEmbeddedAssets;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
17
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncherNoDatabase.h
generated
vendored
Normal file
17
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncherNoDatabase.h
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright © 2019 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXUpdates/EXUpdatesAppLauncher.h>
|
||||
#import <EXUpdates/EXUpdatesConfig.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EXUpdatesAppLauncherNoDatabase : NSObject <EXUpdatesAppLauncher>
|
||||
|
||||
- (void)launchUpdateWithConfig:(EXUpdatesConfig *)config;
|
||||
- (void)launchUpdateWithConfig:(EXUpdatesConfig *)config fatalError:(NSError *)error;
|
||||
+ (nullable NSString *)consumeError;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
109
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncherNoDatabase.m
generated
vendored
Normal file
109
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncherNoDatabase.m
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
// Copyright © 2019 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXUpdates/EXUpdatesAsset.h>
|
||||
#import <EXUpdates/EXUpdatesAppLauncherNoDatabase.h>
|
||||
#import <EXUpdates/EXUpdatesEmbeddedAppLoader.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
static NSString * const EXUpdatesErrorLogFile = @"expo-error.log";
|
||||
|
||||
@interface EXUpdatesAppLauncherNoDatabase ()
|
||||
|
||||
@property (nullable, nonatomic, strong, readwrite) EXUpdatesUpdate *launchedUpdate;
|
||||
@property (nullable, nonatomic, strong, readwrite) NSURL *launchAssetUrl;
|
||||
@property (nullable, nonatomic, strong, readwrite) NSMutableDictionary *assetFilesMap;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXUpdatesAppLauncherNoDatabase
|
||||
|
||||
- (void)launchUpdateWithConfig:(EXUpdatesConfig *)config
|
||||
{
|
||||
_launchedUpdate = [EXUpdatesEmbeddedAppLoader embeddedManifestWithConfig:config database:nil];
|
||||
if (_launchedUpdate) {
|
||||
if (_launchedUpdate.status == EXUpdatesUpdateStatusEmbedded) {
|
||||
NSAssert(_assetFilesMap == nil, @"assetFilesMap should be null for embedded updates");
|
||||
_launchAssetUrl = [[NSBundle mainBundle] URLForResource:EXUpdatesBareEmbeddedBundleFilename withExtension:EXUpdatesBareEmbeddedBundleFileType];
|
||||
} else {
|
||||
_launchAssetUrl = [[NSBundle mainBundle] URLForResource:EXUpdatesEmbeddedBundleFilename withExtension:EXUpdatesEmbeddedBundleFileType];
|
||||
|
||||
NSMutableDictionary *assetFilesMap = [NSMutableDictionary new];
|
||||
for (EXUpdatesAsset *asset in _launchedUpdate.assets) {
|
||||
NSURL *localUrl = [[NSBundle mainBundle] URLForResource:asset.mainBundleFilename withExtension:asset.type];
|
||||
if (localUrl && asset.key) {
|
||||
assetFilesMap[asset.key] = localUrl.absoluteString;
|
||||
}
|
||||
}
|
||||
_assetFilesMap = assetFilesMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isUsingEmbeddedAssets
|
||||
{
|
||||
return _assetFilesMap == nil;
|
||||
}
|
||||
|
||||
- (void)launchUpdateWithConfig:(EXUpdatesConfig *)config fatalError:(NSError *)error;
|
||||
{
|
||||
[self launchUpdateWithConfig:config];
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
[self _writeErrorToLog:error];
|
||||
});
|
||||
}
|
||||
|
||||
+ (nullable NSString *)consumeError;
|
||||
{
|
||||
NSString *errorLogFilePath = [[self class] _errorLogFilePath];
|
||||
NSData *data = [NSData dataWithContentsOfFile:errorLogFilePath options:kNilOptions error:nil];
|
||||
if (data) {
|
||||
NSError *err;
|
||||
if (![NSFileManager.defaultManager removeItemAtPath:errorLogFilePath error:&err]) {
|
||||
NSLog(@"Could not delete error log: %@", err.localizedDescription);
|
||||
}
|
||||
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_writeErrorToLog:(NSError *)error
|
||||
{
|
||||
NSString *serializedError = [NSString stringWithFormat:@"Expo encountered a fatal error: %@", [self _serializeError:error]];
|
||||
NSData *data = [serializedError dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NSError *err;
|
||||
if (![data writeToFile:[[self class] _errorLogFilePath] options:NSDataWritingAtomic error:&err]) {
|
||||
NSLog(@"Could not write fatal error to log: %@", error.localizedDescription);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)_serializeError:(NSError *)error
|
||||
{
|
||||
NSString *localizedFailureReason = error.localizedFailureReason;
|
||||
NSError *underlyingError = error.userInfo[NSUnderlyingErrorKey];
|
||||
|
||||
NSMutableString *serialization = [[NSString stringWithFormat:@"Time: %f\nDomain: %@\nCode: %li\nDescription: %@",
|
||||
[[NSDate date] timeIntervalSince1970] * 1000,
|
||||
error.domain,
|
||||
(long)error.code,
|
||||
error.localizedDescription] mutableCopy];
|
||||
if (localizedFailureReason) {
|
||||
[serialization appendFormat:@"\nFailure Reason: %@", localizedFailureReason];
|
||||
}
|
||||
if (underlyingError) {
|
||||
[serialization appendFormat:@"\n\nUnderlying Error:\n%@", [self _serializeError:underlyingError]];
|
||||
}
|
||||
return serialization;
|
||||
}
|
||||
|
||||
+ (NSString *)_errorLogFilePath
|
||||
{
|
||||
NSURL *applicationDocumentsDirectory = [[NSFileManager.defaultManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];
|
||||
return [[applicationDocumentsDirectory URLByAppendingPathComponent:EXUpdatesErrorLogFile] path];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
29
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncherWithDatabase.h
generated
vendored
Normal file
29
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncherWithDatabase.h
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright © 2019 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXUpdates/EXUpdatesAppLauncher.h>
|
||||
#import <EXUpdates/EXUpdatesSelectionPolicy.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^EXUpdatesAppLauncherCompletionBlock)(NSError * _Nullable error, BOOL success);
|
||||
typedef void (^EXUpdatesAppLauncherUpdateCompletionBlock)(NSError * _Nullable error, EXUpdatesUpdate * _Nullable launchableUpdate);
|
||||
|
||||
@interface EXUpdatesAppLauncherWithDatabase : NSObject <EXUpdatesAppLauncher>
|
||||
|
||||
- (instancetype)initWithConfig:(EXUpdatesConfig *)config
|
||||
database:(EXUpdatesDatabase *)database
|
||||
directory:(NSURL *)directory
|
||||
completionQueue:(dispatch_queue_t)completionQueue;
|
||||
|
||||
- (void)launchUpdateWithSelectionPolicy:(id<EXUpdatesSelectionPolicy>)selectionPolicy
|
||||
completion:(EXUpdatesAppLauncherCompletionBlock)completion;
|
||||
|
||||
+ (void)launchableUpdateWithConfig:(EXUpdatesConfig *)config
|
||||
database:(EXUpdatesDatabase *)database
|
||||
selectionPolicy:(id<EXUpdatesSelectionPolicy>)selectionPolicy
|
||||
completion:(EXUpdatesAppLauncherUpdateCompletionBlock)completion
|
||||
completionQueue:(dispatch_queue_t)completionQueue;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
288
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncherWithDatabase.m
generated
vendored
Normal file
288
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesAppLauncherWithDatabase.m
generated
vendored
Normal file
@ -0,0 +1,288 @@
|
||||
// Copyright © 2019 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXUpdates/EXUpdatesAppLauncherWithDatabase.h>
|
||||
#import <EXUpdates/EXUpdatesEmbeddedAppLoader.h>
|
||||
#import <EXUpdates/EXUpdatesDatabase.h>
|
||||
#import <EXUpdates/EXUpdatesFileDownloader.h>
|
||||
#import <EXUpdates/EXUpdatesUtils.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EXUpdatesAppLauncherWithDatabase ()
|
||||
|
||||
@property (nullable, nonatomic, strong, readwrite) EXUpdatesUpdate *launchedUpdate;
|
||||
@property (nullable, nonatomic, strong, readwrite) NSURL *launchAssetUrl;
|
||||
@property (nullable, nonatomic, strong, readwrite) NSMutableDictionary *assetFilesMap;
|
||||
|
||||
@property (nonatomic, strong) EXUpdatesConfig *config;
|
||||
@property (nonatomic, strong) EXUpdatesDatabase *database;
|
||||
@property (nonatomic, strong) NSURL *directory;
|
||||
@property (nonatomic, strong) EXUpdatesFileDownloader *downloader;
|
||||
@property (nonatomic, copy) EXUpdatesAppLauncherCompletionBlock completion;
|
||||
@property (nonatomic, strong) dispatch_queue_t completionQueue;
|
||||
|
||||
@property (nonatomic, strong) dispatch_queue_t launcherQueue;
|
||||
@property (nonatomic, assign) NSUInteger completedAssets;
|
||||
|
||||
@property (nonatomic, strong) NSError *launchAssetError;
|
||||
|
||||
@end
|
||||
|
||||
static NSString * const EXUpdatesAppLauncherErrorDomain = @"AppLauncher";
|
||||
|
||||
@implementation EXUpdatesAppLauncherWithDatabase
|
||||
|
||||
- (instancetype)initWithConfig:(EXUpdatesConfig *)config
|
||||
database:(EXUpdatesDatabase *)database
|
||||
directory:(NSURL *)directory
|
||||
completionQueue:(dispatch_queue_t)completionQueue
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_launcherQueue = dispatch_queue_create("expo.launcher.LauncherQueue", DISPATCH_QUEUE_SERIAL);
|
||||
_completedAssets = 0;
|
||||
_config = config;
|
||||
_database = database;
|
||||
_directory = directory;
|
||||
_completionQueue = completionQueue;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)launchableUpdateWithConfig:(EXUpdatesConfig *)config
|
||||
database:(EXUpdatesDatabase *)database
|
||||
selectionPolicy:(id<EXUpdatesSelectionPolicy>)selectionPolicy
|
||||
completion:(EXUpdatesAppLauncherUpdateCompletionBlock)completion
|
||||
completionQueue:(dispatch_queue_t)completionQueue
|
||||
{
|
||||
dispatch_async(database.databaseQueue, ^{
|
||||
NSError *error;
|
||||
NSArray<EXUpdatesUpdate *> *launchableUpdates = [database launchableUpdatesWithConfig:config error:&error];
|
||||
dispatch_async(completionQueue, ^{
|
||||
if (!launchableUpdates) {
|
||||
completion(error, nil);
|
||||
}
|
||||
|
||||
// We can only run an update marked as embedded if it's actually the update embedded in the
|
||||
// current binary. We might have an older update from a previous binary still listed in the
|
||||
// database with Embedded status so we need to filter that out here.
|
||||
EXUpdatesUpdate *embeddedManifest = [EXUpdatesEmbeddedAppLoader embeddedManifestWithConfig:config database:database];
|
||||
NSMutableArray<EXUpdatesUpdate *>*filteredLaunchableUpdates = [NSMutableArray new];
|
||||
for (EXUpdatesUpdate *update in launchableUpdates) {
|
||||
if (update.status == EXUpdatesUpdateStatusEmbedded) {
|
||||
if (embeddedManifest && ![update.updateId isEqual:embeddedManifest.updateId]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
[filteredLaunchableUpdates addObject:update];
|
||||
}
|
||||
|
||||
completion(nil, [selectionPolicy launchableUpdateWithUpdates:filteredLaunchableUpdates]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
- (void)launchUpdateWithSelectionPolicy:(id<EXUpdatesSelectionPolicy>)selectionPolicy
|
||||
completion:(EXUpdatesAppLauncherCompletionBlock)completion
|
||||
{
|
||||
NSAssert(!_completion, @"EXUpdatesAppLauncher:launchUpdateWithSelectionPolicy:successBlock should not be called twice on the same instance");
|
||||
_completion = completion;
|
||||
|
||||
if (!_launchedUpdate) {
|
||||
[[self class] launchableUpdateWithConfig:_config database:_database selectionPolicy:selectionPolicy completion:^(NSError * _Nullable error, EXUpdatesUpdate * _Nullable launchableUpdate) {
|
||||
if (error || !launchableUpdate) {
|
||||
if (self->_completion) {
|
||||
dispatch_async(self->_completionQueue, ^{
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary new];
|
||||
userInfo[NSLocalizedDescriptionKey] = @"No launchable updates found in database";
|
||||
if (error) {
|
||||
userInfo[NSUnderlyingErrorKey] = error;
|
||||
}
|
||||
self->_completion([NSError errorWithDomain:EXUpdatesAppLauncherErrorDomain code:1011 userInfo:userInfo], NO);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self->_launchedUpdate = launchableUpdate;
|
||||
[self _ensureAllAssetsExist];
|
||||
}
|
||||
} completionQueue:_launcherQueue];
|
||||
} else {
|
||||
[self _ensureAllAssetsExist];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isUsingEmbeddedAssets
|
||||
{
|
||||
return _assetFilesMap == nil;
|
||||
}
|
||||
|
||||
- (void)_ensureAllAssetsExist
|
||||
{
|
||||
if (_launchedUpdate.status == EXUpdatesUpdateStatusEmbedded) {
|
||||
NSAssert(_assetFilesMap == nil, @"assetFilesMap should be null for embedded updates");
|
||||
_launchAssetUrl = [[NSBundle mainBundle] URLForResource:EXUpdatesBareEmbeddedBundleFilename withExtension:EXUpdatesBareEmbeddedBundleFileType];
|
||||
|
||||
dispatch_async(self->_completionQueue, ^{
|
||||
self->_completion(self->_launchAssetError, self->_launchAssetUrl != nil);
|
||||
self->_completion = nil;
|
||||
});
|
||||
return;
|
||||
} else if (_launchedUpdate.status == EXUpdatesUpdateStatusDevelopment) {
|
||||
dispatch_async(self->_completionQueue, ^{
|
||||
self->_completion(nil, YES);
|
||||
self->_completion = nil;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
_assetFilesMap = [NSMutableDictionary new];
|
||||
|
||||
if (_launchedUpdate) {
|
||||
NSUInteger totalAssetCount = _launchedUpdate.assets.count;
|
||||
for (EXUpdatesAsset *asset in _launchedUpdate.assets) {
|
||||
NSURL *assetLocalUrl = [_directory URLByAppendingPathComponent:asset.filename];
|
||||
[self _ensureAssetExists:asset withLocalUrl:assetLocalUrl completion:^(BOOL exists) {
|
||||
dispatch_assert_queue(self->_launcherQueue);
|
||||
self->_completedAssets++;
|
||||
|
||||
if (exists) {
|
||||
if (asset.isLaunchAsset) {
|
||||
self->_launchAssetUrl = assetLocalUrl;
|
||||
} else {
|
||||
if (asset.key) {
|
||||
self->_assetFilesMap[asset.key] = assetLocalUrl.absoluteString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self->_completedAssets == totalAssetCount) {
|
||||
dispatch_async(self->_completionQueue, ^{
|
||||
self->_completion(self->_launchAssetError, self->_launchAssetUrl != nil);
|
||||
self->_completion = nil;
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_ensureAssetExists:(EXUpdatesAsset *)asset withLocalUrl:(NSURL *)assetLocalUrl completion:(void (^)(BOOL exists))completion
|
||||
{
|
||||
[self _checkExistenceOfAsset:asset withLocalUrl:assetLocalUrl completion:^(BOOL exists) {
|
||||
if (exists) {
|
||||
completion(YES);
|
||||
return;
|
||||
}
|
||||
|
||||
[self _maybeCopyAssetFromMainBundle:asset withLocalUrl:assetLocalUrl completion:^(BOOL success, NSError * _Nullable error) {
|
||||
if (success) {
|
||||
completion(YES);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
NSLog(@"Error copying embedded asset %@: %@", asset.key, error.localizedDescription);
|
||||
}
|
||||
|
||||
[self _downloadAsset:asset withLocalUrl:assetLocalUrl completion:^(NSError * _Nullable error, EXUpdatesAsset *asset, NSURL *assetLocalUrl) {
|
||||
if (error) {
|
||||
if (asset.isLaunchAsset) {
|
||||
// save the error -- since this is the launch asset, the launcher will fail
|
||||
// so we want to propagate this error
|
||||
self->_launchAssetError = error;
|
||||
}
|
||||
NSLog(@"Failed to load missing asset %@: %@", asset.key, error.localizedDescription);
|
||||
completion(NO);
|
||||
} else {
|
||||
// attempt to update the database record to match the newly downloaded asset
|
||||
// but don't block launching on this
|
||||
dispatch_async(self->_database.databaseQueue, ^{
|
||||
NSError *error;
|
||||
[self->_database updateAsset:asset error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Could not write data for downloaded asset to database: %@", error.localizedDescription);
|
||||
}
|
||||
});
|
||||
|
||||
completion(YES);
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)_checkExistenceOfAsset:(EXUpdatesAsset *)asset withLocalUrl:(NSURL *)assetLocalUrl completion:(void (^)(BOOL exists))completion
|
||||
{
|
||||
dispatch_async([EXUpdatesFileDownloader assetFilesQueue], ^{
|
||||
BOOL exists = [NSFileManager.defaultManager fileExistsAtPath:[assetLocalUrl path]];
|
||||
dispatch_async(self->_launcherQueue, ^{
|
||||
completion(exists);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
- (void)_maybeCopyAssetFromMainBundle:(EXUpdatesAsset *)asset
|
||||
withLocalUrl:(NSURL *)assetLocalUrl
|
||||
completion:(void (^)(BOOL success, NSError * _Nullable error))completion
|
||||
{
|
||||
EXUpdatesUpdate *embeddedManifest = [EXUpdatesEmbeddedAppLoader embeddedManifestWithConfig:_config database:_database];
|
||||
if (embeddedManifest) {
|
||||
EXUpdatesAsset *matchingAsset;
|
||||
for (EXUpdatesAsset *embeddedAsset in embeddedManifest.assets) {
|
||||
if ([embeddedAsset.key isEqualToString:asset.key]) {
|
||||
matchingAsset = embeddedAsset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matchingAsset && matchingAsset.mainBundleFilename) {
|
||||
dispatch_async([EXUpdatesFileDownloader assetFilesQueue], ^{
|
||||
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:matchingAsset.mainBundleFilename ofType:matchingAsset.type];
|
||||
NSError *error;
|
||||
BOOL success = [NSFileManager.defaultManager copyItemAtPath:bundlePath toPath:[assetLocalUrl path] error:&error];
|
||||
dispatch_async(self->_launcherQueue, ^{
|
||||
completion(success, error);
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
completion(NO, nil);
|
||||
}
|
||||
|
||||
- (void)_downloadAsset:(EXUpdatesAsset *)asset
|
||||
withLocalUrl:(NSURL *)assetLocalUrl
|
||||
completion:(void (^)(NSError * _Nullable error, EXUpdatesAsset *asset, NSURL *assetLocalUrl))completion
|
||||
{
|
||||
if (!asset.url) {
|
||||
completion([NSError errorWithDomain:EXUpdatesAppLauncherErrorDomain code:1007 userInfo:@{NSLocalizedDescriptionKey: @"Failed to download asset with no URL provided"}], asset, assetLocalUrl);
|
||||
}
|
||||
dispatch_async([EXUpdatesFileDownloader assetFilesQueue], ^{
|
||||
[self.downloader downloadFileFromURL:asset.url toPath:[assetLocalUrl path] successBlock:^(NSData *data, NSURLResponse *response) {
|
||||
dispatch_async(self->_launcherQueue, ^{
|
||||
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
asset.headers = ((NSHTTPURLResponse *)response).allHeaderFields;
|
||||
}
|
||||
asset.contentHash = [EXUpdatesUtils sha256WithData:data];
|
||||
asset.downloadTime = [NSDate date];
|
||||
completion(nil, asset, assetLocalUrl);
|
||||
});
|
||||
} errorBlock:^(NSError *error, NSURLResponse *response) {
|
||||
dispatch_async(self->_launcherQueue, ^{
|
||||
completion(error, asset, assetLocalUrl);
|
||||
});
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (EXUpdatesFileDownloader *)downloader
|
||||
{
|
||||
if (!_downloader) {
|
||||
_downloader = [[EXUpdatesFileDownloader alloc] initWithUpdatesConfig:_config];
|
||||
}
|
||||
return _downloader;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
15
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesSelectionPolicy.h
generated
vendored
Normal file
15
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesSelectionPolicy.h
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright © 2019 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXUpdates/EXUpdatesUpdate.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol EXUpdatesSelectionPolicy
|
||||
|
||||
- (nullable EXUpdatesUpdate *)launchableUpdateWithUpdates:(NSArray<EXUpdatesUpdate *> *)updates;
|
||||
- (NSArray<EXUpdatesUpdate *> *)updatesToDeleteWithLaunchedUpdate:(EXUpdatesUpdate *)launchedUpdate updates:(NSArray<EXUpdatesUpdate *> *)updates;
|
||||
- (BOOL)shouldLoadNewUpdate:(nullable EXUpdatesUpdate *)newUpdate withLaunchedUpdate:(nullable EXUpdatesUpdate *)launchedUpdate;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
14
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesSelectionPolicyNewest.h
generated
vendored
Normal file
14
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesSelectionPolicyNewest.h
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright © 2019 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXUpdates/EXUpdatesSelectionPolicy.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EXUpdatesSelectionPolicyNewest : NSObject <EXUpdatesSelectionPolicy>
|
||||
|
||||
- (instancetype)initWithRuntimeVersion:(NSString *)runtimeVersion;
|
||||
- (instancetype)initWithRuntimeVersions:(NSArray<NSString *> *)runtimeVersions;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
83
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesSelectionPolicyNewest.m
generated
vendored
Normal file
83
node_modules/expo-updates/ios/EXUpdates/AppLauncher/EXUpdatesSelectionPolicyNewest.m
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright © 2019 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXUpdates/EXUpdatesConfig.h>
|
||||
#import <EXUpdates/EXUpdatesSelectionPolicyNewest.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EXUpdatesSelectionPolicyNewest ()
|
||||
|
||||
@property (nonatomic, strong) NSArray<NSString *> *runtimeVersions;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXUpdatesSelectionPolicyNewest
|
||||
|
||||
- (instancetype)initWithRuntimeVersions:(NSArray<NSString *> *)runtimeVersions
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_runtimeVersions = runtimeVersions;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRuntimeVersion:(NSString *)runtimeVersion
|
||||
{
|
||||
return [self initWithRuntimeVersions:@[runtimeVersion]];
|
||||
}
|
||||
|
||||
- (nullable EXUpdatesUpdate *)launchableUpdateWithUpdates:(NSArray<EXUpdatesUpdate *> *)updates
|
||||
{
|
||||
EXUpdatesUpdate *runnableUpdate;
|
||||
NSDate *runnableUpdateCommitTime;
|
||||
for (EXUpdatesUpdate *update in updates) {
|
||||
if (![_runtimeVersions containsObject:update.runtimeVersion]) {
|
||||
continue;
|
||||
}
|
||||
NSDate *commitTime = update.commitTime;
|
||||
if (!runnableUpdateCommitTime || [runnableUpdateCommitTime compare:commitTime] == NSOrderedAscending) {
|
||||
runnableUpdate = update;
|
||||
runnableUpdateCommitTime = commitTime;
|
||||
}
|
||||
}
|
||||
return runnableUpdate;
|
||||
}
|
||||
|
||||
- (NSArray<EXUpdatesUpdate *> *)updatesToDeleteWithLaunchedUpdate:(EXUpdatesUpdate *)launchedUpdate updates:(NSArray<EXUpdatesUpdate *> *)updates
|
||||
{
|
||||
if (!launchedUpdate) {
|
||||
return @[];
|
||||
}
|
||||
|
||||
NSMutableArray<EXUpdatesUpdate *> *updatesToDelete = [NSMutableArray new];
|
||||
// keep the launched update and one other, the next newest, to be safe and make rollbacks faster
|
||||
EXUpdatesUpdate *nextNewestUpdate;
|
||||
for (EXUpdatesUpdate *update in updates) {
|
||||
if ([launchedUpdate.commitTime compare:update.commitTime] == NSOrderedDescending) {
|
||||
[updatesToDelete addObject:update];
|
||||
if (!nextNewestUpdate || [update.commitTime compare:nextNewestUpdate.commitTime] == NSOrderedDescending) {
|
||||
nextNewestUpdate = update;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nextNewestUpdate) {
|
||||
[updatesToDelete removeObject:nextNewestUpdate];
|
||||
}
|
||||
return updatesToDelete;
|
||||
}
|
||||
|
||||
- (BOOL)shouldLoadNewUpdate:(nullable EXUpdatesUpdate *)newUpdate withLaunchedUpdate:(nullable EXUpdatesUpdate *)launchedUpdate
|
||||
{
|
||||
if (!newUpdate) {
|
||||
return false;
|
||||
}
|
||||
if (!launchedUpdate) {
|
||||
return true;
|
||||
}
|
||||
return [launchedUpdate.commitTime compare:newUpdate.commitTime] == NSOrderedAscending;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
Reference in New Issue
Block a user