iOS 中临时目录的文件大小限制是多少?
What is the file size limit in temporary directory in iOS?
我正在尝试保存从 here 下载的大小为 7.9MB 的图像。但是在 'try data.write...' 行,扩展崩溃了,我在控制台中得到了这个。
kernel EXC_RESOURCE -> Notification Extension[3137] exceeded mem limit: ActiveHard 12 MB (fatal)
kernel 46710.034 memorystatus: killing_specific_process pid 3137 [Notification Extension] (per-process-limit 3) - memorystatus_available_pages: 73906
ReportCrash starting prolongation transaction timer
default 18:39:53.104640 +0530
ReportCrash Process Notification Extension [3137] killed by jetsam reason per-process-limit
是不是因为7.9MB的大小太大了,太难处理了。如果是,那么它就没有意义,因为在创建 UNNotificationAttachment 对象之前有必要将媒体保存在临时存储中。在官方文档中,png 文件的限制为 10 MB,视频为 50 MB。我该如何解决?
let fileManager = FileManager.default
let folderName = ProcessInfo.processInfo.globallyUniqueString
guard let folderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(folderName, isDirectory: true) else {
return nil
}
do {
try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true, attributes: nil)
let fileURL = folderURL.appendingPathComponent(fileIdentifier)
try data.write(to: fileURL, options: [])
let attachment = try UNNotificationAttachment(identifier: fileIdentifier, url: fileURL, options: options)
return attachment
} catch let error {
}
我不知道是否有 可以写入临时目录的内容的大小限制(免费 space 除外),但我可以告诉你知道我已经编写了将数百兆字节写入该目录的客户端应用程序。那不是你的问题。
它是这样工作的。我没有使用 NSData(contentsOf:)
下载数据,而是使用 URLSession.shared.downloadTask(with:)
。这会自行存储下载的数据,因此我们无需编写它。只需使用 FileManager.shared.moveItem(at:to:)
将其移动到所需的临时位置即可。看起来问题出在 NSData.write(to:options:)
函数上。它有一些大小限制。
URLSession.shared.downloadTask(with: url) { (location, response, error) in
if let location = location {
let tmpDirectory = NSTemporaryDirectory()
let tmpFile = "file://".appending(tmpDirectory).appending(url.lastPathComponent)
let tmpUrl = URL(string: tmpFile)!
try! FileManager.default.moveItem(at: location, to: tmpUrl)
if let attachment = try? UNNotificationAttachment(identifier: "notification-img", url: tmpUrl) {
bestAttemptContent.attachments = [attachment]
}
}
contentHandler(bestAttemptContent)
}.resume()
我正在尝试保存从 here 下载的大小为 7.9MB 的图像。但是在 'try data.write...' 行,扩展崩溃了,我在控制台中得到了这个。
kernel EXC_RESOURCE -> Notification Extension[3137] exceeded mem limit: ActiveHard 12 MB (fatal)
kernel 46710.034 memorystatus: killing_specific_process pid 3137 [Notification Extension] (per-process-limit 3) - memorystatus_available_pages: 73906
ReportCrash starting prolongation transaction timer default 18:39:53.104640 +0530
ReportCrash Process Notification Extension [3137] killed by jetsam reason per-process-limit
是不是因为7.9MB的大小太大了,太难处理了。如果是,那么它就没有意义,因为在创建 UNNotificationAttachment 对象之前有必要将媒体保存在临时存储中。在官方文档中,png 文件的限制为 10 MB,视频为 50 MB。我该如何解决?
let fileManager = FileManager.default
let folderName = ProcessInfo.processInfo.globallyUniqueString
guard let folderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(folderName, isDirectory: true) else {
return nil
}
do {
try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true, attributes: nil)
let fileURL = folderURL.appendingPathComponent(fileIdentifier)
try data.write(to: fileURL, options: [])
let attachment = try UNNotificationAttachment(identifier: fileIdentifier, url: fileURL, options: options)
return attachment
} catch let error {
}
我不知道是否有 可以写入临时目录的内容的大小限制(免费 space 除外),但我可以告诉你知道我已经编写了将数百兆字节写入该目录的客户端应用程序。那不是你的问题。
它是这样工作的。我没有使用 NSData(contentsOf:)
下载数据,而是使用 URLSession.shared.downloadTask(with:)
。这会自行存储下载的数据,因此我们无需编写它。只需使用 FileManager.shared.moveItem(at:to:)
将其移动到所需的临时位置即可。看起来问题出在 NSData.write(to:options:)
函数上。它有一些大小限制。
URLSession.shared.downloadTask(with: url) { (location, response, error) in
if let location = location {
let tmpDirectory = NSTemporaryDirectory()
let tmpFile = "file://".appending(tmpDirectory).appending(url.lastPathComponent)
let tmpUrl = URL(string: tmpFile)!
try! FileManager.default.moveItem(at: location, to: tmpUrl)
if let attachment = try? UNNotificationAttachment(identifier: "notification-img", url: tmpUrl) {
bestAttemptContent.attachments = [attachment]
}
}
contentHandler(bestAttemptContent)
}.resume()