Chrishon Wyllie
Chrishon Wyllie

Reputation: 209

IOS Swift reading data from a dictionary of [String: [AnotherKindOfDictionary] ] ( )

I would like to read data from a dictionary that contains dictionaries of images (or any sort of object really). Each dictionary has a key (the String).

For a somewhat visual understanding this is what I am trying to achieve:

userIdOne -> [image1, image2, image3, image4]

userIdTwo -> [image1, image2, image3]

userIdThree -> [image1, image2, image3, image4, image5]

userIdFour -> [image1, image2]

NOTE: these images are not the same image despite having the same "title". They just belong to each individual user. The userId is the [String:... and the dictionary of images is the [AnotherKindOfDictionary] I mentioned in the title of this question. I want each userId and their images in each cell. So in total, this would show 4 cells, BUT when tapped, their images would show in sequential order.

The problem is that I want to put this data in a UITableView or UICollectionView. I've worked with both before so whichever works. Something similar to how snapchat works. Whenever a cell is tapped, the images from that user are shown sequentially.

I've been able to load the data into the dictionary with each userID being the key but I am having trouble using the data in a collectionView(my current choice, although I can use a tableView)

Here is my code:

var stories = [String : [StoryMedia]]()

// StoryMedia is a struct containing info

struct StoryMedia {
    var storyMediaId: String?
    var creatorId: String?

    var datePosted: String?

    var imageUrl: String?

    init(storyMediaKey: String, dict: Dictionary<String, AnyObject>) {
        storyMediaId = storyMediaKey
        creatorId = dict["creatorId"] as? String
        datePosted = dict["dateposted"] as? String

        imageUrl = dict["imageUrl"] as? String

    }
}


... Now in the actual viewController class UICollectionViewDataSource

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return stories.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let storyCell: StoryCell!

    storyCell = collectionView.dequeueReusableCell(withReuseIdentifier: storyReuseIdentifier, for: indexPath) as! StoryCell

    // What should I do here?

    return storyCell
}

The problem lies with trying to setup each cell. I cannot pull each dictionary value by its key and use it for each cell.

I've tried using:

// Failed attempt 1)
let story = stories[indexPath.row]
// but I get an ambiguous reference to member 'subscript' error


// Failed attempt 2)
for story in stories {
    let creatorId = story.key
    let sequenceOfStoryItems = story.value


    for singleStoryItem in sequenceOfStoryItems {

        // do something...

    }

}

// but looping through an array for a collection view cell 
// does nothing to display the data and if I were to guess, 
// would be detrimental to memory if 
// I had a lot of "friends" or users in my "timeline"

Upvotes: 0

Views: 782

Answers (2)

dmorrow
dmorrow

Reputation: 5674

Does var stories = [String : [StoryMedia]]() need to be a Dictionary? Dictionaries aren't ordered, so can't index them like you are asking. Can you make it an array of tuples? var stories = [(username:String, media:StoryMedia)]() Then you can add whatever value you were planning to store in the original key into the username: field on the tuple. You could make another struct that has username and media properties if you prefer over the tuple.

It should be trivial to pull individual username or media structs out of the array with a simple stories.filter{} call.

Upvotes: 0

ghostatron
ghostatron

Reputation: 2650

A dictionary isn't ordered, so it's awkward to use that for the cellForItem function (and why you can't use that subscript). You might be able to use the dictionary's values (i.e. ignore the keys), but that could be different b/n runs. What I mean is, you can use the subscript on the stories.values array (don't remember the exact call for "values", but it's close...allValues?...not sure, don't have a way to double check right now) instead of the stories dictionary.

Upvotes: 0

Related Questions