1

i am trying to make a small Social Media app. the friends and friendrequest gets stored as User in different arrays. But when i want to loop the array it an shows which user send a request it first works but when i accept the user and he is remove from the Array i am getting this error "Thread 1: Fatal error: Index out of range" i know its because the loop wants to loop to a index which doesn't exist anymore but how do i fix it ?

struct FriendsView: View {

@EnvironmentObject var appUser: User

var body: some View {
    
List {
    ForEach(0..<appUser.friendAnfrage.count) {
    durchlauf in
        SingleFriendView(user: appUser.friendAnfrage[durchlauf])
            }
        }
    }
}

class User: ObservableObject{

@Published var username: String = ""
@Published var name: String = ""
var password: String = ""
@Published var email: String = ""
@Published var beschreibung: String = ""
@Published var profilBild: UIImage?

@Published var friends = [User]()
@Published var friendAnfrage = [User]()
@Published var anfrageGesendet = [User]()

@Published var feed = [SinglePostView]()

func addFriend(friend: User,appUser: User) {
    friend.friendAnfrage.append(appUser)
    appUser.anfrageGesendet.append(friend)
    
}
func newFriend(newFriend: User) {
    friends.append(newFriend)
    
    for i in 0..<friendAnfrage.count {
        if friendAnfrage[i].username == newFriend.username {
            friendAnfrage.remove(at: i)
        }
    }
}
func friendAnfrage(friend: User,appUser: User) {
    appUser.friendAnfrage.append(friend)
}

func makePost(image: UIImage,appUser: User) {
    
    feed.append(SinglePostView(bild: image, ersteller: appUser))
    
    for i in 0..<friends.count {
        friends[i].feed.append(SinglePostView(bild: image, ersteller: appUser))
    }
}

}

2
  • have you debugged? in which line is it crashing? what's the value of the array before the for starts Commented Mar 2, 2022 at 20:34
  • Where the forEach loop is Commented Mar 2, 2022 at 21:00

2 Answers 2

1

ForEach with an index-based approach is dangerous in SwiftUI. Instead, make your model identifiable.

class User: ObservableObject, Identifiable {
  var id = UUID()
  //...

Then, change your loop:

ForEach(appUser.friendAnfrage) { item in
   SingleFriendView(user: item)
}

Unrelated to this exact issue, but generally SwiftUI does better with using a struct for a model instead of a class. If a User in friends is updated with your current code, because it's a nested ObservableObject, your View will not get automatically updated.

Sign up to request clarification or add additional context in comments.

5 Comments

Where do i need the UUID for ?
i Think i know, that i can better compare the User with each other right ?
Not you necessarily, but the system for sure. The ForEach loop uses it to identify each User.
I should note that if you have another way of identifying the user (which for a social media app, you should), you can use that as well -- you don't necessarily have to generate a random UUID. Just make sure it conforms to Identifiable or explicitly pass the identifier into the ForEach: ForEach(myCollection, id: \.myIdProperty)
Sry mate i am very new to all that Stackoverflow stuff i think i just missclicked at some point but now your answer is marked as correctly. I didnt know i only can mark one Answer because both helped me much.
1

User should be a struct and ForEach isn't a traditional loop, it's a View that must be supplied identifiable data, e.g.

struct FriendsView: View {
    @EnvironmentObject var model: Model

    var body: some View {
        List {
            ForEach($model.users) { $user in
                SingleFriendView(user: $user)
            }
        }
    }
}

struct User: Identifiable{
    let id = UUID()
    var username: String = ""
    var friends: [UUID] = []
}

class Model: ObservableObject {
    @Published var users: [User] = []
}

2 Comments

Thank you for the answer, i have one question, i will try now to get the user into a struct but in my current class i have some Arrays which are set to published, when i change the class to a struct i get the Error "'wrappedValue' is unavailable: Published is only available on properties of classes" so i deleted the @Published keyword but then my functions addFriend and friendAnfrage are not working an having an error.
You can use mutating func in structs. For the friends you might be better using an array of IDs in the User struct.

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.