前言
??最近公司項目里需要獲取本地音樂,開始傻傻的以為蘋果不能獲取本地音樂,后面查了下發(fā)現(xiàn)其實是可以的,也就是獲取媒體資料庫的音樂。好了廢話不多說,我們直接進(jìn)入主題。
獲取權(quán)限
??從 iOS 10之后,關(guān)于權(quán)限的提示都需要在infp.plist文件里寫入對應(yīng)的提示語,不然程序會crash,在infp.plist文件寫入以下代碼即可。
<key>NSAppleMusicUsageDescription</key>
<string>App需要您的同意,才能訪問媒體資料庫</string>
??我想當(dāng)初剛開始做適配iOS 10的同志們估計是哭著踩著這些坑一步步走過來的,別告訴我就我一個人是這樣的。

?? 然后我們需要通過代碼里去獲取用戶關(guān)于訪問媒體資料庫的權(quán)限,如果用戶拒絕了此權(quán)限,我們需要提示用戶打開此權(quán)限。
第一步:導(dǎo)入頭文件
#import <MediaPlayer/MediaPlayer.h>第二步:獲取用戶關(guān)于媒體資料庫的權(quán)限
// MARK:- 判斷是否有權(quán)限
- (void)requestAuthorizationForMediaLibrary {
__weak typeof(self) weakSelf = self;
// 請求媒體資料庫權(quán)限
MPMediaLibraryAuthorizationStatus authStatus = [MPMediaLibrary authorizationStatus];
if (authStatus != MPMediaLibraryAuthorizationStatusAuthorized) {
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
if (appName == nil) {
appName = @"APP";
}
NSString *message = [NSString stringWithFormat:@"允許%@訪問你的媒體資料庫?", appName];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"警告" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[weakSelf dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction *setAction = [UIAlertAction actionWithTitle:@"設(shè)置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
[weakSelf dismissViewControllerAnimated:YES completion:nil];
}
}];
[alertController addAction:okAction];
[alertController addAction:setAction];
[self presentViewController:alertController animated:YES completion:nil];
}
}
獲取媒體資料庫里的音樂數(shù)據(jù)
?? 上面我們講了如何獲取用戶的媒體資料庫權(quán)限,在用戶同意APP訪問媒體資料庫之后,我們開始從媒體資料庫里獲取我們想要的本地音樂數(shù)據(jù)。
- 第一步:獲取
iTunes中的音樂
// MARK:- 獲取 iTunes 中的音樂
- (void)getItunesMusic {
// 創(chuàng)建媒體選擇隊列
MPMediaQuery *query = [[MPMediaQuery alloc] init];
// 創(chuàng)建讀取條件
MPMediaPropertyPredicate *albumNamePredicate = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInt:MPMediaTypeMusic] forProperty:MPMediaItemPropertyMediaType];
// 給隊列添加讀取條件
[query addFilterPredicate:albumNamePredicate];
// 從隊列中獲取條件的數(shù)組集合
NSArray *itemsFromGenericQuery = [query items];
// 遍歷解析數(shù)據(jù)
for (MPMediaItem *music in itemsFromGenericQuery) {
[self resolverMediaItem:music];
}
}
?? 通過創(chuàng)建選擇隊列,添加讀取條件之后,我們獲得了符合讀取條件的數(shù)組NSArray *itemsFromGenericQuery = [query items]。但是此時itemsFromGenericQuery里面裝的是一個個MPMediaItem,我們還需要對MPMediaItem處理,變成方便我們處理的Dictionary或者Model。
- 第二步:對
MPMediaItem進(jìn)行處理
- (void)resolverMediaItem:(MPMediaItem *)music {
// 歌名
NSString *name = [music valueForProperty:MPMediaItemPropertyTitle];
// 歌曲路徑
NSURL *fileURL = [music valueForProperty:MPMediaItemPropertyAssetURL];
// 歌手名字
NSString *singer = [music valueForProperty:MPMediaItemPropertyArtist];
if(singer == nil)
{
singer = @"未知歌手";
}
// 歌曲時長(單位:秒)
NSTimeInterval duration = [[music valueForProperty:MPMediaItemPropertyPlaybackDuration] doubleValue];
NSString *time = @"";
if((int)duration % 60 < 10) {
time = [NSString stringWithFormat:@"%d:0%d",(int)duration / 60,(int)duration % 60];
}else {
time = [NSString stringWithFormat:@"%d:%d",(int)duration / 60,(int)duration % 60];
}
// 歌曲插圖(沒有就返回 nil)
MPMediaItemArtwork *artwork = [music valueForProperty:MPMediaItemPropertyArtwork];
UIImage *image;
if (artwork) {
image = [artwork imageWithSize:CGSizeMake(72, 72)];
}else {
image = [UIImage imageNamed:@"duanshipin"];
}
[_songArr addObject:@{@"name": name,
@"fileURL": fileURL,
@"singer": singer,
@"time": time,
@"image": image,
}];
}
注意
- 歌曲路徑
?? 這里返回的歌曲路徑直接是NSURL類型的,不是NSString類型。 - 歌曲時長
?? 這里查詢出來的音樂的時長是以秒為單位的,也就是說如果一首歌的時長為3分鐘,那這里查詢出來的duration的值為180s,所以我們需要對這個值進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換成mm:ss的形式. - 歌曲封面
?? 這里需要注意的是,如果歌曲沒有封面,MPMediaItemArtwork為nil,所以你需要對這個nil單獨(dú)處理下,最好是放一張默認(rèn)圖片。
寫在最后
??放一張運(yùn)行Demo的圖片,如果需要 Demo的話,我會傳到Github上,然后貼出鏈接的。
