ios swift photosframework

ios - Cómo obtener solo imágenes en el rollo de la cámara utilizando el Marco de Fotos



swift photosframework (8)

A través de algunos experimentos descubrimos una propiedad oculta que no figura en la documentación ( assetSource ). Básicamente, tiene que hacer una solicitud de recuperación regular, luego usar un predicado para filtrar los del rollo de la cámara. Este valor debe ser 3.

Código de muestra:

//fetch all assets, then sub fetch only the range we need var assets = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions) assets.enumerateObjectsUsingBlock { (obj, idx, bool) -> Void in results.addObject(obj) } var cameraRollAssets = results.filteredArrayUsingPredicate(NSPredicate(format: "assetSource == %@", argumentArray: [3])) results = NSMutableArray(array: cameraRollAssets)

El siguiente código carga imágenes que también se encuentran en iCloud o las imágenes de transmisión. ¿Cómo podemos limitar la búsqueda a solo imágenes en el rollo de la cámara?

var assets = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: nil)


Aquí está la versión de Objective-c proporcionada por Apple.

-(NSMutableArray *)getNumberOfPhotoFromCameraRoll:(NSArray *)array{ PHFetchResult *fetchResult = array[1]; int index = 0; unsigned long pictures = 0; for(int i = 0; i < fetchResult.count; i++){ unsigned long temp = 0; temp = [PHAsset fetchAssetsInAssetCollection:fetchResult[i] options:nil].count; if(temp > pictures ){ pictures = temp; index = i; } } PHCollection *collection = fetchResult[index]; if (![collection isKindOfClass:[PHAssetCollection class]]) { // return; } // Configure the AAPLAssetGridViewController with the asset collection. PHAssetCollection *assetCollection = (PHAssetCollection *)collection; PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil]; self. assetsFetchResults = assetsFetchResult; self. assetCollection = assetCollection; self.numberOfPhotoArray = [NSMutableArray array]; for (int i = 0; i<[assetsFetchResult count]; i++) { PHAsset *asset = assetsFetchResult[i]; [self.numberOfPhotoArray addObject:asset]; } NSLog(@"%lu",(unsigned long)[self.numberOfPhotoArray count]); return self.numberOfPhotoArray; }

Donde puedes agarrar los siguientes detalles

PHFetchResult *fetchResult = self.sectionFetchResults[1]; PHCollection *collection = fetchResult[6]; **value 1,6 used to get camera images** **value 1,0 used to get screen shots** **value 1,1 used to get hidden** **value 1,2 used to get selfies** **value 1,3 used to get recently added** **value 1,4 used to get videos** **value 1,5 used to get recently deleted** **value 1,7 used to get favorites**

link demo de Apple

Declara tu propiedad

@property (nonatomic, strong) NSArray *sectionFetchResults; @property (nonatomic, strong) PHFetchResult *assetsFetchResults; @property (nonatomic, strong) PHAssetCollection *assetCollection; @property (nonatomic, strong) NSMutableArray *numberOfPhotoArray;


Después de agregar los álbumes de Camera Roll y Photo Stream, Apple agregó los siguientes tipos de PHAssetCollectionSubtype en iOS 8.1:

  1. PHAssetCollectionSubtypeAlbumMyPhotoStream (junto con PHAssetCollectionTypeAlbum ): PHAssetCollectionTypeAlbum el álbum de Photo Stream.

  2. PHAssetCollectionSubtypeSmartAlbumUserLibrary (junto con PHAssetCollectionTypeSmartAlbum ): obtiene el álbum Camera Roll.

No he probado si esto es compatible con versiones anteriores con iOS 8.0.x sin embargo.


Esto puede ayudar. Puedes usar tu propio modelo de datos en lugar de AlbumModel que usé.

func getCameraRoll() -> AlbumModel { var cameraRollAlbum : AlbumModel! let cameraRoll = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil) cameraRoll.enumerateObjects({ (object: AnyObject!, count: Int, stop: UnsafeMutablePointer) in if object is PHAssetCollection { let obj:PHAssetCollection = object as! PHAssetCollection let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue) let assets = PHAsset.fetchAssets(in: obj, options: fetchOptions) if assets.count > 0 { let newAlbum = AlbumModel(name: obj.localizedTitle!, count: assets.count, collection:obj, assets: assets) cameraRollAlbum = newAlbum } } }) return cameraRollAlbum }


