You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Swift在iOS应用中接收共享数据并注册为接收方?

How to Enable Your iOS App to Receive Shared Data (Images, Files, etc.)

Great question! Getting your iOS app to show up in the share sheet and handle incoming data like images involves two core steps: registering your app as a share target and processing the received data. Let’s break this down with concrete steps and code examples.

The modern, seamless way to accept shared data is using a Share Extension. This lets your app appear in the share sheet without needing to be open first, and runs in a separate process to handle the data.

Add the Extension to Your Project

  1. Open your Xcode project.
  2. Go to File > New > Target.
  3. Under "iOS", select Share Extension and click "Next".
  4. Name your extension (e.g., "ImageShareExtension") and make sure the "Embed in Application" dropdown selects your main app target. Click "Finish".

Configure the Extension to Accept Images

Next, tell the extension what types of data it can handle by editing its Info.plist:

  1. Open the Info.plist for your Share Extension.
  2. Navigate to NSExtension > NSExtensionAttributes > NSExtensionActivationRule.
  3. Replace the default string with a dictionary that specifies supported types. For images, add:
    • NSExtensionActivationSupportsImageWithMaxCount set to 1 (or higher if you want to accept multiple images).
    • Optional: Add other keys like NSExtensionActivationSupportsText if you want to accept text too.

Alternatively, use a predicate for more flexibility (e.g., accept any image type):

<key>NSExtensionActivationRule</key>
<string>SUBQUERY (extensionItems, $extensionItem, SUBQUERY ($extensionItem.attachments, $attachment, ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image").@count &gt; 0).@count &gt; 0</string>

Step 2: Handle Incoming Data in the Share Extension

The Share Extension’s main logic lives in the ShareViewController.swift file (a subclass of SLComposeServiceViewController). Here’s how to retrieve the shared image and pass it to your main app:

import UIKit
import Social
import MobileCoreServices

class ShareViewController: SLComposeServiceViewController {

    override func didSelectPost() {
        guard let inputItems = extensionContext?.inputItems as? [NSExtensionItem] else {
            finishProcessing()
            return
        }

        // Loop through incoming items to find image attachments
        for item in inputItems {
            guard let attachments = item.attachments as? [NSItemProvider] else { continue }
            
            for attachment in attachments {
                if attachment.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
                    // Load the image from the attachment
                    attachment.loadObject(ofClass: UIImage.self) { [weak self] (result, error) in
                        guard let self = self, let image = result as? UIImage else {
                            self?.finishProcessing()
                            return
                        }

                        // Pass the image to your main app using an App Group
                        self.saveImageToAppGroup(image: image)
                        
                        // Notify the main app that new data is available
                        self.notifyMainApp()
                        
                        self.finishProcessing()
                    }
                    return // Exit after processing the first image (adjust if handling multiple)
                }
            }
        }

        finishProcessing()
    }

    private func saveImageToAppGroup(image: UIImage) {
        guard let imageData = image.pngData(),
              let groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "com.yourcompany.yourappgroup") else {
            return
        }
        
        let fileURL = groupURL.appendingPathComponent("shared_image.png")
        try? imageData.write(to: fileURL)
    }

    private func notifyMainApp() {
        UserDefaults(suiteName: "com.yourcompany.yourappgroup")?.set(true, forKey: "has_shared_image")
    }

    private func finishProcessing() {
        extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
    }
}

Set Up App Groups for Data Sharing

Since extensions run in a separate process, you need an App Group to share data between the extension and your main app:

  1. Go to your main app target in Xcode.
  2. Select Signing & Capabilities > Add Capability > App Groups.
  3. Add a group identifier (e.g., com.yourcompany.yourappgroup).
  4. Repeat this step for your Share Extension target to enable the same App Group.

Step 3: Receive Data in Your Main App

Now, your main app needs to check for shared data when it launches or becomes active. Add this logic to your SceneDelegate.swift (or AppDelegate.swift if you’re not using scenes):

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func sceneDidBecomeActive(_ scene: UIScene) {
        checkForSharedImage()
    }

    private func checkForSharedImage() {
        let defaults = UserDefaults(suiteName: "com.yourcompany.yourappgroup")
        guard defaults?.bool(forKey: "has_shared_image") == true else { return }
        
        guard let groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "com.yourcompany.yourappgroup"),
              let imageData = try? Data(contentsOf: groupURL.appendingPathComponent("shared_image.png")),
              let sharedImage = UIImage(data: imageData) else {
            defaults?.set(false, forKey: "has_shared_image")
            return
        }

        // Do something with the image (e.g., display it, save to your app's storage)
        print("Received shared image: \(sharedImage.size)")
        
        // Clean up: reset the flag and delete the temporary file
        defaults?.set(false, forKey: "has_shared_image")
        try? FileManager.default.removeItem(at: groupURL.appendingPathComponent("shared_image.png"))
    }
}

Alternative: Accept Files Directly in the Main App

If you prefer your main app to open immediately when a user shares a file, you can skip the extension and configure your app to accept specific file types via its Info.plist:

  1. Open your main app’s Info.plist.
  2. Add the CFBundleDocumentTypes array:
<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>Image Files</string>
        <key>LSHandlerRank</key>
        <string>Alternate</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.image</string>
        </array>
    </dict>
</array>

Then, handle the incoming file URL in your SceneDelegate or AppDelegate:

// In SceneDelegate
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let fileURL = URLContexts.first?.url, fileURL.isFileURL else { return }
    
    do {
        let imageData = try Data(contentsOf: fileURL)
        if let image = UIImage(data: imageData) {
            // Process the image
        }
    } catch {
        print("Error loading shared file: \(error.localizedDescription)")
    }
}

Testing the Flow

  1. Run your Share Extension target (select it from the scheme dropdown in Xcode).
  2. Choose an app to test with (e.g., Photos).
  3. Select an image, tap the share button, and your extension should appear in the list.
  4. Tap your extension, then "Post"—your main app will receive the image when it’s opened or activated.

内容的提问来源于stack exchange,提问作者David J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:35:49