WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Day 61: Friendface - Get an array of [CachedUser]

Forums > 100 Days of SwiftUI

On top of the original requirments, I want to compare the list of friends in user details page with the full users list so that things like greying out unregistered friends and showing the friend's details page are possible.

I've already done so before implementing Core Data, but after that I couldn't pass around the list of users to work with without first converting it from FetchedResults<CachedUser> type into [CachedUser].

To do so I imagine it to be similar as converting the user's friends NSSet to a Set<CachedFriend>, where the function will be:

  func getUsersArray(_ users: FetchedResults<CachedUser>) -> [CachedUser] {
        let set = users as? Set<CachedFriend> ?? [] // "users" here is the variable storing the original FetchedResults<CachedUser>

        return set.sorted {
            $0.wrappedName < $1.wrappedName

The question is, where should I run the function? I tried putting it inside a didSet like this:

var usersArray: [CachedUser]

@FetchRequest(sortDescriptors: [SortDescriptor(\.name)]) var users: FetchedResults<CachedUser> {
  didSet {
  usersArray = getUsersArray(users)

It first said "Cannot assign to property: 'self' is immutable". So I added @State to before var usersArray: [CachedUser], then another error was shown in the upper (top) level file, next to ContentView() - "Missing arguement for parameter 'usersArray' in call"

Have I been wrong since assuming the function? On the other hand how should a computed property like this be declared in general?

I hope it all makes sense. Thanks for your help.


I don't know that it's the right answer, but what I did was put a computed property in my User class that creates an NSCompoundPredicate from the ids of all a users's friends.

@objc dynamic public var friendsPredicate: NSCompoundPredicate {
        var predicates = [NSPredicate]()
        for friend in friendsArray {
            predicates.append(NSPredicate(format: "id == '\(friend.wrappedId)'"))
        return NSCompoundPredicate(orPredicateWithSubpredicates: predicates)

I then adapted the filtered list view from the singers example to initialize with that predicate and create Content for each fetched User.

init(predicate: NSCompoundPredicate, @ViewBuilder content: @escaping (T) -> Content) {
        fetchRequest = FetchRequest(entity: CacheUser.entity(), sortDescriptors: [], predicate: predicate)
        self.content = content


Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.