es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo almacenar un objeto ListenerRegistration de Firebase en UserDefaults?

Estoy escribiendo un envoltorio para almacenar, recuperar y eliminar un ListenerRegistration de UserDefaults. Sin embargo, tengo algunos problemas. Estoy intentando almacenarlo haciendo lo siguiente:

  1. Codificar el listener ListenerRegistration en Data
  2. Actualizar mi propiedad activeListeners del diccionario [String:Data] con la nueva clave + datos
  3. Almacenar el diccionario activeListeners actualizado en UserDefaults
func storeListener(listener: ListenerRegistration, for objectId: String, atPath path: AppAPI.Path) {
        let key = formatKeyForListener(objectId: objectId, path: path)
        do {
            let encodedListenerData = try NSKeyedArchiver.archivedData(withRootObject: listener, requiringSecureCoding: false)
            activeListeners.updateValue(encodedListenerData, forKey: key)
            UserDefaults.standard.set(activeListeners, forKey: Strings.listenersKey)
            UserDefaults.standard.synchronize()
        } catch {
            print("Error codificando el listener con la clave: \(key)\nError: \(error.localizedDescription).")
        }
    }

Desafortunadamente, estoy viendo el siguiente error: “Error: No se pudo escribir los datos porque no están en el formato correcto…”.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema puede estar en la propiedad de diccionario activeListeners que se almacena en UserDefaults.

    Asegúrate de que todos los valores del diccionario cumplan con PropertyListEncodable, lo cual incluye todos los tipos estándar de Swift, como String, Int, Float, etc. Parece ser que Data no está incluido en esta lista, por lo que es posible que necesites convertirlo a un formato que pueda ser almacenado en UserDefaults.

    Una opción podría ser convertir el objeto Data a una cadena codificada en Base64, que luego puede ser almacenada como un String en UserDefaults. Para recuperar el valor más tarde, puedes decodificar la cadena en Base64 de nuevo en un objeto Data.

    Aquí tienes un ejemplo de cómo podría ser:

    func storeListener(listener: ListenerRegistration, for objectId: String, atPath path: AppAPI.Path) {
        let key = formatKeyForListener(objectId: objectId, path: path)
        do {
            let encodedListenerData = try NSKeyedArchiver.archivedData(withRootObject: listener, requiringSecureCoding: false)
            let base64EncodedData = encodedListenerData.base64EncodedString()
            activeListeners.updateValue(base64EncodedData, forKey: key)
            UserDefaults.standard.set(activeListeners, forKey: Strings.listenersKey)
            UserDefaults.standard.synchronize()
        } catch {
            print("Error al codificar el listener con la clave: \(key)\nError: \(error.localizedDescription).")
        }
    }
    

    Luego, para recuperar el listener:

    func retrieveListener(forKey key: String) -> ListenerRegistration? {
        guard let encodedData = activeListeners[key] as? String,
            let rawData = Data(base64Encoded: encodedData),
            let listener = NSKeyedUnarchiver.unarchiveObject(with: rawData) as? ListenerRegistration
            else { return nil }
    
        return listener
    }
    

    Esto debería permitirte almacenar, recuperar y eliminar el listener de snapshot de UserDefaults sin encontrar ese error.

Comments are closed.