skip to Main Content

I am trying to figure out how to get an array of identifiers and put them in a collection view programmatically. Correct me if I am wrong but, I believe the best way to do this is by using PHAsset.fetchAssets. At most I anticipate the users fetching 10 images (avg. 3-4) so I do not think the process would be very resource intensive. I am testing the code below with a specific array of identifiers. In the cellForItemAt function on the line where I assign the asset I get an error message. See the comment above that line. I have seen similar issues on SO but I have not been able to apply anything that I found. What am I doing wrong?

var identifier: [String] = ["83BDF9C0-E1FB-4F68-9F2C-99649A67E218/L0/001", "18D08CEC-4075-4488-BFD1-E9403B214356/L0/001", "74257416-6D9C-48B2-9CE0-C23B56CB4171/L0/001", "2EA7CACE-9B9B-4FC9-ABC5-03BCE2BDAA2A/L0/001", "46A4CD2B-4FEB-4BBE-86DC-B79ED49BC300/L0/001", "E4290EB0-2B16-46AE-9B98-83379F6128F3/L0/001", "7C0B36FF-320D-4083-92E4-5A1F464FFFB1/L0/001", "DEE1414C-2B92-4147-8C3C-A1775FB324AD/L0/001"]
    
class DetailViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
    
    var myCollectionView: UICollectionView!
    let imgManager = PHImageManager.default()
    let requestOptions = PHImageRequestOptions()
    var fetchResult: PHFetchResult<PHAsset>!
    
    override func viewDidLoad() {
        requestOptions.isSynchronous = false
        requestOptions.deliveryMode = .opportunistic
        let layout = UICollectionViewFlowLayout()
        myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        myCollectionView.delegate = self
        myCollectionView.dataSource = self
        myCollectionView.backgroundColor = UIColor.white
        myCollectionView.allowsMultipleSelection = true
        myCollectionView.register(ImageEditCell.self, forCellWithReuseIdentifier: "Cell")
        myCollectionView.showsVerticalScrollIndicator = false
        self.view.addSubview(myCollectionView)
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ImageEditCell
        cell.representedAssetIdentifier = identifier[0]
        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = false
        
        // LINE BELOW PRODUCES ERROR: Cannot convert value of type '[String]' to expected element type 'Array<String>.ArrayLiteralElement' (aka 'String')
        let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: .none).firstObject
        
        imgManager.requestImage(for: asset!, targetSize: CGSize(width:120, height: 120),
                                contentMode: .aspectFill,
                                options: requestOptions,
                                resultHandler: { result, info in
                                    if cell.representedAssetIdentifier == self.identifier {
                                        cell.imageview.image = result
                                    }
                                })
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    I eventually figured it out. I realized i was not correctly converting the identifier to a UIImage so even if I had fixed the error in the OP it still would not work because of numerous others that would have come up with that solution. Below is the solution i got to work:

        var myCollectionView: UICollectionView!
        var imageViews = [UIImageView]()
        var identifier = [
            "83BDF9C0-E1FB-4F68-9F2C-99649A67E218/L0/001",
            "18D08CEC-4075-4488-BFD1-E9403B214356/L0/001",
            "74257416-6D9C-48B2-9CE0-C23B56CB4171/L0/001",
            "2EA7CACE-9B9B-4FC9-ABC5-03BCE2BDAA2A/L0/001",
            "46A4CD2B-4FEB-4BBE-86DC-B79ED49BC300/L0/001",
            "E4290EB0-2B16-46AE-9B98-83379F6128F3/L0/001",
            "7C0B36FF-320D-4083-92E4-5A1F464FFFB1/L0/001",
            "DEE1414C-2B92-4147-8C3C-A1775FB324AD/L0/001"
        ]
        
        override func viewDidLoad() {
            let layout = UICollectionViewFlowLayout()
            myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
            myCollectionView.delegate = self
            myCollectionView.dataSource = self
            myCollectionView.backgroundColor = UIColor.white
            myCollectionView.allowsMultipleSelection = true
            myCollectionView.showsVerticalScrollIndicator = false
            myCollectionView.register(CollectionCell.self, forCellWithReuseIdentifier: "Cell")
            self.view.addSubview(myCollectionView)
        }
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return identifier.count
        }
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionCell
            
            let options = PHFetchOptions()
            let results = PHAsset.fetchAssets(withLocalIdentifiers: identifier, options: options)
            let manager = PHImageManager.default()
            results.enumerateObjects { (thisAsset, _, _) in
                manager.requestImage(for: thisAsset, targetSize: CGSize(width: 200.0, height: 200.0), contentMode: .aspectFit, options: nil, resultHandler: {(thisImage, _) in
                    self.imageViews.append(UIImageView(image: thisImage))
                })
            }
            let image = imageViews[indexPath.item]
            cell.imageView.image = image.image
            return cell
        }
    

  2. Here I’ve moved fetch function to viewDidLoad in order to prevent other errors and also I am not sure what you are fetching whether it is an array with images(if so then by putting .firstObject you are fetching a single image which may cause an error)

    var identifier: [String] = ["83BDF9C0-E1FB-4F68-9F2C-99649A67E218/L0/001", "18D08CEC-4075-4488-BFD1-E9403B214356/L0/001", "74257416-6D9C-48B2-9CE0-C23B56CB4171/L0/001", "2EA7CACE-9B9B-4FC9-ABC5-03BCE2BDAA2A/L0/001", "46A4CD2B-4FEB-4BBE-86DC-B79ED49BC300/L0/001", "E4290EB0-2B16-46AE-9B98-83379F6128F3/L0/001", "7C0B36FF-320D-4083-92E4-5A1F464FFFB1/L0/001", "DEE1414C-2B92-4147-8C3C-A1775FB324AD/L0/001"]
        
    class DetailViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
        
        var myCollectionView: UICollectionView!
        let imgManager = PHImageManager.default()
        let requestOptions = PHImageRequestOptions()
        var fetchResult: PHFetchResult<PHAsset>!
        
        override func viewDidLoad() {
           
            let requestOptions = PHImageRequestOptions()
            requestOptions.isSynchronous = false
            let layout = UICollectionViewFlowLayout()
            myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
            myCollectionView.delegate = self
            myCollectionView.dataSource = self
            myCollectionView.backgroundColor = UIColor.white
            myCollectionView.allowsMultipleSelection = true
            myCollectionView.register(ImageEditCell.self, forCellWithReuseIdentifier: "Cell")
            myCollectionView.showsVerticalScrollIndicator = false
            self.view.addSubview(myCollectionView)
    let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: .none)
    
        }
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ImageEditCell
            cell.representedAssetIdentifier = identifier[indexPath.row]
           
            imgManager.requestImage(for: asset!, targetSize: CGSize(width:120, height: 120),
                                    contentMode: .aspectFill,
                                    options: requestOptions,
                                    resultHandler: { result, info in
                                        if cell.representedAssetIdentifier == self.identifier {
                                            cell.imageview.image = result
                                        }
                                    })
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search