2016-09-17 5 views
3

카메라에서 가져온 사진을 내 갤러리에 저장하고 검색하려면 Photos.Framework을 사용하고 있습니다.FetchAssetsWithLocalIdentifiers가 빈 배열을 반환합니다.

__block PHAssetCollection *album = [self getMyAlbumWithName:@"MyAlbumName"]; 
    if(album == nil) 
    { 
     [self makeAlbumWithTitle:@"MyAlbumName" onSuccess:^(NSString *AlbumId) { 

      album = [self getMyAlbumWithName:@"MyAlbumName"]; 
      [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) 
      { 
        _imageLocalIdentifier = imageId; 
      } onError:^(NSError *error) { 
       // No need to do anything 
      }]; 
     } onError:^(NSError *error) { 
      // No need to do anything 
     }]; 
    } 
    else 
    { 
     [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) 
     { 
      _imageLocalIdentifier = imageId; 
     } onError:^(NSError *error) { 
      // No need to do anything 
     }]; 
    } 

-(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName 
{ 
    PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum 
                       subtype:PHAssetCollectionSubtypeAlbumRegular 
                      options:nil]; 
    NSLog(@"assetCollections.count = %lu", assetCollections.count); 
    if (assetCollections.count == 0) return nil; 

    __block PHAssetCollection * myAlbum; 
    [assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) { 
    NSLog(@"album:%@", album); 
    NSLog(@"album.localizedTitle:%@", album.localizedTitle); 
    if ([album.localizedTitle isEqualToString:AlbumName]) { 
     myAlbum = album; 
     *stop = YES; 
     } 
    }]; 

    if (!myAlbum) return nil; 
    return myAlbum; 
} 

-(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError 
{ 
    //Check weather the album already exist or not 
    if (![self getMyAlbumWithName:title]) 
    { 
     [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 
      // Request editing the album. 
      PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title]; 
      // Get a placeholder for the new asset and add it to the album editing request. 
      PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection]; 
      if (placeHolder) 
      { 
       onSuccess(placeHolder.localIdentifier); 
      } 
     } completionHandler:^(BOOL success, NSError *error) { 
      NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); 
      if (error) 
      { 
       onError(error); 
      } 
     }]; 
    } 
} 

-(void)addNewAssetWithImage:(UIImage *)image 
        toAlbum:(PHAssetCollection *)album 
        onSuccess:(void(^)(NSString *ImageId))onSuccess 
        onError: (void(^)(NSError * error)) onError 
{ 
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 
     // Request creating an asset from the image. 
     PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; 
     // Request editing the album. 
     PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album]; 
     // Get a placeholder for the new asset and add it to the album editing request. 
     PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset]; 
     [albumChangeRequest addAssets:@[ placeHolder ]]; 
     NSLog(@"%@",placeHolder.localIdentifier); 
     if (placeHolder) { 
      onSuccess(placeHolder.localIdentifier); 
     } 
    } completionHandler:^(BOOL success, NSError *error) { 
     NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); 
     if (error) { 
      onError(error); 
     } 
    }]; 
} 

그리고 이것이 내가이 사진을 검색하는 데 사용하고 코드입니다 :

PHImageManager *imgManager = [[PHImageManager alloc] init]; 
    PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[_imageLocalIdentifier] options:nil]; 
    if([fetchResult count] > 0) 
    { 
     PHAsset *asset = [fetchResult objectAtIndex:0]; 
     PHImageRequestOptions *option = [PHImageRequestOptions new]; 
     option.synchronous = NO; 
     option.version = PHImageRequestOptionsVersionCurrent; 
     option.networkAccessAllowed = YES; 
     option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic; 
     option.resizeMode = PHImageRequestOptionsResizeModeFast; 
     [imgManager requestImageForAsset:asset 
           targetSize:CGSizeMake(CAMERA_GALLERY_SIZE, CAMERA_GALLERY_SIZE) 
          contentMode:PHImageContentModeDefault 
           options:option 
          resultHandler:^(UIImage *result, NSDictionary *info) { 
           [cell.photoIV setImage:result]; 
          }]; 
    } 

이 코드 조각을

내가 사진을 저장하는 데 사용하고 코드입니다 , 저장된 12 개의 사진 샘플 (내 앨범에서는 괜찮음) 4 또는 5 개의 로컬 식별자가 빈 페치 결과를 반환합니다. 이것은 iOS 8, iOS 9 및 iOS 10에서 테스트됩니다 (iOS 10에서는 거의 모든 가져 오기 결과가 비어 있기 때문에 실제로 더 나쁩니다).

나는 이전 버전의 iOS에서 발견 된 버그와 비슷한 점을 읽었지만 지금은 그렇지 않다는 것을 알았습니다. 내가 사진을 검색하기 위해이 방법을 시도했습니다

은 :

- (PHAsset *)getAssetFromGallery:(NSString *)identifier 
{ 
    PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[identifier] options:nil].lastObject; 
    if(asset != nil) 
     return asset; 

    __block PHAsset *result; 
    PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; 

    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init]; 
    [fetchOptions setPredicate:[NSPredicate predicateWithFormat:@"localIdentifier == %@", identifier]]; 

    [userAlbums enumerateObjectsUsingBlock:^(id _Nonnull objectCollection, NSUInteger idx, BOOL * _Nonnull stopCollectionEnumeration) { 

     PHAssetCollection *collection = nil; 
     if(![objectCollection isKindOfClass:[PHAssetCollection class]]) 
      return; 
     collection = (PHAssetCollection *)objectCollection; 

     PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions]; 
     [assetsFetchResult enumerateObjectsUsingBlock:^(id _Nonnull objectAsset, NSUInteger idx, BOOL * _Nonnull stopAssetEnumeration) { 
      PHAsset *asset = nil; 
      if(![objectAsset isKindOfClass:[PHAsset class]]) 
       return; 
      result = asset; 
      *stopAssetEnumeration = YES; 
      *stopCollectionEnumeration = YES; 
     }]; 

    }]; 

    return asset; 
} 

