Topics

How to present a web view while supporting 10.9?

John Brownie
 

My app currently supports 10.9, and I want to add a feature that displays an HTML document stored locally (in the bundle). The obvious way is to have a window which contains a web view. However, WKWebView is only available in 10.10, and WebView is deprecated.

If it were a matter of calling a method, I could wrap it with availability calls, but it's a definition of the class of an element in a window controller class. Presumably there is a way to handle this, but I haven't discovered it.

What I'm looking for is something like

if #available(macOS 10.10, *) {
    var webView: WKWebView
}
else {
    var webView: WebView
}

...but that is for running code, not declarations.

Is there a way to do this through IB? Or is my alternative to build the window in code, using whatever is available based on the runtime platform?

John
--
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland

Sandor Szatmari
 

What SDK are you building against?
I assuming deployment target of 10.9 and not earlier…

What is the exact problem your having? Is it just warnings, or are there compile/link/runtime errors…

I just set the deployment target of an app with a WKWebView to 10.9 and build SDK 10.14. I got warnings of WKWebview et. all… not being available on 10.9 but it compiled and ran fine on Mojave. I’m assuming the availability conditionals would allow selection of WebView code if I ran it on some earlier release.

I added a reference to a plain WebView and it did not complain about that with the deployment target set to 10.9.

Sandor


On Feb 6, 2020, at 08:07, John Brownie <@JohnBrownie> wrote:

My app currently supports 10.9, and I want to add a feature that displays an HTML document stored locally (in the bundle). The obvious way is to have a window which contains a web view. However, WKWebView is only available in 10.10, and WebView is deprecated.

If it were a matter of calling a method, I could wrap it with availability calls, but it's a definition of the class of an element in a window controller class. Presumably there is a way to handle this, but I haven't discovered it.

What I'm looking for is something like

if #available(macOS 10.10, *) {
var webView: WKWebView
}
else {
var webView: WebView
}

...but that is for running code, not declarations.

Is there a way to do this through IB? Or is my alternative to build the window in code, using whatever is available based on the runtime platform?

John
--
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland


John Brownie
 

Thanks for the reply.

Sandor Szatmari wrote on 6/2/20 20:51:
What SDK are you building against?
I assuming deployment target of 10.9 and not earlier…
I'm still on 10.14.6, Xcode 11.0, current SDK, which I assume is 10.14 (I can't see an option to choose anything but a platform in the SDK pop-up).
What is the exact problem your having? Is it just warnings, or are there compile/link/runtime errors…
I create a window in IB, and add a WKWebView to fill the content view. I then create an outlet to that, and Xcode wants me to mark the whole class (in Swift) as being available in 10.10 or later, and that's an error, not a warning. So there is a problem with what I do if I'm running on 10.9. Maybe I should just do it in Objective-C instead?

I have done this before with API available only on some platforms, but it's the first time I've run across it in a view built with IB. It's probably something quite simple, but I haven't been able to find an answer.
I just set the deployment target of an app with a WKWebView to 10.9 and build SDK 10.14. I got warnings of WKWebview et. all… not being available on 10.9 but it compiled and ran fine on Mojave. I’m assuming the availability conditionals would allow selection of WebView code if I ran it on some earlier release.
Not having the luxury of more than my own computer to test on, I can't tell what would happen if I did that and ran on 10.9. I'm still in the design/coding phase of this particular item.
I added a reference to a plain WebView and it did not complain about that with the deployment target set to 10.9.
With all the dire warnings about not using WebView, I'd much rather aim for WKWebView if possible. And this is only for a maintenance release, so I don't want to change the deployment target to 10.10 just for this.

John
--
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland

John Brownie
 

I should note that, once I put the WKWebView into the window, there is an error that I hadn't noticed before:
error: Class Unavailable: WKWebView before macOS 10.12 (NSCoding support was broken in previous versions)
So I would have to drop support for 10.9-10.11 to use WKWebView, so I really need to work out how to do this.

Is building the window in code the solution?

John

Sandor Szatmari
 

Yes I could have been more specific, everything worked, all be it with warnings, with both classes of web views being instantiated in code.  

Sandor

On Feb 7, 2020, at 10:13, John Brownie <john_brownie@...> wrote:

I should note that, once I put the WKWebView into the window, there is an error that I hadn't noticed before:
error: Class Unavailable: WKWebView before macOS 10.12 (NSCoding support was broken in previous versions)
So I would have to drop support for 10.9-10.11 to use WKWebView, so I really need to work out how to do this.

Is building the window in code the solution?

John

 

You'll need two code paths, one that instantiates and runs a WebView, the other that instantiates and runs a WKWebView. Their APIs and functionality are not identical, so it's not just a question of "how do I get IB to instantiate the right class". Your controller code needs to be different.

I would create my own abstract view and controller class for this (MyWebView and MyWebViewController?), then have concrete subclasses of each for the old and new WebViews. Each view class instantiates the appropriate system view and makes it a subview of itself.

—Jens

John Brownie
 

Thanks for all the tips. I have it all worked out now.

John

Jens Alfke wrote on 7/2/20 21:39:

You'll need two code paths, one that instantiates and runs a WebView, the other that instantiates and runs a WKWebView. Their APIs and functionality are not identical, so it's not just a question of "how do I get IB to instantiate the right class". Your controller code needs to be different.

I would create my own abstract view and controller class for this (MyWebView and MyWebViewController?), then have concrete subclasses of each for the old and new WebViews. Each view class instantiates the appropriate system view and makes it a subview of itself.
--
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland