首页 > 解决方案 > 如何在 Swift 中检查 CoreData 的大小

问题描述

我将数据存储在 CoreData 中。我想知道整个 CoreData 的大小(以 MB 为单位)。基本上,要求是在达到 10 MB 时清除整个 CoreData。我没有找到任何有效的答案。我尝试使用下面的代码,但无法获得大小。

public func getSqliteStoreSize(forPersistentContainerUrl storeUrl: URL) -> String {
    do {
        let size = try Data(contentsOf: storeUrl)
        if size.count < 1 {
            print("Size could not be determined.")
            return ""
        }
        let bcf = ByteCountFormatter()
        bcf.allowedUnits = [.useMB] // optional: restricts the units to MB only
        bcf.countStyle = .file
        let string = bcf.string(fromByteCount: Int64(size.count))
        print(string)
        return string
    } catch {
        print("Failed to get size of store: \(error)")
        return ""
    }
}

guard let storeUrl = self.managedObjectContext!.persistentStoreCoordinator!.persistentStores.first?.url else {
    print("There is no store url")
    return
}
print("The size of the store is: \(self.getSqliteStoreSize(forPersistentContainerUrl: storeUrl))")

参考:如何获取 coredata 存储中存在的数据大小?

下面是我的核心数据路径。

file:///var/mobile/Containers/Data/Application/XXXXXX-XXX-XXXX-XXXX-XXXXXXXXXX/Library/Application Support/APPNAME.sqlite

标签: iosswiftcore-data

解决方案


部分答案是您需要计算 SQLite 日志文件。那是大多数数据实际存在的地方。如果只计算中央 SQLite 文件,得到一个非常低的数字是正常的。您可以通过添加.-wal-shm到文件文件名来找到它们。

您的代码的另一个问题是,Data(contentsOf:)除非您的商店文件非常小,否则在这里使用是一个非常糟糕的主意。您正在将整个文件读入内存以了解它有多大,这不是必需的。您链接到的问题有一个答案,显示了如何使用FileManager(实际上NSFileManager在那里,因为它是 ObjC 但函数名称和参数是相同的)在不读取文件的情况下获取大小。

最后一个可能会或可能不会影响您的问题是,如果您为模型中的任何属性打开了外部二进制支持,则创建的外部文件不在任何 SQLite 文件中(这就是重点)。您还需要计算这些。该位置没有记录,但它是一个名为.APPNAME_SUPPORT/_EXTERNAL_DATA/. 如果您需要这个,请尝试使用模拟器构建,以便您可以轻松浏览应用程序的文件并确保它正确。您会计算该文件夹中的每个文件。


推荐阅读