How to open url programmatically but not open in browser swift - ios

I need open url programmatically when user click to cell, but not need segue to Safari browser. It is need for statistic on site.
This is need to imitation like post request
I do:
UIApplication.shared.openURL(URL(string: url)!)
But this open Safari browser.

If I'm not mistaking, you want to open the URL in the application it self (without navigating to external -Safari- browser). Well, if that's the case, you should use UIWebView:
You can use the UIWebView class to embed web content in your app. To
do so, create a UIWebView object, attach it to a window, and send it a
request to load web content. You can also use this class to move back
and forward in the history of webpages, and you can even set some web
content properties programmatically.
WebViewController:
I suggest to add a UIWebView into a ViewController (called WebViewController) and present the ViewController when needed; ViewController on storyboard should looks like:
DON'T forget to assign a Storyboard ID for it.
And the ViewController:
class WebViewController: UIViewController {
#IBOutlet weak private var webVIew: UIWebView!
var urlString: String?
override func viewDidLoad() {
if let unwrappedUrlString = urlString {
let urlRequest = URLRequest(url: URL(string: unwrappedUrlString)!)
webVIew.loadRequest(urlRequest)
}
}
#IBAction private func donePressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
Usage:
Consider that you want present it when the user taps a button in another ViewController:
class ViewController: UIViewController {
#IBAction private func donePressed(_ sender: Any) {
let stoyrboard = UIStoryboard(name: "Main", bundle: nil)
// withIdentifier: the used storyboard ID:
let webViewController = stoyrboard.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
webViewController.urlString = "https://www.google.com/"
}
}
Or specifically for your case (selecting a cell):
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// withIdentifier: the used storyboard ID:
let webViewController = stoyrboard.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
webViewController.urlString = "URL GOES HERE..."
}
Hope this helped.

if your question really means that you have some data on an external website that you need to access, so that you can extract a piece of information from it, then you probably don't need to display the rendered webpage at all.
You can extract the html content of a page like this
var text = ""
let url = URL(string: "https://www.bbc.co.uk")
do
{
text = try String(contentsOf: url!, encoding: String.Encoding.utf8)
}
catch
{
print("error \(error.localizedDescription)")
}
if !text.isEmpty
{
parseThisPageSomehow(text)
}
How you parse the text depends on what you need to get out of it, but this approach will give you the data you need.
If you use http rather than https, you will run into the well-documented transport security issue, which will force you to either set up a temporary override for http, or start using https
Transport security has blocked a cleartext HTTP

Related

WkWebView how manage events and window launched by input type file

This is my first app to iOS and i do the same app to Android without problems and now i'm stucked to this problem.
When the user click on "choose file" into webview the phone ask me where i want pick the photo (or file), and if i select "Close" the entire WebView get closed!
How can i manage that events? (image below show the windows that take me this problems)
Same problem if i click to a loaded attachment a appear a window that show me the image and if i long press the image some buttons appear (copy, download or close).... if i press one of them the WebView get closed...
The back button is disabled because the user can't use back in this case and must follow the workflow forced by webview.
I try with this code but still close the webview
import UIKit
import WebKit
class MyWebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
//Variable used for take received data from other ViewControllers
var urlString = String()
var callerString = String()
// MARK: - Properties
#IBOutlet weak var myWebView: WKWebView!
#IBOutlet weak var backButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
if callerString == "CodeController"{
backButton.isEnabled = false
} else {
backButton.isEnabled = true
}
myWebView.navigationDelegate = self
view.addSubview(myWebView)
// Do any additional setup after loading the view.
let url = URL(string: urlString)
myWebView.load(URLRequest(url : url!))
}
#IBAction func backButtonAction(_ sender: Any) {
if callerString != "CodeController"{
if myWebView.canGoBack{
myWebView.goBack()
}else {
//Go to Main View
self.navigationController?.popViewController(animated: true)
self.performSegue(withIdentifier: "backOnViewControllerSegue", sender: self)
}
}
}
Here some images of which buttons close the entire WebView and how manage them in a different way?
It was a bug from WkWebView libraries.
To avoid that just upgrade OSX and XCODE to last versions and the problem is solved.
Not sure if it's solved for all iOS OS but sure for iOS 12, and maybe 10

How to show a preview for web url contents when web address is typed in Textbox using Swift 3.0?

