22

Estoy tratando de crear un álbum personalizado en la Biblioteca de fotos de un iPhone y luego guardar fotos que tomé con la cámara, o elegir desde los teléfonos Camera Roll a esa álbum personalizado Puedo crear el álbum correctamente, pero las fotos no se guardan allí, sino que se guardan en el álbum de simulaciones Saved Photos ... No estoy seguro de cómo decir UIImageWriteToSavedPhotosAlbum para guardar en el nuevo álbum que acabo de crear usando addAssetsGroupAlbumWithName ...Guardar fotos en álbum personalizado en la biblioteca de fotos de iPhones

Aquí está el código que tengo hasta ahora - he corté unas cuantas secciones de mantener mi ejemplo de código corto ...

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{  
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; 
    if([mediaType isEqualToString:(__bridge NSString *)kUTTypeImage]) 
    {   
    // pull GPS information from photos metadata using ALAssetsLibrary 
    void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *) = ^(ALAsset *asset) 
    { 
     // code snipped out 
    }; 
    NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL]; 
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
    [library assetForURL:assetURL 
      resultBlock:ALAssetsLibraryAssetForURLResultBlock 
      failureBlock:^(NSError *error) 
      { 
       // code snipped out 
      }]; 

    // getimage from imagePicker and resize it to the max size of the iPhone screen 
    UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage]; 
    UIImage *resizedImage = [util_ createThumbnailForImage:originalImage thumbnailSize:[util_ determineIPhoneScreenSize]]; 
    NSData *imageData = UIImagePNGRepresentation(resizedImage); 

       // code snipped out 
       // code snipped out 
       // code snipped out 
       // code snipped out 
       // code snipped out 
       // code snipped out 



    // create a new album called "My Apps Photos" 
    [library addAssetsGroupAlbumWithName:@"My Apps Photos" 
      resultBlock:^(ALAssetsGroup *group) 
      { 
       NSLog(@"in addAssetsGroupAlbumWithName resultBlock"); 

       // save file to album 
       UIImageWriteToSavedPhotosAlbum(resizedImage, self, nil, nil); 

      } 
      failureBlock:^(NSError *error) 
      { 
       NSLog(@"in addAssetsGroupAlbumWithName failureBlock"); 

      } 
    ]; 
    } 
} 

Entonces ... Como he dicho, crea el nuevo álbum pero no guarda la foto allí. ¿Cómo digo que guarde en el nuevo álbum? Quizás suene no usar UIImageWriteToSavedPhotosAlbum ??

Nota: Estoy usando Xcode 4.3.2, iOS 5.1, y ARC

Respuesta

59

Si está utilizando iOS 6, la respuesta de Fernando no va a funcionar, porque el selector de saveImage ya no está disponible.

El proceso es bastante confuso, y no he visto ninguna respuesta clara publicada, así que este es el método que he usado para resolver esto en iOS6.

Usted tendrá que utilizar una combinación de los siguientes:

crear el álbum:

[self.library addAssetsGroupAlbumWithName:albumName 
           resultBlock:^(ALAssetsGroup *group) { 
     NSLog(@"added album:%@", albumName); 
} 
          failureBlock:^(NSError *error) { 
     NSLog(@"error adding album"); 
}]; 

encontrar el álbum:

__block ALAssetsGroup* groupToAddTo; 
[self.library enumerateGroupsWithTypes:ALAssetsGroupAlbum 
          usingBlock:^(ALAssetsGroup *group, BOOL *stop) { 
     if ([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:albumName]) { 
      NSLog(@"found album %@", albumName); 
      groupToAddTo = group; 
     } 
} 
          failureBlock:^(NSError* error) { 
    NSLog(@"failed to enumerate albums:\nError: %@", [error localizedDescription]); 
}]; 

guardar la imagen en Biblioteca de activos, y ponerlo en el álbum:

