Skip to content

Commit

Permalink
[expo-file-system] Extract resumables manger
Browse files Browse the repository at this point in the history
  • Loading branch information
lukmccall committed Apr 15, 2020
1 parent e08b745 commit 937d247
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 48 deletions.
4 changes: 1 addition & 3 deletions packages/expo-file-system/ios/EXFileSystem/EXFileSystem.h
Expand Up @@ -5,10 +5,8 @@
#import <UMCore/UMModuleRegistryConsumer.h>
#import <UMCore/UMEventEmitter.h>
#import <UMFileSystemInterface/UMFileSystemInterface.h>
#import <EXFileSystem/EXSessionResumableDownloadTaskDelegate.h>
#import <EXFileSystem/EXSessionTaskDispatcher.h>

@interface EXFileSystem : UMExportedModule <UMEventEmitter, UMModuleRegistryConsumer, UMFileSystemInterface, NSURLSessionDelegate>
@interface EXFileSystem : UMExportedModule <UMEventEmitter, UMModuleRegistryConsumer, UMFileSystemInterface>

@property (nonatomic, readonly) NSString *documentDirectory;
@property (nonatomic, readonly) NSString *cachesDirectory;
Expand Down
38 changes: 20 additions & 18 deletions packages/expo-file-system/ios/EXFileSystem/EXFileSystem.m
Expand Up @@ -12,10 +12,11 @@
#import <UMFileSystemInterface/UMFileSystemInterface.h>
#import <UMFileSystemInterface/UMFilePermissionModuleInterface.h>


#import <UMCore/UMEventEmitterService.h>

#import <EXFileSystem/EXSessionTaskDispatcher.h>
#import <EXFileSystem/EXSessionDownloadTaskDelegate.h>
#import <EXFileSystem/EXSessionResumableDownloadTaskDelegate.h>
#import <EXFileSystem/EXSessionUploadTaskDelegate.h>

NSString * const EXDownloadProgressEventName = @"expo-file-system.downloadProgress";
Expand All @@ -36,6 +37,7 @@ @interface EXFileSystem ()
@property (nonatomic, strong) NSURLSession *backgroundSession;
@property (nonatomic, strong) NSURLSession *foregroundSession;
@property (nonatomic, strong) EXSessionTaskDispatcher *sessionTaskDispatcher;
@property (nonatomic, strong) EXResumablesManager *resumableManager;
@property (nonatomic, weak) UMModuleRegistry *moduleRegistry;
@property (nonatomic, weak) id<UMEventEmitterService> eventEmitter;
@property (nonatomic, strong) NSString *documentDirectory;
Expand Down Expand Up @@ -65,9 +67,10 @@ - (instancetype)initWithDocumentDirectory:(NSString *)documentDirectory cachesDi
_cachesDirectory = cachesDirectory;
_bundleDirectory = bundleDirectory;

_resumableManager = [EXResumablesManager new];
_sessionTaskDispatcher = [EXSessionTaskDispatcher new];
_backgroundSession = [self _createSession:EXFileSystemBackgroundSession];
_foregroundSession = [self _createSession:EXFileSystemForegroundSession];
_backgroundSession = [self _createSession:EXFileSystemBackgroundSession delegate:_sessionTaskDispatcher];
_foregroundSession = [self _createSession:EXFileSystemForegroundSession delegate:_sessionTaskDispatcher];

[EXFileSystem ensureDirExistsWithPath:_documentDirectory];
[EXFileSystem ensureDirExistsWithPath:_cachesDirectory];
Expand Down Expand Up @@ -588,7 +591,7 @@ - (NSDictionary *)encodingMap
return;
}

NSURLRequest *request = [self _createRequest:[NSURL URLWithString:urlString] headers:options[@"headers"]];
NSMutableURLRequest *request = [self _createRequest:[NSURL URLWithString:urlString] headers:options[@"headers"]];
if (options[@"httpMethod"]) {
NSString *httpMethod = [self _importHttpMethod:options[@"httpMethod"]];
if (!httpMethod) {
Expand All @@ -598,9 +601,7 @@ - (NSDictionary *)encodingMap
return;
}

NSMutableURLRequest *mutableRequest = [request mutableCopy];
[mutableRequest setHTTPMethod:httpMethod];
request = mutableRequest;
[request setHTTPMethod:httpMethod];
}

