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