Swift - Problemas al guardar un documento

 
Vista:
Imágen de perfil de Víctor
Val: 6
Ha mantenido su posición en Swift (en relación al último mes)
Gráfica de Swift

Problemas al guardar un documento

Publicado por Víctor (5 intervenciones) el 30/07/2019 18:58:26
Hola:

Estoy intentando crear una aplicación para MacOs con swift 5, que permita guardar en disco el contenido de un documento. Ya lo había hecho otras veces con swift 3, pero ahora soy incapaz.
He creado una aplicación basada en documentos:
- El documento tiene un atributo llamado persona de la clase Persona. Esta clase tiene dos atributos: nombre (String) y edad (Int).
- En el menú principal he creado un item que se enlaza con la función “guardar” de “AppDelegate”
- En Document he creado la función “encode” y “data”
- En “Persona” la función encode
- Además hay una función: “getDocumentoActivo()” que devuelve una referencia al documento activo.

Me sale el siguiente mensaje en la consola:
2019-07-30 18:45:21.384048+0200 App004[27910:2850438] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}

No entiendo que es lo que hago mal.

Los códigos son:
APPDelegate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import Cocoa
 
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
 
 
 
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
    }
 
    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }
 
    @IBAction func guardar(_ sender: Any) {
        print("en guardar")
        let savePanel = NSSavePanel()
        savePanel.runModal()
        print(savePanel.url)
        if let doc = getDocumentoActivo() {
            do {
                try doc.write(to: savePanel.url!, ofType: "acirme")
            } catch {
                print("Error al guardar el archivo")
            }
        }
    }
 
}

Document:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import Cocoa
 
class Document: NSDocument {
 
    // Atributos añadidos por el programador
    var persona = Persona()
 
    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.persona)
    }
 
    required init?(coder aDecoder: NSCoder) {
        Swift.print("Init coder")
    }
 
    override init() {
        super.init()
        // Add your subclass-specific initialization here.
    }
 
    override class var autosavesInPlace: Bool {
        return true
    }
 
    override func makeWindowControllers() {
        // Returns the Storyboard that contains your Document window.
        let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
        let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController
        self.addWindowController(windowController)
    }
 
    override func data(ofType typeName: String) throws -> Data {
        do {
            return try NSKeyedArchiver.archivedData(withRootObject: self.persona, requiringSecureCoding: false)
        } catch {
            return Data()
        }
    }
 
    override func read(from data: Data, ofType typeName: String) throws {
        // Insert code here to read your document from the given data of the specified type, throwing an error in case of failure.
        // Alternatively, you could remove this method and override read(from:ofType:) instead.
        // If you do, you should also override isEntireFileLoaded to return false if the contents are lazily loaded.
        throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
    }
 
 
}

Persona:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import Cocoa
 
class Persona: NSObject, NSCoding {
 
    override init() {
    }
 
    required init?(coder aDecoder: NSCoder) {
    }
 
    var nombre = "Nombre de la persona"
    var edad   = 20
 
    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.nombre)
        aCoder.encode(self.edad)
    }
}

¿Pueden ayudarme?

Disculpas por la longitud del mensaje.

Saludos de Víctor.-
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Alejandro

Problemas al guardar documento en macOS

Publicado por Alejandro (12 intervenciones) el 21/02/2024 20:38:08
Victor, parece que estás teniendo algunos problemas en tu código. Aquí hay algunas sugerencias y correcciones para resolver los problemas:

1. Error en `encode` de Document:
- En el método `encode(with:)` de la clase `Document`, deberías especificar las claves para cada atributo cuando estás utilizando `NSCoder`.
- Asegúrate de utilizar las mismas claves en `encode(with:)` que en `init?(coder:)` de la clase `Persona`.

1
2
3
4
5
6
7
8
9
10
11
12
class Document: NSDocument {
 
    // ...
 
    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.persona.nombre, forKey: "nombre")
        aCoder.encode(self.persona.edad, forKey: "edad")
    }
 
    // ...
 
}

2. Error en `Persona`:
- En la clase `Persona`, asegúrate de decodificar los atributos en el mismo orden en el que fueron codificados.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Persona: NSObject, NSCoding {
 
    // ...
 
    required init?(coder aDecoder: NSCoder) {
        if let nombre = aDecoder.decodeObject(forKey: "nombre") as? String {
            self.nombre = nombre
        }
        self.edad = aDecoder.decodeInteger(forKey: "edad")
    }
 
    // ...
 
}

3. Manejo de errores en `guardar` de `AppDelegate`:
- En el método `guardar` de `AppDelegate`, deberías manejar la posibilidad de que el usuario cancele el panel de guardado y que la URL sea `nil`.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@IBAction func guardar(_ sender: Any) {
    print("en guardar")
    let savePanel = NSSavePanel()
    guard savePanel.runModal() == NSApplication.ModalResponse.OK, let url = savePanel.url else {
        return
    }
 
    if let doc = getDocumentoActivo() {
        do {
            try doc.write(to: url, ofType: "acirme")
        } catch {
            print("Error al guardar el archivo: \(error)")
        }
    }
}

Estas correcciones deberían ayudarte a resolver los problemas que estás experimentando al guardar el documento en macOS. Asegúrate de haber incluido todas las correcciones en tu código y prueba nuevamente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar