amelia
amelia

Reputation: 111

How to open the desktop version of a link but using SafariServices

I want to open the desktop version of a link using SFSafariViewController. I have found solutions for how to use SFSafariViewController and separately for how to open the desktop version of a link but I cannot get these two to work together. I want to show the in-app default browser with the browser header and footer but I have to use the desktop version of the link. Like I said, I've successfully gotten these each to work separately but not together. The version I've attached is the one where I'm using the desktop version of the link, but I can attach the one where I got SFSafariViewController working if needed.

URL Button and 'Safari' View

struct URLButton<Content: View>: View {

    var content: Content
    var url: String
    
    @AppStorage("LinkDestination") var linkDestination = 0
    
    @State var showSafariView = false
    
    var safariURL: URL {
        return URL(string: url)!
    }
    
    @ViewBuilder var body: some View {
        switch linkDestination {
        case 0:
            Button(action: {
                showSafariView = true
            }) {
                content.fullScreenCover(isPresented: $showSafariView) {
                    SafariView(url: URL(string: url)!).edgesIgnoringSafeArea(.all)
                }
            }
        case 1:
            Link(destination: safariURL) {
                content
            }
        default:
            content
        }
    }
}

struct SafariView: UIViewControllerRepresentable {
    var url: URL
    
    func makeUIViewController(context: Context) -> UIViewController {
        let webView = WKWebView()
        webView.customUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
        webView.load(URLRequest(url: url))
        
        let viewController = UIViewController()
        viewController.view = webView
        
        return viewController
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {

    }
}

view

struct ImportView: View {
    let urlString = "https://www.google.com"

var body: some View {
URLButton(content: ExportButton(), url: urlString)
}
}

Upvotes: 0

Views: 60

Answers (1)

ASAD Parekh
ASAD Parekh

Reputation: 31

To achieve the functionality you described, where you want to use SFSafariViewController to show the desktop version of a link while maintaining the in-app browser header and footer, you need to make some adjustments to your code.

Here's an updated version of your SafariView struct to use SFSafariViewController:

swift

import SwiftUI
import SafariServices

struct SafariView: UIViewControllerRepresentable {
    var url: URL
    
    func makeUIViewController(context: Context) -> UIViewController {
        let safariViewController = SFSafariViewController(url: url)
        safariViewController.preferredControlTintColor = UIColor.systemBlue // Change the color of toolbar items
        
        // Customize Safari view controller properties here if needed
        
        return safariViewController
    }

    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        // Update the Safari view controller if needed
    }
}

And then in your URLButton view, you can use this SafariView to show the desktop version of the link:

struct URLButton<Content: View>: View {
    var content: Content
    var url: String
    
    @AppStorage("LinkDestination") var linkDestination = 0
    @State private var showSafariView = false
    
    var safariURL: URL {
        return URL(string: url)!
    }
    
    @ViewBuilder var body: some View {
        switch linkDestination {
        case 0:
            Button(action: {
                showSafariView = true
            }) {
                content
            }
            .fullScreenCover(isPresented: $showSafariView) {
                SafariView(url: URL(string: url)!)
            }
        case 1:
            Link(destination: safariURL) {
                content
            }
        default:
            content
        }
    }
}

Upvotes: 0

Related Questions