iOS 11 更新
在 iOS 11 下,下面提供的答案不再提供准确结果。现在可以传递新的容量密钥 URL.resourceValues(forKeys:)
,这些密钥提供与设备设置中可用内容匹配的值。
static let volumeAvailableCapacityKey: URLResourceKey
卷的可用容量字节数(只读)的键。
static let volumeAvailableCapacityForImportantUsageKey: URLResourceKey
存储重要资源的卷的可用容量字节数(只读)的键。
static let volumeAvailableCapacityForOpportunisticUsageKey: URLResourceKey
用于存储非必需资源的卷的可用容量字节数(只读)的键。
static let volumeTotalCapacityKey: URLResourceKey
卷的总容量字节数(只读)的键。
来自Apple 文档:
概述
在尝试本地存储大量数据之前,请先验证您是否具有足够的存储容量。要获取卷的存储容量,您构造一个 URL(使用 URL 的实例)来引用要查询的卷上的对象,然后查询该卷。
决定使用哪种查询类型
要使用的查询类型取决于正在存储的内容。如果您根据用户请求存储数据或应用程序需要正确运行的资源(例如,用户即将观看的视频或下一个游戏等级所需的资源),请针对 volumeAvailableCapacityForImportantUsageKey
进行查询。但是,如果您以更有预测性的方式下载数据(例如,下载用户最近观看过的电视系列的新可用剧集),请针对 volumeAvailableCapacityForOpportunisticUsageKey
进行查询。
构造查询
请使用此示例作为构建自己查询的指南:
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
的可选绑定在这里同样适用。
我建议该函数返回一个可选的Int64
,这样它可以返回nil
来表示失败:
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
}
}
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 {
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")
}