I am creating a simple web viewer using WKWebView and the Swift language. Here is my code.
import Cocoa
import WebKit
#NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet var containerView : NSView! = nil
#IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
var webView: WKWebView
webView = WKWebView() //Thread 1:EXC_BAD_ACCESS (code=1,address=0x20)
var url = NSURL(string:"http://www.google.com/")
var req = NSURLRequest(URL: url!)
webView.loadRequest(req)
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}
I'm now getting a "Thread 1:EXC_BAD_ACCESS" error on the webView = WKWebView() line when I try to run the application. How can I fix this?
If that's it's all your code, than I'd say you're missing to instantiate the WKWebView. Put a breakpoint on the self.webView!.loadRequest(req) line and check whether it's nil or not.
I've never worked with WKWebView, but I think that you need a view controller. Maybe this blog post can help you: Getting started with WKWebView using Swift in iOS 8
You forgot to initialise your WKWebView
var webView = WKWebView(frame: CGRectMake(0, 0, 320, 480))
var url = NSURL(string:"http://www.google.com/")
var req = NSURLRequest(URL: url)
webView.loadRequest(req)
I get this error whenever I try to use a brand new minimal class as a delegate. For example:
class MyDelegate: NSObject, UIWebViewDelegate { /* ... */ }
This does not happen when I try to use the default ViewController as a delegate. For example:
class ViewController: UIViewController, UIWebViewDelegate { /* ... */ }
I would suggest using the ViewController as a delegate until we get to the bottom of this.
Related
I have implemented the iOS Intune SDK in my app. The app applies the MAM policies and is working properly. I am trying to implement the Webview content restrictions using the IntuneMAMWebViewPolicyDelegate and isExternalURL as described here
The isExternalURL function is never called.
This is the view containing my WKWebView
import UIKit
import WebKit
import IntuneMAMSwift
class WebviewPage: UIViewController {
let webViewPolicyDelegage = WebViewPolicyClass.init();
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
IntuneMAMPolicyManager.instance().setWebViewPolicyDelegate(webViewPolicyDelegage, forWebViewer: webView!)
let webaddress = "https://www.google.com"
if let url = URL(string: webaddress) {
let urlRequest = URLRequest(url: url)
self.webView.load(urlRequest)
}
}
}
This is my delegate implementation
import IntuneMAMSwift
class WebViewPolicyClass: NSObject, IntuneMAMWebViewPolicyDelegate {
func isExternalURL(_ url: URL) -> Bool {
// TODO: Check if URL is external
return true
}
}
The app MAM policy is configured to require the managed Edge browser.
Any ideas why the delegate method is not called?
I am creating one SDK to get the url from user and load. So ai m creating my own class with WKWebview. But i am getting few issues about Instance member 'webView' cannot be used on type 'MyWebView(UIview)'
Code :
import Foundation
import WebKit
public class MyWebView: UIView, WKNavigationDelegate {
// initialize the view
var webView: WKWebView!
// load the view
private func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
}
// get the url and load the page
public static func loadUrl(Url: String) {
MyWebView.webView.load(URLRequest(url: URL(string: Url)!))
}
}
In my loadUrl, what ever user sending i need to use that url and load the url. Same in my view controller will look like :
import UIKit
class ViewController: UIViewController {
var webView: MyWebView!
override func loadView() {
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Any help would be great.
Your loadUrl function should not be static, since it needs access to an instance property, webView. Making the function non-static solves the issue.
Also a couple of minor improvements: don't force unwrap the URL init, since with an incorrect input that will crash. Use optional binding to safely unwrap it instead. I'd also suggest renaming the input argument label on loadUrl, since there's no point in having to right out loadUrl(Url:) every time you call the func, loadUrl( reads more naturally.
public func loadUrl(_ urlString: String) {
guard let url = URL(string: urlString) else { return }
webView.load(URLRequest(url: url))
}
Could anyone help me in understanding why my webView is not getting initialized here. I am getting the following error because webView is nil.
Fatal error: Unexpectedly found nil while unwrapping an Optional value
What exactly I am missing here?
import UIKit
import WebKit
class MemoriesViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear( animated )
let urlString:String = "https://www.apple.com"
let url:URL = URL(string: urlString)!
let urlRequest:URLRequest = URLRequest(url: url)
webView.load(urlRequest)
}
}
}
Screenshot for better clarity where the error is actually happening:
Add Webkit.Frameworks to Linked Framework and Libraries
You can then add the Outlet for WKWebView and use your code
import UIKit
import WebKit
class MyWebViewController: UIViewController {
#IBOutlet weak var myWV: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let urlString:String = "https://www.apple.com"
let url:URL = URL(string: urlString)!
let urlRequest:URLRequest = URLRequest(url: url)
myWV.load(urlRequest)
}
}
In Xcode 10, you can foll bellow the step:
Click the project
Go to build phase
Go to Link Binary with Libraries
Click add plus sing under Link Binary with Libraries
open a windows & search Webkit.framework
add & enjoy it
Show bellow image
The problem was my output was not connected to the storyboard. That's why #IBOutlet was not getting initialized.
I noticed the WKWebView documentation now lists a method called takeSnapshot that is supported by iOS 11 and macOS 10.13 and above (Xcode 9 beta).
Has anyone played around with yet or implemented? I'm trying to get it working in a playground but I'm not sure where to start? Is this a method on a WKWebView?
My code:
import UIKit
import PlaygroundSupport
import WebKit
let frame = CGRect(x: 0, y: 0, width: 800, height:600)
let web = WKWebView(frame: frame)
let rq = URLRequest(url: NSURL(string: "http://apple.com")! as URL)
web.load(rq)
PlaygroundPage.current.liveView = web
PlaygroundPage.current.needsIndefiniteExecution = true
//Take snapshot?
As far as I tested, the method takeSnapshot(with:completionHandler:) actually exists as an instance method and works as expected.
Just that it's a little hard to use it.
The method declares its first parameter as WKSnapshotConfiguration?, but the class WKSnapshotConfiguration is not imported with import WebKit. You can pass nil to the parameter, but to use the method, you need to import the type WKSnapshotConfiguration. And I could not have found any dependent submodules to import WKSnapshotConfiguration.
So, if you want to play with this new feature, you need to create an App project with bridging-header.
(If you know how to use bridging-header in the Playground, you may test this feature in it. But I do not know if you can or how.)
{ProjectName}-Bridging-Header.h:
#import CoreGraphics;
#import <WebKit/WKSnapshotConfiguration.h>
And an example of ViewController.swift:
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: URL(string: "http://apple.com")!)
webView.load(request)
}
#IBAction func buttonPressed(_ sender: UIButton) {
webView.takeSnapshot(with: nil) {image, error in
if let image = image {
self.imageView.image = image
print("Got snapshot")
} else {
print("Failed taking snapshot: \(error?.localizedDescription ?? "--")")
}
}
}
}
(Place a WKWebView, a UIImageView and a UIButton on a View.)
One more, this seems to be a bug of WebKit framework, you should better send a bug report to Apple.
I'm working on a simple web wrapper application for iOS, and I'm having some issues with WKWebView and WKNavigationDelegate. I want to use the didFinishNavigation function from WKNavigationDelegate, so I can grab information from the URL query on navigation (namely a session GUID). My program launches correctly and loads my webpage when I comment out the "webView.navigationDelegate = self" line, but when I include that, my app crashes immediately with the following errors:
" -[UIWebView setNavigationDelegate:]: unrecognized selector sent to instance
0x7f8251e058f0"
"*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UIWebView setNavigationDelegate:]: unrecognized selector sent to
instance 0x7f8251e058f0'"
I noticed that both of these error messages include "UIWebView," when I'm trying to use WKWebView, so I tried to use the "custom class" field on the webview from the identity inspector part of the storyboard, but when I try to run after that, I get "(lldb)." Any help/insight would be appreciated, I'm including my code below:
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
print("view did load")
webView.navigationDelegate = self
loadURL("http://mydomain/login.html")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func loadURL(targetURL: String){
if let url = NSURL(string: targetURL) {
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
}
}
private func checkDomainGetSessionGUID(){
print ("we are here")
if let query = webView.URL?.query {
let queryArr = query.componentsSeparatedByString("&")
var parsedQuery : [String: String] = [:]
for field in queryArr {
let parts = field.componentsSeparatedByString("=")
parsedQuery.updateValue(parts[1], forKey: parts[0])
print ("key = \(parts[0]) and value = \(parts[1])")
}
}
else {
print ("didn't enter the if let")
}
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
print ("delegate")
checkDomainGetSessionGUID()
}
}
PROCEDURE 1:
Step-1: Check UIElements that you are using in Storyboard design. if you had used Web view instead of using **WebKit View this error might come.Check your IBOutlet connection.
Step-2: Check your IOS deployment target, It must be IOS 11 and above because of UIWebKit View was released in IOS 8 but it contains a bug that was fixed in IOS 11 only. So set your deployment target 11 and above.
Step-3: Check your info.plist property. The following property should add in the listApp Transport Security Settings -> Allow Arbitrary Loads -> YES
PROCEDURE 2:
If in case you want deployment target as IOS 10 or below IOS 11 means you can implement like this
Step-1: Create a new UIViewcontroller with its swift ViewController file. And add below-given code to run your URL:
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
var webView: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string:"https://www.apple.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}}
I hope this might be helpful to you...
I was getting this error inside (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
I removed the line [super webView:webView didFinishNavigation:navigation]; and everything worked as I expected, I'm not sure if it's hacky though.