Integrar con Swift
Safari View Controller integra todo Safari dentro de su aplicaciĂłn usando un controlador de vista opaco. Es decir, no puede diseñarlo, no puede interactuar con Ă©l y no puede extraer ningĂșn dato privado de Ă©l. Como resultado, SFSafariViewController puede aprovechar los datos web seguros del usuario.
En este paso vamos a instalar y configurar las dependencias necesarias para implementar SFSafariViewController en tu proyecto desarrollado en Swift.
InstalaciĂłn de SFSafariViewController
Client-Side
SFSafariViewController no forma parte del UIKit por lo que, para usarlo, deberĂĄs importar Safari Services Framework que contiene los servicios necesarios para integrar comportamientos de Safari en tu aplicaciĂłn iOS.
Para instalarlo, ve al archivo en donde desees utilizar Safari View Controller e importa la biblioteca SafariServices.
Main.swift
import SafariServices
Al trabajar con SFSafariViewController, puedes abrir la URL de preferencia con sĂłlo enviar la URL o agregando algunos ajustes de configuraciĂłn. A continuaciĂłn, te mostramos algunos ejemplos de referencia para la implementaciĂłn de SFSafariViewController.
import SwiftUI
import SafariServices
struct ContentView: View {
var body: some View {
VStack {
Button("Open Preference" ) {
if let url = URL(string:"YOUR-URL-PREFERENCE")
{
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
if let rootViewController = windowScene.windows.first?.rootViewController {
let safariVC = SFSafariViewController(url: url)
rootViewController.present(safariVC, animated: true, completion: nil)
}
}
}
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
import SafariServices
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton()
button.setTitle("Open Preference", for: .normal)
button.backgroundColor = .systemBlue
view.addSubview(button)
button.frame = CGRect(x: 100, y: 100, width: 200, height: 50)
button.layer.cornerRadius = 25
button.addTarget(self, action: #selector(openSafariViewController) , for: .touchDown)
}
@objc func openSafariViewController(_ sender: Any) {
if let url = URL(string: "YOUR-URL-PREFERENCE") {
let safariViewController = SFSafariViewController(url: url)
present(safariViewController, animated: true, completion: nil)
}
}
}
CĂłmo volver a tu App
Client-Side
Los Deep Links, tambiĂ©n conocidos como enlaces profundos, son una forma poderosa de permitir la navegaciĂłn directa a pantallas o secciones especĂficas de una aplicaciĂłn mĂłvil.
Crear un Deep Link
Desde nuestro checkout es posible configurar Deep Links para volver a tu aplicaciĂłn, ya sea haciendo click en un link de âVolverâ, o de forma automĂĄtica al terminar todo un flujo de pago exitoso, para luego ser redirigido a tu App.
Para esto, debemos agregar en la creaciĂłn de la preferencia de pago las propiedades back_urls
y auto_return
, segĂșn corresponda.
Para conocer mĂĄs, puedes acceder a la documentaciĂłn de URLs de retorno.
ConfiguraciĂłn de la aplicaciĂłn para la gestiĂłn del Deep Link
Client-Side
Para configurar un Deep Link nativo en iOS, dirĂgete al archivo <appname>/Info.plist
y agrega el cĂłdigo que se muestra a continuaciĂłn segĂșn sea tu caso.
El siguiente ejemplo aplica para un deep link de la forma iosapp://:
plain
<dict>
âŠ
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>your_identifier_here</string>
<key>CFBundleURLSchemes</key>
<array>
<string>iosapp</string>
</array>
</dict>
</array>
âŠ
</dict>
El valor CFBundleURLName
corresponde al identificador de la aplicaciĂłn (Identifier) y CFBundleURLSchemes
al scheme utilizado en el Deep Link.
Configurar el Deep Link desde Xcode
TambiĂ©n puedes configurar el Deep Link desde Xcode. Para esto, ubĂcate en la informaciĂłn de tu proyecto y agrega una nueva URL Type
.
Luego, ingresa el identifier
de tu aplicaciĂłn y la URL Schemes
del Deep Link.
Esto generarĂĄ automĂĄticamente el mismo cĂłdigo que se indicĂł anteriormente en el archivo <appname>/Info.plist
.
RecepciĂłn y gestiĂłn del Deep Link
Client-Side
En iOS, cuando un deep link intenta redirigir al usuario a la aplicaciĂłn desde una Safari View Controller es necesario configurar un manejador de este evento para cerrarla y cargar la vista o escena que corresponda.
struct ContentView: View {
@State private var showSuccessView = false
var body: some View {
VStack {
Text("SwiftUI")
.font(.system(size: 36, design: .rounded).weight(.bold)).foregroundColor(.black).padding(.bottom, 8)
Text("POC")
.font(.system(size: 24, design: .rounded)).foregroundColor(.gray).padding(.bottom)
Button("Abrir Safari") {
if let url = URL(string: "YOUR-URL-PREFERENCE") {
UIApplication.shared.windows.first?.rootViewController?.present(UIHostingController(rootView: SafariView(url: url)), animated: true, completion: nil)
}
}.padding(.bottom)
Button("Abrir Congrat") {
showSuccessView = true
}
}
.sheet(isPresented: $showSuccessView) {
SuccessView(isPresented: $showSuccessView)
}
// AquĂ la recepciĂłn deep link
.onOpenURL { url in
if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
components.scheme == "iosapp",
components.host == "congrat",
components.path.contains("success") {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if let presenting = UIApplication.shared.windows.first?.rootViewController?.presentedViewController {
presenting.dismiss(animated: true, completion: nil)
showSuccessView = true
}
}
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Desde el AppDelegate.swift o SceneDelegate.swift segĂșn sea tu caso, recibirĂĄs un Deep Link de la forma iosapp://congrat/success. Luego debĂ©ras cerrar Safari View Controller para cargar una vista llamada SuccessViewController.
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let urlContext = URLContexts.first {
let url = urlContext.url
if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
components.scheme == "iosapp",
components.host == "congrat",
components.path.contains("success") {
if let rootViewController = window?.rootViewController {
let successViewController = SuccessViewController {
rootViewController.dismiss(animated: true, completion: nil)
}
if let presentingViewController = rootViewController.presentedViewController {
presentingViewController.dismiss(animated: true) {
rootViewController.present(successViewController, animated: true, completion: nil)
}
} else {
rootViewController.present(successViewController, animated: true, completion: nil)
}
}
}
}
}
}
Desde el ContentView de la aplicaciĂłn recibirĂĄs un Deep Link de la forma iosapp://congrat/success y, luego de un intervalo de tiempo, deberĂĄs cerrar Safari View Controller para cargar una vista llamada SuccessView.