2017-12-31 84 views
0

私はUIViewスナップショットを取るか、UIGraphicsImageRenderer(下に表示)を使用するか、それを作成することができますiOSの10でUIImageを作成して保存します。私は最後から二番目の文を含めることによって、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; 
} 

しかし、Xcodeは、次のエラーレポートとデバッグに入る

(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ファイルに入れる理由の1つは、アクセスのすべての要求が、プロジェクトのどこかでランダムではなく、簡単に目に見える単一の場所にあることです。ここで

EDIT

は、問題を提起し、プライバシーはありません文書に画像を保存する方法である:

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を使用するのではなく、この:

は、
NSData *imageData = UIImageJPEGRepresentation(image, 0.9); // Use whatever compression ratio you want instead of 0.9 
+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

はい、フォトライブラリを共有しました。 –

関連する問題