How can you get input file to work in a WKWebView? - macos

When you have a WKWebView in an OSX application, when you press a <input type="file"> button, you can't select a file from your harddisk. How would you enable this feature?
I heard that normally you use:
func webView(sender: WebView!, runOpenPanelForFileButtonWithResultListener resultListener: WebOpenPanelResultListener!)
Which is part of the WebUIDelegate but altho you set self.webView.UIDelegate = self it does not get fired.

Here is the 100% working solution for WKWebview "File Upload" Problem.
You just need to implement the UIDelegate:
- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray<NSURL *> *URLs))completionHandler;
Follow this link for more description about this delegate:
RunOpenPanel Delegate

This is a known bug in WKWebView.
https://bugs.webkit.org/show_bug.cgi?id=137759

Related

WKWebView process terminates without sandbox entitlement

I'm trying to build a simple MacOS app with a web view. I'm using WKWebView and for no obvious reason the webViewWebContentProcessDidTerminate() method is called immediately after the web view is initialized without the web view even trying to load anything. After hours of looking in the documentation and in issues online, I cannot figure out why this is happening and how to prevent it. The only thing suggested online was to reload the web view when this happens which results in the method getting called again a moment later and so on endlessly. I'm now down to a completely empty MacOS app with the following source code:
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
var webView: WKWebView!
func applicationDidFinishLaunching(_ aNotification: Notification) {
webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
webView.navigationDelegate = self
}
}
extension AppDelegate: WKNavigationDelegate {
func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
print("web view process did terminate")
webView.reload()
}
}
It doesn't matter if the web view is in the view hierarchy, has a non-zero frame and generally if it is visible or not. I've also enabled arbitrary loads just for the sake of trying out everything.
I would really appreciate some help on this. I'm compiling against 10.13 SDK and running on a MacOS 10.12.
Thanks.
I managed to figure it out. For anybody else struggling with this, you need to add the com.apple.security.network.client entitlement to your app.
If wkwebview is getting terminated, you can add reload method inside webViewWebContentProcessDidTerminate method, which basically reloads the webview.
Check the below code,
file name: CRAWKWebView.m
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
{
RCTLogWarn(#"Webview Process Terminated");
if (webView) {
[webView reload];
}
}
reload instance is provided by wkwebview.

User interface is not visible when the app runs (only in interface builder)

I'm stuck on a very stupid issue. I've built my mac osx app user interface with Interface Builder (and xcode3).
Now when I run my app I can't see the app window (but only the menu on top).
The MyDocument.xib file is correctly loaded (from xCode navigation sidebar) and I can see my user interface in interface builder.
In my code I haven't changed this method:
- (NSString *)windowNibName
{
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return #"MyDocument";
}
What am I doing wrong ?
thanks
Check out the following methods in the NSApplicationDelegate documentation:
(BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
(BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
Each window has an option (checkbox) called visible at start (or something like that; can't check ATM). Doublecheck if that's activated.
It was a bad configured ArrayController!
No error messages.. just the interface not showing up

MacOSX Custom Webkit view + Flash content with clickable links

Symptom:
View the flash website with any browser, the links inside the flash content work and launch a new window
view the flash with my custom WebView, click the same links. No response.
I tried delegating "decidePolicyForNewWindowAction" and "decidePolicyForNavigationAction" but ironically, these are only called after I launch a URL from my code, NOT as a response to the user clicking the link from the page.
I am sure the fact this is a flash app content has something to do with it. I don't know how to resolve this. Help will be appreciated.
You'll need to set a UIDelegate for the WebView, and then implement - (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request in that delegate.
If you then set a policy delegate for the new WebView that you return (that WebView can be in a hidden window), the delegate method that will be called is:
- (void)webView:(WebView *)aWebView
decidePolicyForNavigationAction:(NSDictionary *)actionInformation
request:(NSURLRequest *)request
frame:(WebFrame *)frame
decisionListener:(id < WebPolicyDecisionListener >)listener`
The URL to which the Flash app is trying to send the window is in the WebActionOriginalURLKey of the actionInformation dictionary, and you can at that point decide if you want the navigation to proceed, or send an ignore to the WebPolicyDecisionListener and handle the URL some other way.

WebView integration

I am wondering how to integrate a WebView in a cocoa application:
- How to call javascript function from cocoa in the WebView
- How to handle in cocoa the click in a link inside the WebView
...
Thanks in advance for your help
First of all, there is no NSWebView in cocoa, it's called UIWebView on the iphone and WebView on Mac.
If you want to simply load a page with the webview, create an NSURLRequest (using NSURL) then call - (void)loadRequest:(NSURLRequest *)request
If you want to use javascript functions, just make an NSString containing your script, then call - (NSString*)stringByEvaluatingJavaScriptFromString:(NSString *)script.
I don't fully understand why you want to handle a click inside the webview... If you want to detect a redirect, there is a delegate method that can help you:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

Opening a url on launch

What method must I implement in my cocoa application’s delegate so that on launch, it’ll open a url? (http/https, in this case) I’ve already implemented the url schemes, I just need to know how I can get my application to open on a url notification.
Update: I’m sorry, I wasn’t very clear. My application IS a browser that support https/http urls, but can only open them when it’s already running. What can I do to implement support for open urls in my app on launch?
When an application finishes launching on OS X, NSApp (the global NSApplication instance for the program) sends its delegate the applicationDidFinishLaunching: message (via the notification system). You can implement that method in your delegate to handle the notification and open a browser window in response, using NSWorkspace. Something like the following would work:
// Your NSApp delegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:#"http://www.example.com/"]];
}
It's not a delegate method. You need to implement an Apple Event handler for the getURL event.
As luck would have it, this is exactly the case Apple uses to demonstrate implementing an Apple Event handler.
I already had implemented the getURL event, so that alone isn’t enough to get the application to open a url on launch. The trick is that the AppleEvent must be installed in applicationWillFinishLaunching: not applicationDidFinishLaunching:. Otherwise, the event isn’t sent at all because the app hasn’t registered it in time.
To implement a protocol handler that you can select (in Safari preferences, for example) as the "default browser" and which will launch in response to HTTP / HTTPS, you need to do a few things.
Add .scriptSuite and .scriptTerminology files to your project resources. These will tell Mac OS X that you'll be handling the GetURL command.
Add a CFBundleURLTypes key to your Info.plist file listing the "URL Schemes" that your app will handle.
Also in Info.plist, add the NSAppleScriptEnabled key with the value YES.
Add a new class to your application as a subclass of NSScriptCommand and implement the -(id)performDefaultImplementation selector. From within this function you will find the clicked URL in [self directParameter]. Pass this on to your app's URL handler!
For the full details check out the article:
http://www.xmldatabases.org/WK/blog/1154_Handling_URL_schemes_in_Cocoa.item

Resources