iOS - Google Drive Provider doesn’t update when overwritten later, but works after opening the file

I’m seeing odd behavior with the Google Drive File Provider on iOS/iPadOS when using only the system file APIs.

For this feature, I cannot use the Google Drive REST API or SDK. The app must treat Google Drive just like any other location in the Files app and rely strictly on:

  • UIDocumentPickerViewController

  • security-scoped URLs

  • NSFileCoordinator

The goal is to let a user save a plain text file into Google Drive on an iPad, then continue overwriting that same file (for Save / autosave).Minimal test app
To isolate the issue, I built a small test app:

  • SwiftUI front end with a TextEditor and three buttons: Open, Save As, Save.

  • A FileSystem service that uses UIKit’s UIDocumentPickerViewController underneath.

The operations are:

Open

UIDocumentPickerViewController(

forOpeningContentTypes: [.plainText],

asCopy: false

)

The user chooses an existing .txt file from the Files UI (including Google Drive). I then:

  • Call startAccessingSecurityScopedResource() on the URL.

  • Use NSFileCoordinator.coordinate(readingItemAt:) to read the data.

  • Store that URL as the “current file” for later Save.

Save As
To “Save As”, I first write the current text to a temporary file in the app’s sandbox. Then I present:

UIDocumentPickerViewController(

forExporting: [tempURL],

asCopy:true

)

The user chooses a destination (e.g., a folder in Google Drive), and the system copies the temp file there. I capture the URL returned by the picker for debugging and, originally, as the “current file”.

Save (overwrite)

func saveCurrentFile(text: String, completion: @escaping (Result<Void, Error>) -> Void) {

guard let url = currentFileURL else {

completion(.failure(MyError.noCurrentFile))

return

}

guard url.startAccessingSecurityScopedResource() else {

completion(.failure(MyError.securityScopeFailed))

return

}

defer { url.stopAccessingSecurityScopedResource() }

let data = text.data(using: .utf8) ?? Data()

let coordinator = NSFileCoordinator(filePresenter: nil)

var coordError: NSError?

var writeError: Error?

coordinator.coordinate(

writingItemAt: url,

options: .forReplacing,

error: &coordError

) { coordinatedURL in

do {

try data.write(to: coordinatedURL, options: .atomic)

} catch {

writeError = error

}

}

if let error = writeError ?? coordError {

completion(.failure(error))

} else {

completion(.success(()))

}

}

Reads for Open use the same pattern with coordinate(readingItemAt:).

Behavior with local storage and iCloud Drive
With this setup:

  • Saving to On My iPad works exactly as expected.

  • “Save As → Save” creates the file and then overwrites it correctly.

  • Saving to iCloud Drive also works.

  • Both “Save As → Save” and “Open → Save” reliably update the same file.

So the pattern (document picker + security-scoped URL + NSFileCoordinator) is behaving correctly for local and iCloud.

Behavior with Google Drive

Things change when the target is Google Drive (Google Drive iOS app installed and exposed as a File Provider in the Files app).

Case 1: Open → Save
If I:

  1. Use Open to select an existing text file from Google Drive,

  2. Edit the text, and

  3. Press Save (calling the code above),

then the file in Google Drive updates correctly. The contents change as expected, and there are no errors from NSFileCoordinator.

So files obtained through UIDocumentPickerViewController(forOpeningContentTypes:asCopy:) behave as “live” editable documents.

Case 2: Save As → Save
If I:

  1. Enter some text,

  2. Use Save As to create a new file in Google Drive via UIDocumentPickerViewController(forExporting:asCopy:),

  3. Confirm that the file appears in Google Drive with the correct initial content,

  4. Change the text in the app, and

  5. Press Save,

then the coordinated write reports success, but the visible contents of the file in Google Drive do not change. It looks like the overwrite never happened, even though from the app’s perspective everything succeeded.

The exact same Save logic does update the file immediately when that file was originally chosen via Open.Example URLs from Google Drive
Here’s a concrete example of the URLs involved. These are for what is logically the same document, but obtained in two different ways:

Save As - URL:

file:///private/var/mobile/Containers/Shared/AppGroup/3D1452DB-C494-4E2E-AFBA-B3EFA9127134/File%20Provider%20Storage/52759511/1764183970.661987/Example.txt

Open - URL:

file:///private/var/mobile/Containers/Shared/AppGroup/3D1452DB-C494-4E2E-AFBA-B3EFA9127134/File%20Provider%20Storage/52759511/1yrsv8rN37GHl4AT3iLKry9FyIBemuqTX/Example.txt

Important constraint
In this feature, I cannot use the Google Drive REST API or SDK to, for example, resolve the real file ID and update it over HTTP.
I have to treat Google Drive like any other Files location and use only:

  • UIDocumentPickerViewController

  • security-scoped URLs returned by the picker

  • NSFileCoordinator for reading and writing

So the only information I have is the file URLs that the File Provider gives me.

Questions

Given all of the above, I’m trying to understand how this is supposed to work from the Google Drive side.

  • Is it expected that the URL returned from UIDocumentPickerViewController(forExporting:asCopy:) is effectively a one-time import source rather than the canonical document URL?

  • Is there any supported way, using only iOS file APIs (no Drive REST/SDK), to obtain a URL that is guaranteed to be the “real” Google Drive document after Save As, so that later overwrites are reflected in the Drive UI?

  • If the current behavior is “by design”, is the recommended pattern simply to treat Save As as export-only, and require the user to use Open (via forOpeningContentTypes) on that file before we rely on overwriting it?

Any clarification or guidance from the Drive / File Provider team, or from developers who have solved this with only iOS file system APIs, would be very appreciated.