2

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

问题:

  • NSMetadataQuery 找到普通文件(如 test.txt)但没有文件包装器包(myWrapperDocument.pro)
  • 但是,NSFileManager 会在我的 ubiquity 容器中找到所有文件——所以这些文件都在那里,但 NSMetadataQuery 没有找到它们!

事实:

  • 使用 NSFileWrappers 的基于 UIDocument 的应用程序
  • Shared Ubiquity Container(适用于 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

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

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

4

2 回答 2

2

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

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

此设置是为什么我导出的自定义 UTI 文件包装器文件类型未正确识别为文件,而是解释为文件夹的原因。NSMetadataQuery 不查询文件夹,这就是它没有找到我的任何文件的原因。

不幸的是,我还有一个 Mac 应用程序,并且我的自定义文件类型在桌面上正确注册,影响了 Mobile Documents iCloud 文件夹;所以这就是为什么它可以在我的大多数设备上运行,但在我的测试人员中没有。

于 2013-02-21T02:42:47.670 回答
1

与其搜索文件名谓词,不如使用 UTI 类型的树谓词格式。

我使用以下内容返回给定文件 URL 处的所有文件、文件夹、包和捆绑包:

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];
于 2015-02-18T11:27:02.350 回答