KMGoogleDriveManager.m 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. //
  2. // KMGoogleDriveManager.m
  3. // PDF Reader Pro Edition
  4. //
  5. // Created by 万军 on 2020/2/27.
  6. // Copyright © 2020 WanJun. All rights reserved.
  7. //
  8. #import "KMGoogleDriveManager.h"
  9. #import "KMCloudUploadOperationQueue.h"
  10. #import "KMCloudDownloadOperationQueue.h"
  11. #import "AppAuth.h"
  12. #import "GTLRUtilities.h"
  13. #import "GTMAppAuth.h"
  14. #if VERSION_PRO
  15. static NSString *const kClientID = @"943919378557-8d80bu59e7sgs426sum5ttbl3dvca792.apps.googleusercontent.com";
  16. static NSString *const kClientSecret = @"yyuC2iDhjFpXDyHudBWyb4f3";
  17. #else
  18. static NSString *const kClientID = @"701590830852-ndbtpjj13oahpba0l562j3bba8rei5vd.apps.googleusercontent.com";
  19. static NSString *const kClientSecret = @"fgmhFsuan45HJ1oksDnyEVQ-";
  20. #endif
  21. static NSString *const kSuccessURLString = @"http://openid.github.io/AppAuth-iOS/redirect/";
  22. NSString *const kGTMAppAuthKeychainItemName = @"DriveSample: Google Drive. GTMAppAuth.";
  23. @interface KMGoogleDriveManager ()
  24. //@property (nonatomic, assign) NSMutableArray *fileList;
  25. @property (nonatomic, strong) NSMutableArray<KMServicesCloudFile *> *localFileList;
  26. @property (nonatomic, strong) NSMutableArray<KMServicesCloudFile *> *sharedFileList;
  27. @property (nonatomic, strong) KMServicesCloudFile *localRootFolder;//获取本读根文件夹
  28. @property (nonatomic, strong) GTLRServiceTicket *fileListTicket;
  29. @property (nonatomic, strong) GTLRServiceTicket *editFileListTicket;
  30. @property (nonatomic, strong) OIDRedirectHTTPHandler * redirectHTTPHandler;
  31. @property (nonatomic, strong) NSMutableDictionary *cloudFilesCache;
  32. @property (nonatomic, copy) CloudDeleteFileCallBack deleteFileBlock;
  33. @property (nonatomic, copy) CreateFolderCallBack createFolderBlock;
  34. @property (nonatomic, copy) GetFileListCallBack getFileListBlock;
  35. @property (nonatomic, copy) CloudLoginCallBack cloudLoginBlock;
  36. @property (nonatomic, copy) CloudLogoutCallBack cloudLogoutBlock;
  37. @end
  38. @implementation KMGoogleDriveManager
  39. @synthesize localFileList, sharedFileList;
  40. static KMGoogleDriveManager *_instance;
  41. + (instancetype)allocWithZone:(struct _NSZone *)zone {
  42. @synchronized(self) {
  43. if (nil == _instance) {
  44. _instance = [super allocWithZone:zone];
  45. }
  46. return _instance;
  47. }
  48. }
  49. + (instancetype)shareInstance {
  50. @synchronized(self) {
  51. if (nil == _instance) {
  52. _instance = [[self alloc] init];
  53. }
  54. return _instance;
  55. }
  56. }
  57. - (id)copyWithZone:(NSZone *)zone
  58. {
  59. return _instance;
  60. }
  61. - (id)mutableCopyWithZone:(NSZone *)zone
  62. {
  63. return _instance;
  64. }
  65. - (id)init {
  66. self = [super init];
  67. if (self) {
  68. _cloudFilesCache = [[NSMutableDictionary alloc] init];
  69. localFileList = [[NSMutableArray alloc] init];
  70. sharedFileList = [[NSMutableArray alloc] init];
  71. _localRootFolder = [[KMServicesCloudFile alloc] init];
  72. id<GTMFetcherAuthorizationProtocol> authorization =
  73. [GTMAppAuthFetcherAuthorization authorizationFromKeychainForName:kGTMAppAuthKeychainItemName];
  74. self.driveService.authorizer = authorization;
  75. if ([self isSignedIn]) {
  76. [self fetchFileList:@""]; //获取根目录ID,并获取根目录下内容
  77. }
  78. }
  79. return self;
  80. }
  81. #pragma mark -
  82. - (NSString *)signedInUsername {
  83. id<GTMFetcherAuthorizationProtocol> auth = self.driveService.authorizer;
  84. BOOL isSignedIn = auth.canAuthorize;
  85. if (isSignedIn) {
  86. [[NSUserDefaults standardUserDefaults] setValue:auth.userEmail forKey:@"KMDriveLoginStatusKey"];
  87. [[NSUserDefaults standardUserDefaults] synchronize];
  88. return auth.userEmail;
  89. } else {
  90. return nil;
  91. }
  92. }
  93. - (BOOL)isSignedIn {
  94. NSString *name = [self signedInUsername];
  95. return (name != nil);
  96. }
  97. - (KMServicesCloudFile *)cloudFolderCacheForDisPath:(NSString *)path
  98. {
  99. if (!path) {
  100. return self.localRootFolder;
  101. } else {
  102. return [self.cloudFilesCache objectForKey:path];
  103. }
  104. }
  105. #pragma mark - googledrive 授权登陆
  106. - (void)authorizedLoginCompletion:(CloudLoginCallBack)completion
  107. {
  108. self.cloudLoginBlock = completion;
  109. if (![self isSignedIn]) {
  110. [self runSigninThenHandler:^{
  111. [self fetchFileList:@""]; //获取根目录ID,并获取根目录下内容
  112. }];
  113. } else {
  114. NSLog(@"已登陆");
  115. }
  116. }
  117. - (void)runSigninThenHandler:(void (^)(void))handler {
  118. //执行授权
  119. NSURL *successURL = [NSURL URLWithString:kSuccessURLString];
  120. // Starts a loopback HTTP listener to receive the code, gets the redirect URI to be used.
  121. self.redirectHTTPHandler = [[OIDRedirectHTTPHandler alloc] initWithSuccessURL:successURL];
  122. NSError *error;
  123. NSURL *localRedirectURI = [self.redirectHTTPHandler startHTTPListener:&error];
  124. if (!localRedirectURI) {
  125. NSLog(@"Unexpected error starting redirect handler %@", error);
  126. return;
  127. }
  128. // Builds authentication request.
  129. OIDServiceConfiguration *configuration =
  130. [GTMAppAuthFetcherAuthorization configurationForGoogle];
  131. // Applications that only need to access files created by this app should
  132. // use the kGTLRAuthScopeDriveFile scope.
  133. NSArray<NSString *> *scopes = @[ kGTLRAuthScopeDriveReadonly, OIDScopeEmail ];//https://www.googleapis.com/auth/drive.readonly kGTLRAuthScopeDrive
  134. OIDAuthorizationRequest *request =
  135. [[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
  136. clientId:kClientID
  137. clientSecret:kClientSecret
  138. scopes:scopes
  139. redirectURL:localRedirectURI
  140. responseType:OIDResponseTypeCode
  141. additionalParameters:nil];
  142. // performs authentication request
  143. __weak __typeof(self) weakSelf = self;
  144. self.redirectHTTPHandler.currentAuthorizationFlow =
  145. [OIDAuthState authStateByPresentingAuthorizationRequest:request
  146. callback:^(OIDAuthState *_Nullable authState,
  147. NSError *_Nullable error) {
  148. __strong __typeof(weakSelf) strongSelf = weakSelf;
  149. if (!strongSelf) {
  150. return;
  151. }
  152. // Brings this app to the foreground.
  153. [[NSRunningApplication currentApplication]
  154. activateWithOptions:(NSApplicationActivateAllWindows |
  155. NSApplicationActivateIgnoringOtherApps)];
  156. if (authState) {
  157. GTMAppAuthFetcherAuthorization *gtmAuthorization =
  158. [[GTMAppAuthFetcherAuthorization alloc] initWithAuthState:authState];
  159. strongSelf.driveService.authorizer = gtmAuthorization;
  160. [GTMAppAuthFetcherAuthorization saveAuthorization:gtmAuthorization
  161. toKeychainForName:kGTMAppAuthKeychainItemName];
  162. KMGoogleDriveUserMetadata *userMetadata = [[KMGoogleDriveUserMetadata alloc] init];
  163. userMetadata.accessToken = authState.lastTokenResponse.accessToken;
  164. userMetadata.accessTokenExpirationDate = authState.lastTokenResponse.accessTokenExpirationDate;
  165. userMetadata.tokenType = authState.lastTokenResponse.tokenType;
  166. userMetadata.idToken = authState.lastTokenResponse.idToken;
  167. userMetadata.refreshToken = authState.lastTokenResponse.refreshToken;
  168. userMetadata.scope = authState.lastTokenResponse.scope;
  169. userMetadata.userEmail = gtmAuthorization.userEmail;
  170. userMetadata.additionalParameters = authState.lastTokenResponse.additionalParameters;
  171. if (_cloudLoginBlock) {
  172. _cloudLoginBlock(userMetadata ,YES);
  173. }
  174. if (handler) {
  175. handler();
  176. }
  177. } else {
  178. // self->_fileListFetchError = error;
  179. }
  180. }];
  181. }
  182. #pragma mark - 取消授权
  183. - (void)authorizedLogoutCompletion:(CloudLogoutCallBack)completion
  184. {
  185. self.cloudLogoutBlock = completion;
  186. GTLRDriveService *service = self.driveService;
  187. [GTMAppAuthFetcherAuthorization
  188. removeAuthorizationFromKeychainForName:kGTMAppAuthKeychainItemName];
  189. service.authorizer = nil;
  190. if (_cloudLogoutBlock) {
  191. _cloudLogoutBlock(YES);
  192. }
  193. }
  194. #pragma mark - 上传
  195. - (KMCloudOperation *)uploadCloudPath:(KMServicesCloudFile *)cloudPath
  196. localPath:(NSURL *)localPath
  197. currentConvetProgress:(CurrentProgressCallBack)currentProgress
  198. completion:(CompletionCallBack)completion
  199. {
  200. KMCloudUploadOperationQueue *queue = [KMCloudUploadOperationQueue sharedInstance];
  201. queue.maxConcurrentOperationCount = 4;
  202. queue.name = [localPath path];
  203. KMCloudOperation *op = [[KMCloudOperation alloc] initWithLoadCloudPath:cloudPath
  204. serverType:KMGoogleDrive
  205. localPath:localPath
  206. loadState:KMCloudLoadState_Upload
  207. currentConvetProgress:currentProgress
  208. completion:completion];
  209. // if ([self isLoadOperationExisting:op]) {
  210. // return nil;
  211. // } else {
  212. // [queue addUploadOperation:op];
  213. // [operationArr addObject:op];
  214. // }
  215. if (![self isSignedIn]) {
  216. [self runSigninThenHandler:nil];
  217. } else {
  218. if (![self isLoadOperationExisting:op]) {
  219. [queue addUploadOperation:op];
  220. }
  221. }
  222. return op;
  223. }
  224. - (void)uploadCancel:(KMCloudOperation *)operation
  225. {
  226. if ([self isLoadOperationExisting:operation]) {
  227. [operation cancel];
  228. KMCloudUploadOperationQueue *queue = [KMCloudUploadOperationQueue sharedInstance];
  229. [queue cancel:operation.filePath];
  230. [self removeUploadOperation:operation];
  231. } else {
  232. return;
  233. }
  234. }
  235. #pragma mark - 下载
  236. - (KMCloudOperation *)downloadCloudPath:(KMServicesCloudFile *)cloudPath
  237. localPath:(NSURL *)localPath
  238. currentConvetProgress:(CurrentProgressCallBack)currentProgress
  239. completion:(CompletionCallBack)completion
  240. {
  241. KMCloudDownloadOperationQueue *queue = [KMCloudDownloadOperationQueue sharedInstance];
  242. queue.maxConcurrentOperationCount = 4;
  243. queue.name = cloudPath.displayName;
  244. KMCloudOperation *op = [[KMCloudOperation alloc] initWithLoadCloudPath:cloudPath
  245. serverType:KMGoogleDrive
  246. localPath:localPath
  247. loadState:KMCloudLoadState_Download
  248. currentConvetProgress:currentProgress
  249. completion:completion] ;
  250. if (![self isSignedIn]) {
  251. [self runSigninThenHandler:nil];
  252. } else {
  253. if (![self isLoadOperationExisting:op]) {
  254. [queue addDownloadOperation:op];
  255. }
  256. }
  257. return op;
  258. }
  259. - (void)downloadCancel:(KMCloudOperation *)operation
  260. {
  261. if ([self isLoadOperationExisting:operation]) {
  262. [operation cancel];
  263. KMCloudDownloadOperationQueue *queue = [KMCloudDownloadOperationQueue sharedInstance];
  264. [queue cancel:operation.filePath];
  265. [self removeDownloadOperation:operation];
  266. } else {
  267. return;
  268. }
  269. }
  270. #pragma mark - 删除
  271. - (void)deleteFileWithPath:(KMServicesCloudFile *)fileData
  272. completion:(CloudDeleteFileCallBack)completion
  273. {
  274. self.deleteFileBlock = completion;
  275. if (![self isSignedIn]) {
  276. [self runSigninThenHandler:nil];
  277. } else {
  278. GTLRDriveService *service = self.driveService;
  279. NSString *fileID = fileData.fileId;
  280. if (fileID) {
  281. GTLRDriveQuery_FilesDelete *query = [GTLRDriveQuery_FilesDelete queryWithFileId:fileID];
  282. self.editFileListTicket = [service executeQuery:query
  283. completionHandler:^(GTLRServiceTicket *callbackTicket,
  284. GTLRDrive_File *object,
  285. NSError *callbackError) {
  286. self.editFileListTicket = nil;
  287. if (callbackError == nil) {
  288. if (_deleteFileBlock) {
  289. _deleteFileBlock(fileData, YES);
  290. }
  291. [self getListWithFilePath:fileData setResponseBlock:^(NSArray<KMServicesCloudFile *> *fileList,KMServerType serviceType,NSError *error) {
  292. }]; //创建成功后,刷新文件列表
  293. } else {
  294. if (_deleteFileBlock) {
  295. _deleteFileBlock(fileData, NO);
  296. }
  297. }
  298. }];
  299. }
  300. }
  301. }
  302. #pragma mark - 创建文件夹
  303. - (void)createFolderWithPath:(KMServicesCloudFile *)fileData
  304. folderName:(NSString *)folderName
  305. completion:(CreateFolderCallBack)completion
  306. {
  307. self.createFolderBlock = completion;
  308. if (![self isSignedIn]) {
  309. [self runSigninThenHandler:nil];
  310. } else {
  311. [self createFolder:fileData folderName:(NSString *)folderName];
  312. }
  313. }
  314. - (void)createFolder:(KMServicesCloudFile *)fileData folderName:(NSString *)folderName
  315. {
  316. // NSString *parentsID = fileData.identifier;
  317. NSString *parentsID = [self getFolderPathWithFileData:fileData];
  318. GTLRDriveService *service = self.driveService;
  319. GTLRDrive_File *folderObj = [GTLRDrive_File object];
  320. folderObj.name = [NSString stringWithFormat:@"%@",folderName];
  321. folderObj.mimeType = @"application/vnd.google-apps.folder";
  322. folderObj.parents = @[parentsID];
  323. GTLRDriveQuery_FilesCreate *query = [GTLRDriveQuery_FilesCreate queryWithObject:folderObj uploadParameters:nil];
  324. self.editFileListTicket = [service executeQuery:query completionHandler:^(GTLRServiceTicket * _Nonnull callbackTicket, GTLRDrive_File *object, NSError * _Nullable callbackError) {
  325. self.editFileListTicket = nil;
  326. if (callbackError == nil) {
  327. KMServicesCloudFile *fileModel = [[KMServicesCloudFile alloc] init];
  328. fileModel.mimeType = object.mimeType;
  329. fileModel.fileId = object.identifier;
  330. fileModel.kind = object.kind;
  331. fileModel.fileName = object.name;
  332. fileModel.filetype = KMCloudServiceFileType_Folder;
  333. if (_createFolderBlock) {
  334. _createFolderBlock(fileModel, YES);
  335. }
  336. [self getListWithFilePath:fileData setResponseBlock:^(NSArray<KMServicesCloudFile *> *fileList,KMServerType serviceType,NSError *error) {
  337. }];
  338. } else {
  339. NSLog(@"创建文件失败 callbackError=%@",callbackError);
  340. if (_createFolderBlock) {
  341. _createFolderBlock(fileData, NO);
  342. }
  343. }
  344. }];
  345. }
  346. #pragma mark - 获取目录列表
  347. - (void)getListWithFilePath:(KMServicesCloudFile *)fileData setResponseBlock:(GetFileListCallBack)responseBlock
  348. {
  349. //暂时这么修改,如果需要显示全部的共享文件,需要将根目录修改为数组(GoogleDrive需要)
  350. if ([fileData.fileId isEqualToString:_localRootFolder.fileId]) {
  351. fileData = nil;
  352. }
  353. self.getFileListBlock = responseBlock;
  354. NSString *parentsID = [self getFolderPathWithFileData:fileData];
  355. if (fileData.displayName) {
  356. [self.cloudFilesCache setValue:fileData forKey:fileData.displayName];
  357. }
  358. if (![self isSignedIn]) {
  359. [self runSigninThenHandler:^{
  360. [self fetchFileList:parentsID];
  361. }];
  362. } else if ([parentsID isEqualToString:@""] || parentsID == nil) {
  363. [self fetchFileList:@""];
  364. } else {
  365. [localFileList removeAllObjects];
  366. GTLRDriveService *service = self.driveService;
  367. GTLRDriveQuery_FilesList *query = [GTLRDriveQuery_FilesList query];
  368. query.q = [NSString stringWithFormat:@"'%@' in parents",parentsID];
  369. query.pageSize = 1000;
  370. NSLog(@"query.q = %@",query.q);
  371. //ownedByMe:用户是否拥有该文件。未为共享驱动器中的项填充。
  372. //size:文件内容大小
  373. //webViewLink:在浏览器的相关Google编辑器或查看器中打开文件的链接。
  374. //thumbnailLink:指向文件缩略图的短时间链接(如果可用)。通常持续几个小时。仅当请求应用程序可以访问文件内容时填充。
  375. //starred: 用户是否为文件加了星。Uses NSNumber of boolValue.
  376. //modifiedByMeTime:用户上次修改文件的时间
  377. //lastModifyingUser:最后一个修改文件的用户
  378. //createdTime: 创建文件的时间
  379. //descriptionProperty:文件的简短描述。
  380. //fileExtension : 后缀名
  381. query.fields = @"nextPageToken,kind,files(mimeType,kind,id,ownedByMe,size,name,parents,modifiedTime,lastModifyingUser,createdTime,webViewLink,owners)";
  382. self.fileListTicket = [service executeQuery:query
  383. completionHandler:^(GTLRServiceTicket *callbackTicket,
  384. GTLRDrive_FileList *fileList,
  385. NSError *callbackError) {
  386. for (GTLRDrive_File *string in fileList.files) {
  387. NSLog(@"parents == %@, name == %@,mimeType==%@,kind==%@,webViewLink=%@, file.identifier==%@",string.parents , string.name,string.mimeType,string.kind, string.webViewLink, string.identifier);
  388. }
  389. // Callback
  390. self.fileListTicket = nil;
  391. if (callbackError == nil) {
  392. [self.localFileList removeAllObjects];
  393. for (GTLRDrive_File *file in fileList.files) {
  394. if ([file.parents[0] isEqualToString:parentsID]) {
  395. KMServicesCloudFile *tFileMeta = [[KMServicesCloudFile alloc] init];
  396. tFileMeta.mimeType = file.mimeType;
  397. tFileMeta.fileId = file.identifier;
  398. tFileMeta.kind = file.kind;
  399. tFileMeta.fileName = file.name;
  400. tFileMeta.ownedByMe = file.ownedByMe;
  401. tFileMeta.fileSize = file.size.integerValue;
  402. tFileMeta.fileModiDate = file.modifiedTime.date;
  403. tFileMeta.lastUserName = file.lastModifyingUser.displayName;
  404. tFileMeta.authorName = file.owners[0].displayName;
  405. tFileMeta.createdTime = file.createdTime.date;
  406. tFileMeta.webViewLink = file.webViewLink;
  407. tFileMeta.parensID = file.parents[0];
  408. if ([file.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
  409. tFileMeta.filetype = KMCloudServiceFileType_Folder;
  410. } else {
  411. tFileMeta.filetype = KMCloudServiceFileType_File;
  412. }
  413. tFileMeta.displayName = [NSString stringWithFormat:@"%@/%@",fileData.displayName, file.name];
  414. if (![file.name isEqualToString:@".DS_Store"] &&
  415. ![file.mimeType isEqualToString:@"application/vnd.google-apps.shortcut"]) {
  416. [self.localFileList addObject:tFileMeta];
  417. }
  418. }
  419. }
  420. if (_getFileListBlock) {
  421. _getFileListBlock(self.localFileList,KMGoogleDrive,nil);
  422. }
  423. } else {
  424. if (_getFileListBlock) {
  425. _getFileListBlock(nil,KMGoogleDrive,callbackError);
  426. }
  427. }
  428. }];
  429. }
  430. }
  431. #pragma mark -
  432. - (GTLRDriveService *)driveService {
  433. static GTLRDriveService *service;
  434. static dispatch_once_t onceToken;
  435. dispatch_once(&onceToken, ^{
  436. service = [[GTLRDriveService alloc] init];
  437. service.shouldFetchNextPages = YES;
  438. service.retryEnabled = YES;
  439. });
  440. return service;
  441. }
  442. #pragma mark - private methods
  443. - (void)removeUploadOperation:(KMCloudOperation *)operation {
  444. //将传输任务从队列里删除
  445. KMCloudUploadOperationQueue *queue = [KMCloudUploadOperationQueue sharedInstance];
  446. if ([queue isUploadOperationExisting:operation.filePath]) {
  447. NSLog(@"removeUploadOperation operation.filePath == %@",operation.filePath);
  448. [queue cancel:operation.filePath];
  449. }
  450. }
  451. - (void)removeDownloadOperation:(KMCloudOperation *)operation {
  452. //将传输任务从队列里删除
  453. KMCloudDownloadOperationQueue *queue = [KMCloudDownloadOperationQueue sharedInstance];
  454. if ([queue isDownloadOperationExisting:operation.filePath]) {
  455. NSLog(@"removeDownloadOperation operation.filePath == %@",operation.filePath);
  456. [queue cancel:operation.filePath];
  457. }
  458. }
  459. - (BOOL)isLoadOperationExisting:(KMCloudOperation *)operation {
  460. KMCloudUploadOperationQueue *uploadQueue = [KMCloudUploadOperationQueue sharedInstance];
  461. KMCloudDownloadOperationQueue *downloadQueue = [KMCloudDownloadOperationQueue sharedInstance];
  462. NSMutableArray *operationArr = [NSMutableArray array];
  463. for (NSArray *opArr in @[uploadQueue.operations, downloadQueue.operations]) {
  464. for (int j = 0; j < opArr.count; j++) {
  465. [operationArr addObject:opArr[j]];
  466. }
  467. }
  468. for (KMCloudOperation *op in operationArr) {
  469. if ([op.filePath isEqualToString:operation.filePath]) {
  470. return YES;
  471. }
  472. }
  473. return NO;
  474. }
  475. - (BOOL)isBlankString:(NSString *)aStr {
  476. if (!aStr) {
  477. return YES;
  478. }
  479. if ([aStr isKindOfClass:[NSNull class]]) {
  480. return YES;
  481. }
  482. NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  483. NSString *trimmedStr = [aStr stringByTrimmingCharactersInSet:set];
  484. if (!trimmedStr.length) {
  485. return YES;
  486. }
  487. return NO;
  488. }
  489. //获取文件对象所处的文件夹路径
  490. - (NSString *)getFolderPathWithFileData:(KMServicesCloudFile *)fileData {
  491. if ([fileData.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
  492. return fileData.fileId;
  493. } else {
  494. return fileData.parensID;
  495. }
  496. return nil;
  497. }
  498. - (void)fetchFileList:(NSString *)pathID {
  499. [localFileList removeAllObjects];
  500. GTLRDriveService *service = self.driveService;
  501. GTLRDriveQuery_FilesList *query = [GTLRDriveQuery_FilesList query];
  502. if (![pathID isEqualToString:@""]) {
  503. query.q = [NSString stringWithFormat:@"'%@' in parents",pathID];
  504. }
  505. query.pageSize = 1000;
  506. query.fields = @"nextPageToken,kind,files(mimeType,kind,id,ownedByMe,size,name,parents,modifiedTime,lastModifyingUser,createdTime,webViewLink,owners)";
  507. self.fileListTicket = [service executeQuery:query
  508. completionHandler:^(GTLRServiceTicket *callbackTicket,
  509. GTLRDrive_FileList *fileList,
  510. NSError *callbackError) {
  511. // self->_fileListFetchError = callbackError;
  512. self.fileListTicket = nil;
  513. if (callbackError == nil) {
  514. [self.localFileList removeAllObjects];
  515. if ([pathID isEqualToString:@""]) {
  516. NSMutableArray *locadParentsList = [[NSMutableArray alloc] init];
  517. NSMutableArray *locadIdList = [[NSMutableArray alloc] init];
  518. for (GTLRDrive_File *file in fileList.files) {
  519. // if ([file.mimeType isEqualToString:@"application/vnd.google-apps.spreadsheet"]) {
  520. if ([file.ownedByMe integerValue] == 0) {
  521. //googleDrive 共享文件
  522. KMServicesCloudFile *fileMeta = [[KMServicesCloudFile alloc] init];
  523. fileMeta.mimeType = file.mimeType;
  524. fileMeta.fileId = file.identifier;
  525. fileMeta.kind = file.kind;
  526. fileMeta.fileName = file.name;
  527. fileMeta.ownedByMe = file.ownedByMe;
  528. fileMeta.fileSize = file.size;
  529. fileMeta.fileModiDate = file.modifiedTime.date;
  530. fileMeta.displayName = file.lastModifyingUser.displayName;
  531. fileMeta.createdTime = file.createdTime.date;
  532. fileMeta.webViewLink = file.webViewLink;
  533. fileMeta.parensID = file.parents[0];
  534. fileMeta.authorName = file.owners[0].displayName;
  535. if ([file.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
  536. fileMeta.filetype = KMCloudServiceFileType_Folder;
  537. } else {
  538. fileMeta.filetype = KMCloudServiceFileType_File;
  539. }
  540. if (![file.name isEqualToString:@".DS_Store"] &&
  541. ![file.mimeType isEqualToString:@"application/vnd.google-apps.shortcut"] &&
  542. [self isBlankString:file.parents[0]]) {
  543. [self.localFileList addObject:fileMeta];
  544. }
  545. } else {
  546. if (![self isBlankString:file.parents[0]]) {
  547. [locadParentsList addObject:file.parents[0]];
  548. }
  549. [locadIdList addObject:file.identifier];
  550. }
  551. }
  552. for (NSString *parent in locadParentsList) {
  553. if (![locadIdList containsObject:parent]) {
  554. self.localRootFolder.fileId = parent;
  555. self.localRootFolder.parensID = parent;
  556. }
  557. }
  558. }
  559. for (GTLRDrive_File *file in fileList.files) {
  560. // NSLog(@"file.parents[0] == %@, file.name == %@",file.parents[0], file.name);
  561. if ([file.parents[0] isEqualToString:self.localRootFolder.fileId]) {
  562. KMServicesCloudFile *fileMeta = [[KMServicesCloudFile alloc] init];
  563. fileMeta.mimeType = file.mimeType;
  564. fileMeta.fileId = file.identifier;
  565. fileMeta.kind = file.kind;
  566. fileMeta.fileName = file.name;
  567. fileMeta.ownedByMe = file.ownedByMe;
  568. fileMeta.fileSize = file.size.integerValue;
  569. fileMeta.fileModiDate = file.modifiedTime.date;
  570. fileMeta.displayName = file.owners[0].displayName;
  571. fileMeta.createdTime = file.createdTime.date;
  572. fileMeta.webViewLink = file.webViewLink;
  573. fileMeta.parensID = file.parents[0];
  574. fileMeta.authorName = file.owners[0].displayName;
  575. if ([file.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
  576. fileMeta.filetype = KMCloudServiceFileType_Folder;
  577. } else {
  578. fileMeta.filetype = KMCloudServiceFileType_File;
  579. }
  580. if (![file.name isEqualToString:@".DS_Store"] &&
  581. ![file.mimeType isEqualToString:@"application/vnd.google-apps.shortcut"]) {
  582. [self.localFileList addObject:fileMeta];
  583. }
  584. }
  585. }
  586. if (_getFileListBlock) {
  587. _getFileListBlock(self.localFileList,KMGoogleDrive,nil);
  588. [self.localFileList removeAllObjects];
  589. }
  590. } else {
  591. if (_getFileListBlock) {
  592. _getFileListBlock(nil,KMGoogleDrive,callbackError);
  593. }
  594. }
  595. }];
  596. }
  597. @end