PHAsset+Utility.m 5.7 KB

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