okihand
okihand

Reputation: 75

Trigger a segue from a function (without UI element)

I'm very new with programming. Currently, I need to trigger a segue directly after a function is being executed.

This is my code:

func onlineSearch() {
    let urlToGoogle = "https://www.google.com/search?q=\(resultingText)"
    let urlString = urlToGoogle.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
    url = URL(string: urlString!)
    performSegue(withIdentifier: K.goToBrowser, sender: nil)
}

}

When I run this, I get this error:

Warning: Attempt to present <MyApp.SFSafariViewController: 0x10153be70> on <MyApp.CameraViewController: 0x101708460> whose view is not in the window hierarchy!

But if I run all the same, but simply trigger the segue from a button, instead of the way I want, it actually works perfectly.

@IBAction func webViewButtonPressed(_ sender: UIButton) {   // TEMP
    performSegue(withIdentifier: K.goToBrowser, sender: self)
}

P.S.: Nevermind the grotesque unwrapping, it is just working as a placeholder right now.

Upvotes: 3

Views: 58

Answers (3)

Corbell
Corbell

Reputation: 1403

Reposting my comment as an answer with a code snippet -

If the caller of onlinesearch() may be on anything other than the main thread, you need to wrap the performSegue call in a DispatchQueue.main.async{} block.

DispatchQueue.main.async {
    performSegue(withIdentifier: K.goToBrowser, sender: nil)
}

Generally, methods which affect UI (updating controls, performing segues, etc.) need to be on the main thread. Calls from UIKit are already on the main thread (viewDidLoad, draw, events, notifications, timers etc.), but other task completion handlers (and anything run on explicitly on a different queue) may not be.

Upvotes: 1

Here's a function if you want to use it anywhere else. But you should mark Chris Comas answer as the correct one.

func openURL(url: URL) {
        UIApplication.shared.open(url, options: [:])
    }
}

Just for the sake of knowledge:

let urlGoogle = URL(string: "https://www.google.com")
openURL(url: urlGoogle)

if you want to open the browser inside the app check Swift documentation: https://developer.apple.com/documentation/uikit/uiwebview

Upvotes: 1

Chris Comas
Chris Comas

Reputation: 216

try using this to open the safari URL

if let url = URL(string: "https://www.google.com/search?q=\(resultingText)") {
    UIApplication.shared.open(url)
}

Upvotes: 1

Related Questions