swift 3 open URLs in safari or native app - ios

import UIKit
import WebKit
// Add WKWebView in StoryBoard
class ViewController: UIViewController {
#IBOutlet var webView: WebView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
webView.loadUrl(string: "https://url.to/my/template")
}
}
class WebView: WKWebView {
required init?(coder: NSCoder) {
if let _view = UIView(coder: coder) {
super.init(frame: _view.frame, configuration: WKWebViewConfiguration())
autoresizingMask = _view.autoresizingMask
} else {
return nil
}
}
func loadUrl(string: String) {
if let url = URL(string: string) {
load(URLRequest(url: url))
}
}
}
The website is a html5 + CSS3. Purchased a template from themeforest but the developer said he doesn't offer support for xcode.
As for now, all links are opening inside the webview. How can I open them in safari, and urls that go to apps, to open the installed apps, such as facebook, twitter?
All I could find is to open ALL URLS in safari.
L.E. Thank you! So I want to load the template hosted at the url, but the links within the template to load in safari, even better, like the answer with 3 votes from Swift Open Link in Safari. When I try to use that code, I get an error. Sorry and thanks! I don't know swift at all (or coding much).

If you want to open url as safari than You can use Add SafariSevices.Framework
import SafariServices
class ViewController: UIViewController, SFSafariViewControllerDelegate
{
#IBAction func btnClick(_ sender: Any)
{
let safariVC = SFSafariViewController(url: NSURL(string: "https://www.google.co.in") as! URL)
self.present(safariVC, animated: true, completion: nil)
}
func safariViewControllerDidFinish(controller: SFSafariViewController)
{
controller.dismiss(animated: true, completion: nil)
}
}

Related

Xcode Button Going to the Wrong Link

my app currently has two buttons. One leads to a Twitter page, and the other links to a page on my Website. They are both on the same view controller and same view. However, when I click the Feedback button, it goes to my Twitter. Any advice?
Here's my code.
import UIKit
class AboutScreenViewController: UIViewController {
#IBAction func twitterButton(_ sender: Any) {
if let url2 = URL(string: "https://twitter.com/SunnyParks4u") {
UIApplication.shared.open(url2, options: [:], completionHandler: nil)
}
}
#IBAction func FeedbackButton(_ sender: Any) {
if let Contactlink = URL(string: "https://sunnyparks4u.wixsite.com/home-page/contact-8") {
UIApplication.shared.open(Contactlink, options: [:], completionHandler: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Maybe You copy/pasted the button in the interface builder and now both of the buttons executes the same IBAction.
Right-click on both buttons and check

Whats the best way to preserve the state of the WebView in iOS?

For example, when I load a url inside the WebView in an iOS app, and when user clicked back button and navigates in the other sections of the app and when user returns back to the WebView section of the app, the WebView section should not be reloaded. Not only that, even if the user goes to other applications in the smartphone and returns back to the WebView section of the app, the WebView section should not be reloaded. How is it possible to preserve the state of the WebView in iOS?
Any possible solutions are welcomed!
You could possibly use UserDefaults to help with this. Something like the following untested code:
let defaultURLString = "https://yoursite.com/home"
override func viewDidLoad() {
super.viewDidLoad()
if let savedURL = UserDefaults.standard.url(forKey: "webViewUrl") {
// Load webview with url here
webView.load(URLRequest(url: savedURL))
} else {
// Load default url here
if let defaultURL = URL(string: self.defaultURLString) {
webView.load(URLRequest(url: defaultURL))
}
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let currentUrl = webView.url {
UserDefaults.standard.set(currentUrl, forKey: "webViewUrl")
}
}
You may need to clear the defaults for the webViewUrl key upon app startup.
If you would like the user to go to the same url every time they return to the webView try:
let defaultURLString = "https://yoursite.com/home"
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let defaultURL = URL(string: self.defaultURLString) {
webView.load(URLRequest(url: defaultURL))
}
}
If you would like the user to not be able to navigate to other links within the webView, set the delegate to self and add the delegate method shouldStartLoadWith. Here you can check if the user clicked a link and prevent them from going anywhere, like so:
class TestViewController: UIViewController, UIWebViewDelegate {
#IBOutlet private(set) var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
self.webView.delegate = self
let url = URL(string: "https://yoursite.com/home")
self.webView.loadRequest(URLRequest(url: url!))
}
// MARK: UIWebViewDelegate
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
if navigationType == .linkClicked {
return false
}
return true
}
}

Display PDF file in Swift 4

import UIKit
import WebKit
class ViewController: UIViewController, UIDocumentInteractionControllerDelegate {
var docController: UIDocumentInteractionController!
override func viewDidLoad() {
super.viewDidLoad()
docController = UIDocumentInteractionController.init(url: URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(urlVal!))
docController.delegate = self
docController.presentPreview(animated: true)
}
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
}
Above code I'm not able to display the pdf file. Can anyone help?
By seeing your code it seems that you missed to add UIDocumentInteractionControllerDelegate delegate method.
class ViewController: UIViewController,UIDocumentInteractionControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
var docController = UIDocumentInteractionController.init(url: URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(urlVal!))
docController.delegate = self
docController.presentPreview(animated: true)
}
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
}
OR
You can also view PDF by loading it into WKWebView.
override func viewDidLoad() {
super.viewDidLoad()
let pdfFilePath = Bundle.main.url(forResource: "iostutorial", withExtension: "pdf")
let urlRequest = URLRequest.init(url: pdfFilePath!)
webView = WKWebView(frame: self.view.frame)
webView.load(request)
self.view.addSubview(webView)
}
Basically you are missing the UIDocumentInteractionControllerDelegate implementation. For preview, you should implement this method
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController
Return which ViewController need to display the Preview. If you pass the self View Controller it will display the PDF preview in the existing view controller modally. Just do this one in your View controller if you want to display the preview in the same controller.
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
If you are already doing this in your code, there is high chance of PDF URL path might be wrong.
I would use the Quicklook framework instead, it supports a wide range of document types:
iWork documents
Microsoft Office documents
PDF files
Images
Text files
Rich-Text Format documents
Comma-Separated Value files (csv)
Supports sharing of the relevant documents as well and is easy to implement.
Follow this tutorial on how to do it in Swift: https://www.appcoda.com/quick-look-framework/
Swift 5
Import this framework
import SafariServices
Then call this sentences whenever you need
if let url = URL(string: "YOUR_PDF_URL") {
let config = SFSafariViewController.Configuration()
config.entersReaderIfAvailable = true
let vc = SFSafariViewController(url: url, configuration: config)
present(vc, animated: true)
}
The code will present a Safari view with the pdf on it.

Safari ViewController with enabled address bar

I'm using Safari ViewController and address bar is disabled. How can I make it enabled so user can enter other url?
Here is the code that I'm using
class ViewController: UIViewController, SFSafariViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func showSafariVC(_ sender: AnyObject) {
let svc = SFSafariViewController(url: NSURL(string: "http://www.google.com") as! URL)
svc.delegate = self
present(svc, animated: true, completion: nil)
}
}
It is unable to edit SFSafariViewController 's URL as described here.
And in Apple developer site they mentioned that too:
A read-only address field with a security indicator and a Reader
button
Hope this help!

How to open Safari View Controller from a Webview (swift)

I have an app that is currently using a webview and when certain links are clicked in the webview, it opens those links in Safari. I now want to implement the Safari View Controller(SVC) instead of booting it to the Safari app. I have done research and looked at examples on the SVC; however, all I see are ones that open the SVC from the click of a button. Does anyone have any suggestions for me to look at or to try?
Here is some of my code:
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
let host = request.URL!.host!;
if (host != "www.example.com"){
return true
} else {
UIApplication.sharedApplication().openURL(request.URL!)
return false
}
return true
}
func showLinksClicked() {
let safariVC = SFSafariViewController(URL: NSURL(string: "www.example.com")!)
self.presentViewController(safariVC, animated: true, completion: nil)
safariVC.delegate = self }
func safariViewControllerDidFinish(controller: SFSafariViewController) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
If I am understanding correctly you are loading a page on webview which has certain links now when user clicks on link you want to open those page in SVC. You can detect link click in webview using following delegate method and then open SVC from there.
EDIT
Based on edited question I can see that you are not calling showLinksClicked func , you can call this function as I have updated in following code and it should work.
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
self.showLinksClicked()
return false
}
return true;
}
func showLinksClicked() {
let safariVC = SFSafariViewController(url: URL(string: "www.google.com")!)
present(safariVC, animated: true, completion: nil)
safariVC.delegate = self
}
func safariViewControllerDidFinish(controller: SFSafariViewController) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
For Swift 3:
First, import SafariServices and integrate the delegate into your class:
import SafariServices
class YourViewController: SFSafariViewControllerDelegate {
Then, to open Safari with the specified url:
let url = URL(string: "http://www,google.com")!
let controller = SFSafariViewController(url: url)
self.present(controller, animated: true, completion: nil)
controller.delegate = self
And now you can implement the delegate callback to dismiss safari when the user is finished:
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
This piece of code will allow you to do this.
let safariVC = SFSafariViewController(URL: NSURL(string: "https://www.google.co.uk")!)
self.presentViewController(safariVC, animated: true, completion: nil)
safariVC.delegate = self
You may need to add this to the top of the class as well:
import SafariServices
Solution For Swift 4
Step 1:
import Safari Service In you Class
import SafariServices
Step 2:
Import SFSafariViewControllerDelegate in With your View Controller
class ViewController: UIViewController,SFSafariViewControllerDelegate {...}
Step 3:
Create A function to Open Safari View Controller.
func openSafariVC() {
let safariVC = SFSafariViewController(url: NSURL(string: "https://www.google.com")! as URL)
self.present(safariVC, animated: true, completion: nil)
safariVC.delegate = self
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
Step 4:
call the function openSafariVC
openSafariVC()
Note: Don't forget To Add Navigation Controller with your View
Controller.
Now your SafariVC is ready to open your Link within an app without Using UIWebView Oe WKWebView
Follow the steps :
On your controller file(e.g. ViewController.swift) import SafarriServices.
import SafariServices
Then where you want to open link write
let controller = SFSafariViewController(URL: NSURL(string: "https://www.google.co.uk")!)
self.presentViewController(controller, animated: true, completion: nil)
controller = self
Swift 4.2
This is how you can open-up Safari browser within your application.
import SafariServices
whenever you want to open, like wise on
#IBAction func btnOpenWebTapped(_ sender: UIButton) {
self.openWeb(contentLink: "https://www.google.com")
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.openWeb(contentLink: "https://www.google.com")
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.openWeb(contentLink: "https://www.google.com")
}
by write the custom function be like and you can customise the properties of the SFSafariViewController, preferredBarTintColor, preferredControlTintColor, dismissButtonStyle, barCollapsingEnabled
func openWeb(contentLink : String){
let url = URL(string: contentLink)!
let controller = SFSafariViewController(url: url)
controller.preferredBarTintColor = UIColor.darkGray
controller.preferredControlTintColor = UIColor.groupTableViewBackground
controller.dismissButtonStyle = .close
controller.configuration.barCollapsingEnabled = true
self.present(controller, animated: true, completion: nil)
controller.delegate = self
}
last and the most important thing is don't forget to bind the delegate of the SFSafariViewController with your view controller. you can do this by below mentioned extension code.
extension YourViewController: SFSafariViewControllerDelegate
{
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
}
Happy coding Thank you :)
import SafariServices
class ViewController: UIViewController, SFSafariViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
let url = URL(string: "http://www.google.com")!
let controller = SFSafariViewController(url: url)
self.present(controller, animated: true, completion: nil)
controller.delegate = self
}
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
dismiss(animated: true)
}
}

Resources