EXFileSystemSessionType type = [self _importSessionType:options[@"sessionType"]];
Expand Down Expand Up @@ -664,7 +665,7 @@ - (NSDictionary *)encodingMap
resolver:(UMPromiseResolveBlock)resolve
rejecter:(UMPromiseRejectBlock)reject)
{
NSURLSessionDownloadTask *task = [_sessionTaskDispatcher resumableDownload:uuid];
NSURLSessionDownloadTask *task = [_resumableManager getTask:uuid];
if (!task) {
reject(@"ERR_UNABLE_TO_PAUSE",
[NSString stringWithFormat:@"There is no download object with UUID: %@", uuid],
Expand All @@ -676,7 +677,7 @@ - (NSDictionary *)encodingMap
[task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
UM_ENSURE_STRONGIFY(self);
resolve(@{ @"resumeData": UMNullIfNil([resumeData base64EncodedStringWithOptions:0]) });
[self.sessionTaskDispatcher removeResumableDownload:uuid];
[self.sessionTaskDispatcher unregisterTaskDelegate:task]; // It'll also unregister task from the ResumableManager
}];
}

Expand All @@ -700,7 +701,7 @@ - (NSDictionary *)encodingMap

#pragma mark - Internal methods

- (NSURLRequest *)_createRequest:(NSURL *)url headers:(NSDictionary * _Nullable)headers
- (NSMutableURLRequest *)_createRequest:(NSURL *)url headers:(NSDictionary * _Nullable)headers
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
if (headers != nil) {
Expand Down Expand Up @@ -739,7 +740,7 @@ - (BOOL)_checkHeadersDictionary:(NSDictionary * _Nullable)headers
return true;
}

- (NSURLSession *)_createSession:(EXFileSystemSessionType)type
- (NSURLSession *)_createSession:(EXFileSystemSessionType)type delegate:(id<NSURLSessionDelegate>)delegate
{
NSURLSessionConfiguration *sessionConfiguration;
if (type == EXFileSystemForegroundSession) {
Expand All @@ -750,7 +751,7 @@ - (NSURLSession *)_createSession:(EXFileSystemSessionType)type
sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
sessionConfiguration.URLCache = nil;
return [NSURLSession sessionWithConfiguration:sessionConfiguration
delegate:_sessionTaskDispatcher
delegate:delegate
delegateQueue:nil];
}

Expand Down Expand Up @@ -803,13 +804,14 @@ - (void)_downloadResumableCreateSessionWithUrl:(NSURL *)url
downloadTask = [session downloadTaskWithRequest:request];
}
EXSessionTaskDelegate *taskDelegate = [[EXSessionResumableDownloadTaskDelegate alloc] initWithResolve:resolve
reject:reject
localUrl:fileUrl
shouldCalculateMd5:[options[@"md5"] boolValue]
onWriteCallback:onWrite
uuid:uuid];
reject:reject
localUrl:fileUrl
shouldCalculateMd5:[options[@"md5"] boolValue]
onWriteCallback:onWrite
resumableManager:_resumableManager
uuid:uuid];
[_sessionTaskDispatcher registerTaskDelegate:taskDelegate forTask:downloadTask];
[_sessionTaskDispatcher registerResumableDownloadTask:downloadTask uuid:uuid];
[_resumableManager registerTask:downloadTask uuid:uuid];
[downloadTask resume];
}

Expand Down
@@ -0,0 +1,17 @@
// Copyright 2015-present 650 Industries. All rights reserved.

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface EXResumablesManager : NSObject

- (NSURLSessionDownloadTask * _Nullable)getTask:(NSString *)uuid;

- (void)registerTask:(NSURLSessionDownloadTask *)task uuid:(NSString *)uuid;

- (void)unregisterTask:(NSString *)uuid;

@end

NS_ASSUME_NONNULL_END
@@ -0,0 +1,36 @@
// Copyright 2015-present 650 Industries. All rights reserved.

#import "EXResumablesManager.h"

@interface EXResumablesManager ()

@property (nonatomic, strong) NSMutableDictionary<NSString *, NSURLSessionDownloadTask *> *resumableDownloads;

@end

@implementation EXResumablesManager

- (instancetype)init
{
if (self = [super init]) {
_resumableDownloads = [NSMutableDictionary dictionary];
}
return self;
}

- (void)registerTask:(NSURLSessionDownloadTask *)task uuid:(NSString *)uuid
{
_resumableDownloads[uuid] = task;
}

- (NSURLSessionDownloadTask * _Nullable)getTask:(NSString *)uuid
{
return _resumableDownloads[uuid];
}

- (void)unregisterTask:(NSString *)uuid
{
[_resumableDownloads removeObjectForKey:uuid];
}

@end
@@ -1,18 +1,20 @@
// Copyright 2015-present 650 Industries. All rights reserved.

