【问题标题】:swift - Save JSON data to local fileswift - 将 JSON 数据保存到本地文件
【发布时间】:2021-03-19 19:36:07
【问题描述】:

我从 Reddit API 获得帖子。我想对收到的 JSON 进行编码并将其写入本地文件。但是在向其写入数据后,文件为空。请建议我如何将编码的 JSON 数据写入文件或漂亮的 JSON 数据。

class Utils {
        
        func saveToJSON() {
            
            UseCase().createPosts(sub: "ios", limit: 5, completion: { posts in
                print(posts)
                
                let filePath = self.getDocumentsDirectoryUrl().appendingPathComponent("landmarkData.json")
                print(filePath)
                
                do {
                    let jsonData = try JSONEncoder().encode(posts)
                    print(jsonData)
                    try jsonData.write(to: filePath)
                    // here landmarkData.json file is empty
                } catch {
                    print("Error writing to JSON file: \(error)")
                }
            })
        }
        
        func getDocumentsDirectoryUrl() -> URL {
            let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
            let documentsDirectory = paths[0]
            return documentsDirectory
        }
    }


struct RedditPost: Hashable, Codable, Identifiable {
            var username: String
            var createdHoursAgo: String
            var domain: String
            var title: String
            var text: String
            var imageURL: String
            var downs: Int
            var ups: Int
            var rating: Int { ups - downs }
            var comments: Int
            var saved: Bool = false
            var id: String
     }


class UseCase {
        func createPosts(sub: String, limit: Int, completion: (@escaping (_ data: [RedditPost]) -> Void)) {
            Repository().fillPostsArray(sub: sub, limit: limit) { (redditPosts: [RedditPost]) in
                DispatchQueue.main.async {
                    completion(redditPosts)
                }
            }
        }
}

【问题讨论】:

  • catch 有什么错误吗?
  • 打印3237字节怎么可能是空的?
  • 是的,我现在看到了。您看到打印路径中的文件了吗?你能在 Finder 中按 CMD+Shift+G 并粘贴路径以查看 JSON 文件吗?
  • @Satheesh 文件与里面的数据可以在 /Users/veronikababii/Library/Developer/CoreSimulator/Devices/FB97AEE2-335C-4FFB-A54E-13B17AB4C0A6/data/Containers/Data/Application/D449177A 找到-093C-40BA-B2A0-DCAAE8F7616C/Documents/landmarkData.json(无 file:// )
  • @VeronikaBabii 不需要。只需在需要时重建fileURL。您不能保存 fileURL,因为每次启动应用程序时它都会改变(它是沙盒的)。关于"file://" 方案,这可能是因为您获得了URL absoluteString 而不是它的path。如果你的字符串有 "file://" 前缀,你应该使用 URL(string:) 初始化器,否则使用 URL(fileURLWithPath:) 初始化器。

标签: ios json swift api reddit


【解决方案1】:
//Define globally..
let fileName = "landmarkData.json"


func saveToJSON() {
        
        UseCase().createPosts(sub: "ios", limit: 5, completion: { posts in
            print(posts)
            
            let filePath = self.getDocumentsDirectoryUrl().appendingPathComponent(fileName)
            print(filePath)
            
            do {
                let jsonData = try JSONEncoder().encode(posts)
                print(jsonData)
                try jsonData.write(to: filePath)
                // here landmarkData.json file is empty
            } catch {
                print("Error writing to JSON file: \(error)")
            }
        })
    }

然后在读取文件时使用相同的常量...

func readFromJson() {

    let filePath = self.getDocumentsDirectoryUrl().appendingPathComponent(fileName)
    print(filePath)

    do {
        let jsonData = try JSONDecoder().decode(posts)
        print(jsonData)
     } catch {
         print("Error reading from JSON file: \(error)")
     }
}

【讨论】:

  • 你是在建议全局变量吗?解码器不会产生数据。顺便说一句,您的解码语法错误
  • 是一个全局常量来存储文件名,我知道语法错误,只是想给出一个想法。
【解决方案2】:

我建议使用 Codable 对象,这意味着您可以更高效、更轻松地编写/保存 json 数据文件并加载回 Codable 对象。

这是一个小型库,可以处理大多数带有 json 文件和数据的用例,它称为 CodableFiles。 https://github.com/egzonpllana/CodableFiles

【讨论】:

    猜你喜欢
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 2012-10-17
    • 2016-01-07
    • 2017-10-17
    • 2012-06-04
    相关资源
    最近更新 更多