Swift 3 или 4 Сохранение в альбом custum создает дубликаты изображений

Я сохраняю изображения в пользовательский альбом после выбора или завершения камеры. Очевидно, что после завершения камеры остается только одно изображение, но когда пользователь выбирает изображения в средстве выбора галереи, в обработчике завершения, когда я сохраняю это изображение в пользовательском альбоме, ВСЕГДА создается дубликат. Как в галерее, так и в корневом фотоальбоме. Кажется, везде. Я не могу сослаться на идентификатор, чтобы увидеть, был ли он создан ранее, потому что идентификатор создается заново с заполнителем.

Есть ли способ получить базовый идентификатор базового изображения, чтобы я мог связать КАЖДОЕ изображение с оригиналом? Насколько я понимаю, 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)
            })
        }
    }

1 ответ

Никто не удосужился помочь с этим. К счастью, я смог найти решение. Для любого, кто сталкивался с этим или подобным, который также сидел с сверчками: выбор изображения приводит к повторному просмотру фотоаппарата, вот решение.

У меня есть код, чтобы создать новый актив. Это полезно только для сохранения изображения в ваш пользовательский альбом после того, как пользователь сделал снимок с помощью камеры. Это для новых активов.

Однако для существующих активов вы не хотите создавать новый актив. Вместо этого вы хотите добавить существующий ресурс в пользовательский альбом. Для этого вам нужен другой метод. Вот код, который я создал, и он, кажется, работает. Имейте в виду, что вы должны будете сначала получить идентификатор ресурса, чтобы вы могли отправить его своему методу и получить доступ к существующему активу.

Итак, в вашем 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;
}

Теперь, в вашем классе фотопомощи (или в любой функции где угодно, независимо от того), чтобы РЕДАКТИРОВАТЬ актив вместо создания нового, это то, что у меня есть. Я предполагаю, что переменная changeRequest может быть опущена. Я просто играл, пока не понял это правильно. Просматривая совершенно нелепые документы Apple, я смог, по крайней мере, заметить, что есть и другие способы игры. Я обнаружил, что параметр NSFastEnumeration может быть NSArray из PHAssets, а не просто заполнителем объектов PHObjectPlaceholder.

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);
       })
    }

}

Таким образом, это почти то же самое, за исключением того, что вместо создания запроса на создание актива и создания заполнителя для созданного актива, вместо этого вы просто используете существующий идентификатор актива для извлечения существующего актива и добавления существующего актива в NSasray addasset / insertasset. параметр вместо вновь созданного актива

Другие вопросы по тегам