How to detect total available/free disk space on the iPhone/iPad device?
UPDATE: Since a lot of time has passed after this answer and new methods/APIs have been added, please check the updated answers below for Swift etc; Since I've not used them myself, I can't vouch for them.
Original answer:I found the following solution working for me:
-(uint64_t)getFreeDiskspace { uint64_t totalSpace = 0; uint64_t totalFreeSpace = 0; NSError *error = nil; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error]; if (dictionary) { NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize]; NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize]; totalSpace = [fileSystemSizeInBytes unsignedLongLongValue]; totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue]; NSLog(@"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll)); } else { NSLog(@"Error Obtaining System Memory Info: Domain = %@, Code = %ld", [error domain], (long)[error code]); } return totalFreeSpace;}
It returns me exactly the size that iTunes displays when device is connected to machine.
Revised source using unsigned long long:
- (uint64_t)freeDiskspace{ uint64_t totalSpace = 0; uint64_t totalFreeSpace = 0; __autoreleasing NSError *error = nil; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error]; if (dictionary) { NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize]; NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize]; totalSpace = [fileSystemSizeInBytes unsignedLongLongValue]; totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue]; NSLog(@"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll)); } else { NSLog(@"Error Obtaining System Memory Info: Domain = %@, Code = %d", [error domain], [error code]); } return totalFreeSpace;}
EDIT: it seems someone edited this code to use 'uint64_t' instead of 'unsigned long long'. While in the foreseeable future this should be just fine, they are not the same. 'uint64_t' is 64 bits and will always be that. In 10 years 'unsigned long long' might be 128. its a small point but why I used unsignedLongLong.
I have written a class to get available/used memory using Swift. Demo at: https://github.com/thanhcuong1990/swift-disk-status
Swift 4 updated.
import UIKitclass DiskStatus { //MARK: Formatter MB only class func MBFormatter(_ bytes: Int64) -> String { let formatter = ByteCountFormatter() formatter.allowedUnits = ByteCountFormatter.Units.useMB formatter.countStyle = ByteCountFormatter.CountStyle.decimal formatter.includesUnit = false return formatter.string(fromByteCount: bytes) as String } //MARK: Get String Value class var totalDiskSpace:String { get { return ByteCountFormatter.string(fromByteCount: totalDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.file) } } class var freeDiskSpace:String { get { return ByteCountFormatter.string(fromByteCount: freeDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.file) } } class var usedDiskSpace:String { get { return ByteCountFormatter.string(fromByteCount: usedDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.file) } } //MARK: Get raw value class var totalDiskSpaceInBytes:Int64 { get { do { let systemAttributes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory() as String) let space = (systemAttributes[FileAttributeKey.systemSize] as? NSNumber)?.int64Value return space! } catch { return 0 } } } class var freeDiskSpaceInBytes:Int64 { get { do { let systemAttributes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory() as String) let freeSpace = (systemAttributes[FileAttributeKey.systemFreeSize] as? NSNumber)?.int64Value return freeSpace! } catch { return 0 } } } class var usedDiskSpaceInBytes:Int64 { get { let usedSpace = totalDiskSpaceInBytes - freeDiskSpaceInBytes return usedSpace } }}
Demo