ios - 以编程方式请求对媒体库的授权失败

标签 ios ios10 mpmedialibrary

iOS 10 现在需要用户的许可才能访问媒体库。我们在使用之前检查我们是否有权访问媒体库,如果没有,我们将使用 [MPMediaLibrary requestAuthorization: 再次向用户请求授权。

我希望这会显示与我们在应用程序启动时获得的访问媒体库相同的弹出请求,但没有任何反应。它只是返回之前的 MPMediaLibraryAuthorizationStatusDenied 状态。

docs for requestAuthorization目前还不完整,所以我不知道是我用错了,还是其他地方出了问题。

    if ( MPMediaLibrary.authorizationStatus == MPMediaLibraryAuthorizationStatusAuthorized)
    {
        // we already have access to the Media Library - use it here...
    }
    else
    {
        // We expect this to show a popup so the user can grant access, but does not work
        [MPMediaLibrary requestAuthorization:^(MPMediaLibraryAuthorizationStatus authorizationStatus)
         {
             if ( authorizationStatus == MPMediaLibraryAuthorizationStatusAuthorized )
             {
                 // success: the user authorized - use it here...
             }
             else
             {
                 // user did not authorize - tell user why here...
             }
         }];
    }

更新

显然没有办法让原来的对话框重新出现(见下面的评论)。我现在正在使用此代码至少将我带到设置中的正确位置,以便用户可以进行更改。 (适用于 iOS8 及更高版本)

NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:url];

最佳答案

MPMediaLibrary 只会自动提示用户一次。如果您在用户授予或拒绝之前请求它,则状态为 MPMediaLibraryAuthorizationStatusNotDetermined。如果他们之前拒绝访问,您需要将用户转到系统设置,以便他们可以为您的应用手动打开它。

下面的代码是我们如何做的。

+ (void) validateMediaLibraryForMinimumIosAndAboveWithViewController:(UIViewController *)viewController
                                                        ifAuthorized:(void(^)())authorizedBlock
                                                     ifNotAuthorized:(void(^)())notAuthorizedBlock
{
    MPMediaLibraryAuthorizationStatus authorizationStatus = MPMediaLibrary.authorizationStatus;

    switch (authorizationStatus)
    {
        case MPMediaLibraryAuthorizationStatusAuthorized:
        {
            // We are already authorized - proceed
            if( authorizedBlock )
            {
                authorizedBlock();
            }
            break;
        }
        case MPMediaLibraryAuthorizationStatusNotDetermined:
        {
            // Not yet authorized - request it from the system
            [MPMediaLibrary requestAuthorization:^(MPMediaLibraryAuthorizationStatus authorizationStatus)
             {
                 if ( authorizationStatus == MPMediaLibraryAuthorizationStatusAuthorized )
                 {
                     if( authorizedBlock )
                     {
                         authorizedBlock();
                     }
                 }
                 else
                 {
                     PLog(@"The Media Library was not authorized by the user");
                     if( notAuthorizedBlock )
                     {
                         notAuthorizedBlock();
                     }
                 }
             }];
            break;
        }

        case MPMediaLibraryAuthorizationStatusRestricted:
        case MPMediaLibraryAuthorizationStatusDenied:
        {
            // user has previously denied access. Ask again with our own alert that is similar to the system alert
            // then take them to the System Settings so they can turn it on for the app
            NSString *titleString  = NSLocalizedStringWithDefaultValue(@"Media Library Privacy Alert Title",
                                                                       @"Localizable",
                                                                       [NSBundle mainBundle],
                                                                       @"Would Like to Access Apple Music And Your Media Library",
                                                                       @"Title for dialog requesting media library access");

            [self displayPermissionAlertFromViewController:viewController
                                                 withTitle:titleString];
            if( notAuthorizedBlock )
            {
                notAuthorizedBlock();
            }
            break;
        }
    }
}

+ (void)displayPermissionAlertFromViewController:(UIViewController *)viewController withTitle:(NSString *)title
{
    NSString* appName = [[NSProcessInfo processInfo] processName];

    NSString *titleString = [NSString stringWithFormat:@"\"%@\" %@",appName, title];

    NSString *cancelString = NSLocalizedStringWithDefaultValue(@"Don't Allow",
                                                               @"Localizable",
                                                               [NSBundle mainBundle],
                                                               @"Don't Allow",
                                                               @"Don't allow button");

    NSString *settingsString = NSLocalizedStringWithDefaultValue( @"Settings",
                                                                 @"Localizable",
                                                                 [NSBundle mainBundle],
                                                                 @"Settings",
                                                                 @"Settings button label");

    UIAlertController *alertController = [UIAlertController
                                          alertControllerWithTitle:titleString
                                          message:nil
                                          preferredStyle:UIAlertControllerStyleAlert];

    [alertController addAction:[UIAlertAction actionWithTitle:cancelString
                                                        style:UIAlertActionStyleDefault
                                                      handler:nil]];

    [alertController addAction:[UIAlertAction actionWithTitle:settingsString
                                                        style:UIAlertActionStyleDefault
                                                      handler:
                                ^(UIAlertAction * _Nonnull action)
                                {
                                    NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                                    [[UIApplication sharedApplication] openURL:url];
                                }]];

    [viewController presentViewController:alertController animated:true completion:nil];
}

关于ios - 以编程方式请求对媒体库的授权失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39374951/

相关文章:

ios - Nativescript Angular 模拟器不使用 tns run ios 刷新

android - 谷歌应用程序的授权方式是什么?

ios - 媒体库授权不运行处理程序

ios - 请求权限时设置标题?

objective-c - 在没有新初始化的情况下使用类中的数据

ios - 为什么 TableView 委托(delegate)方法没有被调用?

ios - 充满 <FIRInstanceID/WARNING> 的控制台 - Xcode 8/iOS10

iOS 10 中的自动布局增加高度并使 Y 位置为负

ios - iOS 10 中“设置/常规/关于/证书信任设置”的 URL 方案

ios - 处理 UITableViewCells 的图像拼贴 – 可以扩展到数百个单元格的方法?