#import <EXFileSystem/EXSessionDownloadTaskDelegate.h>
#import <EXFileSystem/EXResumablesManager.h>

typedef void (^EXDownloadDelegateOnWriteCallback)(NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite);

@interface EXSessionResumableDownloadTaskDelegate : EXSessionDownloadTaskDelegate

@property (strong, nonatomic, readonly) NSString *uuid;

- (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve
reject:(UMPromiseRejectBlock)reject
localUrl:(NSURL *)localUrl
shouldCalculateMd5:(BOOL)shouldCalculateMd5
onWriteCallback:(EXDownloadDelegateOnWriteCallback)onWriteCallback
resumableManager:(EXResumablesManager *)manager
uuid:(NSString *)uuid;

- (void)invalid;

@end
Expand Up @@ -5,6 +5,8 @@
@interface EXSessionResumableDownloadTaskDelegate ()

@property (strong, nonatomic, readonly) EXDownloadDelegateOnWriteCallback onWriteCallback;
@property (weak, nonatomic) EXResumablesManager *manger;
@property (strong, nonatomic) NSString *uuid;

@end

Expand All @@ -15,18 +17,25 @@ - (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve
localUrl:(NSURL *)localUrl
shouldCalculateMd5:(BOOL)shouldCalculateMd5
onWriteCallback:(EXDownloadDelegateOnWriteCallback)onWriteCallback
resumableManager:(EXResumablesManager *)manager
uuid:(NSString *)uuid;
{
if (self = [super initWithResolve:resolve
reject:reject
localUrl:localUrl
shouldCalculateMd5:shouldCalculateMd5]) {
_onWriteCallback = onWriteCallback;
_manger = manager;
_uuid = uuid;
}
return self;
}

- (void)invalid
{
[_manger unregisterTask:_uuid];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
if (error) {
Expand Down
Expand Up @@ -9,11 +9,7 @@ NS_ASSUME_NONNULL_BEGIN

- (void)registerTaskDelegate:(EXSessionTaskDelegate *)delegate forTask:(NSURLSessionTask *)task;

- (void)registerResumableDownloadTask:(NSURLSessionDownloadTask *)task uuid:(NSString *)uuid;

- (NSURLSessionDownloadTask * _Nullable)resumableDownload:(NSString *)uuid;

- (void)removeResumableDownload:(NSString *)uuid;
- (void)unregisterTaskDelegate:(NSURLSessionTask *)task;

- (void)deactivate;

Expand Down
Expand Up @@ -6,7 +6,6 @@
@interface EXSessionTaskDispatcher ()

@property (nonatomic, strong) NSMutableDictionary<NSURLSessionTask *, EXSessionTaskDelegate *> *tasks;
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSURLSessionDownloadTask *> *resumableDownloads;
@property (nonatomic) BOOL isActive;

@end
Expand All @@ -17,7 +16,6 @@ - (instancetype)init
{
if (self = [super init]) {
_tasks = [NSMutableDictionary dictionary];
_resumableDownloads = [NSMutableDictionary dictionary];
_isActive = true;
}
return self;
Expand All @@ -30,24 +28,10 @@ - (void)registerTaskDelegate:(EXSessionTaskDelegate *)delegate forTask:(NSURLSes
_tasks[task] = delegate;
}

- (void)registerResumableDownloadTask:(NSURLSessionDownloadTask *)task uuid:(NSString *)uuid
- (void)unregisterTaskDelegate:(NSURLSessionTask *)task
{
_resumableDownloads[uuid] = task;
}

- (NSURLSessionDownloadTask * _Nullable)resumableDownload:(NSString *)uuid
{
return _resumableDownloads[uuid];
}

- (void)removeResumableDownload:(NSString *)uuid
{
NSURLSessionTask *task = _resumableDownloads[uuid];
if (!task) {
return;
}

[_resumableDownloads removeObjectForKey:uuid];
EXSessionTaskDelegate *delegate = _tasks[task];
[self _unregisterIfResumableTaskDelegate:delegate];
[_tasks removeObjectForKey:task];
}

Expand All @@ -62,7 +46,7 @@ - (void)_unregisterIfResumableTaskDelegate:(EXSessionTaskDelegate *)taskDelegate
{
if ([taskDelegate isKindOfClass:[EXSessionResumableDownloadTaskDelegate class]]) {
EXSessionResumableDownloadTaskDelegate *exResumableTask = (EXSessionResumableDownloadTaskDelegate *)taskDelegate;
[_resumableDownloads removeObjectForKey:exResumableTask.uuid];
[exResumableTask invalid];
}
}

Expand Down

0 comments on commit 937d247

Please sign in to comment.