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

iOS同应用跨设备传递嵌套数组[[String]]的最优方案咨询

嘿,针对你要在两部iPhone的同一APP间传递嵌套数组的需求,我来帮你梳理下最优方案,先把你提到的两个组件的区别讲清楚,再一步步说实现步骤:

先搞懂 UIActivityViewController vs Share Extension 的区别

这俩组件的定位完全不同,适配的场景也不一样:

  • UIActivityViewController:这是系统提供的快速调用原生分享能力的组件,能直接在你的主APP内触发AirDrop、短信、邮件等分享通道,不需要额外创建扩展Target。它是「主动发起分享」的最佳选择,完美匹配你想要的“点击分享→发送→对方唤起APP加载”流程。
  • Share Extension:这是一个独立的扩展模块,作用是让其他APP能把内容分享到你的APP(比如用户在Safari里分享网页到你的APP)。它只能被动接收外部内容,没法主动发起分享,所以对你的需求来说,它不是发起端的解决方案,除非你还需要支持从其他APP导入数据。
适配你需求的最优方案:UIActivityViewController + AirDrop + 自定义UTI

这套方案完全贴合你的理想流程,而且实现起来简单高效,不需要自己造蓝牙传输的轮子(AirDrop本身就是基于蓝牙+WiFi的高效近场传输方案)。

第一步:把嵌套数组转成可传输的格式

嵌套数组[[String]]没法直接通过AirDrop传递,我们可以把它转成JSON格式——JSON能完美保留嵌套结构,序列化和解析都很方便。

示例代码:

let targetArray = [["John", "27", "First", "Castle"],["Tom", "25", "Second", "Boat"]]

// 转成JSON Data
do {
    let jsonData = try JSONSerialization.data(withJSONObject: targetArray, options: .prettyPrinted)
    // 后续用这个jsonData作为分享内容
} catch {
    print("JSON转换失败:\(error.localizedDescription)")
}

第二步:用UIActivityViewController发起AirDrop分享

为了让对方接收后能直接唤起你的APP,我们需要先给APP定义一个自定义UTI(统一类型标识符),告诉系统“这个数据属于我的APP”。

先配置自定义UTI

在Info.plist里添加配置:

  1. 右键选择「Add Row」,找到Exported Type Identifiers,添加一个子项
  2. 子项的Type Identifier设为自定义值(比如com.yourapp.customarray)
  3. Type Description填你的数据描述(比如“用户信息嵌套数组”)
  4. Conforms To选择public.json(因为我们用JSON格式传输)

发起分享的代码

// 假设已经拿到转换好的jsonData
let activityVC = UIActivityViewController(activityItems: [jsonData], applicationActivities: nil)

// 可选:过滤掉不需要的分享选项,只保留AirDrop
activityVC.excludedActivityTypes = [.message, .mail, .print, .copyToPasteboard]

// iPad上需要设置popover的展示位置
if let popoverController = activityVC.popoverPresentationController {
    popoverController.sourceView = yourShareButton
    popoverController.sourceRect = yourShareButton.bounds
}

present(activityVC, animated: true)

第三步:接收端APP处理传入的数据

当对方通过AirDrop接收数据并选择用你的APP打开时,系统会把数据传递到你的APP,你需要在APP的生命周期方法里解析数据。

针对iOS 13+的SceneDelegate场景

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let fileURL = URLContexts.first?.url, fileURL.isFileURL else { return }
    
    do {
        let data = try Data(contentsOf: fileURL)
        // 解析回嵌套数组
        if let receivedArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String]] {
            // 这里拿到了传递过来的数组,做后续加载逻辑
            print("接收成功:\(receivedArray)")
            // 比如通知主界面更新数据
            NotificationCenter.default.post(name: NSNotification.Name("ReceivedUserArray"), object: receivedArray)
        }
    } catch {
        print("解析失败:\(error.localizedDescription)")
    }
}

针对iOS 12及以下的AppDelegate场景

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    guard url.isFileURL else { return false }
    
    do {
        let data = try Data(contentsOf: url)
        if let receivedArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String]] {
            // 处理数据逻辑
        }
    } catch {
        print("解析失败:\(error.localizedDescription)")
    }
    return true
}

额外配置:让APP能识别自定义UTI的文件

在Info.plist里添加Document Types配置:

  1. 添加一个子项,CFBundleTypeName填数据名称(比如“用户数组数据”)
  2. LSHandlerRank设为Owner
  3. LSItemContentTypes里添加你之前定义的自定义UTI(com.yourapp.customarray)
为什么这是最优方案?
  • 高效省心:直接复用系统AirDrop的传输能力,不需要自己实现蓝牙配对、数据传输的复杂逻辑,系统已经帮你处理了所有底层细节。
  • 体验流畅:完全符合你想要的“点击分享→AirDrop发送→唤起APP加载”的无缝流程,用户不需要额外操作。
  • 兼容性强:UIActivityViewController支持iOS 7+,AirDrop支持iOS 7+的设备,不需要额外权限申请(系统会自动处理蓝牙、WiFi权限)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:13:12