iOS: Available disk space

Hi,

I need to know how much free “disk space” there is available to my app (to be able to warn the user).

Any ideas?

Thanks,

Dan

I think I’m on my way to a solution using the iOSKit as a base but I’m stuck now:

I don’t know how to get a double from vDict.Value(vKey)

[code]Dim vKeyString as new NSString(“NSFileSystemFreeSize”)
Dim vKey as new NSObject(vKeyString)
Dim vSize as double
Dim vPtr as Ptr
if vDict.HasKey(vKey) then

vPtr= vDict.Value(vKey) //I need somehow get a double from this Ptr but no success so far.

end if
[/code]

https://developer.apple.com/documentation/foundation/nsnumber/1414104-doublevalue?language=objc

[NSNumber doubleValue]

Below should do it for you; but I wrote this directly in the forum, so it may or may not work and, I’ve not used any declares on iOS yet…

declare function doubleValue lib "AppKit" selector "doubleValue" ( NSNumberInstance as ptr ) as double Dim dValue as double = doubleValue( vDict.value( vKey ) )

Thanks Sam!

Looks like your declares intuition is really good.

I changed your suggestion to: (Changing Appkit to FoundationLib)

declare function doubleValue lib FoundationLib selector "doubleValue" ( id as ptr ) as double

And it seems to work.

I’ll post the complete function when I see that everything is fine.

I think this is code that is Ok. As of now I have not used it myself but it seems to work.

GetAvailableDiscSpace()
GetTotalDiscSpace()

[code]Public Function GetAvailableDiscSpace() as Double

const NSDocumentDirectory = 9
const NSUserDomainMask = 1

dim librarySourcesEnumerator as Ptr

declare function NSSearchPathForDirectoriesInDomains lib FoundationLib (dir as Integer, mask as Integer, yesNo as Boolean) as ptr
declare function objectEnumerator lib FoundationLib selector “objectEnumerator” (obj_id as ptr) as ptr

declare function nextObject lib FoundationLib selector “nextObject” (obj_id as ptr) as ptr

declare function defaultManager lib FoundationLib selector “defaultManager” (clsRef as ptr) as ptr
declare function enumeratorAtPath lib FoundationLib selector “enumeratorAtPath:” (obj_id as ptr, path as ptr) as ptr

declare function attributesOfFileSystemForPath lib FoundationLib selector “attributesOfFileSystemForPath:error:” (obj_id as ptr, path as ptr, error as ptr) as ptr
declare function doubleValue lib FoundationLib selector “doubleValue” ( id as ptr ) as double

dim sourcePath as Foundation.NSString

librarySourcesEnumerator = objectEnumerator(NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, True))

dim sourcePathPtr as ptr = nextObject(librarySourcesEnumerator)
dim vDefaultFileManager as Ptr = defaultManager(NSClassFromString(“NSFileManager”))
dim vSize as Double

while sourcePathPtr <> nil
sourcePath = new NSString(sourcePathPtr)

dim vDictPtr as ptr

vDictPtr=attributesOfFileSystemForPath(vDefaultFileManager,sourcePath,nil)

Dim vDict as new Foundation.NSDictionary(vDictPtr)


Dim vKeyString as new NSString("NSFileSystemFreeSize")  
Dim vKey as new NSObject(vKeyString)

 if vDict.HasKey(vKey) then
  Dim vDiskSpace as double = doubleValue( vDict.value( vKey ) ) /1024/1024
  return vDiskSpace
end if



sourcePathPtr = nextObject(librarySourcesEnumerator)

wend

Return -1
End Function[/code]

[code]Public Function GetTotalDiscSpace() as Double

const NSDocumentDirectory = 9
const NSUserDomainMask = 1

dim librarySourcesEnumerator as Ptr

declare function NSSearchPathForDirectoriesInDomains lib FoundationLib (dir as Integer, mask as Integer, yesNo as Boolean) as ptr
declare function objectEnumerator lib FoundationLib selector “objectEnumerator” (obj_id as ptr) as ptr

declare function nextObject lib FoundationLib selector “nextObject” (obj_id as ptr) as ptr

declare function defaultManager lib FoundationLib selector “defaultManager” (clsRef as ptr) as ptr
declare function enumeratorAtPath lib FoundationLib selector “enumeratorAtPath:” (obj_id as ptr, path as ptr) as ptr

declare function attributesOfFileSystemForPath lib FoundationLib selector “attributesOfFileSystemForPath:error:” (obj_id as ptr, path as ptr, error as ptr) as ptr
declare function doubleValue lib FoundationLib selector “doubleValue” ( id as ptr ) as double

dim sourcePath as Foundation.NSString

librarySourcesEnumerator = objectEnumerator(NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, True))

dim sourcePathPtr as ptr = nextObject(librarySourcesEnumerator)
dim vDefaultFileManager as Ptr = defaultManager(NSClassFromString(“NSFileManager”))
dim vSize as Double

while sourcePathPtr <> nil
sourcePath = new NSString(sourcePathPtr)

dim vDictPtr as ptr

vDictPtr=attributesOfFileSystemForPath(vDefaultFileManager,sourcePath,nil)

Dim vDict as new Foundation.NSDictionary(vDictPtr)


Dim vKeyString as new NSString("NSFileSystemSize")  
Dim vKey as new NSObject(vKeyString)

 if vDict.HasKey(vKey) then
  Dim vDiskSpace as double = doubleValue( vDict.value( vKey ) ) /1024/1024
  return vDiskSpace
end if



sourcePathPtr = nextObject(librarySourcesEnumerator)

wend

Return -1
End Function
[/code]

@Dan Berghult thank you very much for sharing the code. However, are you able to explain the return value?

According to Apple’s docs, NSFileSystemFreeSize should be a number of bytes but, on my device at least, the number returned by your function does not correlate with the value I get in Settings -> General -> Storage & iCloud Usage -> Available.

Hi Jason,

I can not explain it. I’ve noticed it too.

I’m glad you mentioned it here on the forum. I’ve forgot to do that.

For my usage it is OK if it is not exactly right number of bytes. I’m checking the space to see if my intended video recording will fit or not so there is a lot of variables anyway.

Thanks Dan. On my device the function returns 5,800 available but my device reports 6Gb available. I was wondering whether it might be returning Mb instead of bytes?

I tested now using /1000/1000 instead of /1024/1024

It returns 22.9 GB available space vs my device reporting 22.83 GB.

So I guess Apple is using 1000 as 1 kilo byte.

I’ve seen some threads on Stack Overflow talking about a 200MB difference between what they get using that logic vs what the device reports in Settings. But have not seen a real explanation or resolution. Some folks say they just add 200MB to compensate.

I don’t think it is a 1000 vs 1024 byte thing.