iPhone / iPadデバイスで利用可能な空き容量の合計を検出するにはどうすればよいですか?


147

プログラムでiPhone / iPadデバイスの空き容量または空き容量を検出するより良い方法を探しています。
現在、NSFileManagerを使用してディスク領域を検出しています。以下は私のために仕事をするコードのスニペットです:

-(unsigned)getFreeDiskspacePrivate {
NSDictionary *atDict = [[NSFileManager defaultManager] attributesOfFileSystemForPath:@"/" error:NULL];
unsigned freeSpace = [[atDict objectForKey:NSFileSystemFreeSize] unsignedIntValue];
NSLog(@"%s - Free Diskspace: %u bytes - %u MiB", __PRETTY_FUNCTION__, freeSpace, (freeSpace/1024)/1024);

return freeSpace;
}


上記のスニペットで正しいですか?または、利用可能な空き容量の合計を知るためのより良い方法があります。
ディスク領域が少ないシナリオでアプリケーションが同期を実行しないようにする必要があるため、ディスクの空き領域全体を検出する必要があります。


私は願っていますstackoverflowのリンクが ..あなたを助ける
senthilMuthu

1
彼の質問で使用しているコードは、指定したリンクのコードよりも優れているようです( "/"の下のすべてのサブディレクトリを走査するのではなく、1つのディレクトリをチェックしています)
Kendall Helmstetter Gelner '19

リンクをありがとうミハイル。しかし、私は特定のフォルダだけでなく、iPhone / iPadデバイスの利用可能な空き容量の合計を探しています。たとえば、32GBのiPhoneで、利用可能な空き容量の合計が28GBの場合、それをプログラムで検出できるはずです。
Code.Warrior '19

このリンクがお役に立てば幸いです:jayprakashdubey.blogspot.in/2014/07/…–
Jayprakash Dubey

回答:


152

更新:この回答と新しいメソッド/ APIが追加されてからかなりの時間が経過したため、Swiftなどについて以下の更新された回答を確認してください。自分で使ったことがないので保証できません。

元の回答:次の解決策が私に有効であることがわかりました:

-(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;
}

デバイスがマシンに接続されているときにiTunesが表示するサイズを正確に返します。


4
フロートに変換すると、約2GBを超えると不正確な結果が生じる可能性があります。非常に大きなファイルサイズを処理する必要がある場合は、代わりにdoubleまたはlong doubleを使用してください。
アッシュ

Ashが指摘したように、この方法では結果が不正確になります。私のiPad 2では、64GBで+0.25 GB失敗します... David Hによって投稿された以下の方法は、uint64_t変数を使用すると正確な結果が得られます。
Leandro Alves

3
以下に示すように、コードスニペットは@David Hからの提案を反映するように編集されています。
Code.Warrior

4
+200 MBは問題ありません。設定では、「0バイト」の空き容量があります。アプリを入力して使用すると、このメソッドは約150 MBの空き容量を報告します。次に、この残りのスペースをいっぱいにすると、アプリがクラッシュします。したがって、この方法では、[設定]に表示される情報よりも正確な情報が得られると思います。
ancajic 2015

4
なぜ誰もNSUInteger代わりに使用しないのuint64_tですか?C ++やCではなく、Obj-Cを書いています。NSUIntegerは、符号なし64ビット整数を提供しますが、何かが変わった場合、Appleがそのマクロを更新することを想像します(ある時点で128ビットとしましょう)。
Goles

59

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;
}

編集:誰かがこのコードを編集して、「unsigned long long」ではなく「uint64_t」を使用しているようです。近い将来、これは問題ないはずですが、同じではありません。「uint64_t」は64ビットであり、常にそれです。10年間で「unsigned long long」は128になる可能性があります。これは小さなポイントですが、なぜunsignedLongLongを使用したのですか。


新しい自動カウントシステムの経験はありませんが、__ autoreleaseingの目的は何ですか?通常、返されたNSErrorを自動解放する必要はありません
牧師

これは役立つかもしれません:stackoverflow.com/questions/8862023/…
ファビアンKreiser

3
iOS 5.1を実行している私のiPod Touch 4th Genでは、NSFileSystemFreeSizeは依然として200 MBを報告しすぎています。デバッガーでNSDictionary全体の内容を印刷します... NSFileSystemSizeは正しいですが...この問題の解決策はありますか?
Zennichimaro 2013年

