0

I'm trying to save a list of image url's to an empty array of strings to then show in a collection view. I'm having trouble looping through the dictionary to store the URLs.

I get the Firebase data in the EncounterTableViewController.swift , then have another detailed view controller EncounterDetailViewController.swift that has an EncounterCollectionViewCell.swift

Encounter.swift

class Encounter {
    ...
    ...
    var images: [String] = []
}

EncounterTableViewController.swift

func showAllEncounters() {
    // Firebase tableview data
    FIRDatabase.database().reference().child("encounters").observeSingleEvent(of: .value, with: { (snapshot) in
        for rest in snapshot.children.allObjects as! [FIRDataSnapshot] {
            guard let restDict = rest.value as? [String: Any] else { continue }

            let encounter = Encounter()
            ...
            ...
            let mediaDict = restDict["media"] as! [[String:Any]]

            // need to find nested images and set them to encounter.images here

            self.encounters.append(encounter)

            self.tableView.reloadData()
        }
    })
}

EncounterDetailViewController.swift

private let reuseIdentifier = "imageCell"

class EncounterDetailViewController: UIViewController, 
UICollectionViewDataSource, UICollectionViewDelegate {

// MARK: - Properties
var selectedEncounter: Encounter?

// MARK: - View did load
override func viewDidLoad() {
    super.viewDidLoad()

}

    // MARK: - UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return (selectedEncounter?.images.count)!
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! EncounterCollectionViewCell

    cell.imageView.sd_setImage(with: URL(string: (selectedEncounter?.images[indexPath.row])!))

    return cell
}

Encounter Data structure

encounters
  -12
    -name: "shark"
    -length: "3"
    -media
      -0
        -id: "3242"
        -url: "http://google.com"
        -thumb-url: "http://thisurl.com"
      -1
        -id: "4252"
        -url: "http://google.com"
        -thumb-url: "http://thisurl.com"

1 Answer 1

2

Instead of for loop, simplest solution is to use flatMap.

let mediaDict = restDict["media"] as! [[String:Any]]
images = mediaDict.flatMap { $0["thumb_url"] as? String }

This single line solution will reduce your code of for loop but if still want to go with loop then you can make it like this.

for media in mediaDict {
    if let url = media["thumb_url"] as? String {
        images.append(url)
    } 
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks again @Nirav ;) - haven't used flatMap before but works wondrously
@VladPulichev Its array not dictionary compare your and my one, You are mentioning it dictionary Firebase making it array
@VladPulichev Media is array restDict["media"] as! [[String:Any]] and you are saying it that it is dictionary restDict["media"] as! [String:Any] Hope this gave you idea, When key is number firebase made it array in this case it is array not dictionary, thats why you are wrong This line restDict["Media"] as! Dictionary will give crash to op
@VladPulichev No it still not works because you are telling that it is dictionary but its not dictionary its Array of dictionary
@VladPulichev Glad you made it mate :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.