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