You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift/OC实现应用首次启动时请求音乐库权限的方案

Request Music Library Permission on First App Launch

首先确认你已经在Info.plist中正确配置了以下两个权限描述(这是系统弹窗显示提示文本的必要条件):

  • Privacy - Media Library Usage Description(对应键NSMediaLibraryUsageDescription)
  • Privacy - Music Usage Description(对应键NSAppleMusicUsageDescription)

下面是两种实现方案,你可以根据需求选择:

方案一:在AppDelegate的didFinishLaunchingWithOptions中实现

这是优先推荐的方式,因为didFinishLaunchingWithOptions是应用启动的早期回调,能在界面展示前就发起权限请求。

Swift 代码示例

import MediaPlayer

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 主动请求音乐库权限
    MPMediaLibrary.requestAuthorization { authorizationStatus in
        switch authorizationStatus {
        case .authorized:
            print("音乐库权限已成功授权")
            // 这里可以添加权限授权后的初始化逻辑,比如加载音乐数据
        case .denied, .restricted:
            print("音乐库权限被拒绝或受限")
            // 可以记录状态,后续在需要使用音乐功能时提示用户去设置开启
        case .notDetermined:
            // 主动发起请求后不会进入这个分支
            break
        @unknown default:
            break
        }
    }
    return true
}

Objective-C 代码示例

#import <MediaPlayer/MediaPlayer.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 请求音乐库权限
    [MPMediaLibrary requestAuthorization:^(MPMediaLibraryAuthorizationStatus status) {
        switch (status) {
            case MPMediaLibraryAuthorizationStatusAuthorized:
                NSLog(@"音乐库权限已成功授权");
                // 处理授权成功后的逻辑
                break;
            case MPMediaLibraryAuthorizationStatusDenied:
            case MPMediaLibraryAuthorizationStatusRestricted:
                NSLog(@"音乐库权限被拒绝或受限");
                // 记录权限状态,后续做相应处理
                break;
            case MPMediaLibraryAuthorizationStatusNotDetermined:
                // 主动请求后不会触发这个状态
                break;
            default:
                break;
        }
    }];
    return YES;
}

方案二:在首个ViewController的viewDidLoad中实现

如果需要在界面展示后再发起请求,或者需要在权限变更后更新UI,可以选择这种方式。

Swift 代码示例

import MediaPlayer

class InitialViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        checkAndRequestMusicLibraryPermission()
    }
    
    private func checkAndRequestMusicLibraryPermission() {
        let currentStatus = MPMediaLibrary.authorizationStatus()
        // 仅当权限未确定时发起请求,避免重复弹窗
        guard currentStatus == .notDetermined else {
            handlePermissionStatus(currentStatus)
            return
        }
        
        MPMediaLibrary.requestAuthorization { [weak self] status in
            // 权限回调在后台线程,更新UI需切回主线程
            DispatchQueue.main.async {
                self?.handlePermissionStatus(status)
            }
        }
    }
    
    private func handlePermissionStatus(_ status: MPMediaLibraryAuthorizationStatus) {
        switch status {
        case .authorized:
            print("音乐库权限已授权")
            // 加载音乐相关功能
        case .denied, .restricted:
            print("音乐库权限被拒绝或受限")
            showPermissionGuideAlert()
        default:
            break
        }
    }
    
    private func showPermissionGuideAlert() {
        let alert = UIAlertController(
            title: "需要音乐库权限",
            message: "我们需要访问您的音乐库来提供相关功能,请前往设置开启权限。",
            preferredStyle: .alert
        )
        alert.addAction(UIAlertAction(title: "取消", style: .cancel))
        alert.addAction(UIAlertAction(title: "去设置", style: .default) { _ in
            guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return }
            if UIApplication.shared.canOpenURL(settingsURL) {
                UIApplication.shared.open(settingsURL)
            }
        })
        present(alert, animated: true)
    }
}

Objective-C 代码示例

#import <MediaPlayer/MediaPlayer.h>

@interface InitialViewController ()
@end

@implementation InitialViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self checkAndRequestMusicLibraryPermission];
}

- (void)checkAndRequestMusicLibraryPermission {
    MPMediaLibraryAuthorizationStatus currentStatus = [MPMediaLibrary authorizationStatus];
    if (currentStatus != MPMediaLibraryAuthorizationStatusNotDetermined) {
        [self handlePermissionStatus:currentStatus];
        return;
    }
    
    __weak typeof(self) weakSelf = self;
    [MPMediaLibrary requestAuthorization:^(MPMediaLibraryAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf handlePermissionStatus:status];
        });
    }];
}

- (void)handlePermissionStatus:(MPMediaLibraryAuthorizationStatus)status {
    switch (status) {
        case MPMediaLibraryAuthorizationStatusAuthorized:
            NSLog(@"音乐库权限已授权");
            // 初始化音乐功能
            break;
        case MPMediaLibraryAuthorizationStatusDenied:
        case MPMediaLibraryAuthorizationStatusRestricted:
            NSLog(@"音乐库权限被拒绝或受限");
            [self showPermissionGuideAlert];
            break;
        default:
            break;
    }
}

- (void)showPermissionGuideAlert {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"需要音乐库权限"
                                                                   message:@"我们需要访问您的音乐库来提供相关功能,请前往设置开启权限。"
                                                            preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
    [alert addAction:[UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        if ([[UIApplication sharedApplication] canOpenURL:settingsURL]) {
            [[UIApplication sharedApplication] openURL:settingsURL options:@{} completionHandler:nil];
        }
    }]];
    [self presentViewController:alert animated:YES completion:nil];
}

@end

关键注意事项

  • 两种方案都需要导入MediaPlayer框架,否则无法调用MPMediaLibrary相关API
  • 在ViewController中处理权限时,务必在主线程更新UI,因为权限请求的回调是在后台线程执行的
  • 如果用户已经拒绝过权限,再次调用requestAuthorization不会弹出系统弹窗,此时需要引导用户到系统设置中手动开启权限

内容的提问来源于stack exchange,提问作者Jordan Heath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:41:38