Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save egzonpllana/372d8e8733d90a013532d7377284d70c to your computer and use it in GitHub Desktop.
Save egzonpllana/372d8e8733d90a013532d7377284d70c to your computer and use it in GitHub Desktop.
Save Encodable object to document directory and load as Decodable object.
//
// Created by Egzon Pllana on 28.12.21.
//
import Foundation
class FilesIOManager {
// MARK: - Properties
private static let jsonString = "json"
private static let fileManager = FileManager.default
private static let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
// MARK: - Methods
/// Save Encodable Object
/// - Parameters:
/// - object: Encodable object.
/// - filename: Object name.
/// - Returns: Path url where object is saved.
static func save(_ object: Encodable, filename: String) throws -> URL? {
// Convert encodable object to dictionary string
let userJsonToDictionary = try object.toDictionary()
// Get file path url
guard let url = urls.first else { return nil }
var fileURL = url.appendingPathComponent(filename)
fileURL = fileURL.appendingPathExtension(jsonString)
// Write data to file url
let data = try JSONSerialization.data(withJSONObject: userJsonToDictionary, options: [.prettyPrinted])
try data.write(to: fileURL, options: [.atomicWrite])
return fileURL
}
/// Load Decodable Object
/// - Returns: Returns optional Decodable object
static func load<T: Decodable>(_ type: T.Type, withFilename filename: String) throws -> T? {
// Get file path url
guard let url = urls.first else { return nil }
var fileURL = url.appendingPathComponent(filename)
fileURL = fileURL.appendingPathExtension(jsonString)
// Get data from path url
let contentData = try Data(contentsOf: fileURL)
// Get json object from data
let jsonObject = try JSONSerialization.jsonObject(with: contentData, options: [.mutableContainers, .mutableLeaves])
// Convert json object to data type
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
// Decode data to Decodable object
let decoder = JSONDecoder()
let decodedObject = try! decoder.decode(T.self, from: jsonData)
return decodedObject
}
}
// MARK: - Encodable to Dictionary
extension Encodable {
/// Convert Encodable object to dictionary
/// - Parameter encoder: JSONEncoder
/// - Returns: dictionary [String: Any]
func toDictionary(_ encoder: JSONEncoder = JSONEncoder()) throws -> [String: Any] {
let data = try encoder.encode(self)
let object = try JSONSerialization.jsonObject(with: data)
guard let json = object as? [String: Any] else {
let context = DecodingError.Context(codingPath: [], debugDescription: "Deserialized object is not a dictionary!")
throw DecodingError.typeMismatch(type(of: object), context)
}
return json
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment