iOS 系統(tǒng)提供了文件共享支持
當(dāng)手機通過數(shù)據(jù)線連接到 Mac 的 iTunes 時, 可以在 iTunes 將電腦上的文件傳輸?shù)?App 的沙盒目錄當(dāng)中. 為 App 添加離線數(shù)據(jù). 也可以將 App 沙盒目錄下保存的文件通過 iTunes 導(dǎo)出到電腦當(dāng)中.
官方文檔中的描述
在 "iOS 9.3 Documentation" > "General" > "Guides" > "iOS Technology Overview" 文章中, 對 iOS 系統(tǒng)中相關(guān)技術(shù)做了大致的介紹. 其中 Core Services 層里面, 可以查找到 File-Sharing Support的相關(guān)說明.

以下是官方文檔的原始描述
File-sharing support lets apps make user data files available in iTunes 9.1 and later. An app that declares its support for file sharing makes the contents of its /Documents directory available to the user. The user can then move files in and out of this directory as needed from iTunes. This feature does not allow your app to share files with other apps on the same device; that behavior requires the pasteboard or a document interaction controller object.
To enable file sharing for your app, do the following:
Add the UIFileSharingEnabled key to your app’s Info.plist file, and set the value of the key to YES.
Put whatever files you want to share in your app’s Documents directory.
When the device is plugged into the user’s computer, iTunes displays a File Sharing section in the Apps tab of the selected device.
The user can add files to this directory or move files to the desktop.
Apps that support file sharing should be able to recognize when files have been added to the Documents directory and respond appropriately. For example, your app might make the contents of any new files available from its interface. You should never present the user with the list of files in this directory and ask them to decide what to do with those files.
For additional information about the UIFileSharingEnabled key, see Information Property List Key Reference.
簡單總結(jié)一下:
File-sharing support是在 iTunes9.1 及之后的版本開始支持的.
該功能支持將 App 沙盒目錄下 Document 文件夾中的內(nèi)容進行共享, 即可以通過 iTunes 軟件對 App 的 Document 文件夾的內(nèi)容進行操作, 比如添加,刪除, 導(dǎo)出 Document 中的文件.
File-sharing support并不支持與該設(shè)備上其它 App 進行文件共享
支持文件共享的 App 應(yīng)該識別添加到 Document 目錄中的文件并做出適當(dāng)?shù)捻憫?yīng). 比如當(dāng)有新的文件可用時, App 可以在界面上顯示新的內(nèi)容, 但不應(yīng)該向用戶展示新添加文件列表并詢問用戶對該文件做出什么操作.
使用方式:
- 其實開發(fā)當(dāng)中需要做的配置就一步, 其它都是引導(dǎo)用戶怎么去使用文件共享功能
在 Info.plist 文件中添加 UIFileSharingEnabled 這個Key, 并設(shè)置該值為 YES 即可 -
在填寫完 UIFileSharingEnabled 并回車后, 發(fā)現(xiàn)會自動更正為 Application supports iTunes file sharing , 將值設(shè)置為 YES 即可
image -
引導(dǎo)用戶如何使用 iTunes 與 App 進行文件共享
當(dāng)設(shè)備連接到用戶電腦時, iTunes會在選中設(shè)備的Apps標(biāo)簽頁顯示文件共享的會話
可以添加, 復(fù)制, 刪除指定App的沙盒目錄中的文件, 最后執(zhí)行"Sync"按鈕進行數(shù)據(jù)同步
監(jiān)聽Document目錄的文件改動
使用GCD 與 file descriptor 實現(xiàn)對文件夾內(nèi)容的修改進行監(jiān)聽, 實現(xiàn)的關(guān)鍵代碼如下
// 這里邊需要定義兩個成員變量
{
dispatch_queue_t _zDispatchQueue;
dispatch_source_t _zSource;
}
// 開始監(jiān)聽Document目錄文件改動, 一旦發(fā)生修改則發(fā)出一個名為ZFileChangedNotification的通知
- (void)startMonitoringDocumentAsynchronous
{
// 獲取沙盒的Document目錄
NSString *docuPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
[self startMonitoringDirectory:docuPath];
}
// 監(jiān)聽指定目錄的文件改動
- (void)startMonitoringDirectory:(NSString *)directoryPath
{
// 創(chuàng)建 file descriptor (需要將NSString轉(zhuǎn)換成C語言的字符串)
// open() 函數(shù)會建立 file 與 file descriptor 之間的連接
int filedes = open([directoryPath cStringUsingEncoding:NSASCIIStringEncoding], O_EVTONLY);
// 創(chuàng)建 dispatch queue, 當(dāng)文件改變事件發(fā)生時會發(fā)送到該 queue
_zDispatchQueue = dispatch_queue_create("ZFileMonitorQueue", 0);
// 創(chuàng)建 GCD source. 將用于監(jiān)聽 file descriptor 來判斷是否有文件寫入操作
_zSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, filedes, DISPATCH_VNODE_WRITE, _zDispatchQueue);
// 當(dāng)文件發(fā)生改變時會調(diào)用該 block
dispatch_source_set_event_handler(_zSource, ^{
// 在文件發(fā)生改變時發(fā)出通知
// 在子線程發(fā)送通知, 這個通知觸發(fā)的方法會在子線程當(dāng)中執(zhí)行
[[NSNotificationCenter defaultCenter] postNotificationName:ZFileChangedNotification object:nil userInfo:nil];
});
// 當(dāng)文件監(jiān)聽停止時會調(diào)用該 block
dispatch_source_set_cancel_handler(_zSource, ^{
// 關(guān)閉文件監(jiān)聽時, 關(guān)閉該 file descriptor
close(filedes);
});
// 開始監(jiān)聽文件
dispatch_resume(_zSource);
}
// 停止監(jiān)聽指定目錄的文件改動
- (void)stopMonitoringDocument
{
dispatch_cancel(_zSource);
}
獲取Document目錄下的所有文件
這里邊DirectoryWatcher是做成一個單例的工具類, 具體代碼就不全部寫上了. 關(guān)鍵的實現(xiàn)代碼也比較簡單. 只要監(jiān)聽ZFileChangedNotification并做出相應(yīng)處理即可
- (void)viewDidLoad
{
[super viewDidLoad];
// 監(jiān)聽Document目錄的文件改動
[[DirectoryWatcher defaultWatcher] startMonitoringDocumentAsynchronous];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fileChanageAction:) name:ZFileChangedNotification object:nil];
}
- (void)dealloc
{
// 取消監(jiān)聽Document目錄的文件改動
[[DirectoryWatcher defaultWatcher] stopMonitoringDocument];
[[NSNotificationCenter defaultCenter] removeObserver:ZFileChangedNotification];
}
- (void)fileChanageAction:(NSNotification *)notification
{
// ZFileChangedNotification 通知是在子線程中發(fā)出的, 因此通知關(guān)聯(lián)的方法會在子線程中執(zhí)行
NSLog(@"文件發(fā)生了改變, %@", [NSThread currentThread]);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSError *error;
// 獲取指定路徑對應(yīng)文件夾下的所有文件
NSArray <NSString *> *fileArray = [fileManager contentsOfDirectoryAtPath:filePath error:&error];
NSLog(@"%@", fileArray);
}


