使用Swift查询可用的iOS磁盘空间 [英] Query Available iOS Disk Space with Swift

查看:332
本文介绍了使用Swift查询可用的iOS磁盘空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Swift获取可用的iOS设备存储.我在此处

I'm trying to get the available iOS device storage using Swift. I found this function here

        func deviceRemainingFreeSpaceInBytes() -> NSNumber {
          let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
          let systemAttributes = NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectoryPath.last as String, error: nil)
          return systemAttributes[NSFileSystemFreeSize] as NSNumber
        }

但是在编译时会给出此错误:[NSObject : AnyObject]? does not have a member named 'subscript'我认为此错误是由此处中提到的问题引起的,即attributesOfFileSystemForPath返回一个可选的字典(

But at compile time this error is given: [NSObject : AnyObject]? does not have a member named 'subscript' I believe this error arises from the issue mentioned here, namely that attributesOfFileSystemForPath returns an optional dictionary (documentation). I understand the problem in a general sense, but because the suggested solution involves a nested case, I don't quite see how to fix the function I'm interested in (it doesn't help that I'm quite new to Swift). Can someone suggest how to make the function work? NOTE: I'm not sure if the original function was tested by the author or if it worked under an xcode 6 beta, but it doesn't work under the GM as far as I can see.

推荐答案

iOS 11更新

在iOS 11下,下面给出的答案不再提供准确的结果.可以将新的卷容量键传递给URL.resourceValues(forKeys:),这些键提供的值与设备设置中可用的值匹配.

iOS 11 Update

The answers given below no longer provide accurate results under iOS 11. There are new volume capacity keys that can be passed to URL.resourceValues(forKeys:) that provide values that match what is available in device settings.

  • static let volumeAvailableCapacityKey: URLResourceKey 卷的可用容量的密钥,以字节为单位(只读).

  • static let volumeAvailableCapacityKey: URLResourceKey Key for the volume’s available capacity in bytes (read-only).

static let volumeAvailableCapacityForImportantUsageKey: URLResourceKey 卷的可用容量(以字节为单位)的键,用于存储重要资源(只读).

static let volumeAvailableCapacityForImportantUsageKey: URLResourceKey Key for the volume’s available capacity in bytes for storing important resources (read-only).

static let volumeAvailableCapacityForOpportunisticUsageKey: URLResourceKey 卷的可用容量(以字节为单位)的键,用于存储非必需资源(只读).

static let volumeAvailableCapacityForOpportunisticUsageKey: URLResourceKey Key for the volume’s available capacity in bytes for storing nonessential resources (read-only).

static let volumeTotalCapacityKey: URLResourceKey 卷的总容量的密钥,以字节为单位(只读).

static let volumeTotalCapacityKey: URLResourceKey Key for the volume’s total capacity in bytes (read-only).

来自 Apple的文档:

概述

在尝试在本地存储大量数据之前,请首先验证您是否具有足够的存储容量.为了获得卷的存储容量,您可以构造一个URL(使用URL实例),该URL引用要查询的卷上的对象,然后查询该卷.

Overview

Before you try to store a large amount of data locally, first verify that you have sufficient storage capacity. To get the storage capacity of a volume, you construct a URL (using an instance of URL) that references an object on the volume to be queried, and then query that volume.

要使用的查询类型取决于要存储的内容.如果您要根据用户请求或应用程序正常运行所需的资源来存储数据(例如,用户即将观看的视频或游戏中下一关所需的资源),请查询volumeAvailableCapacityForImportantUsageKey .但是,如果您以更具预测性的方式下载数据(例如,下载用户最近观看的电视连续剧的最新剧集),请查询volumeAvailableCapacityForOpportunisticUsageKey.

The query type to use depends on what's being stored. If you’re storing data based on a user request or resources the app requires to function properly (for example, a video the user is about to watch or resources that are needed for the next level in a game), query against volumeAvailableCapacityForImportantUsageKey. However, if you’re downloading data in a more predictive manner (for example, downloading a newly available episode of a TV series that the user has been watching recently), query against volumeAvailableCapacityForOpportunisticUsageKey.

使用以下示例作为构建您自己的查询的指南:

Use this example as a guide to construct your own query:

let fileURL = URL(fileURLWithPath: NSHomeDirectory() as String)
do {
    let values = try fileURL.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey])
    if let capacity = values.volumeAvailableCapacityForImportantUsage {
        print("Available capacity for important usage: \(capacity)")
    } else {
        print("Capacity is unavailable")
    }
} catch {
    print("Error retrieving capacity: \(error.localizedDescription)")
}


原始答案

if let的可选绑定在这里也适用.


Original Answer

Optional binding with if let works here as well.

我建议该函数返回可选的Int64,以便它可以返回 nil表示失败:

I would suggest that the function returns an optional Int64, so that it can return nil to signal a failure:

func deviceRemainingFreeSpaceInBytes() -> Int64? {
    let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    if let systemAttributes = NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectoryPath.last as String, error: nil) {
        if let freeSize = systemAttributes[NSFileSystemFreeSize] as? NSNumber {
            return freeSize.longLongValue
        }
    }
    // something failed
    return nil
}

Swift 2.1更新:

func deviceRemainingFreeSpaceInBytes() -> Int64? {
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last!
    guard
        let systemAttributes = try? NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectory),
        let freeSize = systemAttributes[NSFileSystemFreeSize] as? NSNumber
    else {
        // something failed
        return nil
    }
    return freeSize.longLongValue
}

Swift 3.0更新:

func deviceRemainingFreeSpaceInBytes() -> Int64? {
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!
    guard
        let systemAttributes = try? FileManager.default.attributesOfFileSystem(forPath: documentDirectory),
        let freeSize = systemAttributes[.systemFreeSize] as? NSNumber
    else {
        // something failed
        return nil
    }
    return freeSize.int64Value
}

用法:

if let bytes = deviceRemainingFreeSpaceInBytes() {
    print("free space: \(bytes)")
} else {
    print("failed")
}

这篇关于使用Swift查询可用的iOS磁盘空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