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


위의 코드 조각으로 맞습니까? 또는 사용 가능한 총 여유 공간을 알 수있는 더 좋은 방법이 있습니까?
디스크 공간 부족 시나리오에서 응용 프로그램이 동기화를 수행하지 못하도록하므로 전체 디스크 여유 공간을 감지했습니다.



1
그가 질문에 사용한 코드가 사용자가 제공 한 링크의 코드보다 더 나은 것 같습니다 ( "/"아래의 모든 하위 디렉토리를 순회하는 대신 하나의 디렉토리를 확인하는
것임

링크 주셔서 감사합니다 Mikhail. 그러나 특정 폴더뿐만 아니라 iPhone / iPad 장치에서 사용 가능한 총 여유 공간을 찾고 있습니다. 예를 들어 32GB iPhone에서 사용 가능한 총 여유 공간이 28GB이면 프로그래밍 방식으로 감지 할 수 있어야합니다.
Code.Warrior

이 링크가 도움이되기를 바랍니다. 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

Ash가 지적한 것처럼이 방법은 결과가 정확하지 않습니다. 64GB의 iPad 2에서는 + 0.25GB까지 실패합니다. David H가 게시 한 아래의 방법은 uint64_t vars를 사용할 때 정확한 결과를 얻습니다.
Leandro Alves 2016 년

3
코드 스 니펫은 다음과 같이 @David H의 제안을 반영하도록 편집되었습니다.
Code.Warrior

4
+ 200MB는 문제가되지 않습니다. 설정에서 "0 바이트"의 사용 가능한 공간이 있습니다. 그리고 앱을 입력하고 사용할 때이 방법은 약 150MB의 여유 공간을보고합니다. 그런 다음이 남은 공간을 채우고 앱 만 충돌합니다. 따라서이 방법을 사용하면 설정에 표시된 것보다 더 정확한 정보를 얻을 수 있습니다.
ancajic

4
NSUInteger같은 물건 대신에 아무도 사용 하지 uint64_t않습니까? 우리는 C ++ 또는 C가 아닌 Obj-C를 작성하고 있습니다 .NSUInteger는 이제 부호없는 64 비트 정수를 제공 할 것입니다.
Goles

59

부호없는 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 년 동안 '서명되지 않은 long long'은 128 일 수 있습니다. 작은 점이지만 왜 unsignedLongLong을 사용했는지입니다.


새로운 자동 계산 시스템에 대한 경험이 없지만 __autoreleasing은 무엇입니까? 당신은 일반적으로 반환 된 NSError
Reverend


3
iOS 5.1을 실행하는 iPod Touch 4 세대에서 NSFileSystemFreeSize는 여전히 ~ 200MB를 너무 많이보고합니다. 디버거에서 전체 NSDictionary의 내용을 인쇄합니다 ... NSFileSystemSize는 맞지만 ...이 문제에 대한 해결책이 있습니까?
Zennichimaro

@Zennichimaro : 문제를 해결 했습니까? 또한 동일한 문제에 직면하여 iPad에서 여유 공간을 확인할 때 0.2GB가 추가로 제공됩니다. iPad의 사용 가능한 공간은 24.1GB이지만 코드에서는 24.3GB입니다.
Sudheer Kumar Palchuri

1
@Diejmon은 NSNumber에이 유형의 정수 크기를 요청할 수 없습니다. 이런 이유로 나는 알려진 비트 크기의 단위를 선호합니다. 기술적으로 귀하의 진술에 동의하지만 NSInteger 및 형식 문자열 사용에 대해 충분한 경고가 이미 있습니다! 내 인생과 당신의 삶에서 64 비트는 충분한 비트가 될 것입니다.
David 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가 왜 있는지 알고 있습니까? 어디서나 사용되지 않습니다.
벤 싱클레어

MBFormatter는 모든 값을 MB 값으로 변환하는 기능입니다. 데모 프로젝트에는 사용하지 않습니다. 하지만 다른 프로젝트가 필요합니다.
Cuong Lam

1
FileManager 확장명에 넣는 것이 좋습니다.
레온

2
iTunes는 18.99GB의 여유 공간을 표시하지만 설명 된 방법을 사용할 때 13.41GB를 얻습니다. 내가 뭘 그리워하는지 아는 사람 있습니까?
Vitalii Boiarskyi

1
@CuongLam Unwrapping 오류가 발생하지 않으며 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;
}


이것은 여전히 ​​같은 + 200MB 버그가 발생하기 쉽습니다 : stackoverflow.com/questions/9270027/…
Paulius Liekis

13

