如何让URL直接打开当前iOS应用而非Safari?及应用内按钮点击加载网页的WebView实现方案问询
问题1:如何使URL直接打开当前iOS应用,而非跳转至Safari浏览器?
要让外部URL直接唤起你的iOS应用而不跳转到Safari,主要有两种实用方案:URL Scheme 和 Universal Links,我给你一步步拆解操作细节:
方式一:URL Scheme(简单易实现,适合自定义唤起链接)
这是最基础的唤起方式,用你自定义的协议前缀就能唤起应用:
配置项目Info.plist
打开项目的Info.plist,添加URL types数组项,在数组里新增一个字典:- 键
CFBundleURLSchemes:值为数组,填入你自定义的Scheme名称(比如mycustomapp,注意别和其他应用重复) - 键
CFBundleURLName:填入你的应用唯一标识,比如com.yourcompany.yourapp
- 键
处理唤起请求
根据你的iOS版本和项目架构,在对应的代理类里实现唤起逻辑:- 对于iOS 12及以下的UIKit项目,在
AppDelegate中添加:func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { if url.scheme == "mycustomapp" { // 这里可以处理URL里的参数,比如跳转到应用内指定页面 return true } return false } - 对于iOS 13+的Scene架构项目,在
SceneDelegate中添加:func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { guard let url = URLContexts.first?.url else { return } if url.scheme == "mycustomapp" { // 执行你的业务逻辑,比如打开某个ViewController } }
- 对于iOS 12及以下的UIKit项目,在
测试唤起
在Safari地址栏输入mycustomapp://,或者在其他应用里调用这个链接,就能直接唤起你的应用了。
方式二:Universal Links(更优雅,支持HTTPS链接,无确认弹窗)
这种方式用正常的HTTPS域名链接就能唤起应用(比如https://yourapp.com/launch),用户点击后直接打开应用,体验更顺滑:
配置关联域名权限
- 登录Apple Developer后台,找到你的App ID,开启
Associated Domains权限 - 在Xcode项目的
Signing & Capabilities面板中添加Associated Domains,然后填入域名:applinks:yourapp.com(替换成你的实际域名)
- 登录Apple Developer后台,找到你的App ID,开启
服务器放置配置文件
在你的域名根目录或者.well-known目录下,上传一个名为apple-app-site-association的无后缀文件,内容示例:{ "applinks": { "apps": [], "details": [ { "appID": "你的团队ID.com.yourcompany.yourapp", "paths": [ "/launch/*", "/home" ] // 匹配需要唤起应用的路径,支持通配符 } ] } }注意:这个文件必须通过HTTPS访问,且不能有重定向。
处理唤起逻辑
同样在对应的代理类里实现处理方法:- UIKit项目的
AppDelegate:func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL { // 处理这个Universal Link,比如跳转到对应页面 return true } return false } - Scene架构的
SceneDelegate:func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL { // 执行你的业务逻辑 } }
- UIKit项目的
问题2:如何在应用界面内打开网页(用WebView实现)
完全正确!用WebView就能实现应用内打开网页,现在iOS官方推荐使用WKWebView(UIWebView已经被废弃,不建议再用),我给你讲具体实现步骤:
步骤1:导入WebKit框架
在你要使用WebView的ViewController文件顶部,导入WebKit:
import WebKit
步骤2:添加WKWebView到视图
你可以选择纯代码实现,或者用Storyboard拖拽:
方式A:纯代码实现
class WebPageViewController: UIViewController, WKNavigationDelegate { private var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() // 初始化WKWebView配置 let webConfig = WKWebViewConfiguration() webView = WKWebView(frame: view.bounds, configuration: webConfig) webView.navigationDelegate = self // 设置代理,监听加载状态、错误等 webView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // 让WebView自适应屏幕大小 view.addSubview(webView) // 加载指定URL if let targetUrl = URL(string: "https://example.com") { let urlRequest = URLRequest(url: targetUrl) webView.load(urlRequest) } } // 可选:监听网页加载状态 func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { // 开始加载,可显示加载指示器 print("网页开始加载") } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 加载完成,隐藏加载指示器 print("网页加载完成") } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { // 加载失败,提示用户 print("网页加载失败:\(error.localizedDescription)") } }
方式B:Storyboard拖拽实现
- 在Storyboard中拖一个
WKWebView到ViewController的视图上,设置约束让它铺满整个屏幕 - 创建IBOutlet关联到ViewController代码中:
@IBOutlet weak var webView: WKWebView! - 在
viewDidLoad中设置代理并加载URL:
别忘了让ViewController遵守override func viewDidLoad() { super.viewDidLoad() webView.navigationDelegate = self if let targetUrl = URL(string: "https://example.com") { webView.load(URLRequest(url: targetUrl)) } }WKNavigationDelegate协议
步骤3:拦截网页内链接(可选)
如果想让网页里的所有链接都在当前WebView打开,而不跳转Safari,可以在代理方法里拦截:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url else { decisionHandler(.allow) return } // HTTP/HTTPS链接在当前WebView打开 if url.scheme == "http" || url.scheme == "https" { decisionHandler(.allow) } else { // 其他协议(比如tel:、mailto:)交给系统处理 UIApplication.shared.open(url) decisionHandler(.cancel) } }
内容的提问来源于stack exchange,提问作者Dhiren