CGImageRef img = [image CGImage]; 
[self.library writeImageToSavedPhotosAlbum:img 
            metadata:[info objectForKey:UIImagePickerControllerMediaMetadata] 
          completionBlock:^(NSURL* assetURL, NSError* error) { 
    if (error.code == 0) { 
     NSLog(@"saved image completed:\nurl: %@", assetURL); 

     // try to get the asset 
     [self.library assetForURL:assetURL 
         resultBlock:^(ALAsset *asset) { 
       // assign the photo to the album 
       [groupToAddTo addAsset:asset]; 
       NSLog(@"Added %@ to %@", [[asset defaultRepresentation] filename], albumName); 
      } 
         failureBlock:^(NSError* error) { 
       NSLog(@"failed to retrieve image asset:\nError: %@ ", [error localizedDescription]); 
      }]; 
    } 
    else { 
     NSLog(@"saved image failed.\nerror code %i\n%@", error.code, [error localizedDescription]); 
    } 
}]; 
+0

me sale un problema con nuestro código causando un ACCESO BAD EXC en la '[ groupToAddTo addAsset: asset]; ' - ¿Alguna idea, por favor? Cheers .. – theiOSDude

+0

Una posible causa es que la variable de su biblioteca ya no es válida; necesita que su biblioteca permanezca allí mientras esté accediendo a los objetos que generó al usarla; es decir, no puede hacer que la biblioteca se desasocie y luego intente ejecutar un selector en groupToAddTo ... Normalmente hago que la biblioteca sea una propiedad y la inicializo en viewDidLoad. –

+0

La respuesta de Fernando me funcionó en iOS 6.0.1 –

3

El código de @Scott Allen estaba cerca pero no me salvó la imagen la primera vez. Entonces, si no hubiera creado el álbum, la imagen no se guardaría. Mi solución fue trasladar este fragmento que crea el álbum a los didFinishLaunchingWithOptions aplicación de delegado:

NSString *[email protected]"album name"; 
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
[library addAssetsGroupAlbumWithName:albumName 
         resultBlock:^(ALAssetsGroup *group) { 
          NSLog(@"added album:%@", albumName); 
         } 
         failureBlock:^(NSError *error) { 
          NSLog(@"error adding album"); 
         }]; 
2

No he visto respuestas muy claras y el código a estas preguntas. Para mí, quería asegurarme de que el álbum fue encontrado o creado, antes de encender la cámara. Este código parece ser correcto, y creo que es un poco más limpio y fácil de robar^H^H^H^H^HInicio de.

// find or create our photo album. If either works 
// we fire up the camera. Crazy asynchronous code here. 

__weak PhotoVC *weakSelf = self; 
__block BOOL found = NO; 

ALAssetsLibraryGroupsEnumerationResultsBlock 
assetGroupEnumerator = ^(ALAssetsGroup *group, BOOL *stop){ 
    if (group) { 
     NSString *thisGroup = [group valueForProperty:ALAssetsGroupPropertyName]; 
     if ([album isEqualToString:thisGroup]) { 
      NSLog(@"album found!"); 
      [weakSelf startCamera: group]; 
      *stop = YES; 
      found = YES; 
     } 
    } else { // not found, create the album 
     if (found) 
      return; 
     NSLog(@"album not found, try making album"); 

     ALAssetsLibraryGroupResultBlock addGroup = 
     ^(ALAssetsGroup *group){ 
      NSLog(@"album created"); 
      [weakSelf startCamera: group]; 
     }; 

     ALAssetsLibraryAccessFailureBlock addGroupFailed = 
     ^(NSError *err){ 
      NSLog(@"add group failed: %@", [err localizedDescription]); 
     }; 

     [library addAssetsGroupAlbumWithName:album resultBlock:addGroup failureBlock:addGroupFailed]; 
    } 
}; 

[library enumerateGroupsWithTypes:ALAssetsGroupAlbum 
         usingBlock:assetGroupEnumerator 
        failureBlock:^(NSError *error) { 
         NSLog(@"album access denied"); 
        }]; 

Tom Duff's law: robo el código siempre que pueda.

11

respuesta de Fernando trabajó para mí en iOS 7.

Pasos:

1) Descarga el código ALAssetsLibrary + CustomPhotoAlbum desde aquí: http://www.touch-code-magazine.com/wp-content/uploads/2011/11/ALAssetsLibrary_CustomPhotoAlbum.zip?a071b6 y copiar los 2 archivos para la categoría dentro de su proyecto de Xcode.

2) En el archivo de cabecera, añadir las siguientes líneas

#import <AssetsLibrary/AssetsLibrary.h> 
#import "ALAssetsLibrary+CustomPhotoAlbum.h" 

@property (strong, atomic) ALAssetsLibrary* library; 

3) en su archivo de aplicación, añadir las siguientes líneas