나는 PHAssetCollectionSubtypeAlbumMyPhotoStream 대신 PHAssetCollectionSubtypeAny으로 시도했습니다. 그리고 @"localIdentifier == %@". 대신 @"localIdentifier ==[cd] %@"을 시도했습니다. 항상 같은 결과가 나오지만 가져 오기 결과가 비어 있습니다. 무슨 일이 벌어지고 있는지 알고 싶습니까?

+0

는 전날이의 원인을 찾았 :

내가 지금 사용하고 코드는 사진을 저장하는 것입니다? 같은 일이 일어나고 있습니다. – StackOverflower

+0

예, 그 이유는 onSuccess (placeHolder.localIdentifier)를 호출했기 때문입니다. completionHandler 블록 내부가 아니라 performChanges 블록 내부. 내 코드 업데이트로 내 자신의 질문에 대답 할 것이므로 확인할 수 있습니다. – Wonton

+0

응답 해 주셔서 감사합니다. 귀하의 답변을 확인합니다 :) – StackOverflower

답변

1

내 문제는 올바른 방법으로 사진을 저장하지 못했다는 것입니다. onSuccess (placeHolder.localIdentifier);를 호출했습니다. completionHandler 블록 내부가 아니라 performChanges 블록 내부.

__block PHAssetCollection *album = [AuxiliaryFunctions getMyAlbumWithName:@"MyAlbumName" orWithIdentifier:@""]; 
if(album == nil) 
    [self makeAlbumWithTitle:@"MyAlbumName" onSuccess:^(NSString *AlbumId) { 

     album = [self getMyAlbumWithName:@"MyAlbumName" orWithIdentifier:AlbumId]; 
     [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) 
     { 
      _imageLocalIdentifier = imageId; 
     } onError:^(NSError *error) { 
      // No need to do anything 
     }]; 
    } onError:^(NSError *error) { 
     // No need to do anything 
    }]; 
else 
{ 
    [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) 
    { 
      _imageLocalIdentifier = imageId; 
    } onError:^(NSError *error) { 
     // No need to do anything 
    }]; 
} 


-(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName orWithIdentifier:(NSString *)identifier 
{ 
    PHFetchResult *assetCollections = nil; 
    if(![identifier isEqualToString:@""]) 
    { 
     PHFetchOptions *options = [PHFetchOptions new]; 
     options.predicate = [NSPredicate predicateWithFormat:@"localIdentifier = %@ OR title = %@", identifier, AlbumName]; 
     assetCollections = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[identifier] 
                       options:options]; 
    } 
    else 
    { 
     PHFetchOptions *options = [PHFetchOptions new]; 
     options.predicate = [NSPredicate predicateWithFormat:@"title = %@", AlbumName]; 
     assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum 
                        subtype:PHAssetCollectionSubtypeAny 
                        options:options]; 
    } 

    NSLog(@"assetCollections.count = %lu", assetCollections.count); 
    if (assetCollections.count == 0) return nil; 

    __block PHAssetCollection * myAlbum; 
    [assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) { 
     NSLog(@"album:%@", album); 
     NSLog(@"album.localizedTitle:%@", album.localizedTitle); 
     if ([album.localizedTitle isEqualToString:AlbumName]) { 
      myAlbum = album; 
      *stop = YES; 
     } 
    }]; 

    if (!myAlbum) return nil; 
    return myAlbum; 
} 

-(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError 
{ 
    __block NSString *localIdentifier = @""; 
    //Check weather the album already exist or not 
    if (![self getMyAlbumWithName:title orWithIdentifier:@""]) 
    { 
     [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 
      // Request editing the album. 
      PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title]; 
      // Get a placeholder for the new asset and add it to the album editing request. 
      PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection]; 
      if (placeHolder) 
      { 
       localIdentifier = placeHolder.localIdentifier; 
       // This line was the problem 
       //onSuccess(localIdentifier); 
      } 
     } completionHandler:^(BOOL success, NSError *error) { 
      NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); 
      if(success) 
      { 
       onSuccess(localIdentifier); 
      } 
      if (error) 
      { 
       onError(error); 
      } 
     }]; 
    } 
} 

-(void)addNewAssetWithImage:(UIImage *)image 
        toAlbum:(PHAssetCollection *)album 
        onSuccess:(void(^)(NSString *ImageId))onSuccess 
        onError: (void(^)(NSError * error)) onError 
{ 
    __block NSString *localIdentifier = @""; 
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 
     // Request creating an asset from the image. 
     PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; 
     // Request editing the album. 
     PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album]; 
     // Get a placeholder for the new asset and add it to the album editing request. 
     PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset]; 
     [albumChangeRequest addAssets:@[ placeHolder ]]; 
     NSLog(@"%@",placeHolder.localIdentifier); 
     if (placeHolder) { 
      localIdentifier = placeHolder.localIdentifier; 
      // This line was the problem 
      //onSuccess(localIdentifier); 
     } 
    } completionHandler:^(BOOL success, NSError *error) { 
     NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); 
     if(success) 
     { 
      onSuccess(localIdentifier); 
     } 
     if (error) 
     { 
      onError(error); 
     } 
    }]; 
} 
+0

fetchAssetCollectionsWithLocalIdentifiers의 첫 번째 매개 변수로 식별자가 전달되면 localIdentifier에 대한 조건부를 지정해야하는 이유는 무엇입니까? 그것은 과장된 것 같습니다. – nishant

관련 문제