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

iOS设备间通过AirDrop传输自定义文件类型的问题排查(涉及excludedActivityTypes配置)

Hey Pete, let's fix this AirDrop issue with your custom data type. The problem isn't actually with excludedActivityTypes (that's just for hiding unwanted sharing options, not adding support for new ones) — instead, we need to teach iOS how to recognize and handle your custom data, both in your app's configuration and how you package the data for sharing. Here's how to do it step by step:

Step 1: Package Your Custom Data Properly

AirDrop relies on recognized data types or file URLs to work correctly. Passing a raw NSMutableArray won't work because iOS has no idea what kind of data this is. You need to either:

  • Serialize your data into a file with your custom extension, or
  • Wrap the data in an NSItemProvider with your custom UTI (Uniform Type Identifier).

Option A: Save to a Temporary File (Most Reliable for AirDrop)

First, serialize your quizDataBase into Data, then save it to a temporary file with your custom extension:

// Serialize your custom data (adjust based on how you store quizDataBase)
guard let data = try? NSKeyedArchiver.archivedData(withRootObject: self.quizDataBase, requiringSecureCoding: false) else {
    print("Failed to serialize quiz data")
    return
}

// Create a temporary file with your custom extension (e.g., .quizdb)
let tempDirectory = NSTemporaryDirectory()
let tempFileURL = URL(fileURLWithPath: tempDirectory)
    .appendingPathComponent("QuizData.quizdb")

do {
    try data.write(to: tempFileURL)
} catch {
    print("Failed to write temp file: \(error.localizedDescription)")
    return
}

Option B: Use NSItemProvider (No File Needed)

If you don't want to create a file, wrap your data in an NSItemProvider and specify your custom UTI:

guard let data = try? NSKeyedArchiver.archivedData(withRootObject: self.quizDataBase, requiringSecureCoding: false) else {
    print("Failed to serialize quiz data")
    return
}

let itemProvider = NSItemProvider(
    item: data as NSSecureCoding?,
    typeIdentifier: "com.yourcompany.quizdatabase" // Replace with your actual UTI
)

Step 2: Configure Info.plist for Your Custom Type

iOS needs to know about your custom file type via Info.plist entries. You mentioned you've already declared the custom file — double-check these entries match your setup:

  1. Add UTExportedTypeDeclarations (declare your custom UTI):
    Add this array to Info.plist, replacing values with your type's details:

    <key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeIdentifier</key>
            <string>com.yourcompany.quizdatabase</string> <!-- Unique reverse-domain UTI -->
            <key>UTTypeDescription</key>
            <string>Quiz Database File</string> <!-- Human-readable description -->
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.data</string> <!-- Base type your data conforms to -->
            </array>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>quizdb</string> <!-- Your custom file extension -->
                </array>
            </dict>
        </dict>
    </array>
    
  2. Add CFBundleDocumentTypes (let iOS know your app handles this type):

    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Quiz Database</string>
            <key>CFBundleTypeRole</key>
            <string>Editor</string> <!-- Or "Viewer" if you only read -->
            <key>LSHandlerRank</key>
            <string>Owner</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.yourcompany.quizdatabase</string> <!-- Match your UTI -->
            </array>
        </dict>
    </array>
    

Step 3: Update Your UIActivityViewController Code

Now pass the packaged data (file URL or item provider) to the activity view controller:

For the Temporary File Approach:

let activityItems: [Any] = [tempFileURL]
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)

// Optional: Exclude unwanted activities (this is what excludedActivityTypes is for!)
controller.excludedActivityTypes = [.postToFacebook, .postToTwitter]

self.present(controller, animated: true) {
    // Clean up the temporary file after sharing completes
    try? FileManager.default.removeItem(at: tempFileURL)
}

For the NSItemProvider Approach:

let activityItems: [Any] = [itemProvider]
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
self.present(controller, animated: true)

Key Notes

  • excludedActivityTypes is not for adding support — it's only for hiding activities you don't want users to see. Your original issue was that iOS didn't recognize your data type, not that AirDrop was excluded.
  • Make sure the receiving app also has the same UTI declarations in its Info.plist, otherwise it won't be able to open the shared data.
  • If you're using NSKeyedArchiver, ensure your custom objects conform to NSCoding (or NSSecureCoding for better security).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 14:52:38