Bry*_*son 23 storage ios swift
我正在尝试使用可用的iOS设备存储Swift.我在这里找到了这个功能
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
}
Run Code Online (Sandbox Code Playgroud)
但是在编译时给出了这个错误:[NSObject : AnyObject]? does not have a member named 'subscript' 我认为这个错误来自这里提到的问题,即attributesOfFileSystemForPath返回一个可选的字典(文档).我在一般意义上理解这个问题,但是由于建议的解决方案涉及嵌套的情况,我不太清楚如何修复我感兴趣的函数(这对我来说并不是很有帮助Swift).有人可以建议如何使功能工作?注意:我不确定作者是否测试了原始函数,或者它是否在xcode 6 beta下运行,但据我所知,它在GM下无效.
Mar*_*n R 54
下面给出的答案不再能够在iOS 11下提供准确的结果.可以传递新的卷容量键URL.resourceValues(forKeys:),提供与设备设置中可用的值相匹配的值.
static let volumeAvailableCapacityKey: URLResourceKey
卷的可用容量的密钥(以字节为单位)(只读).
static let volumeAvailableCapacityForImportantUsageKey: URLResourceKey
用于存储重要资源的卷的可用容量(以字节为单位)的密钥(只读).
static let volumeAvailableCapacityForOpportunisticUsageKey: URLResourceKey
用于存储非必要资源的卷的可用容量(以字节为单位)的密钥(只读).
static let volumeTotalCapacityKey: URLResourceKey
卷的总容量的密钥(以字节为单位)(只读).
来自Apple的文档:
概观
在尝试在本地存储大量数据之前,请先验证您是否具有足够的存储容量.要获取卷的存储容量,请构造一个URL(使用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)")
}
Run Code Online (Sandbox Code Playgroud)
可选的结合有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
}
}
// something failed
return nil
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
用法:
if let bytes = deviceRemainingFreeSpaceInBytes() {
print("free space: \(bytes)")
} else {
print("failed")
}
Run Code Online (Sandbox Code Playgroud)
DàC*_*hún 24
那么,根据上面的代码:
let usedSpace = totalDiskSpaceInBytes - freeDiskSpaceInBytes
Run Code Online (Sandbox Code Playgroud)
您可能会发现usedSpace不等于iPhone设置页面的值.这是因为在iOS11中,Apple 为"重要"资源引入了总可用容量(以字节为单位).
"重要"资源的总可用容量(以字节为单位),包括通过清除非必要资源和缓存资源来清除的空间."重要"是指用户或应用程序明确希望在本地系统上出现的内容,但最终可以替换.这将包括用户通过UI明确请求的项目,以及应用程序为提供功能所需的资源.
示例:用户已明确请求观看但尚未观看的视频或用户请求下载的音频文件.
此值不应用于确定是否存在不可替代资源的空间.在不可替代资源的情况下,始终尝试保存资源而不管可用容量如何,并尽可能优雅地处理故障.
为了获得与我们在iPhone设置页面中看到的完全相同的值,我们可以通过volumeAvailableCapacityForImportantUsage获得可用空间
if let space = try? URL(fileURLWithPath: NSHomeDirectory() as String).resourceValues(forKeys: [URLResourceKey.volumeAvailableCapacityForImportantUsageKey]).volumeAvailableCapacityForImportantUsage {
return space ?? 0
}
Run Code Online (Sandbox Code Playgroud)
您可以使用以下UIDevice扩展:
Swift4
extension UIDevice {
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
var totalDiskSpaceInGB:String {
return ByteCountFormatter.string(fromByteCount: totalDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.decimal)
}
var freeDiskSpaceInGB:String {
return ByteCountFormatter.string(fromByteCount: freeDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.decimal)
}
var usedDiskSpaceInGB:String {
return ByteCountFormatter.string(fromByteCount: usedDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.decimal)
}
var totalDiskSpaceInMB:String {
return MBFormatter(totalDiskSpaceInBytes)
}
var freeDiskSpaceInMB:String {
return MBFormatter(freeDiskSpaceInBytes)
}
var usedDiskSpaceInMB:String {
return MBFormatter(usedDiskSpaceInBytes)
}
//MARK: Get raw value
var totalDiskSpaceInBytes:Int64 {
guard let systemAttributes = try? FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory() as String),
let space = (systemAttributes[FileAttributeKey.systemSize] as? NSNumber)?.int64Value else { return 0 }
return space
}
/*
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.
*/
var freeDiskSpaceInBytes:Int64 {
if #available(iOS 11.0, *) {
if let space = try? URL(fileURLWithPath: NSHomeDirectory() as String).resourceValues(forKeys: [URLResourceKey.volumeAvailableCapacityForImportantUsageKey]).volumeAvailableCapacityForImportantUsage {
return space ?? 0
} else {
return 0
}
} else {
if let systemAttributes = try? FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory() as String),
let freeSpace = (systemAttributes[FileAttributeKey.systemFreeSize] as? NSNumber)?.int64Value {
return freeSpace
} else {
return 0
}
}
}
var usedDiskSpaceInBytes:Int64 {
return totalDiskSpaceInBytes - freeDiskSpaceInBytes
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
Logger.d("totalDiskSpaceInBytes: \(UIDevice.current.totalDiskSpaceInBytes)")
Logger.d("freeDiskSpace: \(UIDevice.current.freeDiskSpaceInBytes)")
Logger.d("usedDiskSpace: \(UIDevice.current.usedDiskSpaceInBytes)")
Run Code Online (Sandbox Code Playgroud)
Cuo*_*Lam 20
我已经编写了一个类来使用Swift获取/使用内存.演示:https://github.com/thanhcuong1990/swift-disk-status
升级以支持Swift 3.
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.binary)
}
}
class var freeDiskSpace:String {
get {
return ByteCountFormatter.string(fromByteCount: freeDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.binary)
}
}
class var usedDiskSpace:String {
get {
return ByteCountFormatter.string(fromByteCount: usedDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.binary)
}
}
//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
}
}
}
Run Code Online (Sandbox Code Playgroud)
演示:

| 归档时间: |
|
| 查看次数: |
14576 次 |
| 最近记录: |