@善ニチマロ:問題は解決しましたか?私も同じ問題に直面しており、iPadの空き容量を確認すると0.2 GB余分に取得されます。iPadは24.1 GBの空き容量を表示していますが、コードでは24.3 GBを表示しています。
Sudheer Kumar Palchuri

1
@Diejmonでは、この型の整数サイズをNSNumberに要求することはできません。これが、そのようなことのために、既知のビットサイズのユニットを好む理由です。技術的にはあなたの発言に同意しますが、NSIntegerとフォーマット文字列の使用に対処するのに十分な警告がすでにあります!私の生涯とあなたの64ビットは、確かに十分なビットです。
デビッドH

34

Swiftを使用して使用可能/使用済みメモリを取得するクラスを作成しました。デモ:https : //github.com/thanhcuong1990/swift-disk-status
Swift 4が更新されました。

import UIKit

class 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
        }
    }

}

デモ

Swiftでディスク容量のステータスを取得する


MBFormatterが存在する理由を何か知っていますか?どこでも使用されていません。
Ben Sinclair

MBFormatterは、任意の値をMB値に変換する関数です。デモプロジェクトでは使用していません。しかし、私は他のプロジェクトが必要です。
Cuong Lam、2015

1
これは、FileManager拡張機能に組み込むのに最適です。
レオン

2
iTunesでは18.99 GBの空き容量が表示されますが、説明されている方法を使用すると13.41 GBが割り当てられます。誰かが私が逃したものを知っていますか?
Vitalii Boiarskyi 2017年

1
@CuongLamアンラップエラーはスローされず、do / catchによってキャッチされません。エラーを正しく処理するために、サンプルソースコードを記述する必要があります。stackoverflow.com/questions/34628999/...
SafeFastExpressive

26

サイズ付きのフォーマットされた文字列が必要な場合は、 、GitHubの素敵なライブラリをご覧ください。

#define MB (1024*1024)
#define GB (MB*1024)

@implementation ALDisk

#pragma mark - Formatter

+ (NSString *)memoryFormatter:(long long)diskSpace {
    NSString *formatted;
    double bytes = 1.0 * diskSpace;
    double megabytes = bytes / MB;
    double gigabytes = bytes / GB;
    if (gigabytes >= 1.0)
        formatted = [NSString stringWithFormat:@"%.2f GB", gigabytes];
    else if (megabytes >= 1.0)
        formatted = [NSString stringWithFormat:@"%.2f MB", megabytes];
    else
        formatted = [NSString stringWithFormat:@"%.2f bytes", bytes];

    return formatted;
}

#pragma mark - Methods

+ (NSString *)totalDiskSpace {
    long long space = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemSize] longLongValue];
    return [self memoryFormatter:space];
}

+ (NSString *)freeDiskSpace {
    long long freeSpace = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemFreeSize] longLongValue];
    return [self memoryFormatter:freeSpace];
}

+ (NSString *)usedDiskSpace {
    return [self memoryFormatter:[self usedDiskSpaceInBytes]];
}

+ (CGFloat)totalDiskSpaceInBytes {
    long long space = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemSize] longLongValue];
    return space;
}

+ (CGFloat)freeDiskSpaceInBytes {
    long long freeSpace = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemFreeSize] longLongValue];
    return freeSpace;
}

+ (CGFloat)usedDiskSpaceInBytes {
    long long usedSpace = [self totalDiskSpaceInBytes] - [self freeDiskSpaceInBytes];
    return usedSpace;
}

2
フォーマットするには、NSBytCounterFormatterを
Daniel Barden

これはまだ同じ+の200メガバイトのバグを起こしやすい:stackoverflow.com/questions/9270027/...
Paulius Liekis

13

「unsigned」は使用しないでください。4ビットを超えてオーバーフローするのは32ビットのみであり、通常のiPad / iPhoneの空き容量よりも少なくなります。unsigned long long(またはuint64_t)を使用し、unsignedLongLongValueを使用してNSNumberから64ビットintとして値を取得します。


3
ヒントよりも優れている-"Its the Law" :-)彼が言ったように、元のコードはまったく間違っている。
David H

13

Swiftを使用して残りの空きスペースを取得したい場合は、少し異なります。attributesOfItemAtPath()の代わりにattributesOfFileSystemForPath()を使用する必要があります。

func deviceRemainingFreeSpaceInBytes() -> Int64? {
    let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    var attributes: [String: AnyObject]
    do {
        attributes = try NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectoryPath.last! as String)
        let freeSize = attributes[NSFileSystemFreeSize] as? NSNumber
        if (freeSize != nil) {
            return freeSize?.longLongValue
        } else {
            return nil
        }
    } catch {
        return nil
    }
}

編集:Swift 1.0用に更新
編集2:安全のためにマーティンRの回答を使用して更新。
編集3:Swift 2.0用に更新(dgellowにより)


私はこの回答を使おうとしましたが、GMではコンパイルされません([NSObject:AnyObject]?には 'subscript'という名前のメンバーがありません)。これはここで提起さた問題によるものだと思いますが、この文脈でその答えを機能させる方法がわかりません。どんな助けも大歓迎です。
ブライアンハンソン

私は今すぐSwift 1.0で動作するように回答を更新しました。attributesOfFileSystemForPathが[NSObject:AnyObject]を返すためですか?NSDictionaryにキャストする必要がありますか?nilの可能性があるため、辞書に添字を付けるためにアンラップします。(これは少し安全ではないので、時間があれば、より安全な解決策を使用して、答えを少し後から更新します。)
RubenSandwich

更新していただきありがとうございます。結局のところ、返信の約1時間前に私は先に進んで、この問題を新しい質問としてここにまとめました。ここで答えはありますが、このオプションを処理する方法は私には少し不透明なので、あなたの都合の良いときに別のアプローチを見てみたいと思います。妹レイチェルよろしくお願いします。
ブライアンハンソン

ブライアン、それは安全性と明快さの良い混合なので、あなたの答えられた質問に対する最初の答えを提案するでしょう。私はそれよりも良い答えを出すことができるかどうかわかりません。オプションは最初はわかりにくいかもしれませんが、オプションに関するSwiftのマニュアルのセクションを読むことを強くお勧めします
RubenSandwich 2014年

大変感謝しております。そのマニュアルをもう一度見ていきます。良いSOの質問もいくつか見つけました。ブライアン
ブライアンハンソン

9

これが私の答えであり、それがより良い理由です。

回答(Swift):

func remainingDiskSpaceOnThisDevice() -> String {
    var remainingSpace = NSLocalizedString("Unknown", comment: "The remaining free disk space on this device is unknown.")
    if let attributes = try? FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory()),
        let freeSpaceSize = attributes[FileAttributeKey.systemFreeSize] as? Int64 {
        remainingSpace = ByteCountFormatter.string(fromByteCount: freeSpaceSize, countStyle: .file)
    }
    return remainingSpace
}

回答(Objective-C):

- (NSString *)calculateRemainingDiskSpaceOnThisDevice
{
    NSString *remainingSpace = NSLocalizedString(@"Unknown", @"The remaining free disk space on this device is unknown.");
    NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
    if (dictionary) {
        long long freeSpaceSize = [[dictionary objectForKey:NSFileSystemFreeSize] longLongValue];
        remainingSpace = [NSByteCountFormatter stringFromByteCount:freeSpaceSize countStyle:NSByteCountFormatterCountStyleFile];
    }
    return remainingSpace;
}

なぜそれが良いのか:

  • Cocoaの組み込みライブラリを利用 NSByteCountFormatter。つまり、バイトからギガバイトまでの計算はありません。アップルがこれを行います!
  • 簡単に翻訳可能:NSByteCountFormatterこれを行います。たとえば、デバイスの言語が英語に設定されている場合、文字列は248.8 MBを読み取りますが、他の言語についてはフランス語などに設定されている場合、248,8 Moを読み取ります。
  • エラーが発生した場合は、デフォルト値が表示されます。

1
@JuanBoeroはSwift 3.1で(ついに)投稿されました!
ChrisJF

7

重要な説明(少なくとも私にとって)。iPodをMacに接続すると、iTunes Appに表示される情報になります。

iTunesアプリからのiPodメモリ情報

上記のコードを使用すると:

long long freeSpace = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil]
                            objectForKey:NSFileSystemFreeSize] longLongValue];

