Querying imported files and folders on iOS using NSMetadataQuery

Hi all,

I’m trying to use NSMetadataQuery on iOS to track changes to folders users have imported from elsewhere but, no matter what I try, I get no results.

Following the documentation for searching file metadata with NSMetadataQuery, I’m creating a live query (albeit in Swift) and listening for […]QueryDidFinishGathering and […]QueryDidUpdate. The former fires, with no results, and the latter never fires.

I’ve also tried following the Synchronizing Documents in the iCloud Environment example, adding the appropriate Ubiquity keys to my Info.plist and .entitlements file, with no change.

I’m importing files and folders using SwiftUI’s View.fileImporter(isPresented:allowedContentTypes:allowsMultipleSelection:onCompletion:), but can’t see how I might security-scope the NSMetadataQuery’s execution (if that’s even a thing?).

My test project is on GitHub, but the main parts are below…

My query method:

extension NSMetadataQueryUbiquitousExternalDocumentsTestApp {
    func findAccessibleFiles() {
        query.stop()
        fileMonitor?.cancel()


        fileMonitor = Publishers.MergeMany(
            [
                .NSMetadataQueryDidFinishGathering,
                .NSMetadataQueryDidUpdate
            ].map { NotificationCenter.default.publisher(for: $0) }
        )
            .receive(on: DispatchQueue.main)
            .sink { notification in
                query.disableUpdates()
                defer { query.enableUpdates() }


                foundItems = query.results as! [NSMetadataItem]
                print("Query posted \(notification.name.rawValue) with results: \(query.results)")
            }


        query.searchScopes = [
            NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope
        ]
        query.predicate = NSPredicate(
            format: "%K LIKE %@",
            argumentArray: [NSMetadataItemFSNameKey, "*"]
        )
        query.sortDescriptors = [
            NSSortDescriptor(key: NSMetadataItemFSNameKey, ascending: true)
        ]


        if query.start() {
            print("Query started")
        } else {
            print("Query didn't start for some reason")
        }
    }
}

Info.plist:

[…]
<key>NSUbiquitousContainers</key>
  <dict>
    <key>iCloud.com.stevemarshall.AnnotateML</key>
		<dict>
			<key>NSUbiquitousContainerIsDocumentScopePublic</key>
			<true/>
			<key>NSUbiquitousContainerName</key>
			<string>AnnotateML</string>
			<key>NSUbiquitousContainerSupportedFolderLevels</key>
			<string>ANY</string>
		</dict>
	</dict>
[…]
Answered by SteveMarshall in 687981022

I eventually raised a TSI for this, and Developer Technical Support indicated that I should file a bug with NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope “since it doesn’t behave as documented”. I've filed that as FB9631965.

In the mean-time, I've discovered that NSFilePresenter's documentation describes it as “The interface […] to inform an object […] about changes to that file”, and allows us to monitor imported directories for changes! 🎉

It does, however, have some decade-old bugs that mean the only subitem-related method that actually works consistently is presentedSubitemDidChange(at:). It's a bit of a blunt instrument, but it'll do for my use case.

Accepted Answer

I eventually raised a TSI for this, and Developer Technical Support indicated that I should file a bug with NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope “since it doesn’t behave as documented”. I've filed that as FB9631965.

In the mean-time, I've discovered that NSFilePresenter's documentation describes it as “The interface […] to inform an object […] about changes to that file”, and allows us to monitor imported directories for changes! 🎉

It does, however, have some decade-old bugs that mean the only subitem-related method that actually works consistently is presentedSubitemDidChange(at:). It's a bit of a blunt instrument, but it'll do for my use case.

I'm having the exact same issue.

Any imported files with SwiftUI's fileImporter are not included in the result of the NSMetadataQuery. (Yes, NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope is included in the search scope.)

Have you resolved the issue eventually?

Same problem here. In .fileImporter I even call startAccessingSecurityScopedResource() and am able to read the file in. But afterwards NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope doesn't find the file when searching for it's name with NSMetadataItemFSNameKey.

iOS 17.5.1 (21F90)

Querying imported files and folders on iOS using NSMetadataQuery
 
 
Q