Scenario:
Creating a social network app type application, when user type the web address or valid url in the text area my app should identify the valid url,then I have to do the following tasks,
1) If it is a valid web url then automatically show the preview of the web contents in the preview section.
2) Share button should not be enabled until the preview is fully loaded, if not there are some chances that URL alone may be posted instead of the web contents.
What I have tried?
Created a Text view and a preview WebUI view, I used following code to identify the valid URL, if valid url then I am showing the web view and loading the web page.
Code what I tried:
class CommentsViewController: UIViewController {
#IBOutlet weak var comments: UITextField!
#IBOutlet weak var preview: UIWebView!
#IBOutlet weak var btnShare: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
preview.isHidden = true
btnShare.isEnabled = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func valueModified(_ sender: Any) {
//Load web preview only after Check for Valid Web URL
if verifyUrl(urlString: comments.text) == true {
preview.isHidden = false
preview.loadRequest(URLRequest(url: URL(string: comments.text!)!))
btnShare.isEnabled = true
}
}
//Check for Valid Web URL
func verifyUrl (urlString: String?) -> Bool {
//Check for nil
if let urlString = urlString {
// create NSURL instance
if let url = NSURL(string: urlString) {
// check if your application can open the NSURL instance
return UIApplication.shared.canOpenURL(url as URL)
}
}
return false
}
}
What I need exactly?
I do not want to load the web page, I have to load the preview of the page.
Share button should be hidden until the preview is fully loaded.
Screen shot of my code output:
Screen shot of what I am expecting:

Xcode Opening a WebView in another ViewController

I'm trying to make an app with a button which launch a webview.
I've followed many tutorial and read differents topic about the subject but I cant get it working : I'm getting this message when I test my code :
"Cannot call value of non-function type UIWebView!"
Here's the steps I did until now
Adding a button in the principal view Controller
Creating an another view Controller named 'WebViewController'
Adding a segue to link the button to WebViewController
Creating a new Cocoa Touch Class file 'WebViewController'
Setting the WebViewController custom class with the WebViewController class
Adding a webView in the WebViewController ViewController named 'myWebView'
Here's the WebViewController class (in which I got the error when I run the project)
import UIKit
class WebViewController: UIViewController{
#IBOutlet weak var myWebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//define url
let url = NSURL (string: "http://www.my-url.com")
//request
let req = NSURLRequest(url: url as! URL)
//load request into the webview
myWebview(req as URLRequest) //error happens here :
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Here's a screenshot (picture talks more than long text, right =)
Thanks !
You can use SFSafariViewController:
import SafariServices
let url = URL(string: "https://www.google.com")
let safariVC: SFSafariViewController = SFSafariViewController(url: url)
self.present(safariVC, animated: true, completion: nil)
I used swift 3 syntax.
That code opens a Safari Web view and you dont need to create segues and view controlles in storyboard.
Try to use:
let url = NSURL (string: "https://google.com")
let request = NSURLRequest(url: url as! URL)
self. myWebView.loadRequest(request as URLRequest)
This code works for me

Open with file in swift

When you open url that contain PDF file safari ask you if you want to open it on safari or in iBook.
I want to do the same thing ,
in my project i had a collection view contains videos and photos,
i want the user to chose if he want to open the file on the app or to open it with other media player.
For loading into your own app it depends on which class you're using to display content on the exact code you'd use but for opening in another app you'd normally use a share button. Here is example code that will work if you wire up the #IBAction and #IBOutlet to the same bar button in your UI (and place a file at the fileURL that you specify):
import UIKit
class ViewController: UIViewController {
// UIDocumentInteractionController instance is a class property
var docController:UIDocumentInteractionController!
#IBOutlet weak var shareButton: UIBarButtonItem!
// called when bar button item is pressed
#IBAction func shareDoc(sender: AnyObject) {
// present UIDocumentInteractionController
if let barButton = sender as? UIBarButtonItem {
docController.presentOptionsMenuFromBarButtonItem(barButton, animated: true)
}
else {
print("Wrong button type, check that it is a UIBarButton")
}
}
override func viewDidLoad() {
super.viewDidLoad()
// retrieve URL to file in main bundle
if let fileURL = NSBundle.mainBundle().URLForResource("MyImage", withExtension: "jpg") {
// Instantiate the interaction controller
self.docController = UIDocumentInteractionController(URL: fileURL)
}
else {
shareButton.enabled = false
print("File missing! Button has been disabled")
}
}
}
Notes
A UIDocumentInteractionController is used to enable the sharing of documents between your app and other apps installed on a user's device. It is simple to set up as long as you remember three rules:
Always make the UIDocumentInteractionController instance a class
(type) property. If you only retain a reference to the controller
for the life of the method that is triggered by the button press
your app will crash.
Configure the UIDocumentInteractionController
before the button calling the method is pressed so that there is not
a wait in which the app is waiting for the popover to appear. This is important because while
the presentation of the controller happens asynchronously, the instantiation does not. And you may find that there is a noticeable delay to open the popover if
you throw all the code for instantiation and presentation inside a
single method called on the press of a button. (When testing you might see a delay anyway because the share button is likely going to be pressed almost straightaway but in real world use there should be more time for the controller to prepare itself and so the possibility of lag is less likely.)
The third rule is that you must test this on a real device not in the simulator.
More can be found in my blogpost on the subject.
Edit: Using a UIActivityViewController
Code for using UIActivityViewController instead of UIDocumentInteractionController
import UIKit
class ViewController: UIViewController {
// UIDocumentInteractionController instance is a class property
var activityController: UIActivityViewController!
#IBOutlet weak var shareButton: UIBarButtonItem!
// called when bar button item is pressed
#IBAction func shareStuff(sender: AnyObject) {
if let barButton = sender as? UIBarButtonItem {
self.presentViewController(activityController, animated: true, completion: nil)
let presCon = activityController.popoverPresentationController
presCon?.barButtonItem = barButton
}
else {
print("not a bar button!")
}
}
override func viewDidLoad() {
super.viewDidLoad()
// retrieve URL to file in main bundle
if let img = UIImage(named:"MyImage.jpg") {
// Instantiate the interaction controller
activityController = UIActivityViewController(activityItems: [img], applicationActivities: nil)
}
else {
shareButton.enabled = false
print("file missing!")
}
}
}
You can also add custom activities to the UIActivityViewController and here is code for adding an "Open In..." button to a UIActivityViewController so that you can switch to a UIDocumentInteractionController from a UIActivityViewController.
I did the same code for saving a PDF file from a URL (whether it's a local URL in your device storage, or it's a URL from somewhere on the internet)
Here is the Code for Swift 3 :
#IBOutlet weak var pdfWebView: UIWebView!
#IBOutlet weak var shareBtnItem: UIBarButtonItem!
var pdfURL : URL!
var docController : UIDocumentInteractionController!
then in viewDidLoad()
// retrieve URL to file in main bundle`
let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("YOUR_FILE_NAME.pdf")
//Instantiate the interaction controller`
self.docController = UIDocumentInteractionController(url: fileURL)`
and in your barButtonItem tapped method (which I have called openIn(sender)):
#IBAction func openIn(_ sender: UIBarButtonItem)
{
// present UIDocumentInteractionController`
docController.presentOptionsMenu(from: sender, animated: true)
}
FYI: You need a webView in your storyboard if you wish to show the pdf file as well
Hope this helps.

