File Export from iOS - eventually import too

iOS 15 - iOS 26.x, SwiftUI, Xcode 26.1.1 (rewritten without links)

I’m attempting to add the capability to export a file from CoreData.

Since ShareLink requires iOS16+, I found an article showing how to create a UIKit wrapper for 'UIActivityViewController' This does work, but I end up with multiple files instead of one. How do I merge this into one file?

Note: I don’t think I want to write to the app’s document directory – rather I’d like to allow the user to export to iCloud. Eventually, I’d like to share a list of dates with descriptions and if someone puts a sensitive date in there – I don’t want it to be left in a directory. I would include a warning that the file that they export needs to be handled with care if there are any sensitive dates. Some might consider birthdays as private information, right?

I'd also like to be able to name the file - so far when the share sheet comes up, I select "Save to Files" and it uses a default name of text.txt

My next step is to be able to import a CSV file (roundtrip) - could you point me to resources for how to do that?

Answered by DTS Engineer in 880189022

No, you don't need to write the data as a file to your the app’s document directory. With UIActivityViewController, you can share a piece of text, as shown in the following code example

let text =  "This is a piece of text."
let activityViewController = UIActivityViewController(activityItems: [text], applicationActivities: nil)

With that, when activityViewController is presented, it shows the system-provided share UI that contains a Save to Files button, which allows you to save the text as a file to iCloud Drive. Tapping the button shows a UI that has a Save as field for you to input the file name for the taget file.

To import a file, consider using SwiftUI fileImporter.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

No, you don't need to write the data as a file to your the app’s document directory. With UIActivityViewController, you can share a piece of text, as shown in the following code example

let text =  "This is a piece of text."
let activityViewController = UIActivityViewController(activityItems: [text], applicationActivities: nil)

With that, when activityViewController is presented, it shows the system-provided share UI that contains a Save to Files button, which allows you to save the text as a file to iCloud Drive. Tapping the button shows a UI that has a Save as field for you to input the file name for the taget file.

To import a file, consider using SwiftUI fileImporter.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thanks for these answers, but I'm afraid I need a bit more help. How do you go about presenting the activityViewController? Could you show this in a small example app?

I had previously written this and it does share but it creates 2 files, and doesn't present any way to rename the file.

import SwiftUI
import UIKit

struct ContentView: View {
    @State private var showShareSheet = false
    @State private var textItem1 = ""
    @State private var textItem2 = ""
    
//    @State private var shareItems: [Any] = [
//      "Check out this file!",
//      URL(fileURLWithPath: FileManager.documentsDirectory.path()) // Replace with a real file URL
//    ]
    
var shareItems: [Any] {
    [   textItem1,
          textItem2
//          URL(fileURLWithPath: "TinySavedItems")
        ]
}
    var body: some View {
        VStack {
            TextField("enter text", text: $textItem1)
                .padding()
            TextField("enter text", text: $textItem2)
                .padding()
          
            Button("Share", systemImage: "square.and.arrow.up") {
              showShareSheet = true
            }
            .sheet(isPresented: $showShareSheet) {
                ActivityViewController(activityItems: shareItems)
            }
        }
    }
    
    struct ActivityViewController: UIViewControllerRepresentable {
        
        // Items to share (e.g., text, URLs, files)
        let activityItems: [Any]
        // Custom activities (optional)
        let applicationActivities: [UIActivity]? = nil
        // Completion handler (optional)
        @Environment(\.dismiss) var dismiss
        
        // Create the UIActivityViewController
        func makeUIViewController(context: Context) -> UIActivityViewController {
            
            let vc = UIActivityViewController(
                activityItems: activityItems,
                applicationActivities: applicationActivities
            )
            vc.excludedActivityTypes = [
                .postToFacebook, .postToTwitter
            ]
            // Handle completion (e.g., dismiss after sharing)
            vc.completionWithItemsHandler = { _, success, _, error in
                if success || error != nil {
                    dismiss() // Close the sheet after sharing
                }
            }
            return vc
        }
        func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {} //doesn't do anything but is required
    }
}

Your code that wraps UIActivityViewController with UIViewControllerRepresentable and presents it in SwiftUI looks good to me. I've tried running the code on my iOS simulator (iOS 26.2 23C54) and here is the behavior I see:

  • When sharing one single item, the code demonstrates the behavior as I described.

  • When sharing two items (by using var shareItems: [Any] { ["textItem1", "textItem1"] }), the Save as field isn't editable, and so there is indeed no way to specify the file names. Also, two files are generated, one for each item.

So it's not that the way you present UIActivityViewController has anything wrong; it's that UIActivityViewController doesn't allow you to specify the file names when sharing multiple items.

I don't see any way that can change the behavior because the UI of UIActivityViewController is system-provided. Please feel free to file a feedback report to request the feature you would like to have. For now, you might consider sharing one single item, if that is appropriate to your use case.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

It took me a little bit to realize that tapping on the "text" in the Share to Files interface provided a way to change the file name - when I share one item. In some online tutorials there was a way to set the full filename (like Export.csv) - but maybe that's only when writing to the app's file directory. Would you agree?

I can't really think of a clean way to be able to name 2 files in that interface - so I fully understand why that's not available - and therefore I don't plan to proceed to a feedback for this. I should be able to combine elements so that I'm only sharing 1 item in for my original request.

Could you clarify how DTS works now relative to these questions answered here on the forum? Since I did ask for a DTS - does this count as one? It doesn't matter to me right now because my dev account will renew soon.

Thanks so much!

In some online tutorials there was a way to set the full filename (like Export.csv)

In the case of sharing a file, you can give the file a name you choose. Here you are sharing a piece of data, and so the use casen is different.

Could you clarify how DTS works now relative to these questions answered here on the forum? Since I did ask for a DTS - does this count as one?

Apple's DTS has been providing our usual code level support in the forums as well as via email. We've also lifted the cap of 2 incidents per account per year so developers can ask questions as needed. As a result, other than the medium of communication, there’s really no difference in the support response we’ll provide.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

When I rename a file I can't seem to change the extension. For example: when I select the file and change to MyFile.csv - it writes MyFile.csv.txt is there any way to get rid of that .txt extension other than make the user delete it? I mean they could edit from .txt to .csv and macOS asks if they are sure - but I'd like to remove that step.

That might be worthy of a feedback...

File Export from iOS - eventually import too
 
 
Q