views:

308

answers:

4

I am working on a database application using the Core Data framework. In this application I need to display how much data the application currently is using on the iPhone. Is there any way to do this?

A: 

Do you mean how much memory? Each application gets about 23MBytes as of now. That number may change and you are not supposed to count on it.

mahboudz
thank , but i mean how much data we can store in sqlite using core data for one application and i need to display currently used data which is stored in underline sqlite and that is to in percentage..!!
Nic
Are you using SQLite or Core Data? If you are using SQLite, then you can get file attributes to see how big it is. I don't think you can get that sort of information for Core Data, but I may be wrong.
mahboudz
Of course you can get that information from Core Data, it doesn't store its data in some magical sizeless fashion! Just use NSFileManager to ask how big the persistent store is.
Mike Abdullah
Each application gets about ~23MBytes **RAM**, but the file storage used is only limited by the overall available space.
Matt B.
Yes Matt. As you can see in my answer, I thought he meant RAM.
mahboudz
+5  A: 

Your persistent store in Core Data is just a file on the file system. You access and possibly create this file when you create your Core Data stack. The following code will print the size of a persistent store and the free space of the file system, in bytes:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *persistentStorePath = [documentsDirectory stringByAppendingPathComponent:@"persistentstore.sqlite"];

NSError *error = nil;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:persistentStorePath error:&error];
NSLog(@"Persistent store size: %@ bytes", [fileAttributes objectForKey:NSFileSize]);

NSDictionary *fileSystemAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:persistentStorePath error:&error];
NSLog(@"Free space on file system: %@ bytes", [fileSystemAttributes objectForKey:NSFileSystemFreeSize]);

This assumes that your persistent store is named persistentstore.sqlite and is stored in the documents directory for your application. If you are uncertain as to the name of your persistent store, look for where you alloc and init your NSPersistentStoreCoordinator. The name of the store should be specified somewhere in the code around there.

Note that the values you get back from the file and file system attributes dictionaries are NSNumbers, so you'll need to convert them to scalar types if you want to work with the file sizes in that manner. One thing to be careful of is that these values are in bytes, so for multi-gigabyte filesystems you might run into number size limitations with 32-bit integer data types.

Brad Larson
Thanks Brad. Its helpful ...
Nic
@Brad: Do you know if the system allows an app to use the full (or close) usage of the free space left on the file system? Or is the free space returned the maximum that the system is allocating to the app?
mahboudz
On a device, it appears to return the total space free on the internal flash memory (the bytes returned value matches the free space reported by iTunes). I assume that the application has that much space to work with.
Brad Larson
+1  A: 

I found this answer on the Apple Dev Forums to be useful for finding disk space available on the apps' home directory partition (note there are currently two partitions on each device).

Use NSPersistentStoreCoordinator to get your store collection.

Use NSFileManager to get each stores' size in bytes (unsigned long long)

NSArray *allStores = [self.persistentStoreCoordinator persistentStores];
unsigned long long totalBytes = 0;
NSFileManager *fileManager = [NSFileManager defaultManager];
for (NSPersistentStore *store in allStores) {
 if (![store.URL isFileURL]) continue; // only file URLs are compatible with NSFileManager
 NSString *path = [[store URL] path];
 DebugLog(@"persistent store path: %@",path);
 // NSDictionary has a category to assist with NSFileManager attributes
 totalBytes += [[fileManager attributesOfItemAtPath:path error:NULL] fileSize];
}

Note that the code above is in a method of my app delegate, and it has a property persistentStoreCoordinator.

ohhorob
Thanks a lot :-)
Nic
A: 

Not sure where I saw it, but I believe that removing entries from the database will not necessarily shrink the database file. SQLite reclaims the storage internally and re-uses it. (This is typical of RDBMSs.) I believe there's a command-line utility somewhere that will compact it, but that's not going to help you if your app wants shrink the file to the dataset (to reclaim space for the OS, for example).

So while the file size method will give you a sense of the high-water-mark size of the database, it's not necessarily going to tell you the amount of storage used by your dataset.

David Goodine