// // NCAutoUpload.m // Nextcloud iOS // // Created by Marino Faggiana on 07/06/17. // Copyright (c) 2017 TWS. All rights reserved. // // Author Marino Faggiana // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // #import "NCAutoUpload.h" #import "AppDelegate.h" #import "NCBridgeSwift.h" #pragma GCC diagnostic ignored "-Wundeclared-selector" @interface NCAutoUpload () { CCHud *_hud; } @end @implementation NCAutoUpload + (NCAutoUpload *)sharedInstance { static NCAutoUpload *sharedInstance; @synchronized(self) { if (!sharedInstance) { sharedInstance = [NCAutoUpload new]; } return sharedInstance; } } #pragma -------------------------------------------------------------------------------------------- #pragma mark === initStateAutoUpload === #pragma -------------------------------------------------------------------------------------------- - (void)initStateAutoUpload { tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive]; if (account.autoUpload) { [self setupAutoUpload]; if (account.autoUploadBackground) { [self checkIfLocationIsEnabled]; } } else { [[CCManageLocation sharedInstance] stopSignificantChangeUpdates]; } } #pragma -------------------------------------------------------------------------------------------- #pragma mark === Camera Upload & Full === #pragma -------------------------------------------------------------------------------------------- - (void)setupAutoUpload { if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { [self performSelectorOnMainThread:@selector(uploadNewAssets) withObject:nil waitUntilDone:NO]; } else { tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive]; if (account.autoUpload == YES) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUpload" state:NO]; [[CCManageLocation sharedInstance] stopSignificantChangeUpdates]; UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_access_photo_not_enabled_", nil) message:NSLocalizedString(@"_access_photo_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; return; } } - (void)setupAutoUploadFull { if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { [self performSelectorOnMainThread:@selector(uploadFullAssets) withObject:nil waitUntilDone:NO]; } else { tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive]; if (account.autoUpload == YES) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUpload" state:NO]; [[CCManageLocation sharedInstance] stopSignificantChangeUpdates]; UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_access_photo_not_enabled_", nil) message:NSLocalizedString(@"_access_photo_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } } #pragma -------------------------------------------------------------------------------------------- #pragma mark === Location === #pragma -------------------------------------------------------------------------------------------- - (BOOL)checkIfLocationIsEnabled { tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive]; [CCManageLocation sharedInstance].delegate = self; if ([CLLocationManager locationServicesEnabled]) { NSLog(@"[LOG] checkIfLocationIsEnabled : authorizationStatus: %d", [CLLocationManager authorizationStatus]); if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedAlways) { if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined ) { NSLog(@"[LOG] checkIfLocationIsEnabled : Location services not determined"); [[CCManageLocation sharedInstance] startSignificantChangeUpdates]; } else { if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { if (account.autoUploadBackground == YES) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUploadBackground" state:NO]; UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_location_not_enabled_", nil) message:NSLocalizedString(@"_location_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } else { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_access_photo_not_enabled_", nil) message:NSLocalizedString(@"_access_photo_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } } } else { if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { if (account.autoUploadBackground == NO) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUploadBackground" state:YES]; [[CCManageLocation sharedInstance] startSignificantChangeUpdates]; } else { if (account.autoUploadBackground == YES) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUploadBackground" state:NO]; [[CCManageLocation sharedInstance] stopSignificantChangeUpdates]; UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_access_photo_not_enabled_", nil) message:NSLocalizedString(@"_access_photo_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } } } else { if (account.autoUploadBackground == YES) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUploadBackground" state:NO]; [[CCManageLocation sharedInstance] stopSignificantChangeUpdates]; if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_location_not_enabled_", nil) message:NSLocalizedString(@"_location_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } else { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_access_photo_location_not_enabled_", nil) message:NSLocalizedString(@"_access_photo_location_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } } tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive]; return tableAccount.autoUploadBackground; } - (void)statusAuthorizationLocationChanged { tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive]; if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined){ if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) { if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { if ([CCManageLocation sharedInstance].firstChangeAuthorizationDone) { if (account.autoUploadBackground == YES) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUploadBackground" state:NO]; [[CCManageLocation sharedInstance] stopSignificantChangeUpdates]; } } else { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_access_photo_not_enabled_", nil) message:NSLocalizedString(@"_access_photo_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } } else if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined){ if (account.autoUploadBackground == YES) { [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUploadBackground" state:NO]; [[CCManageLocation sharedInstance] stopSignificantChangeUpdates]; if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_location_not_enabled_", nil) message:NSLocalizedString(@"_location_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } else { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_access_photo_location_not_enabled_", nil) message:NSLocalizedString(@"_access_photo_location_not_enabled_msg_", nil) preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; [alertController addAction:okAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil]; } } } if (![CCManageLocation sharedInstance].firstChangeAuthorizationDone) { [CCManageLocation sharedInstance].firstChangeAuthorizationDone = YES; } } } - (void)changedLocation { // Only in background tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive]; if (account.autoUpload && account.autoUploadBackground && [[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) { if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { //check location if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) { NSLog(@"[LOG] Changed Location call uploadNewAssets"); [self uploadNewAssets]; } } else { if (account.autoUpload == YES) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUpload" state:NO]; if (account.autoUploadBackground == YES) [[NCManageDatabase sharedInstance] setAccountAutoUploadProperty:@"autoUploadBackground" state:NO]; [[CCManageLocation sharedInstance] stopSignificantChangeUpdates]; } } } #pragma -------------------------------------------------------------------------------------------- #pragma mark ===== Upload Assets : NEW & FULL ==== #pragma -------------------------------------------------------------------------------------------- - (void)uploadNewAssets { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ [self uploadAssetsNewAndFull:NO]; }); } - (void)uploadFullAssets { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ [self uploadAssetsNewAndFull:YES]; }); } - (void)uploadAssetsNewAndFull:(BOOL)assetsFull { if (!app.activeAccount || app.maintenanceMode) return; tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive]; // Check Asset : NEW or FULL PHFetchResult *newAssetToUpload = [self getCameraRollAssets:account assetsFull:assetsFull alignPhotoLibrary:NO]; // News Assets ? if no verify if blocked Table Auto Upload -> Autostart if ([newAssetToUpload count] == 0) { NSLog(@"[LOG] Auto upload, no new asset found"); return; } else { NSLog(@"[LOG] Auto upload, new %lu asset found", (unsigned long)[newAssetToUpload count]); } dispatch_async(dispatch_get_main_queue(), ^{ if (assetsFull) { if (!_hud) _hud = [[CCHud alloc] initWithView:[[[UIApplication sharedApplication] delegate] window]]; [_hud visibleHudTitle:NSLocalizedString(@"_create_full_upload_", nil) mode:MBProgressHUDModeIndeterminate color:nil]; } }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) { if (assetsFull) [self performSelectorOnMainThread:@selector(uploadFullAssetsToNetwork:) withObject:newAssetToUpload waitUntilDone:NO]; else [self performSelectorOnMainThread:@selector(uploadNewAssetsToNetwork:) withObject:newAssetToUpload waitUntilDone:NO]; }); } - (void)uploadNewAssetsToNetwork:(PHFetchResult *)newAssetToUpload { [self uploadAssetsToNetwork:newAssetToUpload assetsFull:NO]; } - (void)uploadFullAssetsToNetwork:(PHFetchResult *)newAssetToUpload { [self uploadAssetsToNetwork:newAssetToUpload assetsFull:YES]; } - (void)uploadAssetsToNetwork:(PHFetchResult *)newAssetToUpload assetsFull:(BOOL)assetsFull { tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive]; NSMutableArray *metadataNetFull = [NSMutableArray new]; NSString *autoUploadPath = [[NCManageDatabase sharedInstance] getAccountAutoUploadPath:app.activeUrl]; BOOL useSubFolder = tableAccount.autoUploadCreateSubfolder; // Create the folder for Photos & if request the subfolders if(![[NCAutoUpload sharedInstance] createFolderSubFolderAutoUploadFolderPhotos:autoUploadPath useSubFolder:useSubFolder assets:newAssetToUpload selector:selectorUploadAutoUploadAll]) { // end loading [_hud hideHud]; return; } for (PHAsset *asset in newAssetToUpload) { NSString *serverUrl; NSDate *assetDate = asset.creationDate; PHAssetMediaType assetMediaType = asset.mediaType; NSString *session; NSString *fileName = [CCUtility createFileName:[asset valueForKey:@"filename"] fileDate:asset.creationDate fileType:asset.mediaType keyFileName:k_keyFileNameAutoUploadMask keyFileNameType:k_keyFileNameAutoUploadType]; // Select type of session if (assetMediaType == PHAssetMediaTypeImage && tableAccount.autoUploadWWAnPhoto == NO) session = k_upload_session; if (assetMediaType == PHAssetMediaTypeVideo && tableAccount.autoUploadWWAnVideo == NO) session = k_upload_session; if (assetMediaType == PHAssetMediaTypeImage && tableAccount.autoUploadWWAnPhoto) session = k_upload_session_wwan; if (assetMediaType == PHAssetMediaTypeVideo && tableAccount.autoUploadWWAnVideo) session = k_upload_session_wwan; NSDateFormatter *formatter = [NSDateFormatter new]; [formatter setDateFormat:@"yyyy"]; NSString *yearString = [formatter stringFromDate:assetDate]; [formatter setDateFormat:@"MM"]; NSString *monthString = [formatter stringFromDate:assetDate]; if (useSubFolder) serverUrl = [NSString stringWithFormat:@"%@/%@/%@", autoUploadPath, yearString, monthString]; else serverUrl = autoUploadPath; CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:app.activeAccount]; metadataNet.assetLocalIdentifier = asset.localIdentifier; if (assetsFull) { metadataNet.selector = selectorUploadAutoUploadAll; // Option if ([[NCBrandOptions sharedInstance] use_storeLocalAutoUploadAll] == true) metadataNet.selectorPost = nil; else metadataNet.selectorPost = selectorUploadRemovePhoto; } else { metadataNet.selector = selectorUploadAutoUpload; metadataNet.selectorPost = nil; } if (assetMediaType == PHAssetMediaTypeImage) metadataNet.priority = k_priorityAutoUploadImage; else metadataNet.priority = k_priorityAutoUploadVideo; metadataNet.fileName = fileName; metadataNet.serverUrl = serverUrl; metadataNet.session = session; metadataNet.taskStatus = k_taskStatusResume; [metadataNetFull addObject:metadataNet]; // Update database if (!assetsFull) [self addQueueUploadAndPhotoLibrary:metadataNet asset:asset]; } // Insert all assets (Full) in tableQueueUpload if (assetsFull && [metadataNetFull count] > 0) { [[NCManageDatabase sharedInstance] addQueueUploadWithMetadatasNet:metadataNetFull]; // Update icon badge number [app updateApplicationIconBadgeNumber]; } // end loading [_hud hideHud]; } - (void)addQueueUploadAndPhotoLibrary:(CCMetadataNet *)metadataNet asset:(PHAsset *)asset { @synchronized(self) { if ([[NCManageDatabase sharedInstance] addQueueUploadWithMetadataNet:metadataNet]) { [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Auto Upload, add new asset" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:app.activeUrl]; } else { [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Auto Upload, asset already present or db in write transaction" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:app.activeUrl]; } // Add asset in table Photo Library if ([metadataNet.selector isEqualToString:selectorUploadAutoUpload]) { if (![[NCManageDatabase sharedInstance] addPhotoLibrary:@[asset]]) { [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Photo Library, db in write transaction" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:app.activeUrl]; } } dispatch_async(dispatch_get_main_queue(), ^{ // Update icon badge number [app updateApplicationIconBadgeNumber]; }); } } #pragma -------------------------------------------------------------------------------------------- #pragma mark ===== Create Folder SubFolder Auto Upload Folder Photos ==== #pragma -------------------------------------------------------------------------------------------- - (BOOL)createFolderSubFolderAutoUploadFolderPhotos:(NSString *)folderPhotos useSubFolder:(BOOL)useSubFolder assets:(PHFetchResult *)assets selector:(NSString *)selector { OCnetworking *ocNetworking = [[OCnetworking alloc] initWithDelegate:nil metadataNet:nil withUser:app.activeUser withUserID:app.activeUserID withPassword:app.activePassword withUrl:app.activeUrl]; if ([ocNetworking automaticCreateFolderSync:folderPhotos]) { (void)[[NCManageDatabase sharedInstance] addDirectoryWithServerUrl:folderPhotos permissions:nil]; } else { // Activity [[NCManageDatabase sharedInstance] addActivityClient:folderPhotos fileID:@"" action:k_activityDebugActionAutoUpload selector:selector note:NSLocalizedStringFromTable(@"_not_possible_create_folder_", @"Error", nil) type:k_activityTypeFailure verbose:k_activityVerboseDefault activeUrl:app.activeUrl]; if ([selector isEqualToString:selectorUploadAutoUploadAll]) [app messageNotification:@"_error_" description:@"_error_createsubfolders_upload_" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:0]; return false; } // Create if request the subfolders if (useSubFolder) { for (NSString *dateSubFolder in [CCUtility createNameSubFolder:assets]) { if ([ocNetworking automaticCreateFolderSync:[NSString stringWithFormat:@"%@/%@", folderPhotos, dateSubFolder]]) { (void)[[NCManageDatabase sharedInstance] addDirectoryWithServerUrl:[NSString stringWithFormat:@"%@/%@", folderPhotos, dateSubFolder] permissions:nil]; } else { // Activity [[NCManageDatabase sharedInstance] addActivityClient:[NSString stringWithFormat:@"%@/%@", folderPhotos, dateSubFolder] fileID:@"" action:k_activityDebugActionAutoUpload selector:selector note:NSLocalizedString(@"_error_createsubfolders_upload_",nil) type:k_activityTypeFailure verbose:k_activityVerboseDefault activeUrl:app.activeUrl]; if ([selector isEqualToString:selectorUploadAutoUploadAll]) [app messageNotification:@"_error_" description:@"_error_createsubfolders_upload_" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:0]; return false; } } } return true; } #pragma -------------------------------------------------------------------------------------------- #pragma mark ===== get Camera Roll new Asset ==== #pragma -------------------------------------------------------------------------------------------- - (PHFetchResult *)getCameraRollAssets:(tableAccount *)account assetsFull:(BOOL)assetsFull alignPhotoLibrary:(BOOL)alignPhotoLibrary { @synchronized(self) { if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil]; NSPredicate *predicateImage = [NSPredicate predicateWithFormat:@"mediaType = %i", PHAssetMediaTypeImage]; NSPredicate *predicateVideo = [NSPredicate predicateWithFormat:@"mediaType = %i", PHAssetMediaTypeVideo]; NSPredicate *predicate; NSMutableArray *newAssets =[NSMutableArray new]; if (alignPhotoLibrary || (account.autoUploadImage && account.autoUploadVideo)) { predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[predicateImage, predicateVideo]]; } else if (account.autoUploadImage) { predicate = predicateImage; } else if (account.autoUploadVideo) { predicate = predicateVideo; } else { return nil; } PHFetchOptions *fetchOptions = [PHFetchOptions new]; fetchOptions.predicate = predicate; PHAssetCollection *collection = result[0]; PHFetchResult *assets = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions]; if (assetsFull == NO) { NSString *creationDate; NSString *idAsset; NSArray *idsAsset = [[NCManageDatabase sharedInstance] getPhotoLibraryIdAssetWithImage:account.autoUploadImage video:account.autoUploadVideo]; for (PHAsset *asset in assets) { (asset.creationDate != nil) ? (creationDate = [NSString stringWithFormat:@"%@", asset.creationDate]) : (creationDate = @""); idAsset = [NSString stringWithFormat:@"%@%@%@", account.account, asset.localIdentifier, creationDate]; if (![idsAsset containsObject: idAsset]) [newAssets addObject:asset]; } return (PHFetchResult *)newAssets; } else { return assets; } } } return nil; } #pragma -------------------------------------------------------------------------------------------- #pragma mark ===== Align Photo Library ==== #pragma -------------------------------------------------------------------------------------------- - (void)alignPhotoLibrary { tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive]; PHFetchResult *assets = [self getCameraRollAssets:account assetsFull:YES alignPhotoLibrary:YES]; [[NCManageDatabase sharedInstance] clearTable:[tablePhotoLibrary class] account:app.activeAccount]; (void)[[NCManageDatabase sharedInstance] addPhotoLibrary:(NSArray *)assets]; NSLog(@"[LOG] Align Photo Library %lu", (unsigned long)[assets count]); } @end