Search code examples
iosswiftshareurl-schemeuiapplicationdelegate

How to handle a file shared from another app to my own iOS app?


I follow the previous question (Swift , Xcode, iOS - How to handle a file sent with 'Open in...' from another app to my own app) to integrate the function to Open in... in my app. I would like to, for example, use the Files app to select a document file (e.g., PDF) and open in my own application.

However, the following code in AppDelegate does not get called. I wonder if this is because of the Swift's version difference? Apple changed the source code to do this for iOS 15 or earlier versions? I would appreciate it if I could hear how to implement this in Swift 5, iOS 15.

func application(_ app: UIApplication,
                     open url: URL,
                          options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool{
    do {
        let data = try Data(contentsOf: url)
        // Do something with the file
        print ("File was shared!")
        print (data)
       
        
    } catch {
        print("Unable to load data: \(error)")
    }

    return true
}

I have already set up the app in the way that other apps can attempt to share a file. When trying to open in my app, my app opens up, but the above code does not seem to be called.


Solution

  • It looks like you followed the approach from this previous question only partially. In that case, the person had successfully implemented 2 of 3 parts of the solution for the custom URL scheme, so the answer only provided the 3rd part.

    As https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app says:

    To support a custom URL scheme:

    1. Define the format for your app’s URLs.
    2. Register your scheme so that the system directs appropriate URLs to your app.
    3. Handle the URLs that your app receives.

    Their question was:

    My app is being displayed in the available applications to which I can send the file to. My question is what happens after? When I choose to send it to my app it then switches over to my app and from there, I don't know how to receive the file and read it to extract its content.

    So they had already done steps 1 and 2 (so, their app was being displayed properly in the available applications, etc.).

    In your case, it sounds like you haven't done steps 1 and 2 yet?

    The other possibility is (also from https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) if you are using Scenes, note that there are additional entry points to your app.

    If your app has opted into Scenes, and your app is not running, the system delivers the URL to the scene(:willConnectTo:options:) delegate method after launch, and to scene(:openURLContexts:) when your app opens a URL while running or suspended in memory.

    Something like

    func scene(_ scene: UIScene, 
           willConnectTo session: UISceneSession, 
           options connectionOptions: UIScene.ConnectionOptions) {
    
    // Determine who sent the URL.
    if let urlContext = connectionOptions.urlContexts.first {
    
        let sendingAppID = urlContext.options.sourceApplication
        let url = urlContext.url
        print("source application = \(sendingAppID ?? "Unknown")")
        print("url = \(url)")
    
        // Process the URL similarly to the UIApplicationDelegate example.
    }
    
    /*
     *
     */
    }
    

    and as the Apple docs say, for the case the app is in the background, then implement something like

    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>){
            let url = URLContexts.first?.url
            print("url = \(url)")
    
        // Process the URL similarly to the UIApplicationDelegate example.
    }