22

Sto provando a creare un album personalizzato nella libreria di foto di un iPhone e quindi salvare le foto che ho scattato con la fotocamera o scelto dai telefoni album personalizzato. Posso creare l'album con successo ma le foto non vengono salvate qui, ma vengono salvate nei simulatori Album di foto salvate ... Non so come dire a UIImageWriteToSavedPhotosAlbum di salvare nel nuovo album che ho appena creato usando addAssetsGroupAlbumWithName ...Salvare le foto in album personalizzato nell'iPhone Photo Library

Ecco il codice che ho finora - ho tagliò fuori un paio di sezioni per mantenere il mio esempio di codice breve ...

- (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"); 

      } 
    ]; 
    } 
} 

quindi ... Come ho detto, è crea il nuovo album ma non salva la foto lì. Come posso dire di salvarlo nel nuovo album? Forse suono non usare UIImageWriteToSavedPhotosAlbum ??

Nota: sto usando Xcode 4.3.2, iOS 5.1, e ARC

risposta

59

Se si utilizza iOS6, la risposta di Fernando non funziona, perché il selettore SaveImage non è più disponibile.

Il processo è piuttosto confuso, e non ho visto nessuna risposta chiara pubblicata, quindi ecco il metodo che ho usato per risolvere questo in iOS6.

Sarà necessario utilizzare una combinazione dei seguenti elementi:

creare l'album:

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

trovare l'album:

__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]); 
}]; 

salvare l'immagine Asset Library e inseriscile nell'album:

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

ottengo un problema con il nostro codice di provocare un ACCESSO BAD EXC sul '[ groupToAddTo addAsset: asset]; ' - Qualche idea per favore? Cheers .. – theiOSDude

+0

Una possibile causa è che la tua variabile di libreria non è più valida - hai bisogno che la tua libreria rimanga in gioco finché si accede agli oggetti che hai generato utilizzandolo; Ad esempio, non è possibile ottenere il dealloc'd della libreria e quindi provare a eseguire un selettore su groupToAddTo ... Generalmente la libreria è una proprietà e la si inizializza in viewDidLoad. –

+0

La risposta di Fernando ha funzionato per me in iOS 6.0.1 –

3

Il codice di @Scott Allen era vicino ma non salvava l'immagine per me la prima volta. Quindi, se non avessi già creato l'album, l'immagine non salverebbe. La mia soluzione era quella di spostare questo frammento di codice che crea l'album ai didFinishLaunchingWithOptions app delegato:

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

non ho visto risposte molto chiare e il codice a queste domande. Per quanto mi riguarda, volevo assicurarmi che l'album fosse stato trovato o creato, prima che accendessi la fotocamera. Questo codice sembra avere ragione, e penso che sia un po 'più pulito e più facile da rubare^H^H^H^H^Hstart da.

// 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"); 
        }]; 

La legge di Tom Duff: rubare il codice quando è possibile.

11

risposta di Fernando ha lavorato per me in iOS 7.

Passi:

1) Scaricare il codice ALAssetsLibrary + CustomPhotoAlbum da qui: http://www.touch-code-magazine.com/wp-content/uploads/2011/11/ALAssetsLibrary_CustomPhotoAlbum.zip?a071b6 e copiare i file 2 per la categoria all'interno del vostro progetto Xcode.

2) Nel file di intestazione, aggiungere le seguenti righe

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

@property (strong, atomic) ALAssetsLibrary* library; 

3) Nel file di implementazione, aggiungere le seguenti linee

@synthesize library=_library; 

EDIT: 4) inizializzare la libreria di asset esempio, preferibilmente nel metodo "viewDidLoad", altrimenti il ​​metodo saveImage di seguito non verrà eseguito. (CONFERMATO):

[sto inviare nuovamente la modifica suggerita perché qualcuno con le abilità di non-iPhone ha respinto la presentazione precedente. Questa è senza dubbio un'ottima risposta di @santhu & Fernando e mi ha aiutato molto, tuttavia, mancava il codice di inizializzazione del codice, quindi mi ci è voluto un po 'di tempo per capire perché il codice non funzionava. Quindi, sarei grato se un moderatore con iPhone sviluppo skillset cliente la modifica]

_library = [[ALAssetsLibrary alloc] init]; 

5) Aggiungere questo nel metodo in cui si desidera salvare

//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

Ha funzionato per me, grazie. – makkuzu

+0

Non funziona su iOS8. – SarpErdag

9

Per gli utenti veloci: -. Ho fatto funzione per fare la stessa cosa

chiusura dichiarare definizione della classe fuori standard (sopra definizione di classe)

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

dichiarare variabile libreria all'interno classe

var library:ALAssetsLibrary?; 

inizializzare variabile in viewDidLoad

library = ALAssetsLibrary(); 

metodo per aggiungere un'immagine a particolari Album

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); 
    }); 
} 

chiamare questo metodo come: -

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

Funziona con un fascino in iOS8 (8.1.3) grazie a – TimWhiting

+0

Fai attenzione con il bit metaData in self.addImage (immagine, metaData: metadata, toAlbum: "SwiftAlbum"). Perché se non ce n'è uno (che è abbastanza spesso il caso) riceverai un errore – TimWhiting

+3

ALAssetsLibrary verrà Deprecato in iOS 9.0 – Lucas