Overcome punctuation and prefix "Prefix" in song titles when matching MPMediaQuery

The code works and populates the table with sections, but it has a flaw: it does not omit punctuation marks and the "The" prefixes in song titles, as a native music app does.

It would be very helpful to know how I should do this.

- (void)viewDidLoad
    [super viewDidLoad];
    MPMediaQuery *songQuery = [MPMediaQuery songsQuery];
    self.songsArray = [songQuery items];
    self.sectionedSongsArray = [self partitionObjects:self.songsArray collationStringSelector:@selector(title)];

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



source to share

2 answers

I completely forgot about it. The answer here is simple to use MPMediaQuerySection

. Apple docs are there for a reason!



Cocotutch -

Here is the implementation I used to index a query containing all the songs in my music library:

MPMediaQuery *allSongsQuery = [MPMediaQuery songsQuery];

// Fill in the all songs array with all the songs in the user media library
allSongsArray = [allSongsQuery items];

allSongsArraySections = [allSongsQuery itemSections];


allSongsArraySections is an NSArray from MPMediaQuerySection, each with a name and range. The NSArray for slice zero (with @ "A" heading in my case) has .location 0 and range.length 158.

I am returning a range.length value for each section when numberOfRowsInSection is called on my UITableView. I am using the range.location value in cellForRowAtIndexPath as the start row of the section and then I add indexPath.row to it to come to the cell, I need to return from my allSongsArray.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    // Return the number of rows in the section.
    MPMediaQuerySection *allSongsArraySection = globalMusicPlayerPtr.allSongsArraySections[section];
    return allSongsArraySection.range.length;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    MPMediaQuerySection *allSongsArraySection = globalMusicPlayerPtr.allSongsArraySections[indexPath.section];
    rowItem = [globalMusicPlayerPtr.allSongsArray objectAtIndex:allSongsArraySection.range.location + indexPath.row];


Before using this, I tried to match the implementation of the built-in music player by writing my own and it didn't behave quite the same. Not only that, but internal indexing is much faster!



All Articles