2017-12-31 53 views
0

내가 만들고 저장할 나는 UIView 스냅 샷을 찍거나 UIGraphicsImageRenderer ( 아래에 표시 )를 사용하여 하나를 만들 수 있습니다 UIImage 아이폰 OS (10)에. 나는 마지막에서 두 번째 문을 포함하여 UIImageWriteToSavedPhotosAlbum를 사용하여 저장하려고하면iOS10 UIImageWriteToSavedPhotosAlbum는 TCC__CRASHING_DUE_TO_PRIVACY_VIOLATION

- (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; 
} 

그러나, 엑스 코드는 다음과 같은 오류 보고서 디버그로 전환

(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 

그래서 난에 카메라를 사용하지 않은 경우에도 이미지를 사진 앨범에 저장하면 사생활 침해가됩니다 (hiss, boo)! privacy keys in the plist을 설정하는 것이 가능하다는 것을 알고 있지만 더 합리적인 대안이 있습니까?

설명 내가 응용 프로그램에 자산으로 렌더링 된 이미지 (또는 스냅 샷보기)를 사용하는 희망

. 따라서 대신 더 현명한 대안이 있습니까?

아마도 나는

이미지를 저장하는 다른 장소가

을 요청해야 (즉, PNG 또는 JPG 파일로) 그래서 개인 정보 보호가 문제가되지 않습니다?

답변

1

UIImage를 사진 앨범에 저장할 수 있지만 먼저 개인 정보 보호 문제이므로이 작업을 수행 할 수있는 권한을 사용자에게 요청해야합니다. 그들이 당신에게 접근을주지 않으면 당신은 전혀 이미지를 저장할 수 없습니다.

가장 현명한 접근 방식은 필요한 개인 정보 키를 info.plist에 추가하는 것입니다.

이 인의 Info.plist XML 정의는 재산 목록에서 키를 더욱 쉽게 추가 할 수 있지만 :

<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 파일에 넣는 좋은 이유 중 하나는 모든 액세스 요청이 프로젝트의 임의 어딘가에서가 아닌 한 눈에 쉽게 볼 수있는 장소에 있다는 것입니다.

편집

다음

인상 및 개인 정보 보호 문제되지 않는 문서의 이미지를 저장하는 방법입니다 :이 대신 대신 PNG 사용의 JPG를 원하는 경우

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 

을 :

+0

에 이미지를 저장, 그것은 유일한 방법입니다. 'UIImageWriteToSavedPhotosAlbum'을 사용하려면이 키를 추가해야합니다. – rmaddy

+0

나는 당신이 가야 할 가장 의미있는 접근 방식을 말했을 때 그것을 분명하게해야했습니다. 일부 액세스 (예 : 이미지 라이브러리 액세스) 코드 대신 Info.plist 업데이트 요청할 수 있지만 이미지 라이브러리에 추가하는 것이 사실인지 확신 할 수 없습니다. –

+0

@rmaddy 및 UpholderOfTruth, 설명. 렌더링 된 이미지 (또는 스냅 샷보기)를 앱의 애셋으로 사용하겠습니다. 그래서 프라이버시 문제가 있는지 질문했습니다. – Greg

2

다음 코드를 따르십시오 :

,
#import <Photos/Photos.h> 

프라 그마 마크 - 사진 앨범 NSPhotoLibraryAddUsageDescription`는 "가장 현명한 방법"아니다`추가

- (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); 
     } 
    }]; 
} 
} 
+0

kalpesh, 감사합니다. 이미지 애셋을 공유 사진 라이브러리가 아닌 다른 폴더에 추가 할 수 있습니까? (위의 설명에 대한 답변을 참조하십시오.) – Greg

+0

예, 사진 보관함을 공유했습니다. –