1

I am storing data in CoreData. I want to know what is the size of whole CoreData in MBs. Basically the requirement is to clear the whole CoreData once it reaches 10 MB. I did not find any working answers for this. I have tried using below code but unable to get the size.

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))")

Reference: How to get the size of data present in coredata store?

Below is my coredata path.

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

2
  • What happens when you try using the code that is not what you expect to happen? What error messages appear, if any? Commented Nov 4, 2020 at 17:21
  • Every time i am getting just 0.01 MB file size. Commented Nov 5, 2020 at 4:02

2 Answers 2

2

Part of the answer is that you need to count the SQLite journal files. That's where most of the data actually lives. Getting a very low number is normal if you only count the central SQLite file. You find those by adding .-wal and -shm to file file name.

Another issue with your code is that using Data(contentsOf:) is a really bad idea here unless your store files are really small. You're reading the entire file into memory to find out how big it is, and that's not needed. The question you linked to has an answer showing how to use FileManager (actually NSFileManager there since it's ObjC but the function names and arguments are the same) to get the size without reading the file.

A final problem which might or might not affect you is that if you have external binary support turned on for any attribute in your model, the external files that get created are not in any of the SQLite files (that's the point). You also need to count those. The location is undocumented, but it's a directory named something like .APPNAME_SUPPORT/_EXTERNAL_DATA/. If you need this, try using a simulator build so that you can easily browse the app's files and make sure you have it right. You'd count every file in that folder.

Sign up to request clarification or add additional context in comments.

Comments

0

By default, CoreData uses SQLite’s WAL mode (https://www.sqlite.org/wal.html) so SQLite creates 3 files for the database: the usual .sqlite file, a .sqlite-wal file, and a .sqlite-shm file. You will need to combine the sizes for all these.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.