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

iOS中通过openURL跨应用启动时如何传递任意多个对象?

iOS跨App传递多对象(MyApp1→MyApp2)方案

我来帮你搞定从MyApp1用openURL启动MyApp2并传递任意多对象的需求~你说的用Dictionary包裹对象的思路完全可行,核心是把Dictionary转成URL能承载的格式,下面是具体实现步骤:

1. 给MyApp2配置URL Scheme

首先得让MyApp2能被其他App通过URL唤起,步骤如下:

  • 打开MyApp2的Info.plist,添加CFBundleURLTypes数组
  • 在数组里新增一个字典,设置CFBundleURLSchemes为你自定义的Scheme(比如myapp2),CFBundleURLName可以填App的标识(比如com.yourcompany.MyApp2)

或者在Xcode的Target设置里,选择Info→URL Types,点击+号添加,直接填写Scheme名称更直观。

2. 序列化包含任意对象的Dictionary

因为URL只能传递字符串,所以我们需要把Dictionary(里面包含自定义对象)转成URL安全的字符串:

  • 首先确保你的自定义对象遵循Codable协议(或者NSCoding,不过Codable更简洁)
  • 把Dictionary转成JSON Data,再转成Base64字符串(避免URL编码的麻烦),或者直接对JSON字符串做URL编码

示例代码(MyApp1中):

// 自定义对象示例
struct CustomObject: Codable {
    let id: Int
    let name: String
}

// 构造包含多对象的Dictionary
let obj1 = CustomObject(id: 1, name: "Obj1")
let obj2 = CustomObject(id: 2, name: "Obj2")
let dataDict: [String: Any] = [
    "userID": 123,
    "customObjs": [obj1, obj2],
    "message": "Hello from MyApp1"
]

// 序列化Dictionary
do {
    // 先把Dictionary转成JSON Data
    let jsonData = try JSONSerialization.data(withJSONObject: dataDict, options: [])
    // 转成Base64字符串(URL安全)
    let base64String = jsonData.base64EncodedString()
    // 或者直接转成JSON字符串再做URL编码
    // let jsonString = String(data: jsonData, encoding: .utf8)!
    // let encodedString = jsonString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
} catch {
    print("序列化失败:\(error)")
}

3. 构造URL并唤起MyApp2

把序列化后的字符串作为URL的参数,构造完整的Scheme URL,然后调用open方法:

// 构造URL
guard let url = URL(string: "myapp2://open?data=\(base64String)") else {
    print("URL构造失败")
    return
}

// 唤起MyApp2
if UIApplication.shared.canOpenURL(url) {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
    print("MyApp2未安装或未配置Scheme")
}

4. MyApp2接收并解析数据

在MyApp2中,需要在合适的生命周期方法里接收URL并解析:

如果你用的是UIKit(AppDelegate):

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    // 取出参数
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
          let dataParam = components.queryItems?.first(where: { $0.name == "data" })?.value else {
        return false
    }
    
    // 解析Base64字符串
    guard let jsonData = Data(base64Encoded: dataParam),
          let dataDict = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] else {
        return false
    }
    
    // 从Dictionary中取出对象,比如解析自定义对象数组
    if let customObjsData = try? JSONSerialization.data(withJSONObject: dataDict["customObjs"] as? [[String: Any]] ?? []),
       let customObjs = try? JSONDecoder().decode([CustomObject].self, from: customObjsData) {
        print("收到自定义对象:\(customObjs)")
    }
    
    // 处理其他数据
    let userID = dataDict["userID"] as? Int
    let message = dataDict["message"] as? String
    
    return true
}

如果你用的是SceneDelegate:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else { return }
    // 后续解析逻辑和上面AppDelegate的一致
}

备选方案:处理大对象传递

如果你的对象体积很大,URL的长度可能会受限(iOS里URL一般建议不超过2048字符),这时候可以用App Groups共享数据:

  • 给两个App配置同一个App Group
  • MyApp1把大对象存在UserDefaults(App Group容器)或者FileManager的共享目录里,生成一个唯一标识
  • 把这个标识通过URL传递给MyApp2,MyApp2再根据标识去共享容器里取数据

这样就不用担心URL长度限制的问题啦~

内容的提问来源于stack exchange,提问作者M.Masa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:43:12