Skip to content

Instantly share code, notes, and snippets.

@eleev
Last active February 17, 2024 23:56
Show Gist options
  • Save eleev/2f041bb8b1936093773f0bde42af3a49 to your computer and use it in GitHub Desktop.
Save eleev/2f041bb8b1936093773f0bde42af3a49 to your computer and use it in GitHub Desktop.
Getting URL for PHAsset (Swift 3.0)
func getURL(ofPhotoWith mPhasset: PHAsset, completionHandler : @escaping ((_ responseURL : URL?) -> Void)) {
if mPhasset.mediaType == .image {
let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
return true
}
mPhasset.requestContentEditingInput(with: options, completionHandler: { (contentEditingInput, info) in
completionHandler(contentEditingInput!.fullSizeImageURL)
})
} else if mPhasset.mediaType == .video {
let options: PHVideoRequestOptions = PHVideoRequestOptions()
options.version = .original
PHImageManager.default().requestAVAsset(forVideo: mPhasset, options: options, resultHandler: { (asset, audioMix, info) in
if let urlAsset = asset as? AVURLAsset {
let localVideoUrl = urlAsset.url
completionHandler(localVideoUrl)
} else {
completionHandler(nil)
}
})
}
}
@RamohanReddy
Copy link

RamohanReddy commented Mar 27, 2019

Hi @jVirus
I am using below code some times getting asset values some times getting nil.
what is the issue here? how can i do ?

  PHImageManager.default().requestAVAsset(forVideo: mPhasset, options: options, resultHandler: { (asset, audioMix, info) in
                if let urlAsset = asset as? AVURLAsset {
                    let localVideoUrl = urlAsset.url
                    completionHandler(localVideoUrl)
                } else {
                    completionHandler(nil)
                }
            })

Thanks&Regards
Ramohan reddy

@ptvyas
Copy link

ptvyas commented Feb 12, 2020

Hi @jVirus
I have not got URL in the iPhone X device
My code is,

if mPhasset.mediaType == .image {
                let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions.init()
                options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
                    return true
                }
                mPhasset.requestContentEditingInput(with: options, completionHandler: { (contentEditingInput, info) in
                    //completionHandler(contentEditingInput!.fullSizeImageURL)
                    if let value = contentEditingInput {
                        completionHandler(value.fullSizeImageURL)
                    }
                })
            } else if mPhasset.mediaType == .video {
                let options: PHVideoRequestOptions = PHVideoRequestOptions()
                options.version = .original
                PHImageManager.default().requestAVAsset(forVideo: mPhasset, options: options, resultHandler: { (asset, audioMix, info) in
                    if let urlAsset = asset as? AVURLAsset {
                        let localVideoUrl = urlAsset.url
                        completionHandler(localVideoUrl)
                    } else {
                        completionHandler(nil)
                    }
                })
            } 

Any idea ??

@ptvyas
Copy link

ptvyas commented Feb 12, 2020

I have get the contentEditingInput nil value in Image and
asset value is nil form video asses

@sravyagajavalli
Copy link

I am also having the same issue. It is not getting in the iPhone X device how should I solve it. -@ptvyas

@eleev
Copy link
Author

eleev commented Feb 18, 2020

Hello, @RamohanReddy, @ptvyas, @sravyagajavalli!

As the description of the gist mentions, it was originally developed and tested alongside the Swift 3.0 and the corresponding iOS SDK. Since then, a lot of things have changed. I can't tell you immediately what's wrong with the snippet for the iPhone X and iOS 13.0 += 1 version.

I will later check it out and post an update.

@freemansion
Copy link

freemansion commented Jun 19, 2020

thanks for sharing the snippet.
I would just add - in order to fetch videos stored in iCloud (otherwise result handler will return nil) - set PHVideoRequestOptions's param isNetworkAccessAllowed to be true.

@eleev
Copy link
Author

eleev commented Jun 22, 2020

@freemansion greatly appreciate for pointing that important case out.

@fernandodev
Copy link

Thanks! I slightly changed it for what i need

    func requestAssetUrl() -> AnyPublisher<URL, Error> {
        Future { [self] promise in
            if self.mediaType == .image {
                self.requestContentEditingInput(with: nil) { input, info in
                    if let input = input, let url = input.fullSizeImageURL {
                        promise(.success(url))
                    } else {
                        promise(.failure(Errors.urlNotAvailable))
                    }
                }
            } else if self.mediaType == .video {
                let options: PHVideoRequestOptions = PHVideoRequestOptions()
                options.version = .original
                PHImageManager.default().requestAVAsset(forVideo: self, options: options) { asset, audio, info in
                    if let urlAsset = asset as? AVURLAsset {
                        let localVideoUrl = urlAsset.url
                        promise(.success(localVideoUrl))
                    } else {
                        promise(.failure(Errors.urlNotAvailable))
                    }
                }
            } else {
                promise(.failure(Errors.mediaNotSupported))
            }
        }.eraseToAnyPublisher()
    }
    
    extension PHAsset {
      enum Errors: Error {
          case urlNotAvailable
          case mediaNotSupported
      }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment