Por qué Swift no es solo sobre UI, sino también sobre archivos
\n\nCuando los desarrolladores comienzan a aprender Swift, la mayoría de las veces escriben aplicaciones con interfaces, animaciones y solicitudes de red. Pero tarde o temprano surge la tarea: guardar datos en el dispositivo, leer un archivo de configuración, analizar un archivo JSON o simplemente copiar un documento. Y aquí muchos se pierden. Y es una lástima, porque trabajar con archivos en Swift es tan elegante y bien pensado que después de ello no quieres volver a otros lenguajes.
\n\nEn este artículo, analizaremos la interacción con el sistema de archivos en Swift de lo simple a lo complejo. Aprenderá cómo crear, leer, escribir y eliminar archivos, trabajar con directorios, manejar errores e incluso cifrar datos. ¡Allá vamos!
\n\nFundamentos: FileManager y FileHandle
\n\nEl corazón del sistema de archivos en Swift es la clase FileManager. Es un "administrador" que lo sabe todo sobre las carpetas y archivos en el dispositivo. Permite verificar la existencia, mover, copiar y eliminar objetos. Para trabajar con el contenido de los archivos (lectura y escritura) se utiliza FileHandle o métodos de más alto nivel como Data, String y Codable.
¿Dónde almacenar archivos? Rutas y directorios
\n\nAntes de escribir código, debe comprender dónde tenemos permiso para guardar datos. En iOS y macOS existen reglas estrictas: la aplicación solo puede escribir en su propia zona de pruebas (sandbox). Los directorios más populares son:
\n\n- \n
- Documents — para datos del usuario que deben conservarse durante las copias de seguridad. \n
- Library/Caches — para archivos temporales que el sistema puede eliminar. \n
- tmp — para archivos de un solo uso, se elimina al reiniciar. \n
Obtener la ruta a la carpeta deseada es muy sencillo:
\n\nimport Foundation\n\nlet fileManager = FileManager.default\nlet documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!\nprint("Documents: \\(documentsURL.path)")\n\nlet cachesURL = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!\nprint("Caches: \\(cachesURL.path)")\n\nCreación y eliminación de archivos en Swift
\n\nEmpecemos con lo más básico: crearemos un archivo vacío en el directorio Documents:
\n\nlet fileURL = documentsURL.appendingPathComponent("myFile.txt")\n\n// Creamos el archivo si no existe\nif !fileManager.fileExists(atPath: fileURL.path) {\n fileManager.createFile(atPath: fileURL.path, contents: nil, attributes: nil)\n print("¡Archivo creado!")\n}\n\nTenga en cuenta: createFile(atPath:contents:attributes:) devuelve un Bool que indica si se pudo crear el archivo. Siempre verifique el resultado; esto le evitará errores inesperados.
La eliminación de un archivo se hace con una sola línea:
\n\ndo {\n try fileManager.removeItem(at: fileURL)\n print("Archivo eliminado")\n} catch {\n print("Error al eliminar: \\(error.localizedDescription)")\n}\n\nAquí usamos try y el bloque do-catch, el enfoque estándar para el manejo de errores en Swift. Nunca llame a removeItem sin verificar, de lo contrario la aplicación fallará.
Lectura y escritura de archivos de texto
\n\nEl escenario más común es trabajar con datos de texto. Swift ofrece métodos convenientes para leer archivos en Swift y escribir a través de cadenas:
\n\n// Escritura de texto\nlet text = "¡Hola, mundo! Hello, Swift!"\ndo {\n try text.write(to: fileURL, atomically: true, encoding: .utf8)\n print("Texto escrito")\n} catch {\n print("Error de escritura: \\(error)")\n}\n\n// Lectura de texto\ndo {\n let savedText = try String(contentsOf: fileURL, encoding: .utf8)\n print("Leído: \\(savedText)")\n} catch {\n print("Error de lectura: \\(error)")\n}\n\nLa bandera atomically: true garantiza que la escritura sea atómica: primero los datos se escriben