2016-11-13 47 views
0

爲了避免已知的錯誤,我需要在枚舉目錄之前知道,如果用戶可以讀取它。如何知道用戶是否可以快速讀取目錄的內容

如何在swift(最新版本,使用Xcode和MAC OS最新版本)中執行此操作?

更多信息: 試圖在swift中枚舉目錄會導致應用程序崩潰,如果用戶無法訪問它。無法捕獲錯誤以防止崩潰,但只有在用戶無法訪問目錄時纔會發生。所以,事先知道目錄是否可以被讀取(如此列舉)將有助於防止崩潰。

可變現代碼:

有這個例子:https://bugs.swift.org/browse/SR-2872通過蒂莫西·伍德

而且這個例子中報道:http://prod.lists.apple.com/archives/cocoa-dev/2016/Oct/msg00166.html通過讓瑞士

+0

你能展示可破解的代碼嗎? – matt

+0

@matt好吧,這是一個已知的bug。可支付代碼中沒有任何東西可以回答這個問題。沒有必要downvote。這沒有幫助。但是,這個問題的答案(即如何避免枚舉不可訪問的文件夾)可以幫助其他人。 – Adeline

+0

看到導致崩潰的代碼仍然很有幫助,並且可能引用了您正在討論的錯誤。 (你不知道這是否是啞光投影,順便說一句) –

回答

1

一種解決方法報告這個錯誤是在Xcode 8.1的release notes中提供。引用的發行說明:

SDK中的一些目標C的方法可能會錯誤地註釋或 假設類型是nonnull而非nullable。甲類型夫特 將其視爲一個結構,如NSURLFoundation.URL)或NSDateFoundation.Date),導致在方法的運行時間的碰撞與名稱 像bridgeFromObjectiveC;在其他情況下,它可能會導致用戶代碼中的未定義行爲崩潰或不可用。如果您確定了這樣一種方法,請 在bugreport.apple.com上提交報告。解決方法是,在Objective-C中添加一個 蹦牀函數,註釋的正確可空性爲 。例如,下面的函數可以讓你 通話 FileManagerenumerator(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)更換呼叫FileManager.default.enumerator在您電話斯威夫特像這樣的東西:

let enumerator = fileManagerEnumeratorAtURL(FileManager.default, url, [], [], { 
     (errorURL, error) in 
     return true 
    }) 
+0

謝謝你真正有用的答案。我很高興仍然有「低代表人」願意提供幫助。我擔心「老人們」在永恆的「代碼在哪裏」迷失了方向? /「你試過什麼?」/「你想做什麼?」追求,直到他們盲目地問這個問題,即使不相關。回到話題:所以,我應該在我的代碼中添加這一行?但是哪裏?我的應用程序只有快捷方式,沒有橋接頭。 – Adeline

+0

我添加了將膠水代碼添加到項目的說明,希望有所幫助。 –

+0

這很完美。非常感謝你的幫助。 – Adeline

相關問題