我正在使用一个很大的json。将其作为api响应需要花费很多时间。我想获取一次并将其保存在本地,以便可以在我的应用程序中使用它。我想将其保存在文件中,但问题是我应该将该文件存储在哪里。
答案 0 :(得分:2)
这是我在这种情况下的工作。
首先,我在邮递员上运行API,然后复制JSON
并将其粘贴到here。然后指定一个对象名称,并将代码模板选择为swifty JSON
,因为您可以使用SwiftyJSON,这使得处理JSON
对象非常容易。现在,您可以下载所有类文件并将其添加到您的项目中。那么您需要创建一个新文件,该文件将处理将JSON
文件存储和提取到文档目录的过程,看起来像这样:
import Foundation
/// `Cacher` is a super simple cross platform solution to persist `Cachable` types into the filesystem.
final public class Cacher {
/// The path in the filesystem that will hold all the persisted items
let destination: URL
private let queue = OperationQueue()
/// A type for the type of persistance options.
///
/// - temporary: stores `Cachable` types into the temporary folder of the OS.
/// - atFolder: stores `Cachable` types into a specific folder in the OS.
public enum CacheDestination {
/// Stores items in `NSTemporaryDirectory`
case temporary
/// Stores items at a specific location
case atFolder(String)
}
// MARK: Initialization
/// Initializes a newly created `Cacher` instance using the specified storage destination.
/// *Note* If using `.atFolder(String)` make sure the destination is valid.
///
/// - Parameter destination: path to the location where `Cacher` will persist its `Cachable` items.
public init(destination: CacheDestination) {
switch destination {
case .temporary:
self.destination = URL(fileURLWithPath: NSTemporaryDirectory())
case .atFolder(let folder):
let documentFolder = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
self.destination = URL(fileURLWithPath: documentFolder).appendingPathComponent(folder, isDirectory: true)
}
try? FileManager.default.createDirectory(at: self.destination, withIntermediateDirectories: true, attributes: nil)
}
// MARK
/// Store a `Cachable` object in the directory selected by this `Cacher` instance.
///
/// - Parameters:
/// - item: `Cachable` object to persist in the filesystem
/// - completion: callback invoked when the persistance finishes, it will either contain the `URL` of the persisted item, or the `Error` raised while trying to.
public func persist(item: Cachable, completion: @escaping (_ url: URL?, _ error: Error?) -> Void) {
var url: URL?
var error: Error?
// Create an operation to process the request.
let operation = BlockOperation {
do {
url = try self.persist(data: item.transform(), at: self.destination.appendingPathComponent(item.fileName, isDirectory: false))
} catch let persistError {
error = persistError
}
}
// Set the operation's completion block to call the request's completion handler.
operation.completionBlock = {
completion(url, error)
}
// Add the operation to the queue to start the work.
queue.addOperation(operation)
}
/// Load cached data from the directory
///
/// - Parameter fileName: of the cached data stored in the file system
/// - Returns: the decoded cached data (if any)
public func load<T: Cachable & Codable>(fileName: String) -> T? {
guard
let data = try? Data(contentsOf: destination.appendingPathComponent(fileName, isDirectory: false)),
let decoded = try? JSONDecoder().decode(T.self, from: data)
else { return nil }
return decoded
}
// MARK: Private
private func persist(data: Data, at url: URL) throws -> URL {
do {
try data.write(to: url, options: [.atomicWrite])
return url
} catch let error {
throw error
}
}
}
/// A type that can persist itself into the filesystem.
public protocol Cachable {
/// The item's name in the filesystem.
var fileName: String { get }
/// Returns a `Data` encoded representation of the item.
///
/// - Returns: `Data` representation of the item.
func transform() -> Data
}
extension Cachable where Self: Codable {
public func transform() -> Data {
do {
let encoded = try JSONEncoder().encode(self)
return encoded
} catch let error {
fatalError("Unable to encode object: \(error)")
}
}
}
还要再创建一个结构:
struct CachableObject: Cachable, Codable {
let fileName: String
let value: JSON
}
现在将需要此struct
来存储和获取数据。
从服务器获取数据后,可以使用以下命令将其存储在文档目录中:
let cacher: Cacher = Cacher(destination: .temporary)
let cachableText = CachableObject(fileName: "yourfilename", value: jsonresponse)
cacher.persist(item: cachableText) { url, error in
if let error = error {
print("Text failed to persist: \(error)")
} else {
print("Text persisted in \(String(describing: url))")
}
}
现在,它存储在您的文档目录中。
如果您想再次获取完整的JSON,则可以使用:
if let data: CachableObject = cacher.load(fileName: "yourfilename") {
let jsonData = data.value
self.yourCustomObject = YourCustomObject.init(fromJson: jsonData)
}
您可以将其与具有不同文件名的任意数量的API一起使用,并可以存储完整的JSON
。
答案 1 :(得分:0)
您可以将其存储为应用程序目录中的文本文件
let file = "jsonResponse.txt"
let text = "<Json String>"
func writeFile(text : String){
if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
let fileURL = dir.appendingPathComponent(file)
//writing
do {
try text.write(to: fileURL, atomically: false, encoding: .utf8)
}
catch {}
}
}
func readFile() -> Sting{
if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
let fileURL = dir.appendingPathComponent(file)
//reading
do {
let text2 = try String(contentsOf: fileURL, encoding: .utf8)
return text2
}
catch {}
}
return ""
}
相应地调用writeFile和ReadFile函数