0

I updated the published var chats in a sheet. And when the sheet is dismissed (by button press), the MessageView navigates to ChatView. I hope to use that updated chats in the ChatView, but now when it's first pushed, chats isn't updated, until you go back and push the view again. Is there a way to get around?

getAllChats is the observableobject with var chats

class getAllChats : ObservableObject{
    
    @Published var chats = [Chat]()
    
    @EnvironmentObject var userInfo : UserData
    
    init() {
        
        let db = Firestore.firestore()
        let currentid = Auth.auth().currentUser!.uid
        
        db.collection("users").document(currentid).getDocument { (document, err) in
            if let document = document {
                
                //all chat ids
                if let chatIDs = document.get("chats") as? [String]{
                    
                    for chatid in chatIDs{ //download chat from chat ids
                        db.collection("chats").document(chatid).getDocument { (doc, error) in
                            if let doc = doc{
                                let frienduid = doc.get("user1") as! String == currentid ? doc.get("user2") as! String : doc.get("user1") as! String
                                let friendname = doc.get("user1") as! String == currentid ? doc.get("user2_username") as! String : doc.get("user1_username") as! String
                                
                                let friend = FetchedUser.init()
                                friend.uid = frienduid
                                friend.username = friendname
                                
                                //parse msg
                                var messages: [Message] = []
                                
                                let messagesArr = doc.get("messages") as! [[String:Any]]
                                for msg in messagesArr {
                                    messages.append(Message.fromDB(object: msg))
                                }
                                
                                //create chat
                                let chat = Chat.init(friend: friend, messages: [])
                                self.chats.append(chat)
                                print(self.chats.count)
                            }
                        }
                    }
                }
            }
        }
    }
}

MessageView

    struct MessagingView: View {
    @State var addChat = false //show search user view
    @State var showNewChat = false
   
    @State var addedUser = FetchedUser.init()

    @ObservedObject var chatsData = getAllChats()
    
    @EnvironmentObject var userInfo: UserData
    
    init(){
        UITableView.appearance().tableFooterView = UIView()
        UITableView.appearance().separatorStyle = .none
    }
    
    @ViewBuilder
    var body: some View {
        VStack{
            List(chatsData.chats, id: \.chatID){ chat in
                NavigationLink(destination: ChatView(chat: chat)) {
                    ChatCellView(chat: chat)
                }
            }
            
            //navigate to a new chat
            if !chatsData.chats.isEmpty{
            NavigationLink(destination: ChatView(chat: chatsData.chats[0]), isActive: $showNewChat){
                Text("")
            }
            }
            
        }
        .navigationBarItems(trailing: Button(action: {
                        self.addChat.toggle()
                    }, label: {
                        Image(systemName: "plus.circle.fill")
                            .font(.headline)
                    }).accentColor(.white))
                                                  
                        .sheet(isPresented: $addChat) {
                            AddChatView(addedUser: self.$addedUser, addChat: self.$addChat, showNewChat: self.$showNewChat)
                                .environmentObject(self.userInfo)
                            
        }
                    
    }
}


struct ChatCellView: View{
    var chat: Chat
    
    var body: some View{
        VStack(spacing: 0){
            HStack{
                Image(systemName: "person.crop.circle")
                    .font(.title)
                    .padding()
                
                VStack(alignment: .leading){
                    Text(chat.friend.username)
                        .font(.headline)
                    
                    HStack{
                        Text(chat.mostRecentMessage()?.body ?? "Tap to chat")
                            .font(.body)
                            .padding(.trailing, 10)
                        
                        Spacer()
                    }
                }
                
                Circle()
                    .fill(isUnread() ? Color.navIconColor : Color.clear)
                    .frame(width: 12, height: 12)
                
                Spacer()
            }
        }
    }
    
    func isUnread() -> Bool{
        if let mostRecentMessage = chat.mostRecentMessage() {
            return !mostRecentMessage.hasRead && mostRecentMessage.recipient == "user"
        }
        return false
    }
    
}

ChatView

struct ChatView: View{
    
    var chat: Chat

    @State var write = ""
    
    var body: some View {
        VStack {
            List(chat.messages) { i in
                ListMessage(msg: i.body, sentFromUser: i.sender == "user")
            }
            .navigationBarTitle(
                Text(chat.friend.username), displayMode: .inline)
                .accentColor(.white)
           
            
            HStack {
                TextField("message...",text: self.$write).padding(10)
                    .background(Color(red: 233.0/255, green: 234.0/255, blue: 243.0/255))
                    .cornerRadius(25)
                
                Button(action: {
                    if self.write.count > 0 {
                        //self.message.addInfo(msg: self.write, user: self.name, image: self.image)
                        self.write = ""
                    } else {
                        
                    }
                }) {
                    Image(systemName: "paperplane.fill").font(.system(size: 20))
                        .foregroundColor((self.write.count > 0) ? Color.navIconColor : Color.gray)
                        .rotationEffect(.degrees(50))
                    
                }
            }.padding()
        }.padding(.top)
         .modifier(AdaptsToKeyboard())
    }
}

struct ListMessage : View {
    
    var msg = ""
    
    var sentFromUser = false
    
    var body: some View {
        
        HStack {
            if sentFromUser {
                Spacer()
                
                HStack {
                    Text(msg).padding(10).background(Color.secondary)
                        .cornerRadius(18)
                        .foregroundColor(.white)
                    
                    
                }
            } else {
                HStack {
                    
                    Text(msg).padding(10).background(Color.titleBarColor)
                        .cornerRadius(28)
                        .foregroundColor(.white)
                    
                }
                Spacer()
            }
        }
    }
}
guckmalmensch
  • 973
  • 2
  • 9
  • 22
  • You have many missing dependencies... Try to create a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – pawello2222 Jul 07 '20 at 21:11

2 Answers2

0

I assume the link is toggled too early, so instead of activate link by binding in sheet, try to activate it after sheet got dismissed

Here is a way (scratchy, as provided snapshot is not testable)

.sheet(isPresented: $addChat, 
       onDismiss: { self.$showNewChat }) {  // << here
    
    // refactor AddChatView to remove dependency on showNewChat
    AddChatView(addedUser: self.$addedUser, addChat: self.$addChat)
        .environmentObject(self.userInfo)
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
0

So the problem is you want to update the chatView with new chats which is in object chat

And you are not observing chat inside ChatView, but you are observing chat inside Messageview, so it cannot update inside ChatView. That's th reason its updating when you are going back to messageView

so you need to convert your chat to a ObservedObject to listed its publisher.

struct ChatView: View{
    
    @ObservedObject var chat: Chat

    @State var write = ""
...................
............

}

and also you need to modify Chat(individual) to be a ObservableObject in its class.

Reed
  • 944
  • 7
  • 15