Swift 2 - Cannot load UIWebView in separate ViewController

I'm running into a bizarre problem - I cannot load a UIWebView in the background of a separate viewcontroller. Specifically, I have a UITableViewCell with a button to load a UIWebView in the viewcontroller behind it. However, I keep getting the error "found nil while unwrapping an Optional value"...
Here is my code:
func loadWebView(URLString:String) {
print("the urlstring is \(URLString)")
let theRequestURL = NSURL (string: URLString)
let theRequest = NSURLRequest (URL: theRequestURL!)
fullScreenWebView.loadRequest(theRequest)
}
The print statement yields the correct URL, so the issue isn't that the URL string isn't being passed.
Furthermore, if I load the UIWebView from the viewcontroller it's defined in, it works perfectly. I'm guessing the issue has to do with not being the correct viewcontroller when loadWebView() is called... I read Unable to display URL in WebView from another view controller, which was somewhat helpful.
What am I doing wrong?
When calling loadRequest using
SecondViewController().loadWebView("URL STRING HERE")
You are creating a new instance of the SecondViewController rather than using the one that has already been loaded.
What you need is call loadRequest on the instance that is already in memory, and has your UIWebView initialized.
For this you can get reference of the previous view controller and call a method to load your request
Assuming SecondViewController is the controller with UIWebView
Add this In the top view controller (Controller with your UITableView)
func loadWebView(URLString:String) {
print("the urlstring is \(URLString)")
let theRequestURL = NSURL (string: URLString)
if let theRequest = NSURLRequest (URL: theRequestURL!) {
//In case you push view controller on a navigation stack
let vc : SecondViewController = self.backViewController()
vc.loadWebView(theRequest)
}
}
//Get previous view controller on navigation stack
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for(var i=stack.count-1;i>0;--i) {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
Now in your SecondViewController, add
func loadWebView(request : NSURLRequest) {
// Replace customWebView with the reference variable of your `UIWebView`
customWebView.loadRequest(request)
}
The reason you are getting this error is because you are force unwrapping a nil value. I would always suggest unwrapping nullable values using an if let statement:
func loadWebView(URLString:String) {
print("the urlstring is \(URLString)")
if let theRequestURL = NSURL (string: URLString) {
let theRequest = NSURLRequest (URL: theRequestURL!)
fullScreenWebView.loadRequest(theRequest)
}
}
Not every string can be converted into a URL, which is why NSURL(string:) returns a optional value. I would inspect why your URLString can't be parsed into a URL

Resources