KMCloudServer.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. //
  2. // KMCloudServer.m
  3. // PDF Reader
  4. //
  5. // Created by wanjun on 2020/7/16.
  6. // Copyright © 2020 Kdan Mobile. All rights reserved.
  7. //
  8. #import "KMCloudServer.h"
  9. #import "KMGoogleDriveManager.h"
  10. #import "KMDropboxManager.h"
  11. #import "Reachability.h"
  12. NSString *const KMServerCloudFileManagerDownloadStateChangeNotification = @"KMServerCloudFileManagerDownloadStateChangeNotification";
  13. NSString *const KMServerCloudFileManagerDownloadSuccessfulNotification = @"KMServerCloudFileManagerDownloadSuccessfulNotification";
  14. NSString *const KMServerCloudFileManagerDownloadFailureNotification = @"KMServerCloudFileManagerDownloadFailureNotification";
  15. NSString *const KMServerCloudFileManagerUploadSuccessfulNotification = @"KMServerCloudFileManagerUploadSuccessfulNotification";
  16. NSString *const KMServerCloudFileManagerUploadFailureNotification = @"KMServerCloudFileManagerUploadFailureNotification";
  17. @interface KMCloudServer ()
  18. @property (nonatomic, retain) NSMutableDictionary *cloudFilesCache;
  19. @end
  20. @implementation KMCloudServer
  21. @synthesize GoogleDriveLocalFileList, DropboxLocalFileList, operationArr;
  22. static NSMutableArray *cloudArray = nil;
  23. - (void)dealloc {}
  24. #pragma mark -
  25. + (NSArray <KMCloudServer *>*)getAllLoginServer {
  26. NSMutableArray *cloudArray = [[NSMutableArray alloc] init];
  27. if ([[KMDropboxManager shareInstance] isSignedIn]) {
  28. KMCloudServer *server = [[KMCloudServer alloc] initCloudWithServerType:KMDropbox];
  29. server.accountId = [KMDropboxManager shareInstance].accountId;
  30. server.userEmail = [KMDropboxManager shareInstance].email;
  31. [cloudArray addObject:server];
  32. }
  33. if ([[KMGoogleDriveManager shareInstance] isSignedIn]) {
  34. KMCloudServer *server = [[KMCloudServer alloc] initCloudWithServerType:KMGoogleDrive];
  35. server.userEmail = [[NSUserDefaults standardUserDefaults] objectForKey:@"KMDriveLoginStatusKey"];
  36. [cloudArray addObject:server];
  37. }
  38. return cloudArray;
  39. }
  40. - (KMServicesCloudFile *)cloudFolderCacheForDisPath:(NSString *)path {
  41. if (!path) {
  42. return self.localRootFolder;
  43. } else {
  44. return [self.cloudFilesCache objectForKey:path];
  45. }
  46. }
  47. - (KMServicesCloudFile *)localRootFolder {
  48. KMServicesCloudFile *fileData = [[KMServicesCloudFile alloc] init];
  49. fileData.displayName = @"";
  50. fileData.path_lower = @"";
  51. fileData.filetype = KMCloudServiceFileType_Folder;
  52. return fileData;
  53. }
  54. - (KMServicesCloudFile *)getUpperPathCloudFolder:(KMServicesCloudFile *)file {
  55. KMServicesCloudFile *serverCloud = [[KMServicesCloudFile alloc] init];
  56. NSString *name = [file.displayName stringByDeletingLastPathComponent];
  57. if ([name isEqualToString:@"/"]) {
  58. name = @"";
  59. }
  60. serverCloud.displayName = name;
  61. return serverCloud;
  62. }
  63. + (BOOL)isConnectionAvailable {
  64. BOOL isExistenceNetwork = YES;
  65. Reachability *reach = [Reachability reachabilityWithHostname:@"www.apple.com"];
  66. switch ([reach currentReachabilityStatus]) {
  67. case NotReachable:
  68. isExistenceNetwork = NO;
  69. break;
  70. case ReachableViaWiFi:
  71. isExistenceNetwork = YES;
  72. break;
  73. case ReachableViaWWAN:
  74. isExistenceNetwork = YES;
  75. break;
  76. }
  77. if (NotReachable == [[Reachability reachabilityForInternetConnection] currentReachabilityStatus]) {
  78. return NO;
  79. }
  80. return YES;
  81. }
  82. + (BOOL)networkConnectionStatus {
  83. if (![self isConnectionAvailable]) {
  84. NSAlert *alert = [[NSAlert alloc] init];
  85. [alert setAlertStyle:NSAlertStyleCritical];
  86. [alert setMessageText:NSLocalizedString(@"Connection Error", nil)];
  87. NSString *tStrVPN = NSLocalizedString(@"The network is currently unavailable. Please try again later.", nil);
  88. [alert setInformativeText:tStrVPN];
  89. [alert addButtonWithTitle:NSLocalizedString(@"OK", nil)];
  90. if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) {
  91. [alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:nil];
  92. } else {
  93. [alert runModal];
  94. }
  95. return YES;
  96. } else {
  97. return NO;
  98. }
  99. return NO;
  100. }
  101. #pragma mark - init
  102. - (id)initCloudWithServerType:(KMServerType)type {
  103. self = [super init];
  104. if (self) {
  105. self.serverType = type;
  106. if (!DropboxLocalFileList) {
  107. DropboxLocalFileList = [[NSMutableArray alloc] init];
  108. }
  109. if (!GoogleDriveLocalFileList) {
  110. GoogleDriveLocalFileList = [[NSMutableArray alloc] init];
  111. }
  112. operationArr = [[NSMutableArray alloc] init];
  113. _cloudFilesCache = [[NSMutableDictionary alloc] init];
  114. //获取根目录
  115. }
  116. return self;
  117. }
  118. #pragma mark - Login
  119. - (BOOL)isSignedIn {
  120. if (self.serverType == KMDropbox) {
  121. return [[KMDropboxManager shareInstance] isSignedIn];
  122. } else if (self.serverType == KMGoogleDrive) {
  123. return [[KMGoogleDriveManager shareInstance] isSignedIn];
  124. }
  125. return NO;
  126. }
  127. - (void)authorizedLoginCompletion:(CloudLoginCallBack)completion {
  128. if ([KMCloudServer networkConnectionStatus])
  129. return;
  130. switch (self.serverType) {
  131. case KMDropbox:
  132. [[KMDropboxManager shareInstance] authorizedLoginCompletion:completion];
  133. break;
  134. case KMGoogleDrive:
  135. [[KMGoogleDriveManager shareInstance] authorizedLoginCompletion:completion];
  136. break;
  137. default:
  138. break;
  139. }
  140. }
  141. - (void)authorizedLogoutCompletion:(CloudLogoutCallBack)completion {
  142. switch (self.serverType) {
  143. case KMDropbox:
  144. [[KMDropboxManager shareInstance] authorizedLogoutCompletion:completion];
  145. break;
  146. case KMGoogleDrive:
  147. [[KMGoogleDriveManager shareInstance] authorizedLogoutCompletion:completion];
  148. break;
  149. default:
  150. break;
  151. }
  152. }
  153. #pragma mark - upload/download file
  154. - (KMCloudOperation *)uploadCloudPath:(KMServicesCloudFile *)cloudPath
  155. localPath:(NSURL *)localPath
  156. currentConvetProgress:(CurrentProgressCallBack)currentProgress
  157. completion:(CompletionCallBack)completion
  158. {
  159. if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable])
  160. return nil;
  161. if (self.serverType == KMDropbox) {
  162. return [[KMDropboxManager shareInstance] uploadCloudPath:cloudPath
  163. localPath:localPath
  164. currentConvetProgress:currentProgress
  165. completion:completion];
  166. } else if (self.serverType == KMGoogleDrive) {
  167. return [[KMGoogleDriveManager shareInstance] uploadCloudPath:cloudPath
  168. localPath:localPath
  169. currentConvetProgress:currentProgress
  170. completion:completion];
  171. }
  172. return nil;
  173. }
  174. - (void)uploadCancel:(KMCloudOperation *)operation {
  175. if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable])
  176. return;
  177. switch (self.serverType) {
  178. case KMDropbox:
  179. [[KMDropboxManager shareInstance] uploadCancel:operation];
  180. break;
  181. case KMGoogleDrive:
  182. [[KMGoogleDriveManager shareInstance] uploadCancel:operation];
  183. break;
  184. default:
  185. break;
  186. }
  187. }
  188. - (KMCloudOperation *)downloadCloudPath:(KMServicesCloudFile *)cloudPath
  189. localPath:(NSURL *)localPath
  190. currentConvetProgress:(CurrentProgressCallBack)currentProgress
  191. completion:(CompletionCallBack)completion
  192. {
  193. if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable])
  194. return nil;
  195. if (self.serverType == KMDropbox) {
  196. return [[KMDropboxManager shareInstance] downloadCloudPath:cloudPath
  197. localPath:localPath
  198. currentConvetProgress:currentProgress
  199. completion:completion];
  200. } else if (self.serverType == KMGoogleDrive) {
  201. return [[KMGoogleDriveManager shareInstance] downloadCloudPath:cloudPath
  202. localPath:localPath
  203. currentConvetProgress:currentProgress
  204. completion:completion];
  205. }
  206. return nil;
  207. }
  208. - (void)downloadCancel:(KMCloudOperation *)operation {
  209. if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable])
  210. return;
  211. switch (self.serverType) {
  212. case KMDropbox:
  213. [[KMDropboxManager shareInstance] downloadCancel:operation];
  214. break;
  215. case KMGoogleDrive:
  216. [[KMGoogleDriveManager shareInstance] downloadCancel:operation];
  217. break;
  218. default:
  219. break;
  220. }
  221. }
  222. #pragma mark - delete file
  223. - (void)deleteFileWithPath:(KMServicesCloudFile *)fileData
  224. completion:(CloudDeleteFileCallBack)completion
  225. {
  226. if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable])
  227. return;
  228. switch (self.serverType) {
  229. case KMDropbox:
  230. [[KMDropboxManager shareInstance] deleteFileWithPath:fileData completion:completion];
  231. break;
  232. case KMGoogleDrive:
  233. [[KMGoogleDriveManager shareInstance] deleteFileWithPath:fileData completion:completion];
  234. break;
  235. default:
  236. break;
  237. }
  238. }
  239. #pragma mark - create Folder
  240. - (void)createFolderWithPath:(KMServicesCloudFile *)fileData
  241. folderName:(NSString *)folderName
  242. completion:(CreateFolderCallBack)completion
  243. {
  244. if ([KMCloudServer networkConnectionStatus])
  245. return;
  246. switch (self.serverType) {
  247. case KMDropbox:
  248. [[KMDropboxManager shareInstance] createFolderWithPath:fileData folderName:folderName completion:completion];
  249. break;
  250. case KMGoogleDrive:
  251. [[KMDropboxManager shareInstance] createFolderWithPath:fileData folderName:folderName completion:completion];
  252. break;
  253. default:
  254. break;
  255. }
  256. }
  257. #pragma mark - get list
  258. - (void)getListWithFilePath:(KMServicesCloudFile *)fileData
  259. setResponseBlock:(GetFileListCallBack)responseBlock
  260. {
  261. if ([KMCloudServer networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable])
  262. return;
  263. if (fileData.displayName) {
  264. [self.cloudFilesCache setValue:fileData forKey:fileData.displayName];
  265. }
  266. switch (self.serverType) {
  267. case KMDropbox:
  268. [self.DropboxLocalFileList removeAllObjects];
  269. [[KMDropboxManager shareInstance] getListWithFilePath:fileData setResponseBlock:responseBlock];
  270. break;
  271. case KMGoogleDrive:
  272. [self.GoogleDriveLocalFileList removeAllObjects];
  273. [[KMGoogleDriveManager shareInstance] getListWithFilePath:fileData setResponseBlock:responseBlock];
  274. break;
  275. default:
  276. break;
  277. }
  278. }
  279. @end
  280. static NSString * const kKMAppNextLanuchBeforeNoLongerPromptKey = @"KMAppNextLanuchBeforeNoLongerPromptKey";
  281. @implementation KMCloudServer (Additions)
  282. + (void)load {
  283. static dispatch_once_t onceToken;
  284. dispatch_once(&onceToken, ^{
  285. [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kKMAppNextLanuchBeforeNoLongerPromptKey];
  286. [[NSUserDefaults standardUserDefaults] synchronize];
  287. });
  288. }
  289. + (BOOL)networkConnectionStatusOnceAlertWhileNetworkNotReachable {
  290. if (![self isConnectionAvailable]) {
  291. if ([[NSUserDefaults standardUserDefaults] boolForKey:kKMAppNextLanuchBeforeNoLongerPromptKey]) {
  292. return YES;
  293. }
  294. static BOOL needShow = YES;
  295. if (!needShow) {
  296. return YES;
  297. }
  298. needShow = NO;
  299. NSAlert *alert = [[NSAlert alloc] init];
  300. [alert setAlertStyle:NSAlertStyleCritical];
  301. [alert setMessageText:NSLocalizedString(@"Connection Error", nil)];
  302. NSString *tStrVPN = NSLocalizedString(@"The network is currently unavailable. Please try again later.", nil);
  303. [alert setInformativeText:tStrVPN];
  304. [alert addButtonWithTitle:NSLocalizedString(@"OK", nil)];
  305. NSButton *button = [NSButton checkboxWithTitle:NSLocalizedString(@"Don't show this again until the app is relaunched.", nil) target:self action:@selector(noLongerPromptAction:)];
  306. alert.accessoryView = button;
  307. if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) {
  308. [alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:^(NSModalResponse returnCode) {
  309. needShow = YES;
  310. }];
  311. } else {
  312. [alert runModal];
  313. needShow = YES;
  314. }
  315. return YES;
  316. } else {
  317. return NO;
  318. }
  319. return NO;
  320. }
  321. + (void)noLongerPromptAction:(NSButton *)sender {
  322. if (sender.state == NSControlStateValueOn) {
  323. [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kKMAppNextLanuchBeforeNoLongerPromptKey];
  324. [[NSUserDefaults standardUserDefaults] synchronize];
  325. }
  326. }
  327. + (BOOL)networkConnectionStatusForAdjectiveFunctionAlertWhileNetworkNotReachable {
  328. if (![self isConnectionAvailable]) {
  329. NSAlert *alert = [[NSAlert alloc] init];
  330. [alert setAlertStyle:NSAlertStyleCritical];
  331. [alert setMessageText:NSLocalizedString(@"Connection Error", nil)];
  332. // extern NSString * const kKMNotNetworkAlertMessage;
  333. NSString * const kKMNotNetworkAlertMessage = @"This feature requires Internet access. Please make sure your Internet connection is available.";
  334. NSString *tStrVPN = NSLocalizedString(kKMNotNetworkAlertMessage, nil);
  335. [alert setInformativeText:tStrVPN];
  336. [alert addButtonWithTitle:NSLocalizedString(@"OK", nil)];
  337. if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) {
  338. [alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:nil];
  339. } else {
  340. [alert runModal];
  341. }
  342. return YES;
  343. } else {
  344. return NO;
  345. }
  346. return NO;
  347. }
  348. @end