在 UIKit 中处理深度链接主要涉及两种机制:自定义 URL 方案 (Custom URL Schemes) 和 通用链接 (Universal Links)。虽然两者都允许用户直接导航到您应用中的特定内容,但通用链接通常因其无缝的用户体验和更好的回退行为而更受青睐。
1. 自定义 URL 方案
自定义 URL 方案允许您为应用的 URL 定义一个唯一的前缀(例如 myapp://product/123)。当用户点击带有此方案的链接时,iOS 会启动您的应用。
设置:
-
在 Xcode 中注册 URL 方案:
- 在 Xcode 中打开您的项目。
- 在项目导航器中选择您的项目,然后选择您的目标。
- 转到 "Info" 选项卡。
- 在 "URL Types" 部分下,单击 "+" 按钮添加新的 URL 类型。
- 对于 "Identifier",您可以使用应用的 bundle ID(例如
com.yourcompany.yourapp)。 - 对于 "URL Schemes",输入您想要的自定义方案(例如
myapp)。
-
在
AppDelegate或SceneDelegate中处理传入的 URL:-
对于使用
AppDelegate的应用(旧应用或未使用 Scene Delegates 的应用): 实现application(_:open:options:)方法。swift func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { // Parse the URL and navigate to the appropriate content print("Received URL: \(url)") handleDeepLink(url) return true } -
对于使用
SceneDelegate的应用(iOS 13 及更高版本): 实现scene(_:openURLContexts:)或scene(_:continue:)。```swift func scene(_ scene: UIScene, openURLContexts URLContexts: Set
) { guard let url = URLContexts.first?.url else { return } print("Received URL: (url)") handleDeepLink(url) } // For Universal Links, you'll also use this method func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else { return } print("Received Universal Link: (url)") handleDeepLink(url) } ```
-
2. 通用链接
通用链接是标准的 HTTPS 链接,可同时用于您的网站和您的应用。如果您的应用已安装,链接将直接在您的应用中打开;否则,它将在 Safari 中打开。这提供了更流畅的用户体验。
设置:
-
创建
apple-app-site-association文件:- 此 JSON 文件告诉 iOS 您的应用可以处理哪些 URL。
- 将此文件托管在您的 Web 服务器的根目录或
.well-known子目录中(例如https://yourdomain.com/apple-app-site-association)。 - 示例内容:
json { "applinks": { "apps": [], "details": [ { "appID": "TEAM_ID.com.yourcompany.yourapp", "paths": [ "/product/*", "/settings/*" ] } ] } }用您的实际值替换TEAM_ID和com.yourcompany.yourapp。
-
在 Xcode 中启用关联域功能:
- 在 Xcode 中,选择您的项目和目标。
- 转到 "Signing & Capabilities" 选项卡。
- 单击 "+ Capability" 并选择 "Associated Domains"。
- 为您的应用应处理的每个域添加一个条目,前缀为
applinks:(例如applinks:yourdomain.com)。
-
在
AppDelegate或SceneDelegate中处理传入的 URL:- 通用链接使用
NSUserActivity对象进行处理。 -
对于
AppDelegate: 实现application(_:continue:restorationHandler:)。swift func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else { return false } print("Received Universal Link: \(url)") handleDeepLink(url) return true } -
对于
SceneDelegate: 使用上面自定义 URL 方案部分中显示的scene(_:continue:)方法。
- 通用链接使用
3. 通用深度链接处理逻辑 (handleDeepLink 函数)
无论您使用自定义 URL 方案还是通用链接,解析 URL 并导航到应用内的核心逻辑都非常相似。
func handleDeepLink(_ url: URL) {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
return
}
// Example: myapp://product/123?color=red
// Example: https://yourdomain.com/product/123?color=red
if components.host == "product" {
// Extract product ID from path components or query parameters
let productID = components.path.replacingOccurrences(of: "/", with: "")
let color = components.queryItems?.first(where: { $0.name == "color" })?.value
// Navigate to product detail screen
// (e.g., using a UINavigationController or presenting a new view controller)
if let rootViewController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController {
let productViewController = ProductDetailViewController() // Your custom VC
productViewController.productID = productID
productViewController.selectedColor = color
rootViewController.pushViewController(productViewController, animated: true)
}
} else if components.host == "settings" {
// Navigate to settings screen
if let rootViewController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController {
let settingsViewController = SettingsViewController() // Your custom VC
rootViewController.pushViewController(settingsViewController, animated: true)
}
}
// Add more conditions for different paths/hosts
}
4. 安全注意事项
深度链接可能成为潜在的攻击向量。始终验证所有 URL 参数并丢弃任何格式错误的 URL。限制通过深度链接可用的操作,使其不至于冒用户数据的风险,并且切勿允许它们直接删除内容或访问敏感信息。
5. 测试深度链接
您可以通过以下方式测试深度链接:
* 在 Safari 中输入自定义 URL 方案(例如 myapp://product/123)。
* 使用终端中的 xcrun simctl openurl booted <URL> 命令在 iOS 模拟器中打开 URL。
* 从网页在 Safari 中点击通用链接。