NSMetadataQuery does not find NSFileWrapper folder bundles, only files (but they're there)

时光怂恿深爱的人放手 提交于 2019-12-10 11:33:02

问题


I have a strange problem which I can't seem to solve on my own. Any help or thought is appreciated.

The problem:

  • NSMetadataQuery finds normal files (like test.txt) but no filewrapper bundle (myWrapperDocument.pro)
  • However, NSFileManager finds all files in my ubiquity container - so the files are there, but NSMetadataQuery doesn't find them!

The facts:

  • UIDocument based app using NSFileWrappers
  • Shared Ubiquity Container (for iOS and Desktop app)
  • Works perfect on Mac OS
  • Works perfect on my iPad Mini and my iPhone 4S and iPhone 3GS (running iOS6 and iOS5)
  • Doesn't work on my iPad1 nor on most of my beta tester's devices (iPads 1,2&3 running iOS5 or 6)

What I did so far:

  • Studied WWDC12 UIDocument & iCloud example (CloudNotes.xcodeproj)
  • Studied hours in Apple's dev forum and here, unfortunately without any luck
  • Tested many different predicates, checked the entitlements and the document setup (so the system knows, that it's not a folder, but a document bundle)
  • Clearing and resetting the Ubiquity container

The relevant code:

Entitlements should be correct; Info.plist document setup ( I think the document type has been registered correctly )

<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>

The ubiquity container and iCloud documents url are all fine, this is how I set up the query:

- (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);
}

The really strange thing is, that the query returns with just one file "test.txt", but the others remain undetected. But as you can see from the log, the container has 84 .pro files (all called "something.pro"), but the query only finds the one "test.txt".

Unfortunately accessing these files with NSFileManager isn't an option, as I don't seem to have the rights to read those. I don't think my container's corrupt as this issue also happens on fresh installations of my beta tester's devices?

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

I think it's the predicate, but:

@"%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

I really don't know what to do anymore. The most strange thing is, that it works on some devices while not working at all on other devices.

I would be super thankful for any hint on this issue. Thanks a lot!


回答1:


strangely enough, I had to remove the LSItemContentTypes setting from the info.plist file:

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

this setting was the reason, why my exported custom UTI filewrapper filetype was not recognized properly as file, but interpreted as folder. NSMetadataQuery does not query folders, that's why it didn't find any of my files.

Unfortunately I also have a Mac app and my custom filetype was registered correctly on the desktop affecting the Mobile Documents iCloud folder; so that was the reason why it worked on most of my devices, but on none of my testers.




回答2:


Rather than searching on a file-name predicate, use the UTI-type tree predicate format.

I've used the following to return all files, folders, packages and bundles at a given file 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];


来源:https://stackoverflow.com/questions/14940602/nsmetadataquery-does-not-find-nsfilewrapper-folder-bundles-only-files-but-they

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!