iOS项目运行时如何向项目内本地JSON文件写入内容?
问题根源
- 你通过
Bundle.main.url(forResource:withExtension:)获取的是应用安装后,沙盒内.app安装包目录下的资源文件,不是你Xcode工程源码目录里存放的Container.json原文件。就算写入操作执行成功,修改的也只是运行时生成的临时副本,源码目录下的原文件不会有任何改动,所以你直接打开工程里的文件查看会发现内容为空。 .app安装包目录本身是只读权限:真机环境下该目录经过系统签名校验,应用完全没有写入权限,强行写入会直接抛出权限错误;模拟器环境权限管控相对宽松,可能不会抛错,但写入的内容会在下次重新编译安装应用时被新的安装包覆盖,既不会持久保留,也不会同步回工程源码目录。
正确写入方案
应用运行时产生的持久化数据,不能存放在Bundle目录下,需要将初始资源文件复制到沙盒的可写目录后,再对可写目录下的副本执行读写操作,常用的可写目录为Documents目录、Application Support目录,实现步骤如下:
- 应用首次启动时,将Bundle中存放的初始
Container.json复制到沙盒可写路径 - 后续所有读写操作,都针对沙盒可写路径下的这个文件副本执行
参考实现代码:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 获取沙盒Documents目录路径 guard let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } let writableJsonURL = documentsDir.appendingPathComponent("Container.json") // 首次启动时,如果可写路径下不存在目标文件,从Bundle复制初始空JSON文件 if !FileManager.default.fileExists(atPath: writableJsonURL.path) { guard let bundleJsonURL = Bundle.main.url(forResource: "Container", withExtension: "json") else { print("Bundle中未找到Container.json资源") return } do { try FileManager.default.copyItem(at: bundleJsonURL, to: writableJsonURL) } catch { print("初始文件复制失败:\(error)") return } } // 对可写路径下的文件执行写入操作 do { try "test".write(to: writableJsonURL, atomically: true, encoding: .utf8) print("写入成功,文件沙盒路径:\(writableJsonURL.path)") } catch { print("内容写入失败:\(error)") } } }
验证提示:要确认写入结果,不要查看Xcode工程导航栏里的源码文件,可在模拟器运行时复制控制台打印的沙盒路径,在Finder中按
Cmd+Shift+G粘贴路径回车,即可打开对应目录查看写入后的文件。
内容的提问来源于stack exchange,提问作者ScottyBlades
相关产品推荐
相关产品推荐

