如何使用用户的 iPod 库艺术家索引 UITableView?

Posted

技术标签:

【中文标题】如何使用用户的 iPod 库艺术家索引 UITableView?【英文标题】:How can I index a UITableView with the user's iPod Library artists? 【发布时间】:2011-11-12 19:04:28 【问题描述】:

我想在我的应用程序中获取和索引所有 iPod 库艺术家,就像音乐应用程序一样。我遇到的问题是我不知道解决这个问题的最佳方法是什么。有什么帮助吗?

【问题讨论】:

你还有这个问题吗?我相信我有适合你的解决方案。 如果你愿意,我会爱你的。我做了一个解决方案,但速度很慢(通过检查文章单词,通过分隔字符......)。它也很慢,所以是的,我很想听听你的解决方案。 【参考方案1】:

让我们将您的UITableViewController 类命名为LibraryArtistsBrowserTableViewController

1.准备

接口文件LibraryArtistsBrowserTableViewController.h将包含以下变量:

@interface LibraryArtistsBrowserTableViewController : UITableViewController 

@property (nonatomic, strong) MPMediaQuery *artistsQuery;
@property (nonatomic, strong) NSArray *artistsArray,*sectionedArtistsArray;
@property (nonatomic, strong) UILocalizedIndexedCollation *collation;

