Rainbow-CPaaS / Rainbow-iOS-SDK-Samples

All samples of the Rainbow SDK for iOS
Other
4 stars 3 forks source link

MessageBrowser crash #12

Closed Patresko closed 2 years ago

Patresko commented 2 years ago

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSPathStore2 itemsBrowser:didAddCacheItems:atIndexes:]: unrecognized selector sent to instance 0x283789bc0'

My code in SWIFT

import Foundation
import Rainbow

class ChatLogViewModel: NSObject, ObservableObject, CKItemsBrowserDelegate {

    @Published var chatMessages = [ChatMessage]()

    private let serviceManager: ServicesManager
    private let conversationsManager : ConversationsManagerService
    private let messagesPerPage = 20
    private let conversation: Conversation?

    required init?(conversation: Conversation?) {
        serviceManager = ServicesManager.sharedInstance()
        conversationsManager = serviceManager.conversationsManagerService
        self.conversation = conversation
        super.init()

        fetchMessages()
    }  
}

And this is fetchMesssages function

    private func fetchMessages() {

        chatMessages.removeAll()

        let messageBrowser: MessagesBrowser = serviceManager.conversationsManagerService.messagesBrowser(for: conversation, withPageSize: messagesPerPage, preloadMessages: true)

        messageBrowser.delegate = self
        messageBrowser.reset()

        messageBrowser.resyncBrowsingCache { (addedCacheItems : Optional<Array<Any>>, removedCacheItems : Optional<Array<Any>>, updatedCacheItems : Optional<Array<Any>>, error : Optional<Error>) in

            if error != nil {
                NSLog("Messages Sync Error \(error?.localizedDescription ?? "Unknown error")")
            } else {
                NSLog("Messages Resync Done")
            }
        }

       // self.sortChatMessages()

        serviceManager.conversationsManagerService.markAllMessagesAsRead(for: conversation!)
    }

Also your provided sample for Swift is not valid.

Cannot declare conformance to 'NSObjectProtocol' in Swift

Patresko commented 2 years ago

After little research, that was problem with SwiftUI and not with SDK.

Here is solution how to fix it.

You have to use @StateObject instead of @ObservedObject because view state changes multiple times in every @State variable update.

So in your view, you need to use something like this

   struct ChatLogView: View {

    let conversation: Conversation
    let contact: Contact?

    init(conversation: Conversation) {
        print("CHAT LOG VIEW INIT")
        self.conversation = conversation
        self.contact = conversation.peer as? Contact

        _chatLogViewModel = StateObject(wrappedValue: ChatLogViewModel(conversation: conversation))
    }

    @StateObject private var chatLogViewModel: ChatLogViewModel
}

And this is correct class syntax for latest SWIFT

class ChatLogViewModel: NSObject, ObservableObject, CKItemsBrowserDelegate {

    @Published var chatMessages = [ChatMessage]()

    private let serviceManager: ServicesManager
    private let conversationsManager : ConversationsManagerService
    private let messagesPerPage = 20
    private let conversation: Conversation?

    init(conversation: Conversation?) {
        print("CHAT LOG VIEW MODEL INIT")
        self.conversation = conversation
        serviceManager = ServicesManager.sharedInstance()
        conversationsManager = serviceManager.conversationsManagerService

        super.init()
    }
}