NSString *free1 = [NSByteCountFormatter stringFromByteCount:freeSpace countStyle:NSByteCountFormatterCountStyleFile];

[label1 setText:free1];

NSString *free2 = [NSByteCountFormatter stringFromByteCount:freeSpace countStyle:NSByteCountFormatterCountStyleBinary];

[label2 setText:free2];

countStyle NSByteCountFormatterCountStyleFile show me:17,41 GB

countStyle NSByteCountFormatterCountStyleBinary show me:16,22 GB

16,22 GBNSByteCountFormatterCountStyleBinary)これは、iPodをMacに接続したときにiTunesアプリが表示する数値そのものです。


多分ファイルはMACファイル専用でiOSではありませんか?
ジョアン・ヌネス

それは1024対1000(KBその後、MB、その後GB)として乗じバイトの同じ量だ
Jim75

7

新しい正確なAPIで更新して、iOS11で利用可能なディスクで利用可能なサイズを取得します。新しいAPIリソースキーの説明は次のとおりです。

#if os(OSX) || os(iOS)
/// Total available capacity in bytes for "Important" resources, including space expected to be cleared by purging non-essential and cached resources. "Important" means something that the user or application clearly expects to be present on the local system, but is ultimately replaceable. This would include items that the user has explicitly requested via the UI, and resources that an application requires in order to provide functionality.
/// Examples: A video that the user has explicitly requested to watch but has not yet finished watching or an audio file that the user has requested to download.
/// This value should not be used in determining if there is room for an irreplaceable resource. In the case of irreplaceable resources, always attempt to save the resource regardless of available capacity and handle failure as gracefully as possible.
@available(OSX 10.13, iOS 11.0, *) @available(tvOS, unavailable) @available(watchOS, unavailable)
public var volumeAvailableCapacityFor Usage: Int64? { return _get(.volumeAvailableCapacityForImportantUsageKey) }
#endif

私はキー「からの結果と比較にクロスFileAttributeKey.systemFreeSize」とキー「URLResourceKey.volumeAvailableCapacityForImportantUsageKeyの」および「フォーム結果が返さ見出さvolumeAvailableCapacityForImportantUsageKeyが」正確UIに表示される利用可能なストレージと一致します。 利用可能な空きディスク容量の比較 ここに迅速な実装があります:

class var freeDiskSpaceInBytesImportant:Int64 {
    get {
        do {
            return try URL(fileURLWithPath: NSHomeDirectory() as String).resourceValues(forKeys: [URLResourceKey.volumeAvailableCapacityForImportantUsageKey]).volumeAvailableCapacityForImportantUsage!
        } catch {
            return 0
        }
    }
}

スクリーンショットの「日和見的な使用法」はどこから来ていますか?
rshev 2017

それを見つけましたvolumeAvailableCapacityForOpportunisticUsageKey
rshev 2017

はい、rshev、volumeAvailableCapacityForOpportunisticUsageKeyがスクリーンショットで「日和見の使用法」を取得します
Evilisn Jiang

NSHomeDirectory()またはで照会する必要がある使用可能なストレージサイズを確認しますNSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)。これら2つを使用して違いはありますか?
Suryakant Sharma

7

あなたが使用して別の解決策を見つけることができスウィフト4extensionあなたに良いオプションを与えます。

これがUIDevice拡張です。

extension UIDevice {

    func totalDiskSpaceInBytes() -> Int64 {
        do {
            guard let totalDiskSpaceInBytes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[FileAttributeKey.systemSize] as? Int64 else {
                return 0
            }
            return totalDiskSpaceInBytes
        } catch {
            return 0
        }
    }

    func freeDiskSpaceInBytes() -> Int64 {
        do {
            guard let totalDiskSpaceInBytes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[FileAttributeKey.systemFreeSize] as? Int64 else {
                return 0 
            }
            return totalDiskSpaceInBytes
        } catch {
            return 0
        }
    }

    func usedDiskSpaceInBytes() -> Int64 {
        return totalDiskSpaceInBytes() - freeDiskSpaceInBytes()
    }

    func totalDiskSpace() -> String {
        let diskSpaceInBytes = totalDiskSpaceInBytes()
        if diskSpaceInBytes > 0 {
            return ByteCountFormatter.string(fromByteCount: diskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.binary)
        }
        return "The total disk space on this device is unknown"
    }