- (NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector;

@end

2。索引

在您的实现文件 LibraryArtistsBrowserTableViewController.m 中,将以下代码放入您的 viewDidLoad 方法中:

- (void)viewDidLoad

    [super viewDidLoad];

    //Make a query for artists
    self.artistsQuery = [MPMediaQuery artistsQuery];
    //Group by Album Artist
    [self.artistsQuery setGroupingType:MPMediaGroupingAlbumArtist];
    //Grab the "MPMediaItemCollection"s and store it in "artistsArray"
    self.artistsArray = [self.artistsQuery collections];

    //We then populate an array "artists" with the individual "MPMediaItem"s that self.artistsArray` contains
    NSMutableArray *artists = [NSMutableArray array];

    for (MPMediaItemCollection *artist in artistsArray) 
        //Grab the individual MPMediaItem representing the collection
        MPMediaItem *representativeItem = [artist representativeItem];
        //Store it in the "artists" array
        [artists addObject:representativeItem];
    
    //We then index the "artists" array and store individual sections (which will be the alphabet letter and a numbers section), all containing the corresponding MPMediaItems
    self.sectionedArtistsArray = [self partitionObjects:artists collationStringSelector:@selector(albumArtist)];    

我们用来分割项目的函数定义如下,把它放在你的实现文件的某个地方:

- (NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector

    self.collation = [UILocalizedIndexedCollation currentCollation];
    NSInteger sectionCount = [[collation sectionTitles] count];
    NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
    for(int i = 0; i < sectionCount; i++)
        [unsortedSections addObject:[NSMutableArray array]];

    for (id object in array)
    
        NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
        [[unsortedSections objectAtIndex:index] addObject:object];
    
    NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
    for (NSMutableArray *section in unsortedSections)
        [sections addObject:[self.collation sortedArrayFromArray:section collationStringSelector:selector]];

    return sections;

然后我们确保视图控制器知道每个部分中有多少个部分和行,以及每个部分的标题(索引字母/数字):

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
    return [[self.collation sectionTitles] objectAtIndex:section];


- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 
    return [self.collation sectionIndexTitles];


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return [[self.collation sectionTitles] count];


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return [[self.sectionedArtistsArray objectAtIndex:section] count];

3.显示艺术家

然后我们按如下方式显示艺术家:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    
    //We grab the MPMediaItem at the nth indexPath.row corresponding to the current section (or letter/number)
    MPMediaItem *temp = [[self.sectionedArtistsArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    //Title the current cell with the Album artist
    cell.textLabel.text = [temp valueForProperty:MPMediaItemPropertyAlbumArtist];

    return cell;

你应该很高兴。我对此的唯一问题是它无法逃避标点符号(撇号等)和艺术家的“The”前缀。除此之外,它工作得很好。

【讨论】:

如何在选择单元格时播放歌曲?有帮助吗? 看起来您没有在 viewDidLoad 之外使用 ArtistArray;您可能可以摆脱该属性。 您如何索引歌曲?如果您要在 tableview 中选择一首歌曲,则排序规则的索引路径将只返回一首歌曲。完整的艺术家数组是不可能的,因为它对 indexpath.section 没有任何价值。【参考方案2】:

您应该阅读iPod Library Access Guide。您需要提出请求并用结果填充您的表格视图。根据您的需要,您可以使用MPMediaPickerController。如果您只想要艺术家,您应该使用MPMediaQuery

MPMediaQuery *artistQuery = [MPMediaQuery artistsQuery];

编辑:

NSString *artistKey = [MPMediaItem titlePropertyForGroupingType:MPMediaGroupingArtist];
MPMediaQuery *artistsQuery = [MPMediaQuery artistsQuery];
NSMutableArray *artists = [NSMutableArray arrayWithCapacity:artistsQuery.collections.count];

for (MPMediaItemCollection *album in artistsQuery.collections) 
    MPMediaItem *albumItem = [album representativeItem];
    [artists addObject:[albumItem valueForProperty:artistKey]];

reprsentativeItem 的文档指出:

集合中的媒体项通常具有共同的属性 值,取决于集合的构建方式。例如,如果您 基于谓词构建一个集合,该谓词使用 MPMediaItemPropertyArtist 属性,集合中的所有项目共享 同一个艺术家的名字。您可以使用代表项目属性 有效地获得这些共同属性的值——通常更多 比从 items 数组中获取项目更有效。

【讨论】:

是的,去过那里,做过这一切。特别难做的是用查询给你的所有东西来索引一个 UITableView。当我 4 周前第一次尝试这个时,当我得知查询没有按字母顺序将对象放在它自己的数组中时,我感到很失望。 “我想获取并索引我的应用程序中的所有 iPod 库艺术家”,在问题中说明您已经完成的工作并更清楚地定义您的问题很有用。 - 我主要尝试使用集合和集合部分,但没有办法使用它们按字母顺序获取艺术家。 - 我尝试制作一个 NSArrays 的 NSArray:每个子数组将包含所有以给定字母开头的艺术家。这种方法的问题是,当尝试获取每个艺术家的第一个字母时,以“the”、“a”和其他开头的艺术家会终止整个索引。 好吧,这可以进行实际的提取。不过,实际索引仍然存在问题,哈哈。【参考方案3】:

可能想看看 UILocalizedIndexedCollat​​ion

- (NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector

UILocalizedIndexedCollation *collation = [UILocalizedIndexedCollation currentCollation];
NSInteger sectionCount = [[collation sectionTitles] count];
NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
for(int i = 0; i < sectionCount; i++)

    [unsortedSections addObject:[NSMutableArray array]];

for (id object in array)

    NSInteger index = [collation sectionForObject:object collationStringSelector:selector];
    [[unsortedSections objectAtIndex:index] addObject:object];

NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
for (NSMutableArray *section in unsortedSections)

    [sections addObject:[collation sortedArrayFromArray:section collationStringSelector:selector]];

return sections;

把它放在上面,然后像这样使用它:

self.sectionedArray = [self partitionObjects:ArrayOfItemsFromQuery collationStringSelector:@selector(title)];

sectionedArray 是在 .h 中声明的 NSArray。

我认为这仅适用于歌曲列表。

【讨论】:

这个解决方案的工作原理与上面 Sooper 的解决方案一样。你问如何索引图书馆,我告诉你如何。不要仅仅因为您想让您的手持设备从头到尾就对解决方案投反对票。文档在那里是有原因的。 嘿,我对此表示最深切的歉意,并且为时已晚。老实说,我不知道为什么我对你的回答投了反对票。我从没想过能把整个代码放在银盘或任何东西上,当时任何指针都很有帮助。 - 再次抱歉,我真的不记得为什么我对此投了反对票,除非您编辑答案,否则我无法“解决”这个问题。再次抱歉。

以上是关于如何使用用户的 iPod 库艺术家索引 UITableView?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 如何从歌曲(ipod 库)中获取音频样本?

如何防止我的用户从 iPod 中删除 MP3 文件

有没有办法一次从 iPod 库中搜索多个艺术家的曲目。

如何在我的 iPhone 应用程序中访问 iPod 库

在 iPhone 上:找出当前正在播放的歌曲? (在 iPod 音乐播放器中)[重复]

如何使用 AVAssetExportSession 覆盖 iPhone/iPod 库中的歌曲?