Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get size of iPad/iPhone app programmatically in Swift

I'm trying to get the size of my an app programmatically. The app downloads large amounts of audio files, and I'm trying to check that when I delete files, the app size diminishes as expected. So far the only way I know how to do this is by looking in the settings of the iPad, but the numbers there don't seem to be correct always.

func getAppSize(){
    let paths : NSArray = NSSearchPathForDirectoriesInDomains(.LibraryDirectory, .UserDomainMask, true)
    var errorP = NSErrorPointer()
    let pathDictionary: NSDictionary = NSFileManager.defaultManager().attributesOfFileSystemForPath(paths.firstObject as String, error: errorP)!
    if(pathDictionary.count != 0){
        var fileSystemSizeInBytes: Double = pathDictionary.objectForKey("NSFileSystemSize") as Double
        var fileSystemSizeInMegaBytes : Double = fileSystemSizeInBytes/1000000
        println("Total Space: \(fileSystemSizeInMegaBytes) MB")
    }else{

    }
}

Currently I'm just using the File-System Attirbute Key for the File System Size, which I expected to be the size of my current app, but since it is returning 249 GB, its obviouslly reading my entire MacBook File System size, rather than the simulator's document path.

I looked up the other Attribute Key options and found:

let NSFileSystemSize: NSString!
let NSFileSystemFreeSize: NSString!
let NSFileSystemNodes: NSString!
let NSFileSystemFreeNodes: NSString!
let NSFileSystemNumber: NSString!

However, I haven't found a key that specifies the size of the actual space taken by my app. I'm thinking maybe there is a way to get all the nodes, and then add up their sizes, but I'm not quite sure how to do that.

EDIT: So the bundle does appear to give me my apps size, but without any of the mp3 files I save into the document path. I'm guessing I might be saving them to the wrong spot or something, here is a simplified version of how I save them to the app.

//Make HTTP Request Ect... before here...
if(data.length > 1000){
    let documentPath = NSSearchPathForDirectoriesInDomains(.LibraryDirectory, .UserDomainMask, true)
    let uuid = NSUUID().UUIDString
    let localUrl = uuid + ".mp3"
    let destPath = (documentPath[0] as String) + "/" + localUrl
    data.writeToFile(destPath, atomically: true)
    var error: NSErrorPointer = nil
    data.writeToFile(destPath, options: NSDataWritingOptions.DataWritingAtomic, error: error)
    if(error != nil){
        println("data write error: \(error.memory?.localizedDescription)")
    }
}
like image 730
Unome Avatar asked Dec 20 '22 08:12

Unome


1 Answers

According to the docs, "the file systems in OS X and iOS handle the persistent storage of data files, apps, and the files associated with the operating system itself." Also according to the docs, "an NSBundle object represents a location in the file system that groups code and resources that can be used in a program," so your app's main bundle is the location where its files live. And according to this link, each iOS app consists of a bundle, documents directory, library, and tmp.

To get the total size of your app, enumerate through the bundle, documents, library, and tmp subpaths, ex:

func appSize() {

    // Go through the app's bundle
    let bundlePath = NSBundle.mainBundle().bundlePath
    let bundleArray:NSArray = NSFileManager.defaultManager().subpathsOfDirectoryAtPath(bundlePath, error: nil)!
    let bundleEnumerator = bundleArray.objectEnumerator()
    var fileSize: UInt64 = 0

    while let fileName:String = bundleEnumerator.nextObject() as? String {
        let fileDictionary:NSDictionary = NSFileManager.defaultManager().attributesOfItemAtPath(bundlePath.stringByAppendingPathComponent(fileName), error: nil)!
        fileSize += fileDictionary.fileSize();
    }

    // Go through the app's document directory
    let documentDirectory:NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, .UserDomainMask, true)
    let documentDirectoryPath:NSString = documentDirectory[0] as NSString
    let documentDirectoryArray:NSArray = NSFileManager.defaultManager().subpathsOfDirectoryAtPath(documentDirectoryPath, error: nil)!
    let documentDirectoryEnumerator = documentDirectoryArray.objectEnumerator()

    while let file:String = documentDirectoryEnumerator.nextObject() as? String {
        let attributes:NSDictionary = NSFileManager.defaultManager().attributesOfItemAtPath(documentDirectoryPath.stringByAppendingPathComponent(file), error: nil)!
        fileSize += attributes.fileSize();
    }

    // Go through the app's library directory
    let libraryDirectory:NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, true)
    let libraryDirectoryPath:NSString = libraryDirectory[0] as NSString
    let libraryDirectoryArray:NSArray = NSFileManager.defaultManager().subpathsOfDirectoryAtPath(libraryDirectoryPath, error: nil)!
    let libraryDirectoryEnumerator = libraryDirectoryArray.objectEnumerator()

    while let file:String = libraryDirectoryEnumerator.nextObject() as? String {
        let attributes:NSDictionary = NSFileManager.defaultManager().attributesOfItemAtPath(libraryDirectoryPath.stringByAppendingPathComponent(file), error: nil)!
        fileSize += attributes.fileSize();
    }

    // Go through the app's tmp directory
    let tmpDirectoryPath:NSString = NSTemporaryDirectory()
    let tmpDirectoryArray:NSArray = NSFileManager.defaultManager().subpathsOfDirectoryAtPath(tmpDirectoryPath, error: nil)!
    let tmpDirectoryEnumerator = tmpDirectoryArray.objectEnumerator()

    while let file:String = tmpDirectoryEnumerator.nextObject() as? String {
        let attributes:NSDictionary = NSFileManager.defaultManager().attributesOfItemAtPath(tmpDirectoryPath.stringByAppendingPathComponent(file), error: nil)!
        fileSize += attributes.fileSize();
    }

    var fileSystemSizeInMegaBytes : Double = Double(fileSize)/1000000
    println("Total App Space: \(fileSystemSizeInMegaBytes) MB")
}
like image 159
Lyndsey Scott Avatar answered Dec 24 '22 03:12

Lyndsey Scott