首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >iOS10 UIImageWriteToSavedPhotosAlbum TCC__CRASHING_DUE_TO_PRIVACY_VIOLATION

iOS10 UIImageWriteToSavedPhotosAlbum TCC__CRASHING_DUE_TO_PRIVACY_VIOLATION
EN

Stack Overflow用户
提问于 2017-12-31 12:20:13
回答 2查看 1.3K关注 0票数 0

我希望在UIImage 10中创建和保存一个iOS,我可以通过获取UIView快照或使用UIGraphicsImageRenderer创建它(如下所示)。

代码语言:javascript
运行
复制
- (UIView *)createIcon
{
    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:CGSizeMake(200, 200)];

    UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull context) {
        [[UIColor darkGrayColor] setStroke];
        [context strokeRect:renderer.format.bounds];
        [[UIColor colorWithRed:158/255.0 green:215/255.0 blue:245/255.0 alpha:0.5] setFill];
        [context fillRect:CGRectMake(30, 30, 140, 140)];
        [[UIColor colorWithRed:243/255.0 green:122/255.0 blue:216/255.0 alpha:0.3] setFill];
        CGContextFillEllipseInRect(context.CGContext, CGRectMake(30, 30, 120, 120));
    }];

    UIImageView *showImage = [[UIImageView alloc] initWithImage:image];

    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

    return showImage;
}

但是,当我试图通过包含第二条最后一条语句来保存UIImageWriteToSavedPhotosAlbum时,Xcode将使用以下错误报告进行调试

代码语言:javascript
运行
复制
(lldb) bt
* thread #5, queue = 'com.apple.root.default-qos', stop reason = signal SIGABRT
  * frame #0: 0x00000001101611a6 libsystem_kernel.dylib`__abort_with_payload + 10
    frame #1: 0x000000011015b86e libsystem_kernel.dylib`abort_with_payload_wrapper_internal + 89
    frame #2: 0x000000011015b89b libsystem_kernel.dylib`abort_with_payload + 9
    frame #3: 0x0000000108ab3af7 TCC`__CRASHING_DUE_TO_PRIVACY_VIOLATION__ + 182
    frame #4: 0x0000000108ab3a41 TCC`__TCCAccessRequest_block_invoke.77 + 665
    frame #5: 0x0000000108ab7273 TCC`__tccd_send_block_invoke + 274

所以,即使我没有用相机来创建图像,把它保存到相册中是对隐私的侵犯(嘘,嘘)!我知道建立privacy keys in the plist是可能的,但还有更明智的选择吗?

澄清

我希望在应用程序中使用渲染的图像(或查看快照)作为资产。那么,是否有更明智的替代方案?

也许我该问问

有没有其他地方可以保存图片(例如PNG或JPG文件),这样隐私就不是问题了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-31 13:53:50

您可以将任何UIImage保存到相册中,但首先您必须请求用户允许您这样做,因为这确实是一个隐私问题。如果他们不给您访问权限,那么您就根本无法保存图像。

最明智的方法是将所需的隐私密钥添加到info.plist中。

这是info.plist xml定义,尽管在属性列表中添加键比较容易:

代码语言:javascript
运行
复制
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Message requesting the ability to add to the photo library</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Message requestion the ability to access the photo library</string>

如果您添加这些,那么当您第一次尝试访问或添加到照片库时,弹出窗口将与您的消息一起显示,允许用户决定他们是否希望您的应用程序具有访问权限。

将其放入info.plist文件的一个很好的理由是,所有访问请求都位于一个容易看到的位置,而不是项目中的任意位置。

编辑

以下是如何在不引起隐私问题的文档中保存图像:

代码语言:javascript
运行
复制
NSData *imageData = UIImagePNGRepresentation(image);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"image.png"]; //Add the file name
[imageData writeToFile:filePath atomically:YES]; //Write the file

如果您希望使用jpg而不是png,请使用以下代码:

代码语言:javascript
运行
复制
NSData *imageData = UIImageJPEGRepresentation(image, 0.9); // Use whatever compression ratio you want instead of 0.9
票数 2
EN

Stack Overflow用户

发布于 2018-01-01 04:44:05

遵循以下代码:

代码语言:javascript
运行
复制
#import <Photos/Photos.h>

pragma标记-在相册中保存图像

代码语言:javascript
运行
复制
- (void)addImageToCameraRoll:(UIImage *)image {
NSString *albumName = @"Your app name";

void (^saveBlock)(PHAssetCollection *assetCollection) = ^void(PHAssetCollection *assetCollection) {
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
        PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
        [assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];

    } completionHandler:^(BOOL success, NSError *error) {
        if (!success) {
            NSLog(@"Error creating asset: %@", error);
        }
    }];
};

PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"localizedTitle = %@", albumName];
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:fetchOptions];
if (fetchResult.count > 0) {
    saveBlock(fetchResult.firstObject);
} else {
    __block PHObjectPlaceholder *albumPlaceholder;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName];
        albumPlaceholder = changeRequest.placeholderForCreatedAssetCollection;

    } completionHandler:^(BOOL success, NSError *error) {
        if (success) {
            PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[albumPlaceholder.localIdentifier] options:nil];
            if (fetchResult.count > 0) {
                saveBlock(fetchResult.firstObject);
            }
        } else {
            NSLog(@"Error creating album: %@", error);
        }
    }];
}
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48042371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档