'부호없는'을 사용하지 마십시오. 이는 32 비트에 불과하며 4GB를 초과하여 오버플로되므로 일반적인 iPad / iPhone 여유 공간보다 적습니다. unsigned long long (또는 uint64_t)을 사용하고 unsignedLongLongValue를 사용하여 NSNumber에서 64 비트 정수로 값을 검색하십시오.


3
팁보다 낫다- "법칙":-) 그가 말했듯이, 원래 코드는 단지 틀렸다.
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 : 안전을 위해 업데이트 Martin R의 답변을 사용하여 .
편집 3 : Swift 2.0 용 업데이트 ( dgellow )


이 답변을 사용하려고했지만 GM에서 컴파일되지 않습니다 ([NSObject : AnyObject]?에 'subscript'라는 멤버가 없음). 나는 이것이 여기서 제기 된 문제 때문이라고 생각 하지만이 맥락에서 그 대답을 작동시키는 방법을 이해하지 못합니다. 어떤 도움이라도 대단히 감사합니다.
Bryan Hanson

Swift 1.0에서 작동하도록 답변을 업데이트했습니다. attributesOfFileSystemForPath가 [NSObject : AnyObject]를 반환하기 때문에? NSDictionary로 캐스팅해야합니까? nil이 될 수 있기 때문에 첨자를 첨자하기 위해 사전을 언랩하십시오. (이것은 약간 안전하지 않으므로 시간이 있으면 더 안전한 솔루션으로 답변을 조금 나중에 업데이트하겠습니다.)
RubenSandwich

업데이트 해 주셔서 감사합니다. 그것은 귀하의 회신 전에 한 시간 정도 밝혀으로 나는 사라 앞서 있었고, 새로운 질문으로 문제를 공식화 여기 . 지금 거기에 답이 있지만 옵션을 다루는이 방법은 약간 불투명하기 때문에 편의에 따라 다른 접근 방식을보고 싶습니다. 여동생 레이첼에게 안부를 전 해주세요.
Bryan Hanson

브라이언 씨, 귀하의 답변에 대한 첫 번째 답변은 안전과 명확성이 잘 혼합되어 있기 때문에 제안 해 드리겠습니다. 나는 그보다 더 나은 대답을 줄 수 있을지 확신하지 못한다. 선택 사항은 처음에는 혼란 스러울 수 있습니다. Swift 매뉴얼 섹션을 좋습니다.
RubenSandwich

고맙게도, 나는 그 매뉴얼을 다시 볼 것이고 좋은 SO 질문도 발견했습니다. Bryan
Bryan Hanson

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

더 나은 이유 :

  • 코코아 내장 라이브러리 활용 NSByteCountFormatter 사용하므로 바이트에서 기가 바이트까지 수동으로 계산할 필요가 없습니다. 애플이 당신을 위해 이것을합니다!
  • 쉽게 번역 NSByteCountFormatter할 수 있습니다. 예를 들어 장치의 언어가 영어로 설정된 경우 문자열은 248.8MB이지만 프랑스어로 설정된 경우에는 다른 언어의 경우 248,8 Mo를 읽습니다.
  • 오류가 발생하면 기본값이 제공됩니다.

1
@JuanBoero 스위프트 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 표시 : 17,41GB

countStyle NSByteCountFormatterCountStyleBinary 표시 : 16,22GB

16, 22 GB ( NSByteCountFormatterCountStyleBinary )이이 정확히 내 Mac에 내 iPod을 연결하면 아이튠즈 앱 나를 보여하는 수.


어쩌면 File은 iOS가 아닌 MAC 파일 전용입니까?
João Nunes

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

찾았습니다 volumeAvailableCapacityForOpportunisticUsageKey.
rshev

예 rshev, volumeAvailableCapacityForOpportunisticUsageKey가 스크린 샷에서 "기회 사용"을 얻습니다.
Evilisn 지앙

사용 가능한 스토리지 크기를 확인하려면 NSHomeDirectory()또는NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) . 이 두 가지를 사용하는 데 차이가 있습니까?
Suryakant Sharma

7

당신은 사용을 가진 다른 해결책을 찾을 수 있습니다 스위프트 사extension 당신에게 좋은 옵션을 제공한다.

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안전 장치 typecastingnil점검 장치 를 사용하지 마십시오 .
TheTiger

귀하의 의견에 감사드립니다 @TheTiger.
abdullahselek

3

iOS> = 6.0의 경우 new를 사용할 수 있습니다 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의 사용 가능한 디스크 공간 정보보다 많은 정보를 반환하는 것입니까? 아이폰의 '설정 메뉴 9백98메가바이트, 그 수익률 1.2 GB 말할 때
희망

1

UIDevice 확장으로 Swift

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

반환 된 값을 테스트하는 동안 다른 앱에 표시된 것과 동일합니다. 적어도 내 아이폰 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.