Как открыть любой URL-адрес, щелкнутый в моем приложении iOS, во встроенном браузере?

Как я могу установить правило, чтобы когда мой пользователь щелкал любую веб-ссылку в моем приложении, она открывалась во встроенном в приложение браузере, а не в Safari?

Контекст. Я создаю приложение, в котором есть несколько мест, где ссылки либо встроены мной, либо загружаются в результате различных действий пользователя, например. ссылка, ведущая на страницу, на которой размещена другая ссылка. Я хочу убедиться, что пользователь редко покидает мое приложение и, следовательно, хочет открывать все внешние веб-ссылки во встроенном в приложение браузере, который уже разработан

Целевая сборка: iOS 11. Окружающая среда/язык: Swift 4


person zaam    schedule 16.10.2018    source источник


Ответы (2)


Простое решение с использованием SFSafariViewController, доступного в отдельном пакете.

import SafariServices

Swift 4, iOS 9.0+

let url = URL(string: "your URL here")
let vc = SFSafariViewController(url: url)
present(vc, animated: true)

Если вам нужно больше контроля, используйте параметр Configuration (Swift 4, iOS 11.0+):

Пример:

let config = SFSafariViewController.Configuration()
config.entersReaderIfAvailable = true

let url = URL(string: "your URL here")
let vc = SFSafariViewController(url: url, configuration: config)
present(vc, animated: true)
person Petr Lazarev    schedule 11.11.2018
comment
Действительно элегантное решение. Есть ли способ, которым мы могли бы по умолчанию ВСЕ URL-адреса в любом месте приложения открывать через службы Safari? - person zaam; 30.03.2019
comment
Это настолько просто, что alertControllers кажется сложным. Ницца. - person John Pitts; 22.07.2020

...он открывается во встроенном в приложение браузере, а не в Safari?

В этом случае вам понадобится собственный WebView. Вот краткий фрагмент простого веб-представления внутри контроллера:

import UIKit
import WebKit

/// The controller for handling webviews.
class WebViewController: UIViewController {

    // MARK: - Properties
    internal lazy var button_Close: UIButton = {
        let button = UIButton(type: .custom)
        button.setImage(.close, for: .normal)
        button.imageEdgeInsets = UIEdgeInsets.init(top: 0, left: -30, bottom: 0, right: 0)
        button.addTarget(self, action: #selector(back(_:)), for: .touchUpInside)
        return button
    }()

    public var urlString: String! {
        didSet {
            if let url = URL(string: urlString) {
                let urlRequest = URLRequest(url:url)
                self.webView.load(urlRequest)
            }
        }
    }

    private lazy var webView: WKWebView = {
        let webView = WKWebView()
        webView.navigationDelegate = self
        return webView
    }()

    // MARK: - Functions
    // MARK: Overrides

    override func viewDidLoad() {
        super.viewDidLoad()

        let barButton = UIBarButtonItem(customView: self.button_Close)
        self.button_Close.frame = CGRect(x: 0, y: 0, width: 55.0, height: 44.0)
        let negativeSpacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
        if #available(iOS 11.0, *) {
            negativeSpacer.width = -30
        }
        self.navigationItem.leftBarButtonItems = [negativeSpacer, barButton]

        self.view.addSubview(self.webView)
        self.webView.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
    }

    @objc func back(_ sender: Any) {
        self.dismiss()
    }
}

extension WebViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        // Show here a HUD or any loader
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // Dismiss your HUD
    }
}

и представляя такой webViewController, например (передавая URLString):

let webViewVC = WebViewController()
webViewVC.urlString = "https://www.glennvon.com/"
let navCon = UINavigationController(rootViewController: webViewVC)
self.navigationController?.present(navCon, animated: true, completion: nil)

Если вы используете раскадровку, просто перетащите веб-просмотр в свой контроллер и настройте делегат. Это должно вам помочь :)

person Glenn Posadas    schedule 16.10.2018
comment
Спасибо за ваш ответ, я не понял, как я смогу открывать ссылки, созданные в результате взаимодействия с пользователем или ссылки из другого класса. Например, у меня есть полнофункциональный веб-просмотр, в котором я открываю определенные ссылки. Однако в другом представлении, управляемом другим viewController, у меня есть текст с несколькими встроенными ссылками - вы имеете в виду, что для каждой ссылки я должен продолжать отображать браузер в приложении? Я больше думал о чем-то вроде настройки в AppDelegate, которая преобладает во всем приложении — существует ли что-то подобное? Если нет, то как я могу открыть столько URL-адресов? - person zaam; 17.10.2018
comment
Это просто. Просто помните, что вы можете открывать ссылки только по одной. Итак, какие бы ссылки ни были в вашем проекте, будь то динамические или статические, и вам нужно их посетить, просто передайте строку URL-адреса в свой webViewVC. Надеюсь, это поможет. - person Glenn Posadas; 17.10.2018
comment
Проблема в том, что у меня есть почти 100 ссылок в приложении, встроенных в тексты. Например, представьте себе статический блог, на одних страницах которого есть несколько ссылок, а на других нет. Есть ли более разумный способ обеспечить возможность открытия всех этих ссылок (даже по одной за раз) в уже созданном встроенном браузере приложения? Имея в виду, что текст этого блога динамически генерируется в приложении. - person zaam; 17.10.2018
comment
Количество не имеет значения, это не проблема! Этот ответ должен был ответить на ваш вопрос со вчерашнего дня. Теперь, если вы хотите встроить ссылки в некоторые строки в целой строке, вы можете использовать строку с атрибутами или библиотеку, такую ​​​​как ActiveLabel, а затем, опять же, просто передать строку URL-адреса вашему веб-просмотру. Вот и все! - person Glenn Posadas; 18.10.2018
comment
Спасибо. Это дает мне некоторое направление. - person zaam; 19.10.2018