Xcode — URL Scheme
This article is extracted from the chat log with AI. Please identify it with caution.

在 iOS 开发中,​URL Scheme​ 和 ​UIOpenURLContext​ 是处理应用间通信和深度链接(Deep Linking)的核心技术。以下是它们的详细解释和对比:


一、URL Scheme(URL 方案) #

1. ​概念#

  • URL Scheme​ 是一种自定义协议,允许应用通过特定格式的 URL 被其他应用唤醒或传递数据。
  • 例如:myapp://profile?user=123 表示调用 myapp 的 Scheme,并传递参数。

2. ​核心用法#

(1) ​注册自定义 Scheme#

在 Info.plist 中添加以下配置:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.example.myapp</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myapp</string> <!-- 自定义 Scheme 名称 -->
        </array>
    </dict>
</array>
(2) ​处理 Scheme 请求#

在 AppDelegate 中实现方法:

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    // 解析 URL,例如:myapp://profile?user=123
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
          components.scheme == "myapp",
          let queryItems = components.queryItems else {
        return false
    }
    
    if components.host == "profile" {
        let userID = queryItems.first(where: { $0.name == "user" })?.value
        // 跳转到用户详情页
        return true
    }
    return false
}

3. ​调用其他应用#

使用 UIApplication.shared.open 触发其他应用的 Scheme:

if let url = URL(string: "tel://10086") {
    UIApplication.shared.open(url)
}

4. ​常见内置 Scheme#

Scheme用途示例
tel://拨打电话tel://10086
mailto://发送邮件mailto://support@apple.com
http:// 或 https://打开网页https://www.apple.com
maps://打开地图maps://?q=Beijing

二、UIOpenURLContext(iOS 13+) #

1. ​概念#

  • UIOpenURLContext​ 是 iOS 13 引入的 SceneDelegate 中的新 API,用于在多窗口(Multi-Scene)环境下处理 URL 打开请求。
  • 替代传统的 AppDelegate 方法,支持更精细的场景管理。

2. ​核心用法#

(1) ​在 SceneDelegate 中处理#
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let urlContext = URLContexts.first else { return }
    let url = urlContext.url
    
    // 解析 URL(逻辑与 AppDelegate 类似)
    if url.scheme == "myapp" {
        // 处理跳转逻辑
    }
}
(2) ​获取额外信息#
let options = urlContext.options
let sourceApp = options.sourceApplication // 来源应用 Bundle ID
let annotation = options.annotation        // 附加数据

3. ​多场景支持#

  • 如果应用支持多窗口,可以通过 UIOpenURLContext 的 scene 属性判断来源场景:
if let scene = urlContext.scene as? UIWindowScene {
    print("URL 来自场景:\(scene.session.persistentIdentifier)")
}

三、URL Scheme 与 UIOpenURLContext 对比 #

特性URL Scheme(传统方式)UIOpenURLContext(新方式)
兼容性所有 iOS 版本iOS 13+
适用场景单窗口应用多窗口应用(如 iPad 分屏)
入口类AppDelegateSceneDelegate
数据获取通过 options 字典通过 UIOpenURLContext 对象
多窗口处理不支持支持

四、安全注意事项 #

  1. 验证来源应用​:

    if let sourceApp = options.sourceApplication, sourceApp == "com.legitimate.app" {
        // 仅处理可信来源
    }
    
  2. 防止 URL 参数篡改​:

    // 使用 URLComponents 解析参数,避免手动拼接
    guard let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: true)?.queryItems else { return }
    
  3. 白名单配置​:
    在 Info.plist 中限制可调用的 Scheme:

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>myapp</string>
        <string>tel</string>
    </array>
    

  • Universal Links​ 是 Apple 推荐的深度链接方案,比 URL Scheme 更安全(需配置 apple-app-site-association 文件)。
  • 示例:https://www.example.com/profile/user123 可以直接跳转到应用。

六、完整示例代码 #

1. ​调用其他应用#

// 拨打电话
if let url = URL(string: "tel://10086"), UIApplication.shared.canOpenURL(url) {
    UIApplication.shared.open(url)
}

// 跳转到 App Store 评分页
if let url = URL(string: "itms-apps://itunes.apple.com/app/id123456?action=write-review") {
    UIApplication.shared.open(url)
}

在 SceneDelegate 中:

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
       let url = userActivity.webpageURL {
        // 处理 Universal Link
    }
}

通过理解 URL Scheme 和 UIOpenURLContext 的原理和用法,您可以实现应用间的无缝跳转和深度链接功能。

onOpenURL #

本文共 1217 字,创建于 May 24, 2025
相关标签: Xcode, ByAI, SwiftUI, DeepSeek