    func freeDiskSpace() -> String {
        let freeSpaceInBytes = freeDiskSpaceInBytes()
        if freeSpaceInBytes > 0 {
            return ByteCountFormatter.string(fromByteCount: freeSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.binary)
        }
        return "The free disk space on this device is unknown"
    }

    func usedDiskSpace() -> String {
        let usedSpaceInBytes = totalDiskSpaceInBytes() - freeDiskSpaceInBytes()
        if usedSpaceInBytes > 0 {
            return ByteCountFormatter.string(fromByteCount: usedSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.binary)
        }
        return "The used disk space on this device is unknown"
    }

}

そして使用例:

UIDevice.current.totalDiskSpaceInBytes()
UIDevice.current.totalDiskSpace()
UIDevice.current.freeDiskSpaceInBytes()
UIDevice.current.freeDiskSpace()
UIDevice.current.usedDiskSpaceInBytes()
UIDevice.current.usedDiskSpace()

!代わりguardに金庫typecastingまたはnilチェックに入れて使用しないでください。
TheTiger 2018

コメント@TheTigerをありがとう。
abdullahselek

3

iOS> = 6.0の場合、新しいを使用できますNSByteCountFormatter。このコードは、フォーマットされた文字列として残っている空きバイト数を取得します。

NSError *error = nil;
NSArray * const paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary * const pathAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths firstObject] error:&error];
NSAssert(pathAttributes, @"");
NSNumber * const fileSystemSizeInBytes = [pathAttributes objectForKey: NSFileSystemFreeSize];
const long long numberOfBytesRemaining = [fileSystemSizeInBytes longLongValue];
NSByteCountFormatter *byteCountFormatter = [[NSByteCountFormatter alloc] init];
NSString *formattedNmberOfBytesRemaining = [byteCountFormatter stringFromByteCount:numberOfBytesRemaining];

2

以下のコードは、以前にChrisJFによって提供された回答のSwift 3.0バージョンの実装です。

func freeSpaceInBytes() -> NSString {

    var remainingSpace = NSLocalizedString("Unknown", comment: "The remaining free disk space on this device is unknown.")

    do {
        let dictionary =  try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())
        let freeSpaceSize = ((dictionary[FileAttributeKey.systemFreeSize] as AnyObject).longLongValue)!
        remainingSpace = ByteCountFormatter.string(fromByteCount: freeSpaceSize, countStyle: ByteCountFormatter.CountStyle.file)
    }
    catch let error {
        NSLog(error.localizedDescription)
    }

    return remainingSpace as NSString

}

なぜ、iPhoneの利用可能なディスク容量情報よりも多くを返すのですか。iPhoneのセットアップメニューに998MBと表示された場合、1.2 GBが返されます
Hope

1

スウィフト UIDevice拡張として

extension UIDevice {
    func freeDiskspace() -> NSString {
        let failedResult: String = "Error Obtaining System Memory"
        guard let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last else {
            return failedResult
        }
        do {
            let dictionary = try NSFileManager.defaultManager().attributesOfFileSystemForPath(path)
            if let fileSystemSizeInBytes = dictionary[NSFileSystemSize] as? UInt,
                let freeFileSystemSizeInBytes =     dictionary[NSFileSystemFreeSize] as? UInt {
                    return "Memory \(freeFileSystemSizeInBytes/1024/1024) of \(fileSystemSizeInBytes/1024/1024) Mb available."
            } else {
                    return failedResult
            }
        } catch {
            return failedResult
        }
    }
}

使い方:

print("\(UIDevice.currentDevice().freeDiskspace())")

出力は次のようになります。

Memory 9656 of 207694 Mb available.

1

私はこの投稿が少し古いことを知っていますが、この答えは誰かを助けることができると思います。デバイスの使用済み/空き/合計ディスク容量を知りたい場合は、Luminousを使用できます。Swiftで書かれています。あなたは電話するだけです:

Luminous.System.Disk.freeSpace()
Luminous.System.Disk.usedSpace()

または

Luminous.System.Disk.freeSpaceInBytes()
Luminous.System.Disk.usedSpaceInBytes()

1

上記のコードの迅速な実装:-

import UIKit

class DiskInformation: NSObject {

