为了避免已知错误,我需要在枚举目录之前kwnow,如果用户可以读取它。
我如何在swift(最新版本,使用Xcode和MAC OS最新版本)中做到这一点?
更多信息: 尝试在swift中枚举目录可能会导致应用程序崩溃,如果用户无法访问它。没有办法捕获错误以防止崩溃,但只有在用户无法访问目录时才会发生。因此,事先知道是否可以读取目录(因此枚举)将有助于防止崩溃。
可兑现代码:
有一个例子: Timothy Wood报道的https://bugs.swift.org/browse/SR-2872
此示例: Jean Suisse
报告的http://prod.lists.apple.com/archives/cocoa-dev/2016/Oct/msg00166.html答案 0 :(得分:1)
Xcode 8.1的release notes中提供了此错误的解决方法。引用发行说明:
SDK中的某些Objective-C方法可能会错误地注释或 假设类型为
nonnull
而不是nullable
。 Swift的一种类型 视为结构,例如NSURL
(Foundation.URL
)或NSDate
(Foundation.Date
)导致具有名称的方法中的运行时崩溃 像bridgeFromObjectiveC
;在其他情况下,它可能导致崩溃或 用户代码中的未定义行为。如果你确定了这种方法,请 在bugreport.apple.com上提交报告。作为解决方法,添加一个 Objective-C中的蹦床功能具有正确的可空性 注释。例如,以下功能将允许您 呼叫FileManager
'enumerator(at:includingPropertiesForKeys:options:errorHandler:)
带有错误处理程序的方法,该处理程序接受nil
个网址:
static inline NSDirectoryEnumerator<NSURL *> * _Nullable
fileManagerEnumeratorAtURL(NSFileManager *fileManager, NSURL * _Nonnull url, NSArray<NSURLResourceKey> * _Nullable keys, NSDirectoryEnumerationOptions options, BOOL (^ _Nullable errorHandler)(NSURL * _Nullable errorURL, NSError * _Nonnull error)) {
return [fileManager enumeratorAtURL:url includingPropertiesForKeys:keys options:options errorHandler:^(NSURL * _Nonnull errorURL, NSError * _Nonnull error) {
return errorHandler(errorURL, error);
}];
}
此功能可以包含在您的桥接标题中(适用于应用或 测试目标)或伞头(用于框架目标)。 (27749845)
采取的步骤:
1)将新的.m文件添加到名为DirectoryEnumeratorGlue.m的项目中。当你添加它时,Xcode会问你是否希望它为你创建一个桥接标题,说是。将以下内容放在DirectoryEnumeratorGlue.m中:
NSDirectoryEnumerator<NSURL *> * _Nullable
fileManagerEnumeratorAtURL(NSFileManager * _Nonnull fileManager, NSURL * _Nonnull url, NSArray<NSURLResourceKey> * _Nullable keys, NSDirectoryEnumerationOptions options, BOOL (^ _Nullable errorHandler)(NSURL * _Nullable errorURL, NSError * _Nonnull error)) {
return [fileManager enumeratorAtURL:url includingPropertiesForKeys:keys options:options errorHandler:^(NSURL * _Nonnull errorURL, NSError * _Nonnull error) {
return errorHandler(errorURL, error);
}];
}
2)将新的.h文件添加到项目中,名为DirectoryEnumeratorGlue.h。将以下内容放在DirectoryEnumeratorGlue.h中:
extern NSDirectoryEnumerator<NSURL *> * _Nullable
fileManagerEnumeratorAtURL(NSFileManager * _Nonnull fileManager, NSURL * _Nonnull url, NSArray<NSURLResourceKey> * _Nullable keys, NSDirectoryEnumerationOptions options, BOOL (^ _Nullable errorHandler)(NSURL * _Nullable errorURL, NSError * _Nonnull error));
3)将以下内容添加到您的桥接标题中:
#import <Foundation/Foundation.h>
#import "DirectoryEnumeratorGlue.h"
4)用你喜欢的方式替换你在Swift调用中对FileManager.default.enumerator的调用:
let enumerator = fileManagerEnumeratorAtURL(FileManager.default, url, [], [], {
(errorURL, error) in
return true
})