// // KMCloudServer.m // PDF Reader // // Created by wanjun on 2020/7/16. // Copyright © 2020 Kdan Mobile. All rights reserved. // #import "KMCloudServer.h" #import "KMGoogleDriveManager.h" #import "KMDropboxManager.h" #import "Reachability.h" NSString *const KMServerCloudFileManagerDownloadStateChangeNotification = @"KMServerCloudFileManagerDownloadStateChangeNotification"; NSString *const KMServerCloudFileManagerDownloadSuccessfulNotification = @"KMServerCloudFileManagerDownloadSuccessfulNotification"; NSString *const KMServerCloudFileManagerDownloadFailureNotification = @"KMServerCloudFileManagerDownloadFailureNotification"; NSString *const KMServerCloudFileManagerUploadSuccessfulNotification = @"KMServerCloudFileManagerUploadSuccessfulNotification"; NSString *const KMServerCloudFileManagerUploadFailureNotification = @"KMServerCloudFileManagerUploadFailureNotification"; @interface KMCloudServer () @property (nonatomic, retain) NSMutableDictionary *cloudFilesCache; @end @implementation KMCloudServer @synthesize GoogleDriveLocalFileList, DropboxLocalFileList, operationArr; static NSMutableArray *cloudArray = nil; - (void)dealloc {} #pragma mark - + (NSArray *)getAllLoginServer { NSMutableArray *cloudArray = [[NSMutableArray alloc] init]; if ([[KMDropboxManager shareInstance] isSignedIn]) { KMCloudServer *server = [[KMCloudServer alloc] initCloudWithServerType:KMDropbox]; server.accountId = [KMDropboxManager shareInstance].accountId; server.userEmail = [KMDropboxManager shareInstance].email; [cloudArray addObject:server]; } if ([[KMGoogleDriveManager shareInstance] isSignedIn]) { KMCloudServer *server = [[KMCloudServer alloc] initCloudWithServerType:KMGoogleDrive]; server.userEmail = [[NSUserDefaults standardUserDefaults] objectForKey:@"KMDriveLoginStatusKey"]; [cloudArray addObject:server]; } return cloudArray; } - (KMServicesCloudFile *)cloudFolderCacheForDisPath:(NSString *)path { if (!path) { return self.localRootFolder; } else { return [self.cloudFilesCache objectForKey:path]; } } - (KMServicesCloudFile *)localRootFolder { KMServicesCloudFile *fileData = [[KMServicesCloudFile alloc] init]; fileData.displayName = @""; fileData.path_lower = @""; fileData.filetype = KMCloudServiceFileType_Folder; return fileData; } - (KMServicesCloudFile *)getUpperPathCloudFolder:(KMServicesCloudFile *)file { KMServicesCloudFile *serverCloud = [[KMServicesCloudFile alloc] init]; NSString *name = [file.displayName stringByDeletingLastPathComponent]; if ([name isEqualToString:@"/"]) { name = @""; } serverCloud.displayName = name; return serverCloud; } + (BOOL)isConnectionAvailable { BOOL isExistenceNetwork = YES; Reachability *reach = [Reachability reachabilityWithHostname:@"www.apple.com"]; switch ([reach currentReachabilityStatus]) { case NotReachable: isExistenceNetwork = NO; break; case ReachableViaWiFi: isExistenceNetwork = YES; break; case ReachableViaWWAN: isExistenceNetwork = YES; break; } if (NotReachable == [[Reachability reachabilityForInternetConnection] currentReachabilityStatus]) { return NO; } return YES; } + (BOOL)networkConnectionStatus { if (![self isConnectionAvailable]) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSAlertStyleCritical]; [alert setMessageText:NSLocalizedString(@"Connection Error", nil)]; NSString *tStrVPN = NSLocalizedString(@"The network is currently unavailable. Please try again later.", nil); [alert setInformativeText:tStrVPN]; [alert addButtonWithTitle:NSLocalizedString(@"OK", nil)]; if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) { [alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:nil]; } else { [alert runModal]; } return YES; } else { return NO; } return NO; } #pragma mark - init - (id)initCloudWithServerType:(KMServerType)type { self = [super init]; if (self) { self.serverType = type; if (!DropboxLocalFileList) { DropboxLocalFileList = [[NSMutableArray alloc] init]; } if (!GoogleDriveLocalFileList) { GoogleDriveLocalFileList = [[NSMutableArray alloc] init]; } operationArr = [[NSMutableArray alloc] init]; _cloudFilesCache = [[NSMutableDictionary alloc] init]; //获取根目录 } return self; } #pragma mark - Login - (BOOL)isSignedIn { if (self.serverType == KMDropbox) { return [[KMDropboxManager shareInstance] isSignedIn]; } else if (self.serverType == KMGoogleDrive) { return [[KMGoogleDriveManager shareInstance] isSignedIn]; } return NO; } - (void)authorizedLoginCompletion:(CloudLoginCallBack)completion { if ([KMCloudServer networkConnectionStatus]) return; switch (self.serverType) { case KMDropbox: [[KMDropboxManager shareInstance] authorizedLoginCompletion:completion]; break; case KMGoogleDrive: [[KMGoogleDriveManager shareInstance] authorizedLoginCompletion:completion]; break; default: break; } } - (void)authorizedLogoutCompletion:(CloudLogoutCallBack)completion { switch (self.serverType) { case KMDropbox: [[KMDropboxManager shareInstance] authorizedLogoutCompletion:completion]; break; case KMGoogleDrive: [[KMGoogleDriveManager shareInstance] authorizedLogoutCompletion:completion]; break; default: break; } } #pragma mark - upload/download file - (KMCloudOperation *)uploadCloudPath:(KMServicesCloudFile *)cloudPath localPath:(NSURL *)localPath currentConvetProgress:(CurrentProgressCallBack)currentProgress completion:(CompletionCallBack)completion { if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable]) return nil; if (self.serverType == KMDropbox) { return [[KMDropboxManager shareInstance] uploadCloudPath:cloudPath localPath:localPath currentConvetProgress:currentProgress completion:completion]; } else if (self.serverType == KMGoogleDrive) { return [[KMGoogleDriveManager shareInstance] uploadCloudPath:cloudPath localPath:localPath currentConvetProgress:currentProgress completion:completion]; } return nil; } - (void)uploadCancel:(KMCloudOperation *)operation { if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable]) return; switch (self.serverType) { case KMDropbox: [[KMDropboxManager shareInstance] uploadCancel:operation]; break; case KMGoogleDrive: [[KMGoogleDriveManager shareInstance] uploadCancel:operation]; break; default: break; } } - (KMCloudOperation *)downloadCloudPath:(KMServicesCloudFile *)cloudPath localPath:(NSURL *)localPath currentConvetProgress:(CurrentProgressCallBack)currentProgress completion:(CompletionCallBack)completion { if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable]) return nil; if (self.serverType == KMDropbox) { return [[KMDropboxManager shareInstance] downloadCloudPath:cloudPath localPath:localPath currentConvetProgress:currentProgress completion:completion]; } else if (self.serverType == KMGoogleDrive) { return [[KMGoogleDriveManager shareInstance] downloadCloudPath:cloudPath localPath:localPath currentConvetProgress:currentProgress completion:completion]; } return nil; } - (void)downloadCancel:(KMCloudOperation *)operation { if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable]) return; switch (self.serverType) { case KMDropbox: [[KMDropboxManager shareInstance] downloadCancel:operation]; break; case KMGoogleDrive: [[KMGoogleDriveManager shareInstance] downloadCancel:operation]; break; default: break; } } #pragma mark - delete file - (void)deleteFileWithPath:(KMServicesCloudFile *)fileData completion:(CloudDeleteFileCallBack)completion { if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable]) return; switch (self.serverType) { case KMDropbox: [[KMDropboxManager shareInstance] deleteFileWithPath:fileData completion:completion]; break; case KMGoogleDrive: [[KMGoogleDriveManager shareInstance] deleteFileWithPath:fileData completion:completion]; break; default: break; } } #pragma mark - create Folder - (void)createFolderWithPath:(KMServicesCloudFile *)fileData folderName:(NSString *)folderName completion:(CreateFolderCallBack)completion { if ([KMCloudServer networkConnectionStatus]) return; switch (self.serverType) { case KMDropbox: [[KMDropboxManager shareInstance] createFolderWithPath:fileData folderName:folderName completion:completion]; break; case KMGoogleDrive: [[KMDropboxManager shareInstance] createFolderWithPath:fileData folderName:folderName completion:completion]; break; default: break; } } #pragma mark - get list - (void)getListWithFilePath:(KMServicesCloudFile *)fileData setResponseBlock:(GetFileListCallBack)responseBlock { if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable]) return; if (fileData.displayName) { [self.cloudFilesCache setValue:fileData forKey:fileData.displayName]; } switch (self.serverType) { case KMDropbox: [self.DropboxLocalFileList removeAllObjects]; [[KMDropboxManager shareInstance] getListWithFilePath:fileData setResponseBlock:responseBlock]; break; case KMGoogleDrive: [self.GoogleDriveLocalFileList removeAllObjects]; [[KMGoogleDriveManager shareInstance] getListWithFilePath:fileData setResponseBlock:responseBlock]; break; default: break; } } @end static NSString * const kKMAppNextLanuchBeforeNoLongerPromptKey = @"KMAppNextLanuchBeforeNoLongerPromptKey"; @implementation KMCloudServer (Additions) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kKMAppNextLanuchBeforeNoLongerPromptKey]; [[NSUserDefaults standardUserDefaults] synchronize]; }); } + (BOOL)networkConnectionStatusOnceAlertWhileNetworkNotReachable { if (![self isConnectionAvailable]) { if ([[NSUserDefaults standardUserDefaults] boolForKey:kKMAppNextLanuchBeforeNoLongerPromptKey]) { return YES; } static BOOL needShow = YES; if (!needShow) { return YES; } needShow = NO; NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSAlertStyleCritical]; [alert setMessageText:NSLocalizedString(@"Connection Error", nil)]; NSString *tStrVPN = NSLocalizedString(@"The network is currently unavailable. Please try again later.", nil); [alert setInformativeText:tStrVPN]; [alert addButtonWithTitle:NSLocalizedString(@"OK", nil)]; NSButton *button = [NSButton checkboxWithTitle:NSLocalizedString(@"Don't show this again until the app is relaunched.", nil) target:self action:@selector(noLongerPromptAction:)]; alert.accessoryView = button; if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) { [alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:^(NSModalResponse returnCode) { needShow = YES; }]; } else { [alert runModal]; needShow = YES; } return YES; } else { return NO; } return NO; } + (void)noLongerPromptAction:(NSButton *)sender { if (sender.state == NSControlStateValueOn) { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kKMAppNextLanuchBeforeNoLongerPromptKey]; [[NSUserDefaults standardUserDefaults] synchronize]; } } + (BOOL)networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable { if (![self isConnectionAvailable]) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSAlertStyleCritical]; [alert setMessageText:NSLocalizedString(@"Connection Error", nil)]; // extern NSString * const kKMNotNetworkAlertMessage; NSString * const kKMNotNetworkAlertMessage = @"This feature requires Internet access. Please make sure your Internet connection is available."; NSString *tStrVPN = NSLocalizedString(kKMNotNetworkAlertMessage, nil); [alert setInformativeText:tStrVPN]; [alert addButtonWithTitle:NSLocalizedString(@"OK", nil)]; if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) { [alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:nil]; } else { [alert runModal]; } return YES; } else { return NO; } return NO; } @end