-1

I am saving a list of file names/paths so I can load the image at a later time to upload it.

When the user selects the images from the camera roll, I get back this

file:///Users/admin/Library/Developer/CoreSimulator/Devices/B31CE61D-FB46-41F0-B254-B66B9335E1E4/data/Media/DCIM/100APPLE/IMG_0005.JPG

But when I try to load up the image,

   if let image = UIImage(named: filepath) {
        imageView.image = image
   } 

It doesn't load.

How do I load an image from a filepath?

The code I use to get the file path

func getURL(ofPhotoWith mPhasset: PHAsset, completionHandler : @escaping ((_ responseURL : URL?) -> Void)) {
    let options = PHContentEditingInputRequestOptions()
    options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
        return true
    }
    mPhasset.requestContentEditingInput(with: options, completionHandler: { (contentEditingInput, info) in
        completionHandler(contentEditingInput!.fullSizeImageURL)
    })
}


func add(images: [PHAsset])  {
    for image in images {
        getURL(ofPhotoWith: image) { (imgURL) in
            if let imgURL = imgURL {
                print ("ImageURL: \(imgURL.absoluteString)")
            }
        }
     }
 }
user-44651
  • 3,227
  • 4
  • 26
  • 64
  • `absoluteString` returns an URL string, not a file path. Compare e.g. https://stackoverflow.com/questions/34135305/nsfilemanager-defaultmanager-fileexistsatpath-returns-false-instead-of-true. – Martin R Oct 16 '18 at 18:40
  • `UIImage` requires a string for `contentsOfFile`, or `named` – user-44651 Oct 16 '18 at 18:43

2 Answers2

0

I am saving a list of file names/paths so I can load the image at a later time to upload it.

PHContentEditingInput is the wrong tool for that job. As the names of that class and the functions you're using to get one suggest, it's for content editing — tasks like applying a filter to an asset in the library.

When PHContentEditingInput gives you a file URL, it's granting you temporary access to that file. PhotoKit makes no guarantee that the asset in question will always be backed by a file at that URL, and even if it is, PhotoKit revokes temporary access to that URL when the owning PHContentEditingInput is deallocated.

A user's Photos library isn't a directory full of image files — it's a database, where each asset can have data resources stored in one or more files, which might or might not even be in local storage at all times. If you want to upload assets to an external service and preserve all the original data, you need an API that's meant for getting data resources. PhotoKit gives you two choices for that:

  1. If you want just some image representation of the current state of the asset, use PHImageManager. This downloads and/or generates image data ready for you to save as a file, incorporating whatever edits the user has already applied to the asset:

    let options = PHImageRequestOptions()
    options.deliveryMode = .highQualityFormat
    options.isNetworkAccessAllowed = true
    PHImageManager.default().requestImageData(for: myAsset, options: options) { data, uti, orientation, info in
        // save `data` to file / upload to web service
        // use `uti` to find out what file type it is
    }
    
  2. If you want the original image data resources — that is, enough data that you could back up and restore the asset, including features like in-progress edits, Live Photo modes, and RAW format image data — use PHAssetResource and PHAssetResourceManager:

    let resources = PHAssetResource.resources(for: myAsset)
    let options = PHAssetResourceRequestOptions()
    options.isNetworkAccessAllowed = true
    for resource in resources {
        let outputURL = myOutputDirectory.appendingPathComponent(resource.originalFilename)
        PHAssetResourceManager.default().writeData(for: resource, to: outputURL, options: options) { error in
            // handle error if not nil
        }
    }
    
rickster
  • 118,448
  • 25
  • 255
  • 308
0

I am saving a list of file names/paths so I can load the image at a later time to upload it when the user selects the images from the camera roll

Don't. The thing to save so that you can retrieve something from the camera roll at a later time is the PHAsset's localIdentifier. You can use that to get the same asset again later, and now you can ask for the associated image.

matt
  • 447,615
  • 74
  • 748
  • 977