PHAsset+Utility.m 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //
  2. // PHAsset+Utilities.m
  3. //
  4. // Created by Zakk Hoyt on 9/22/14.
  5. // Copyright (c) 2014 Zakk Hoyt. All rights reserved.
  6. //
  7. #import "PHAsset+Utility.h"
  8. @import Photos;
  9. @implementation PHAsset (Utilities)
  10. #pragma mark Public methods
  11. -(void)saveToAlbum:(NSString*)title completionBlock:(PHAssetBoolBlock)completionBlock{
  12. void (^saveAssetCollection)(PHAssetCollection *assetCollection) = ^(PHAssetCollection *assetCollection){
  13. [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
  14. PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
  15. [changeRequest addAssets:@[self]];
  16. } completionHandler:^(BOOL success, NSError *error) {
  17. if(success == NO) {
  18. NSLog(@"[LOG] Failed to add PHAsset to album: %@ error: %@", title, error.localizedDescription);
  19. }
  20. return completionBlock(success);
  21. }];
  22. };
  23. PHAssetCollection *assetCollection = [self albumWithTitle:title];
  24. if(assetCollection){
  25. // Album exists
  26. saveAssetCollection(assetCollection);
  27. } else {
  28. // Need to create album before saving
  29. // Create new album (will create duplicates)
  30. [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
  31. [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
  32. } completionHandler:^(BOOL success, NSError *error) {
  33. if (!success) {
  34. NSLog(@"[LOG] Error creating album: %@", error);
  35. } else {
  36. PHAssetCollection *assetCollection = [self albumWithTitle:title];
  37. saveAssetCollection(assetCollection);
  38. }
  39. }];
  40. }
  41. }
  42. -(void)requestMetadataWithCompletionBlock:(PHAssetMetadataBlock)completionBlock{
  43. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  44. PHContentEditingInputRequestOptions *editOptions = [[PHContentEditingInputRequestOptions alloc]init];
  45. editOptions.networkAccessAllowed = YES;
  46. [self requestContentEditingInputWithOptions:editOptions completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
  47. CIImage *image = [CIImage imageWithContentsOfURL:contentEditingInput.fullSizeImageURL];
  48. dispatch_async(dispatch_get_main_queue(), ^{
  49. completionBlock(image.properties);
  50. });
  51. }];
  52. });
  53. }
  54. -(void)updateLocation:(CLLocation*)location creationDate:(NSDate*)creationDate completionBlock:(PHAssetBoolBlock)completionBlock{
  55. [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
  56. PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest changeRequestForAsset:self];
  57. if(location) assetRequest.location = location;
  58. if(creationDate) assetRequest.creationDate = creationDate;
  59. } completionHandler:^(BOOL success, NSError *error) {
  60. if(success){
  61. completionBlock(YES);
  62. } else {
  63. completionBlock(NO);
  64. }
  65. }];
  66. }
  67. +(void)saveImageToCameraRoll:(UIImage*)image location:(CLLocation*)location completionBlock:(PHAssetAssetBoolBlock)completionBlock{
  68. __block PHObjectPlaceholder *placeholderAsset = nil;
  69. [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
  70. PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
  71. newAssetRequest.location = location;
  72. newAssetRequest.creationDate = [NSDate date];
  73. placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
  74. } completionHandler:^(BOOL success, NSError *error) {
  75. if(success){
  76. PHAsset *asset = [self getAssetFromlocalIdentifier:placeholderAsset.localIdentifier];
  77. completionBlock(asset, YES);
  78. } else {
  79. completionBlock(nil, NO);
  80. }
  81. }];
  82. }
  83. +(void)saveVideoAtURL:(NSURL*)url location:(CLLocation*)location completionBlock:(PHAssetAssetBoolBlock)completionBlock{
  84. __block PHObjectPlaceholder *placeholderAsset = nil;
  85. [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
  86. PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url];
  87. newAssetRequest.location = location;
  88. newAssetRequest.creationDate = [NSDate date];
  89. placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
  90. } completionHandler:^(BOOL success, NSError *error) {
  91. if(success){
  92. PHAsset *asset = [self getAssetFromlocalIdentifier:placeholderAsset.localIdentifier];
  93. completionBlock(asset, YES);
  94. } else {
  95. completionBlock(nil, NO);
  96. }
  97. }];
  98. }
  99. #pragma mark Private helpers
  100. -(PHAssetCollection*)albumWithTitle:(NSString*)title{
  101. // Check if album exists. If not, create it.
  102. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"localizedTitle == %@", title];
  103. PHFetchOptions *options = [[PHFetchOptions alloc]init];
  104. options.predicate = predicate;
  105. PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:options];
  106. if(result.count){
  107. return result[0];
  108. }
  109. return nil;
  110. }
  111. +(PHAsset*)getAssetFromlocalIdentifier:(NSString*)localIdentifier{
  112. if(localIdentifier == nil){
  113. NSLog(@"[LOG] Cannot get asset from localID because it is nil");
  114. return nil;
  115. }
  116. PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
  117. if(result.count){
  118. return result[0];
  119. }
  120. return nil;
  121. }
  122. @end