1 // Copyright 2015-present 650 Industries. All rights reserved. 2 3 #import <Foundation/Foundation.h> 4 #import "EXAppFetcher.h" 5 #import "EXCachedResource.h" 6 7 @class EXKernelAppRecord; 8 @class EXAbstractLoader; 9 @class EXManifestsManifest; 10 11 NS_ASSUME_NONNULL_BEGIN 12 13 FOUNDATION_EXPORT NSTimeInterval const kEXAppLoaderDefaultTimeout; 14 FOUNDATION_EXPORT NSTimeInterval const kEXJSBundleTimeout; 15 16 typedef enum EXAppLoaderStatus { 17 kEXAppLoaderStatusNew, 18 kEXAppLoaderStatusHasManifest, // possibly optimistic 19 kEXAppLoaderStatusHasManifestAndBundle, 20 kEXAppLoaderStatusError, 21 } EXAppLoaderStatus; 22 23 typedef enum EXAppLoaderRemoteUpdateStatus { 24 kEXAppLoaderRemoteUpdateStatusChecking, 25 kEXAppLoaderRemoteUpdateStatusDownloading 26 } EXAppLoaderRemoteUpdateStatus; 27 28 @protocol EXAppLoaderDelegate <NSObject> 29 30 - (void)appLoader:(EXAbstractLoader *)appLoader didLoadOptimisticManifest:(EXManifestsManifest *)manifest; 31 - (void)appLoader:(EXAbstractLoader *)appLoader didLoadBundleWithProgress:(EXLoadingProgress *)progress; 32 - (void)appLoader:(EXAbstractLoader *)appLoader didFinishLoadingManifest:(EXManifestsManifest *)manifest bundle:(NSData *)data; 33 - (void)appLoader:(EXAbstractLoader *)appLoader didFailWithError:(NSError *)error; 34 - (void)appLoader:(EXAbstractLoader *)appLoader didResolveUpdatedBundleWithManifest:(EXManifestsManifest * _Nullable)manifest isFromCache:(BOOL)isFromCache error:(NSError * _Nullable)error; 35 36 @end 37 38 /** 39 Class with stub methods to load apps. 40 It has two subclasses: EXHomeLoader (for loading the home app), and 41 EXAppLoaderExpoUpdates (for loading and displaying apps in the home UI) 42 */ 43 @interface EXAbstractLoader : NSObject <EXAppFetcherDelegate, EXAppFetcherCacheDataSource> 44 45 @property (nonatomic, readonly) NSURL *manifestUrl; 46 @property (nonatomic, readonly) EXManifestsManifest * _Nullable manifest; // possibly optimistic 47 @property (nonatomic, readonly) EXManifestsManifest * _Nullable cachedManifest; // we definitely have this manifest and its bundle on the device 48 @property (nonatomic, readonly) NSData * _Nullable bundle; 49 @property (nonatomic, readonly) EXAppLoaderStatus status; 50 @property (nonatomic, readonly) EXAppLoaderRemoteUpdateStatus remoteUpdateStatus; 51 @property (nonatomic, readonly) BOOL shouldShowRemoteUpdateStatus; 52 @property (nonatomic, readonly) BOOL isUpToDate; 53 54 @property (nonatomic, weak) id<EXAppLoaderDelegate> delegate; 55 @property (nonatomic, weak) id<EXAppFetcherDataSource> dataSource; 56 57 - (instancetype)initWithManifestUrl:(NSURL *)url; 58 - (instancetype)initWithLocalManifest:(EXManifestsManifest * _Nonnull)manifest; 59 60 /** 61 * Begin a new request. 62 * In production, this will fetch a manifest and a bundle using the caching behavior specified by the Updates API. 63 * If the manifest enables developer tools, this will stop after it gets a manifest, and wait for `forceBundleReload`. 64 */ 65 - (void)request; 66 67 /** 68 * Begin a new request, but only use the most recently cached manifest. 69 * In production, this will fetch a manifest and a bundle using the caching behavior specified by the Updates API. 70 * If the manifest enables developer tools, this will stop after it gets a manifest, and wait for `forceBundleReload`. 71 */ 72 - (void)requestFromCache; 73 74 /** 75 * Tell this AppLoader that everything has finished successfully and its manifest resource can be cached. 76 */ 77 - (void)writeManifestToCache; 78 79 /** 80 * Reset status to `kEXAppLoaderStatusHasManifest` and fetch the bundle at the existing 81 * manifest. This is called when RN devtools reload an AppManager/RCTBridge directly 82 * via reload, live reload, etc. 83 * 84 * This will throw if not supported, i.e. if `supportsBundleReload` returns false. 85 */ 86 - (void)forceBundleReload; 87 88 /** 89 * Return whether this AppLoader supports directly reloading the bundle. Right now the only case 90 * where that's possible is if we're running an app in dev mode. 91 */ 92 - (BOOL)supportsBundleReload; 93 94 /** 95 * Fetch manifest without any side effects or interaction with the timer. 96 */ 97 - (void)fetchManifestWithCacheBehavior:(EXManifestCacheBehavior)cacheBehavior success:(void (^)(EXManifestsManifest *))success failure:(void (^)(NSError *))failure; 98 99 @end 100 101 NS_ASSUME_NONNULL_END 102