AVFoundation iOS: ¿cómo obtengo obras de arte de un archivo mp3?

Mi código:

- (void)metadata { AVURLAsset *asset = [AVURLAsset URLAssetWithURL:self.fileURL options:nil]; NSArray *artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyArtwork keySpace:AVMetadataKeySpaceCommon]; NSArray *titles = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyTitle keySpace:AVMetadataKeySpaceCommon]; NSArray *artists = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyArtist keySpace:AVMetadataKeySpaceCommon]; NSArray *albumNames = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyAlbumName keySpace:AVMetadataKeySpaceCommon]; AVMetadataItem *artwork = [artworks objectAtIndex:0]; AVMetadataItem *title = [titles objectAtIndex:0]; AVMetadataItem *artist = [artists objectAtIndex:0]; AVMetadataItem *albumName = [albumNames objectAtIndex:0]; if ([artwork.keySpace isEqualToString:AVMetadataKeySpaceID3]) { NSDictionary *dictionary = [artwork.value copyWithZone:nil]; self.currentSongArtwork = [UIImage imageWithData:[dictionary objectForKey:@"data"]]; } else if ([artwork.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) { self.currentSongArtwork = [UIImage imageWithData:[artwork.value copyWithZone:nil]]; } self.currentSongTitle = [title.value copyWithZone:nil]; self.currentSongArtist = [artist.value copyWithZone:nil]; self.currentSongAlbumName = [albumName.value copyWithZone:nil]; self.currentSongDuration = self.audioPlayer.duration; } 

Esto funciona para buscar ilustraciones de archivos m4a, pero no funciona para archivos mp3. Si el asset apunta a un archivo mp3, las artworks están vacías. ¿Qué estoy haciendo mal y cómo lo soluciono?

Descubrí que las obras de arte se estaban cargando de forma asíncrona mientras la imagen se estaba configurando de forma síncrona. Lo solucioné de esta manera:

 - (void)metadata { AVURLAsset *asset = [AVURLAsset URLAssetWithURL:self.fileURL options:nil]; NSArray *titles = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyTitle keySpace:AVMetadataKeySpaceCommon]; NSArray *artists = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyArtist keySpace:AVMetadataKeySpaceCommon]; NSArray *albumNames = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyAlbumName keySpace:AVMetadataKeySpaceCommon]; AVMetadataItem *title = [titles objectAtIndex:0]; AVMetadataItem *artist = [artists objectAtIndex:0]; AVMetadataItem *albumName = [albumNames objectAtIndex:0]; NSArray *keys = [NSArray arrayWithObjects:@"commonMetadata", nil]; [asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{ NSArray *artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyArtwork keySpace:AVMetadataKeySpaceCommon]; for (AVMetadataItem *item in artworks) { if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) { NSDictionary *d = [item.value copyWithZone:nil]; self.currentSongArtwork = [UIImage imageWithData:[d objectForKey:@"data"]]; } else if ([item.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) { self.currentSongArtwork = [UIImage imageWithData:[item.value copyWithZone:nil]]; } } }]; self.currentSongTitle = [title.value copyWithZone:nil]; self.currentSongArtist = [artist.value copyWithZone:nil]; self.currentSongAlbumName = [albumName.value copyWithZone:nil]; self.currentSongDuration = self.audioPlayer.duration; } 

Acabo de encontrar la respuesta a eso aquí: ¿cómo puedo extraer metadatos del archivo mp3 en el desarrollo de iOS y ahora estaba buscando ver por qué ese código no funciona en un archivo m4a? Saqué un poco de tu código y presento lo siguiente que parece funcionar tanto para m4a como para mp3. Tenga en cuenta que dejé el código que funciona para mp3 como una cláusula else abierta sin el calificador: si alguien gana más experiencia con esto, ¡puede redefinirlos!

  - (void)getMetaDataForSong:(MusicItem *)musicItem { AVAsset *assest; // filePath looks something like this: /var/mobile/Applications/741647B1-1341-4203-8CFA-9D0C555D670A/Library/Caches/All Summer Long.m4a NSURL *fileURL = [NSURL fileURLWithPath:musicItem.filePath]; NSLog(@"%@", fileURL); assest = [AVURLAsset URLAssetWithURL:fileURL options:nil]; NSLog(@"%@", assest); for (NSString *format in [assest availableMetadataFormats]) { for (AVMetadataItem *item in [assest metadataForFormat:format]) { if ([[item commonKey] isEqualToString:@"title"]) { musicItem.strSongTitle = (NSString *)[item value]; } if ([[item commonKey] isEqualToString:@"artist"]) { musicItem.strArtistName = (NSString *)[item value]; } if ([[item commonKey] isEqualToString:@"albumName"]) { musicItem.strAlbumName = (NSString *)[item value]; } if ([[item commonKey] isEqualToString:@"artwork"]) { UIImage *img = nil; if ([item.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) { img = [UIImage imageWithData:[item.value copyWithZone:nil]]; } else { // if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) { NSData *data = [(NSDictionary *)[item value] objectForKey:@"data"]; img = [UIImage imageWithData:data] ; } musicItem.imgArtwork = img; } } } }