如何检查标题,艺术家等AVMetadataItem项是否为空或不存在?

时间:2018-03-15 22:38:47

标签: ios objective-c avmetadataitem

我正在构建一个音乐应用程序,我正在尝试使用这段代码获取MP3文件元数据:

for (NSString *format in [assest availableMetadataFormats]) {

        for (AVMetadataItem *item in [assest metadataForFormat:format]) {
            if ([[item commonKey] isEqualToString:@"title"]) {

                [SongNameMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
            }
            if ([[item commonKey] isEqualToString:@"artist"]) {

                [ArtistMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
            }
            if ([[item commonKey] isEqualToString:@"albumName"]) {

            }
            if ([[item commonKey] isEqualToString:@"artwork"]) {
                UIImage *img = nil;
                if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {
                    img = [UIImage imageWithData:item.dataValue];

                }
                else {
                    NSDictionary *dict ;
                    [item.value copyWithZone:nil];
                    img = [UIImage imageWithData:[dict objectForKey:@"data"]];

                }
            }
        }
    }

代码工作正常。唯一的事情是当可变数组被填充时,它们以下列方式执行:

  • SongNameMutableArray => [song1,song2,song3,songX];
  • ArtistMutableArray => [Artists1,Artist3,Artist 10,ArtistX];

因为并非所有歌曲都有元数据中的艺术家。

根据代码的这一特定部分

if ([[item commonKey] isEqualToString:@"artist"]) {
    [ArtistMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
}

如果找到的项目是艺术家,请将其插入数组中。

现在我的问题是如何检测歌曲中元素中没有艺术家的时间?这样我就可以在ArtistMutableArray =>中插入“null” [Artists1,null,Artist3,null,Artist 5,ArtistX];

我尝试过:

if ([[item commonKey] isEqualToString:@"null"])
if ([[item value] isEqualToString:@"null"])

我不确定我在这里缺少什么。

1 个答案:

答案 0 :(得分:0)

您正在做的每件事都需要以不同的方式完成。不要将数据拆分为单独的数组,尤其是如果您希望每个数组具有相同数量的元素并且每个相应的索引引用相同的资产。

而是定义一个类,其中包含您要为每个资产跟踪的少数属性。然后有一个这样的类实例的数组。然后,无需担心保持多个数组同步并通过在需要时向数组添加“null”值来执行技巧。

拥有一个数据阵列还有许多其他好处。例如,排序。通过拥有一个数组,您可以按艺术家对该数据数组进行排序。在排序或过滤时尝试保持多个阵列同步是一个巨大的痛苦。

由于您只获得了公共元数据,因此无需迭代所有格式并查看每种格式的属性。只需使用资产的commonMetadata属性即可。

获取commonKey值时,请勿将其与硬编码字符串进行比较。使用API​​提供的常量,例如AVMetadataCommonKeyAlbumName

由于每个元数据项只能有commonKey的一个值,因此请使用if/else来提高代码效率。并使用元数据项的stringValue属性来获取字符串值,而不是使用stringWithFormat

这是元数据类的开始。您认为合适的名称并添加您需要的任何其他属性。

@interface MyMetaData: NSObject

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *artist;
@property (nonatomic, copy) NSString *albumName;
@property (nonatomic, copy) UIImage *artwork;

@end

@implementation MyMetaData
@end

以下是您在问题中发布的代码的替代品:

NSMutableArray *metadata = [NSMutableArray array]; // your array of obtained metadata

AVAsset *asset = // some asset

MyMetaData *data = [[MyMetaData alloc] init];

NSArray *commonData = asset.commonMetadata;
for (AVMetadataItem *item in commonData) {
    AVMetadataKey key = item.commonKey;
    if ([key isEqual: AVMetadataCommonKeyTitle]) {
        data.title = item.stringValue;
    } else if ([key isEqual:AVMetadataCommonKeyArtist]) {
        data.artist = item.stringValue;
    } else if ([key isEqual:AVMetadataCommonKeyAlbumName]) {
        data.albumName = item.stringValue;
    } else if ([key isEqual:AVMetadataCommonKeyArtwork]) {
        data.artwork = // your code to get the image
    }
}

[metadata addObject:data];

这个更干净,你现在只有一个数组可以处理。如果给定资源没有艺术家的数据,那么该值只会在给定nil个实例上保留MyMetaData