    var totalSpaceInBytes: CLongLong = 0; // total disk space
    var totalFreeSpaceInBytes: CLongLong = 0; //total free space in bytes

    func getTotalDiskSpace() -> String { //get total disk space
        do{
        let space: CLongLong = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[FileAttributeKey.systemSize] as! CLongLong; //Check for home dirctory and get total system size
            totalSpaceInBytes = space; // set as total space
            return memoryFormatter(space: space); // send the total bytes to formatter method and return the output

        }catch let error{ // Catch error that may be thrown by FileManager
            print("Error is ", error);
        }
        return "Error while getting memory size";
    }

    func getTotalFreeSpace() -> String{ //Get total free space
        do{
            let space: CLongLong = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[FileAttributeKey.systemFreeSize] as! CLongLong;
            totalFreeSpaceInBytes = space;
            return memoryFormatter(space: space);

        }catch let error{
            print("Error is ", error);
        }
        return "Error while getting memory size";
    }

    func getTotalUsedSpace() -> String{ //Get total disk usage from above variable
        return memoryFormatter(space: (totalSpaceInBytes - totalFreeSpaceInBytes));
    }

    func memoryFormatter(space : CLongLong) -> String{ //Format the usage to return value with 2 digits after decimal
        var formattedString: String;

        let totalBytes: Double = 1.0 * Double(space);
        let totalMb: Double = totalBytes / (1024 * 1024);
        let totalGb: Double = totalMb / 1024;
        if (totalGb > 1.0){
            formattedString = String(format: "%.2f", totalGb);
        }else if(totalMb >= 1.0){
            formattedString = String(format: "%.2f", totalMb);
        }else{
            formattedString = String(format: "%.2f", totalBytes);
        }
        return formattedString;
    }


}

他のクラスから呼び出します。

func getDiskInfo(){
        let diskInfo = DiskInformation();
        print("Total disk space is", diskInfo.getTotalDiskSpace(),"Gb");
        print("Total free space is", diskInfo.getTotalFreeSpace(),"Gb");
        print("Total used space is", diskInfo.getTotalUsedSpace(),"Gb");
    }

戻り値をテストしている間、それは他のアプリによって示されたものと同じです。少なくとも私のiPhone 6S +では。それは、上に示した答えの迅速な実装にすぎません。そして、私にとって受け入れられた答えはうまくいきませんでした。


0

Swift 2.1バージョンでのChrisJFの回答:

func freeSpaceInBytes() -> NSString{

    var remainingSpace = NSLocalizedString("Unknown", comment: "The remaining free disk space on this device is unknown.")

    do {

        let dictionary =  try NSFileManager.defaultManager().attributesOfFileSystemForPath(NSHomeDirectory())
        freeSpaceSize = (dictionary[NSFileSystemFreeSize]?.longLongValue)!
        remainingSpace = NSByteCountFormatter.stringFromByteCount(freeSpaceSize, countStyle: NSByteCountFormatterCountStyle.File)

    }
    catch let error as NSError {

        error.description
        NSLog(error.description)

    }

    return remainingSpace

}


0

FileManager適切なエラー処理と自動文字列変換(必要に応じてバイトカウントを文字列に変換)なしのSwift 5拡張。FileManagerの命名にも従います。

extension FileManager {
    func systemFreeSizeBytes() -> Result<Int64, Error> {
        do {
            let attrs = try attributesOfFileSystem(forPath: NSHomeDirectory())
            guard let freeSize = attrs[.systemFreeSize] as? Int64 else {
                return .failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Can't retrieve system free size"]))
            }
            return .success(freeSize)
        } catch {
            return .failure(error)
        }
    }

    func systemSizeBytes() -> Result<Int64, Error> {
         do {
             let attrs = try attributesOfFileSystem(forPath: NSHomeDirectory())
             guard let size = attrs[.systemSize] as? Int64 else {
                 return .failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Can't retrieve system size"]))
             }
             return .success(size)
         } catch {
             return .failure(error)
         }
     }
}

使用例:

let freeSizeResult = FileManager.default.systemFreeSizeBytes()
switch freeSizeResult {
case .failure(let error):
    print(error)
case .success(let freeSize):
    let freeSizeString = ByteCountFormatter.string(fromByteCount: freeSize, countStyle: .file)
    print("free size: \(freeSizeString)")
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.