1// Copyright 2015-present 650 Industries. All rights reserved. 2 3#if __has_include(<EXFileSystem/EXFileSystem.h>) 4#import "EXScopedFileSystemModule.h" 5 6// TODO @sjchmiela: Should this be versioned? It is only used in detached scenario. 7NSString * const EXShellManifestResourceName = @"shell-app-manifest"; 8 9@implementation EXScopedFileSystemModule 10 11- (instancetype)initWithExperienceId:(NSString *)experienceId andConstantsBinding:(EXConstantsBinding *)constantsBinding 12{ 13 NSString *escapedExperienceId = [EXScopedFileSystemModule escapedResourceName:experienceId]; 14 15 NSString *mainDocumentDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; 16 NSString *exponentDocumentDirectory = [mainDocumentDirectory stringByAppendingPathComponent:@"ExponentExperienceData"]; 17 NSString *experienceDocumentDirectory = [[exponentDocumentDirectory stringByAppendingPathComponent:escapedExperienceId] stringByStandardizingPath]; 18 19 NSString *mainCachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; 20 NSString *exponentCachesDirectory = [mainCachesDirectory stringByAppendingPathComponent:@"ExponentExperienceData"]; 21 NSString *experienceCachesDirectory = [[exponentCachesDirectory stringByAppendingPathComponent:escapedExperienceId] stringByStandardizingPath]; 22 23 if (![@"expo" isEqualToString:constantsBinding.appOwnership]) { 24 return [super init]; 25 } 26 27 return [super initWithDocumentDirectory:experienceDocumentDirectory 28 cachesDirectory:experienceCachesDirectory 29 bundleDirectory:nil]; 30} 31 32- (NSDictionary *)constantsToExport 33{ 34 NSMutableDictionary *constants = [[NSMutableDictionary alloc] initWithDictionary:[super constantsToExport]]; 35 constants[@"bundledAssets"] = [self bundledAssets] ?: [NSNull null]; 36 return constants; 37} 38 39+ (NSString *)escapedResourceName:(NSString *)name 40{ 41 NSString *charactersToEscape = @"!*'();:@&=+$,/?%#[]"; 42 NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet]; 43 return [name stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters]; 44} 45 46- (NSArray<NSString *> *)bundledAssets 47{ 48 static NSArray<NSString *> *bundledAssets = nil; 49 static dispatch_once_t once; 50 dispatch_once(&once, ^{ 51 NSString *manifestBundlePath = [[NSBundle mainBundle] pathForResource:EXShellManifestResourceName ofType:@"json"]; 52 NSData *data = [NSData dataWithContentsOfFile:manifestBundlePath]; 53 if (data.length == 0) { 54 return; 55 } 56 __block NSError *error; 57 id manifest = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 58 if (error) { 59 UMLogError(@"Error parsing bundled manifest: %@", error); 60 return; 61 } 62 bundledAssets = manifest[@"bundledAssets"]; 63 }); 64 return bundledAssets; 65} 66 67@end 68#endif 69