2017-09-30 10 views
0

선택 또는 카메라 완료 후 이미지를 사용자 정의 앨범에 저장합니다. 분명히 카메라가 완료된 후에는 하나의 이미지 만 있지만 사용자가 갤러리 선택 도구에서 이미지를 선택하면 완료 핸들러에서 해당 이미지를 사용자 정의 앨범에 저장할 때 항상 복제본이 만들어집니다. 갤러리와 루트 사진 앨범 모두. 도처에, 그것은 보인다. 이전에 생성되었는지 확인하기 위해 ID를 참조 할 수 없습니다. ID가 자리 표시자를 사용하여 새로 작성되기 때문입니다.스위프트 3 또는 4 custum 앨범에 저장하면 중복 이미지가 생성됩니다.

모든 이미지를 원본 이미지에 연결할 수 있도록 기본 이미지 참조 ID를 가져 오는 방법이 있습니까? 내가 이해하는 것처럼, IOS는 (ios btw가 싫다.) 하나의 실제 이미지 만 저장하고 나머지는 원래 이미지 객체에 대한 포인터 일 뿐이다. 그렇다면 원래 이미지에 대한 확실한 참조를 얻을 수있는 방법이있을 것이라고 기대합니다. 거기에서 그 기본 이미지로 생성 된 애셋을 쉽게 관리 할 수 ​​있습니다.

public static func addNewImage(_ image:UIImage, toAlbum albumName:String,imageID:String?,onSuccess success:@escaping(String)->Void, onFailure failure:@escaping(Error?)->Void) { 
     guard let album = self.getAlbum(withName: albumName) else { 
      failure(SDPhotosHelper.albumNotFoundError) 
      return 
     } 

     var localIdentifier = String(); 

     if(imageID != nil){ 
      if(self.hasImageInAlbum(withIdentifier: imageID!, fromAlbum: albumName)){ 
       failure(SDPhotosHelper.albumNotFoundError) 
       return; 
       } 
     } 

     PHPhotoLibrary.shared().performChanges({ 
       let albumChangeRequest = PHAssetCollectionChangeRequest(for: album) 

      let assetCreationRequest = PHAssetChangeRequest.creationRequestForAsset(from: image) 
      //assetCreationRequest.location = ""; 
      let placeHolder = assetCreationRequest.placeholderForCreatedAsset 
      albumChangeRequest?.addAssets([placeHolder!] as NSArray) 
      if placeHolder != nil { 
       localIdentifier = (placeHolder?.localIdentifier)! 
      } 

     }) { (didSucceed, error) in 
      OperationQueue.main.addOperation({ 
       didSucceed ? success(localIdentifier) : failure(error) 
      }) 
     } 
    } 
+0

이것은 매우 유용합니다! 비슷한 질문이 있습니다. https://stackoverflow.com/questions/47378305/how-do-i-copy-an-image-from-the-iphone-photos-library-to-my-album-without-having? noredirect = 1 # comment81709017_47378305 –

답변

0

아무도이 문제에 도움이되지 않습니다. 다행히도 솔루션을 찾을 수있었습니다. 귀뚜라미와 함께 앉아 있던 비슷한 사람이나 비슷한 사람은 Choosing a picture causes resave to camera roll 여기에 해결책이 있습니다.

내가 가진 코드는 새로운 자산을 만드는 것입니다. 사용자가 카메라로 사진을 찍은 후에 이미지를 사용자 정의 앨범에 저장하는 경우에만 유용합니다. 그것은 새로운 자산을위한 것입니다.

그러나 기존 저작물의 경우 새 저작물을 만들고 싶지 않습니다. 기존 저작물을 맞춤 앨범에 추가하려고합니다. 이렇게하려면 다른 방법이 필요합니다. 여기 내가 만든 코드가 작동하는 것 같습니다. 저작물 ID를 먼저 가져 와서 방법으로 전송하고 기존 저작물에 액세스 할 수 있도록해야합니다.

따라서 imagePickerController에서 사용자가 기존 이미지를 선택했는지 또는 새 카메라 작업에서 메서드를 호출하는지 여부를 결정해야합니다.

let pickerSource = picker.sourceType; 
switch(pickerSource){ 
case .savedPhotosAlbum, .photoLibrary: 
    if(let url = info[UIIMagePickerControllerReferenceURL] as? NSURL{ 
    let refURLString = refURL?.absoluteString; 
    /* value for refURLString looks something like assets-library://asset/asset.JPG?id=82A6E75C-EA55-4C3A-A988-4BF8C7F3F8F5&ext=JPG */ 
    let refID = {function here to extract the id query param from the url string} 
    /*above gets you the asset ID, you can get the asset directly, but it is only 
    available in ios 11+. 
    */ 
    MYPHOTOHELPERCLASS.transferImage(toAlbum: "myalbumname", withID: refID!, ...) 

} 
break; 
case .camera: 
... 
break; 
} 

지금, 당신의 photohelper 클래스 (또는 무엇이든 어디서나 어떤 기능에서), 자산을 편집하는 대신 새로운 하나를 만들려면 내가 가진 것입니다. changeRequest 변수를 생략 할 수 있다고 가정합니다. 나는이 권리를 얻을 때까지 그냥 놀고 있었어. 완전 우스꽝스런 사과 문서를 살펴보면 다른 방법이 있다는 것을 눈치 채지 못했습니다. NSFastEnumeration 매개 변수는 단지 자리 표시 자 PHObjectPlaceholder 객체뿐만 아니라 PHAssets의 NSArray가 될 수 있다는 것을 알았습니다.

public static func transferImage(toAlbum albumName:String, withID imageID:String, onSuccess success:@escaping(String)->Void, onFailure failure:@escaping(Error?)->Void){ 

    guard let album = self.getAlbum(withName: albumName) else{ 
    ... failure here, albumNotFoundError 
    return; 
    } 

    if(self.hasImageInAlbum(withIdentifier: imageID, fromAlbum: albunName)){ 
    ... failure here, image already exists in the album, do not make another 
    return; 
    } 

    let theAsset = self.getExistingAsset(withLocalIdentifier: imageID); 
    if(theAsset == nil){ 
    ... failure, no asset for asset id 
    return; 
    } 

    PHPhotoLibrary.shared().performChanges({ 
     let albumChangeRequest = PHAssetCollectionChangeRequest(for: album); 
     let changeRequest = PHAssetChangeRequest.init(for: theAsset!); 
     let enumeration:NSArray = [theAsset!]; 
     let cnt = album.estimatedAssetCount; 
     if(cnt == 0){ 
      albumChangeRequest?.addAssets(enumeration); 
     }else{ 
      albumChangeRequest?.inserAssets(enumeration, at: [0]); 
     } 
    }){didSucceed, error) in 
     OperationQueue.main.addOperation({ 
     didSucceed ? success(imageID) : failure(error); 
     }) 
    } 

} 

그래서, 대신 자산 생성 요청을 생성하고 생성 된 자산에 대한 자리 표시자를 생성을 제외하고 거의 동일합니다, 당신은 대신 기존 자산을 가져 오기 위해 기존 자산 ID를 사용하고 기존 추가 자산을 새로 생성 된 자산 대신 addasset/insertasset NSArray 매개 변수에 추가