NSMetadataQuery找不到NSFileWrapper文件夹包,只找到文件(但它们在那里)

时间:2013-02-18 16:15:07

标签: cocoa-touch nspredicate icloud uidocument nsfilewrapper

我有一个奇怪的问题,我似乎无法自己解决。任何帮助或想法都表示赞赏。

问题:

  • NSMetadataQuery查找普通文件(如test.txt),但没有找到filewrapper bundle(myWrapperDocument.pro)
  • 但是,NSFileManager会在我的ubiquity容器中找到所有文件 - 所以文件就在那里,但NSMetadataQuery找不到它们!

事实:

  • 使用NSFileWrappers的基于UIDocument的应用
  • 共享Ubiquity容器(适用于iOS和桌面应用)
  • 适用于Mac OS
  • 在我的iPad Mini以及我的iPhone 4S和iPhone 3GS(运行iOS6和iOS5)上完美运行
  • 不能在我的iPad1上运行,也不适用于我的大多数Beta测试版设备(运行iOS5或6的iPad 1,2和3)

到目前为止我做了什么:

  • 研究过WWDC12 UIDocument& iCloud示例(CloudNotes.xcodeproj)
  • 在Apple的开发论坛上学习了几个小时,不幸的是没有运气
  • 测试了许多不同的谓词,检查了权利和文档设置(因此系统知道它不是文件夹,而是文档包)
  • 清除并重置Ubiquity容器

相关代码:

权利应该是正确的; Info.plist文档设置(我认为文档类型已正确注册)

<key>CFBundleDocumentTypes</key>
    <array>
  <dict>
      <key>CFBundleTypeExtensions</key>
      <array>
        <string>pro</string>
      </array>
      <key>CFBundleTypeName</key>
      <string>Prowriting Sketch</string>
      <key>LSItemContentTypes</key>
      <array>
        <string>de.ac.prowriting.sketch</string>
      </array>
      <key>LSTypeIsPackage</key>
      <true/>
  </dict>

  …

  <key>UTExportedTypeDeclarations</key>
    <array>
    <dict>
      <key>CFBundleTypeExtensions</key>
      <array>
        <string>pro</string>
      </array>
      <key>LSTypeIsPackage</key>
      <true/>
      <key>UTTypeConformsTo</key>
      <array>
        <string>com.apple.package</string>
      </array>
      <key>UTTypeDescription</key>
      <string>Prowriting Sketch</string>
      <key>UTTypeIdentifier</key>
      <string>de.ac.prowriting.sketch</string>
    </dict>

ubiquity容器和iCloud文档url都很好,这就是我设置查询的方式:

- (void)startMetadataQuery {
  // ...
  [self.query setSearchScopes:@[NSMetadataQueryUbiquitousDocumentsScope]];

  // search for all .pro documents, also tried other predicates, see below
  NSString *predicate = [NSString stringWithFormat:@"%K like '*'"];
  [self.query setPredicate:[NSPredicate predicateWithFormat:predicate, NSMetadataItemFSNameKey]];

  // register observer (...)
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishMetadataQuery:) name:NSMetadataQueryDidFinishGatheringNotification object:nil];

  [self.query startQuery];
}

- (void)didFinishMetadataQuery:(NSNotification*)notification {
    [self.query disableUpdates];
    NSLog(@"+++ found %i results: \n%@", self.query.resultCount, self.query.results);
    NSLog(@"+++ Results in iCloud folder: %i", [self.fileManager contentsOfDirectoryAtPath:self.iCloudDocumentsFolder.path error:nil].count);
}

真正奇怪的是,查询只返回一个文件“test.txt”,但其他文件仍未检测到。但是从日志中可以看出,容器有84个.pro文件(全部称为“something.pro”),但查询只找到一个“test.txt”。

不幸的是,使用NSFileManager访问这些文件不是一种选择,因为我似乎没有权限阅读这些文件。我不认为我的容器损坏了,因为这个问题也发生在我的beta测试仪设备的全新安装上?

2013-02-18 +++ found 1 results: ("<NSMetadataItem: 0x3ac390> /private/var/mobile/Library/Mobile Documents/ABCD123456~de~ac~prowriting/Documents/test.txt")
2013-02-18 +++ Results in iCloud folder: 84

我认为这是谓词,但是:

@"%K like '*.pro*'"                // returns nothing
@"%%K like '*.*'"                  // returns only the test.txt file
@"%%K like '*'"                    // returns only the test.txt file
@"%K LIKE *"                       // returns only the test.txt file
@"NSMetadataItemFSNameKey == '*'"  // returns only the test.txt file

我真的不知道该怎么办了。 最奇怪的是,它在某些设备上工作,而在其他设备上根本不工作。

我会非常感谢有关此问题的任何暗示。非常感谢!

2 个答案:

答案 0 :(得分:1)

奇怪的是,我不得不从info.plist文件中 删除 LSItemContentTypes 设置:

<key>LSItemContentTypes</key>
  <array>
    <string>de.ac.prowriting.sketch</string>
  </array>

此设置是我导出的自定义UTI filewrapper文件类型无法正确识别为文件但被解释为文件夹的原因。 NSMetadataQuery不查询文件夹,这就是为什么它找不到我的任何文件。

不幸的是,我还有一个Mac应用程序,我的自定义文件类型在桌面上正确注册,影响了Mobile Documents iCloud文件夹;所以这就是为什么它适用于我的大部分设备,而不是我的测试人员。

答案 1 :(得分:1)

不是搜索文件名谓词,而是使用UTI类型树谓词格式。

我已使用以下命令返回给定文件网址中的所有文件,文件夹,包和包:

NSMetadataQuery *query = [NSMetadataQuery new];
[query setSearchScopes:@[url]];

NSPredicate *filePredicate = [NSPredicate predicateWithFormat:@"kMDItemContentTypeTree = %@", kUTTypeData];
NSPredicate *bundlePredicate = [NSPredicate predicateWithFormat:@"kMDItemContentTypeTree = %@", kUTTypeBundle];
NSPredicate *packagePredicate = [NSPredicate predicateWithFormat:@"kMDItemContentTypeTree = %@", kUTTypePackage];
NSPredicate *folderPredicate = [NSPredicate predicateWithFormat:@"kMDItemContentTypeTree = %@", kUTTypeFolder];

NSPredicate *searchPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[filePredicate, bundlePredicate, packagePredicate, folderPredicate]];

[query setPredicate:searchPredicate];