已经过了一个星期了,我仍然不能弄清楚我的代码中缺少了什么。我只是想将JSON文件保存在我的本地cacheDirectory中,并将其加载回离线用户。我的代码能够从本地目录中保存和读回,但是如果我更新了GitHub存储库中的JSON数据,它就不起作用了。只有原始的JSON数据被加载,更新的JSON文件只有在我更改了一些代码并重新启动模拟器时才被加载。看起来没有覆盖代码来覆盖现有的JSON文件。
简单地说,我想将最新的JSON数据保存在本地目录中,并在每次对GitHub存储库进行更改时加载回来。例如,我用两个稍微不同的JSON链接进行了测试,通过注解掉这两个链接来查看更新的JSON。请帮助我解决我的代码中无法解决的问题。提前感谢。我的代码如下:
class FetchingJSONFile5 {
@Published var allSongs: [TuunoLabu] = []
@Published var isNewFile: Bool = true
let folderOne = "TuunoLabu_Folder1"
init() {
createFolderOne()
downloadJSON()
if let lyrics = fetchTuunoLabu(from: "TuunoLabu") {
allSongs = lyrics
}
}
private func createFolderOne() {
guard let directoryOne = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first?.appendingPathComponent(folderOne).relativePath else { return }
if !FileManager.default.fileExists(atPath: directoryOne) {
do {
try FileManager.default.createDirectory(atPath: directoryOne, withIntermediateDirectories: true)
print("Successfully created Folder One")
//print(directoryOne)
} catch let error {
print("Error while creating Folder One", error)
}
}
}
private func downloadJSON() {
guard let urlRequest = URL(string:
// This JSON has id 1 to 748
"https://raw.githubusercontent.com/siantung/TuunoLabu/fac87c9d6b63f5e52cadb8873fb0d77cd0fc91e1/JSON/TuunoLabu.json"
// This JSON has id 1 to 800
//"https://raw.githubusercontent.com/siantung/Hymn-iOS/main/HymnSong(02-25-2023).json"
)
else {
print("ERROR: Could not find the URL")
return
}
guard let directory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
.first?.appendingPathComponent(folderOne)
.appendingPathComponent("TuunoLabu.json") else { return }
//print(directory)
let dataTask = URLSession.shared.dataTask(with: urlRequest) { [weak self] data, _, error in
guard let data = data, error == nil else { return }
do {
try data.write(to: directory, options: .atomic)
print("Successfully saved downloaded JSON new file.")
self?.isNewFile = true
} catch let error {
print("Error decoding: ",error)
self?.isNewFile = false
}
}
dataTask.resume()
}
private func fetchTuunoLabu(from name: String) -> [TuunoLabu]? {
guard let directoryOne = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
.first?.appendingPathComponent(folderOne)
.appendingPathComponent("TuunoLabu.json") else {
print("Error to retrieve directory while fetching file")
return nil
}
if FileManager.default.fileExists(atPath: directoryOne.relativePath) {
do {
let data = try Data(contentsOf: directoryOne)
return try JSONDecoder().decode([TuunoLabu].self, from: data)
} catch {
print("Error JSON decoding: \(error)")
}
}
return nil
}
}
1条答案
按热度按时间qvtsj1bj1#
这是一个典型的计时问题。数据是异步下载的,
fetchTuunoLabu
的结果在URLSession的完成处理程序被调用之前被检索到。在代码中,将表达式
if let lyrics = ...
放入完成处理程序中的try data.write
之后,或者直接使用该数据但是我建议利用
async/await
和Swift中的错误处理。首先,用下面的方法替换
createFolderOne
。它返回缓存目录中给定文件名的文件的URL,如果不存在,则动态创建目录。可能的错误是thrown
给调用者downloadJSON
方法可以简化为以下几行async
的好处是,尽管数据是异步加载的,但该方法的行为类似于同步方法,而await
是结果第三种方法也包含几行
其他同学都是