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
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!
source to share