2014-12-26 48 views
3

因此,我試圖以編程方式獲取我的應用程序的大小。該應用程序下載大量的音頻文件,並且我試圖檢查當我刪除文件時,應用程序大小按預期降低。到目前爲止,我知道如何做到這一點的唯一方法是通過查看iPad的設置,但那裏的數字似乎總是不正確。如何在Swift中以編程方式獲取iPad/iPhone應用程序的大小

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{ 

    } 
} 

目前我只是用文件系統Attirbute關鍵的文件系統的大小,我預計我目前的應用程序的大小,但因爲它返回249 GB,其obviouslly閱讀我的整個MacBook文件系統的大小,而不是模擬器的文件路徑。

我擡頭其他屬性鍵的選項,結果發現:

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

不過,我還沒有發現,指定由我的應用程序所採取的實際空間大小的關鍵。我想也許有一種方法可以獲得所有的節點,然後將它們的大小相加,但我不太確定如何做到這一點。

在此先感謝

編輯: 所以包確實出現給我的應用程序的大小,但沒有任何mp3文件的我保存到文件的路徑。我猜測我可能會將它們保存到錯誤的地方或什麼,下面是我將它們保存到應用程序的簡化版本。

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

回答

3

According to the docs,「在OS X和iOS的文件系統處理數據文件,應用程序,並與操作系統本身相關聯的文件的持久性存儲。」還有according to the docs,「一個NSBundle對象表示文件系統中的一個位置,該位置將程序中可以使用的代碼和資源分組,」因此,您的應用程序的主包是它的文件所在的位置。根據this link,每個iOS應用程序都由一個包,文檔目錄,庫和tmp組成。

爲了讓您的應用程序的總規模,通過捆綁,文檔,圖書館,和TMP枚舉子路徑,例如:

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") 
} 
+0

所以這些數字使一噸多的意義,現在使用的包,它使應用程序大小12.95 MB,但我知道,實際的大小比根據這個(100MB- 500MB)更大多少的該文件已被下載。我在想我可能會把我的文件保存在錯誤的地方。我將編輯我的帖子,以顯示我將它們保存在代碼 – Unome

+1

@Unome哦,如果文件正在下載,那麼它們將不會在應用程序包中找到。我們還必須搜索這些文件夾以獲取完整大小。 –

+0

我添加了更多的代碼來顯示我保存它們的位置,有趣的是我通過.LibraryDirectory將它們保存到文檔路徑,這是我在開始時搜索的內容,所以也許我會將它們保存到錯誤的位置。 – Unome

2

你計算庫文件夾的大小。不是你的應用目錄文件夾大小

根據NSSearchPathDirectory

NSLibraryDirectory

各種用戶可見的文檔,支持,和配置文件 (/庫)。

適用於iOS 2.0及更高版本。

你應該改變你的文件的保存和計算代碼:

保存:

//Make HTTP Request Ect... before here... 
if(data.length > 1000) 
{ 
    let documentPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .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)") 
    } 
} 

計算:

func getAppSize() 
{ 
    let paths : NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) 
    let path : NSString = paths.firstObject? as NSString 
    let files : NSArray = NSFileManager.defaultManager().subpathsOfDirectoryAtPath(path, error: nil)! 
    let dirEnumerator  = files.objectEnumerator() 
    var totalSize: UInt64 = 0 
    let fileManager  = NSFileManager.defaultManager(); 
    while let file:String = dirEnumerator.nextObject() as? String 
    { 
     let attributes:NSDictionary = fileManager.attributesOfItemAtPath(path.stringByAppendingPathComponent(file), error: nil)! 
     totalSize += attributes.fileSize(); 
    } 

    var fileSystemSizeInMegaBytes : Double = Double(totalSize)/1000000 
    println("Total Space: \(fileSystemSizeInMegaBytes) MB") 
} 
+0

那麼我應該計算哪個文件夾? – Unome

+0

@Unome:請檢查我的更新答案 –

0

你是什麼應用程序的大小是什麼意思?
如果您擔心從網上下載的數據量很大,根據最佳實踐,您應該下載到Cache目錄中,並在系統需要時準備好將其逐出。或者您可以將它們保存在Documents目錄中,並注意將「無備份」屬性添加到您下載的文件中,否則您的應用可能會被拒絕。

2

更新和重構@ lyndsey-scott的回答爲Swift 3。我修改了代碼以便以兆字節爲單位返回Float64的大小,而不是將其打印到控制檯,因爲這適合我的目的。

private class func appSizeInMegaBytes() -> Float64 { // approximate value 

    // create list of directories 
    var paths = [Bundle.main.bundlePath] // main bundle 
    let docDirDomain = FileManager.SearchPathDirectory.documentDirectory 
    let docDirs = NSSearchPathForDirectoriesInDomains(docDirDomain, .userDomainMask, true) 
    if let docDir = docDirs.first { 
     paths.append(docDir) // documents directory 
    } 
    let libDirDomain = FileManager.SearchPathDirectory.libraryDirectory 
    let libDirs = NSSearchPathForDirectoriesInDomains(libDirDomain, .userDomainMask, true) 
    if let libDir = libDirs.first { 
     paths.append(libDir) // library directory 
    } 
    paths.append(NSTemporaryDirectory() as String) // temp directory 

    // combine sizes 
    var totalSize: Float64 = 0 
    for path in paths { 
     if let size = bytesIn(directory: path) { 
      totalSize += size 
     } 
    } 
    return totalSize/1000000 // megabytes 
} 

private class func bytesIn(directory: String) -> Float64? { 
    let fm = FileManager.default 
    guard let subdirectories = try? fm.subpathsOfDirectory(atPath: directory) as NSArray else { 
     return nil 
    } 
    let enumerator = subdirectories.objectEnumerator() 
    var size: UInt64 = 0 
    while let fileName = enumerator.nextObject() as? String { 
     do { 
      let fileDictionary = try fm.attributesOfItem(atPath: directory.appending("/" + fileName)) as NSDictionary 
      size += fileDictionary.fileSize() 
     } catch let err { 
      print("err getting attributes of file \(fileName): \(err.localizedDescription)") 
     } 
    } 
    return Float64(size) 
} 
相關問題