Me he estado golpeando la cabeza por esto también. No he encontrado ninguna forma de filtrar solo los activos en el dispositivo con fetchAssetsWithMediaType o fetchAssetsInAssetCollection. Puedo usar requestContentEditingInputWithOptions o requestImageDataForAsset para determinar si el activo está en el dispositivo o no, pero esto es asíncrono y parece que está usando demasiados recursos para hacer por cada activo en la lista. Tiene que haber una mejor manera.

PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil]; for (int i=0; i<[fetchResult count]; i++) { PHAsset *asset = fetchResult[i]; [asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) { if ([[info objectForKey:PHContentEditingInputResultIsInCloudKey] intValue] == 1) { NSLog(@"asset is in cloud"); } else { NSLog(@"asset is on device"); } }]; }


Si está buscando, como yo, el código de Objective C, y tampoco recibió la Respuesta de la nueva biblioteca / Marco de fotos ya que estaba obteniendo el código obsoleto de AssetsLibrary, entonces esto lo ayudará a: Swift

Variables globales:

var imageArray: [AnyObject] var mutableArray: [AnyObject] convenience func getAllPhotosFromCamera() { imageArray = [AnyObject]() mutableArray = [AnyObject]() var requestOptions: PHImageRequestOptions = PHImageRequestOptions() requestOptions.resizeMode = .Exact requestOptions.deliveryMode = .HighQualityFormat requestOptions.synchronous = true var result: PHFetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: nil) NSLog("%d", Int(result.count)) var manager: PHImageManager = PHImageManager.defaultManager() var images: [AnyObject] = [AnyObject](minimumCapacity: result.count) // assets contains PHAsset objects. var ima: UIImage for asset: PHAsset in result { // Do something with the asset manager.requestImageForAsset(asset, targetSize: PHImageManagerMaximumSize, contentMode: .Default, options: requestOptions, resultHandler: {(image: UIImage, info: [NSObject : AnyObject]) -> void in

C objetivo

Variables globales:

NSArray *imageArray; NSMutableArray *mutableArray;

El siguiente método te ayudará a:

-(void)getAllPhotosFromCamera { imageArray=[[NSArray alloc] init]; mutableArray =[[NSMutableArray alloc]init]; PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init]; requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact; requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; requestOptions.synchronous = true; PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil]; NSLog(@"%d",(int)result.count); PHImageManager *manager = [PHImageManager defaultManager]; NSMutableArray *images = [NSMutableArray arrayWithCapacity:[result count]]; // assets contains PHAsset objects. __block UIImage *ima; for (PHAsset *asset in result) { // Do something with the asset [manager requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:requestOptions resultHandler:^void(UIImage *image, NSDictionary *info) { ima = image; [images addObject:ima]; }]; } imageArray = [images copy]; // You can direct use NSMutuable Array images }


Si no desea confiar en una API no documentada, consulte [asset canPerformEditOperation:PHAssetEditOperationContent] . Esto solo devuelve verdadero si el original completo está disponible en el dispositivo.

Es cierto que esto también es frágil, pero las pruebas muestran que funciona para todos los tipos de fuentes de recursos (secuencia de fotos, sincronización de iTunes, etc.).


Si usa su propio PHCachingImageManager lugar de la instancia de PHImageManager compartida, cuando llame a requestImageForAsset:targetSize:contentMode:options:resultHandler: puede configurar una opción en PHImageRequestOptions para especificar que la imagen es local.

networkAccessAllowed Property

Un valor booleano que especifica si las fotos pueden descargar la imagen solicitada desde iCloud.

networkAccessAllowed

Discusión

Si es SÍ, y la imagen solicitada no se almacena en el dispositivo local, Photos descarga la imagen de iCloud. Para recibir una notificación sobre el progreso de la descarga, use la propiedad progressHandler para proporcionar un bloque al que Photos llame periódicamente mientras descarga la imagen. Si NO (el valor predeterminado) y la imagen no se encuentra en el dispositivo local, el valor de PHImageResultIsInCloudKey en el diccionario de información del controlador de resultados indica que la imagen no está disponible a menos que habilite el acceso a la red.