Swift - Local image manipulation without cache

goal

Manipulate several local high-resolution images without catching them, and then select and display some of them as a collection.

Limitations

PHImageManager does not have the ability to retrieve a local image without intercepting it. PHAsset does not have a property to indicate its local path. Finally, I cannot use an array of UIImage or NSData objects because it quickly reaches the memory limit and crashes.

Instruments

Xcode 8.1 - Swift 3.0.1

Current situation

First I retrieve the assets and then iterate over them to get their local path. The reason to get their local path is to access them without infecting them using UIImage(contentsOfFile: localPath) or UIImage.init(data: Data(contentsOf: localPath)) . Then I run some business logic on the images, and I select some of them. Finally, I save the local path of the selected images in an array, which will then be used in the collection view.

Note. In iOS 10 or later, the requestContentEditingInput completion handler calls the call in the main queue.

Problem

Everything works until the moment when browsing the collection tries to load a local image. The local image path is successfully loaded using UIImage(contentsOfFile: localPath) inside the UIImage(contentsOfFile: localPath) completion handler. However, the same image of the local path when loaded using the same function inside the collection view function collectionView(_ collectionView:, cellForItemAt indexPath:) it brings nil .

Therefore, I wonder what I do not see or do wrong. I already tried to use the cancelContentEditingInputRequest resource, thinking that there might have been some kind of lock on the image, but it did not fix the problem.

Code example

 var imagesSelected = [String]() @IBOutlet weak var imageCollectionView: UICollectionView! private func processImages() { ... assets.enumerateObjects({ (asset, count, stop) in ... asset.requestContentEditingInput(with: PHContentEditingInputRequestOptions(), completionHandler: { (input, _) in if let url = input?.fullSizeImageURL { if let image = UIImage(contentsOfFile: url.relativePath) { ... if (...) { self. imagesSelected.append(url.relativePath) self.imageCollectionView.reloadData() } } } }) }) } // MARK: - UICollectionViewDataSource func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath as IndexPath) as! ImageCollectionViewCell cell.productImage.image = UIImage(contentsOfFile: self.images[indexPath.row]) return cell; } 
+5
source share

Source: https://habr.com/ru/post/1260484/


All Articles