Last active
December 29, 2021 15:58
-
-
Save egzonpllana/372d8e8733d90a013532d7377284d70c to your computer and use it in GitHub Desktop.
Save Encodable object to document directory and load as Decodable object.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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