You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测iCloud/OneDrive目录中文件是onDisk还是onDemand状态?

判断iCloud/OneDrive按需文件是否已本地下载

在macOS里,iCloud或OneDrive这类特殊目录下的文件有两种状态:onDisk(本地存储) 和 onDemand(按需获取),Finder中会显示对应的云图标。现有一段Swift代码用于获取这类目录内容,需要判断文件是已经完整下载到本地,还是仅存在文件名占位。

原代码:

func getDirContent(){
  let startURL = URL(fileURLWithPath: "/Users/name/Library/Mobile Documents/iCloud~com~bbc~Pic/Documents")
   do
   { let enumerator = FileManager.default.enumerator(at: startURL,
                             includingPropertiesForKeys: [ .contentModificationDateKey, .fileSizeKey, .isRegularFileKey],
                                                options: [ .skipsHiddenFiles,
                                                           .skipsPackageDescendants],
                                           errorHandler: { (url, error) -> Bool in
                                                           print("directoryEnumerator error at \(url): ", error)
                                                           return true
                                                         }
     )!
     print("Level: \(enumerator.level)")
     
     for item in enumerator {
       
       let fileURL = item as! URL
       print("URL: >\(fileURL.absoluteString)<")
       let resourceValues = try fileURL.resourceValues(forKeys: Set([.creationDateKey, .isDirectoryKey, .fileSizeKey, .isRegularFileKey]))
       if (resourceValues.isRegularFile!) {
         // is this file on Disk or "on Demand"

         // if let size = resourceValues.fileSize {
         // do something ....
         // }
       }
     }
   } catch
   { print(error)
   }
}

解决方法

要判断文件状态,核心是通过URL的资源键读取对应状态值,区分iCloud和第三方云服务的文件:

  1. 添加状态判断的资源键:

    • 针对iCloud文件:使用isUbiquitousItemDownloadedKey
    • 针对OneDrive等第三方云文件:使用isDownloadedKey(macOS 10.15+支持)
  2. 修改代码实现判断:
    把这些资源键加入请求集合,然后通过可选绑定读取状态值,判断文件是否已本地下载。

修改后的代码:

func getDirContent(){
    let startURL = URL(fileURLWithPath: "/Users/name/Library/Mobile Documents/iCloud~com~bbc~Pic/Documents")
    do {
        // 新增用于判断下载状态的资源键
        let resourceKeys: Set<URLResourceKey> = [
            .creationDateKey, .isDirectoryKey, .fileSizeKey, .isRegularFileKey,
            .isUbiquitousItemDownloadedKey, .isDownloadedKey
        ]
        
        let enumerator = FileManager.default.enumerator(
            at: startURL,
            includingPropertiesForKeys: Array(resourceKeys),
            options: [.skipsHiddenFiles, .skipsPackageDescendants],
            errorHandler: { (url, error) -> Bool in
                print("directoryEnumerator error at \(url): ", error)
                return true
            }
        )!
        
        print("Level: \(enumerator.level)")
        
        for item in enumerator {
            guard let fileURL = item as? URL else { continue }
            print("URL: >\(fileURL.absoluteString)<")
            
            let resourceValues = try fileURL.resourceValues(forKeys: resourceKeys)
            guard let isRegularFile = resourceValues.isRegularFile, isRegularFile else { continue }
            
            // 检查iCloud文件状态
            if let isICloudDownloaded = resourceValues.isUbiquitousItemDownloaded {
                print("\(fileURL.lastPathComponent): \(isICloudDownloaded ? "已本地下载" : "仅按需存在")")
            }
            
            // 检查第三方云(如OneDrive)文件状态
            if let isThirdPartyDownloaded = resourceValues.isDownloaded {
                print("\(fileURL.lastPathComponent): \(isThirdPartyDownloaded ? "已本地下载" : "仅按需存在")")
            }
        }
    } catch {
        print(error)
    }
}

补充说明

  • isUbiquitousItemDownloadedKey是iCloud专属的判断键,返回true意味着文件已完整下载到本地,false则是仅显示文件名的占位文件。
  • isDownloadedKey是通用型键,适配大多数第三方云服务的按需文件,同样true代表本地已存储,false代表仅占位。
  • 非云按需文件对应的状态值会是nil,所以用可选绑定来安全读取,避免崩溃。

内容的提问来源于stack exchange,提问作者mica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:47:04