@synthesize library=_library; 

EDIT: 4) inicializar la biblioteca de activos instancia, preferiblemente en el método "viewDidLoad"; de lo contrario, el método saveImage a continuación no se ejecutará. (CONFIRMADO):

[estoy de volver a presentar la edición sugerido porque alguien con habilidades no iphone rechazó la presentación anterior. Esta es, sin duda, una gran respuesta por @santhu & Fernando y me ayudó mucho, sin embargo, faltaba la pieza de inicialización del código, así que me tomó un poco de tiempo averiguar por qué el código no funcionaba. Por lo tanto, le agradecería si un moderador con el iPhone de habilidades de desarrollo revisa el editar]

_library = [[ALAssetsLibrary alloc] init]; 

5) Agregar esto en el método en el que desea guardar

//Add this in the method where you wish to save 
    [self.library saveImage:(UIImage *) toAlbum:(NSString *) withCompletionBlock:^(NSError     *error) { 
    if (error!=nil) { 
     NSLog(@"Big error: %@", [error description]); 
    } 
}]; 
+0

funcionó para mí, gracias. – makkuzu

+0

No funciona en iOS8. – SarpErdag

9

Para los usuarios de SWIFT: -. Hice función para hacer lo mismo.

cierre declare definición de clase outsize (por encima de definición de clase)

typealias CompletionHandler = (success:Bool!) -> Void 

declarar variable de biblioteca dentro de clase

var library:ALAssetsLibrary?; 

inicializar variable en viewDidLoad

library = ALAssetsLibrary(); 

método para agregar la imagen al álbum especial

func addImage(image:UIImage, metaData:NSDictionary, toAlbum albumName:String, handler:CompletionHandler){ 

    library?.addAssetsGroupAlbumWithName(albumName, resultBlock: {(group:ALAssetsGroup!) -> Void in 
     print("\nAlbum Created:= \(albumName)"); 
     /*-- Find Group --*/ 

     var groupToAddTo:ALAssetsGroup?; 

     self.library?.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupAlbum), 
      usingBlock: { (group:ALAssetsGroup?, stop:UnsafeMutablePointer<ObjCBool>) -> Void in 

       if(group != nil){ 

        if group!.valueForProperty(ALAssetsGroupPropertyName) as String == albumName{ 
         groupToAddTo = group; 

         print("\nGroup Found \(group!.valueForProperty(ALAssetsGroupPropertyName))\n"); 

         self.library?.writeImageToSavedPhotosAlbum(image.CGImage, metadata:metaData, completionBlock: {(assetURL:NSURL!,error:NSError!) -> Void in 

          if(error == nil){ 
           self.library?.assetForURL(assetURL, 
            resultBlock: { (asset:ALAsset!) -> Void in 
             var yes:Bool? = groupToAddTo?.addAsset(asset); 
             if (yes == true){ 
              handler(success: true); 
             } 
            }, 
            failureBlock: { (error2:NSError!) -> Void in 
             print("Failed to add asset"); 
             handler(success: false); 
           }); 
          } 
         }); 
        } 
       } /*Group Is Not nil*/ 
      }, 
      failureBlock: { (error:NSError!) -> Void in 
       print("Failed to find group"); 
       handler(success: false); 
     }); 

     }, failureBlock: { (error:NSError!) -> Void in 
      print("Failed to create \(error)"); 
      handler(success: false); 
    }); 
} 

llamada a este método como: -

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]){ 

    var image:UIImage = info[UIImagePickerControllerOriginalImage] as UIImage; 
    var metadata:NSDictionary = info[UIImagePickerControllerMediaMetadata] as NSDictionary; 

    self.addImage(image, metaData: metadata, toAlbum: "SwiftAlbum") { (success) -> Void in 
     print("Image Added : \(success)"); 
    } 

    picker.dismissViewControllerAnimated(true, completion: nil); 
} 
+0

Funciona con encanto en iOS8 (8.1.3) gracias – TimWhiting

+0

Tenga cuidado con el bit de metadatos en self.addImage (image, metaData: metadata, toAlbum: "SwiftAlbum"). Porque si no hay ninguno (que a menudo es el caso) obtendrá un error – TimWhiting

+3

ALAssetsLibrary será Deprecated en iOS 9.0 – Lucas

Cuestiones relacionadas