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

iOS Swift开发:通过deeplink唤起App如何获取返回登录结果

跨App Deeplink登录结果回传实现方案

核心逻辑是通过双向自定义URL Scheme完成跳转和参数传递,不需要调用私有API,符合App Store审核规则。

前置配置

  • 给第一款App新增专属回调URL Scheme:打开工程配置的「Info - URL Types」项,新增标识(例如firstapp),确保和其他App Scheme不重名,配置完成后第一款App即可被firstapp://开头的链接唤起。
  • 两个App都在Info.plist中添加跳转白名单LSApplicationQueriesSchemes,把对方的Scheme加入数组,否则iOS 9+系统会拦截跳转请求:
<key>LSApplicationQueriesSchemes</key>
<array>
    <!-- 第一款App中加入第二款App的Scheme -->
    <string>lg</string>
    <!-- 第二款App中加入第一款App的回调Scheme -->
    <string>firstapp</string>
</array>

第一款App修改点

1. 调整唤起第二款App的逻辑

原有跳转逻辑没有携带回调标识,需要把自身的回调Scheme作为参数拼到跳转链接里,告诉第二款App登录完成后的跳转目标:

// FIRST APP 登录按钮点击逻辑
let callbackScheme = "firstapp"
guard let url = URL(string: "lg://loginapp.com/login?callback=\(callbackScheme)") else { return }
if #available(iOS 10.0, *) {
    UIApplication.shared.open(url, options: [:])
} else {
    UIApplication.shared.openURL(url)
}

2. 实现回调参数接收逻辑

根据工程是否使用Scene,在对应生命周期方法中解析第二款App回传的参数:

// 未使用Scene的旧版本工程,在AppDelegate中实现
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    // 仅处理自身回调Scheme触发的唤起
    guard url.scheme == "firstapp" else { return false }
    // 解析URL参数
    let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
    let queryItems = components?.queryItems ?? []
    let params = Dictionary(uniqueKeysWithValues: queryItems.map { ($0.name, $0.value ?? "") })
    
    // 处理登录结果
    if params["status"] == "success", let token = params["token"] {
        // 在此写入登录成功逻辑:存储token、刷新UI等
        print("收到回传登录凭证:\(token)")
    } else {
        // 处理登录失败、用户取消场景
        let errorMsg = params["error"] ?? "登录失败"
        print(errorMsg)
    }
    return true
}

// iOS13+使用Scene的工程,需要在SceneDelegate中补充实现
@available(iOS 13.0, *)
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else { return }
    guard url.scheme == "firstapp" else { return }
    // 参数解析逻辑和上述AppDelegate中完全一致
    let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
    let queryItems = components?.queryItems ?? []
    let params = Dictionary(uniqueKeysWithValues: queryItems.map { ($0.name, $0.value ?? "") })
    
    if params["status"] == "success", let token = params["token"] {
        print("收到回传登录凭证:\(token)")
    }
}

第二款App修改点

1. 删除原有私有API调用

注意:原有代码中调用的NSXPCConnection.suspend属于未公开私有API,上架审核有极大概率被拒,必须替换为官方允许的openURL跳转方案,系统会自动将当前App退至后台,切回目标App。

2. 解析入参保存回调地址

在被第一款App唤起时,从链接参数中取出回调Scheme暂存:

// SECOND APP 定义全局变量存储回调地址
var callbackScheme: String?

// 在openURL代理方法中解析入参
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    if url.scheme == "lg" {
        let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
        callbackScheme = components?.queryItems?.first(where: { $0.name == "callback" })?.value
        // 在此写入跳转自身登录页的逻辑
        return true
    }
    return false
}

3. 登录完成后回传结果并跳回

登录流程结束后,把token、登录状态等参数拼到回调链接中,直接唤起第一款App完成回传:

// SECOND APP 登录完成回调方法,替换原有suspend调用
func loginDidFinish(token: String?, error: Error?) {
    guard let callbackScheme = callbackScheme else { return }
    var callbackUrlStr = "\(callbackScheme)://logincallback?"
    // 拼接结果参数
    if let token = token {
        callbackUrlStr += "status=success&token=\(token)"
    } else {
        callbackUrlStr += "status=fail&error=\(error?.localizedDescription ?? "未知错误")"
    }
    // 对参数做URL编码,避免特殊字符导致链接失效
    guard let encodedUrlStr = callbackUrlStr.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
          let callbackUrl = URL(string: encodedUrlStr) else { return }
    // 跳回第一款App
    if #available(iOS 10.0, *) {
        UIApplication.shared.open(callbackUrl, options: [:])
    } else {
        UIApplication.shared.openURL(callbackUrl)
    }
}

优化建议

  • 如果对登录安全性要求较高,不要直接把正式token明文拼在URL中,可以先回传一次性临时授权码,第一款App收到授权码后通过服务端接口换取正式token,降低凭证被劫持的风险。
  • 可以给回调链接增加来源校验,避免其他恶意App伪造回调链接窃取登录状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:45:33