mirror of
https://github.com/dirtydishes/dreamio.git
synced 2026-06-06 13:37:24 +00:00
build wkwebview mvp shell
This commit is contained in:
parent
e8993ee7d1
commit
d4e49cde1e
7 changed files with 830 additions and 0 deletions
19
Dreamio/AppDelegate.swift
Normal file
19
Dreamio/AppDelegate.swift
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import UIKit
|
||||
|
||||
@main
|
||||
final class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
true
|
||||
}
|
||||
|
||||
func application(
|
||||
_ application: UIApplication,
|
||||
configurationForConnecting connectingSceneSession: UISceneSession,
|
||||
options: UIScene.ConnectionOptions
|
||||
) -> UISceneConfiguration {
|
||||
UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
||||
}
|
||||
}
|
||||
140
Dreamio/DreamioWebViewController.swift
Normal file
140
Dreamio/DreamioWebViewController.swift
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
import UIKit
|
||||
import WebKit
|
||||
|
||||
final class DreamioWebViewController: UIViewController {
|
||||
private enum Constants {
|
||||
static let stremioWebURL = URL(string: "https://web.stremio.com/")!
|
||||
}
|
||||
|
||||
private lazy var webView: WKWebView = {
|
||||
let configuration = WKWebViewConfiguration()
|
||||
configuration.defaultWebpagePreferences.allowsContentJavaScript = true
|
||||
configuration.allowsInlineMediaPlayback = true
|
||||
configuration.mediaTypesRequiringUserActionForPlayback = []
|
||||
configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
|
||||
|
||||
let webView = WKWebView(frame: .zero, configuration: configuration)
|
||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||
webView.allowsBackForwardNavigationGestures = true
|
||||
webView.customUserAgent = "Dreamio/0.1 WKWebView"
|
||||
webView.navigationDelegate = self
|
||||
webView.uiDelegate = self
|
||||
webView.scrollView.contentInsetAdjustmentBehavior = .never
|
||||
return webView
|
||||
}()
|
||||
|
||||
private let progressView: UIProgressView = {
|
||||
let view = UIProgressView(progressViewStyle: .bar)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.tintColor = UIColor(red: 0.55, green: 0.35, blue: 0.95, alpha: 1.0)
|
||||
return view
|
||||
}()
|
||||
|
||||
private var progressObservation: NSKeyValueObservation?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
view.backgroundColor = .systemBackground
|
||||
view.addSubview(webView)
|
||||
view.addSubview(progressView)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
webView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||
progressView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
progressView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
progressView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
|
||||
])
|
||||
|
||||
progressObservation = webView.observe(\.estimatedProgress, options: [.new]) { [weak self] webView, _ in
|
||||
self?.updateProgress(webView.estimatedProgress)
|
||||
}
|
||||
|
||||
loadDreamio()
|
||||
}
|
||||
|
||||
private func loadDreamio() {
|
||||
let request = URLRequest(url: Constants.stremioWebURL)
|
||||
webView.load(request)
|
||||
}
|
||||
|
||||
private func updateProgress(_ progress: Double) {
|
||||
progressView.isHidden = progress >= 1.0
|
||||
progressView.setProgress(Float(progress), animated: true)
|
||||
}
|
||||
|
||||
private func showLoadFailure(_ error: Error) {
|
||||
let alert = UIAlertController(
|
||||
title: "Could not load Dreamio",
|
||||
message: error.localizedDescription,
|
||||
preferredStyle: .alert
|
||||
)
|
||||
alert.addAction(UIAlertAction(title: "Retry", style: .default) { [weak self] _ in
|
||||
self?.loadDreamio()
|
||||
})
|
||||
present(alert, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension DreamioWebViewController: WKNavigationDelegate {
|
||||
func webView(
|
||||
_ webView: WKWebView,
|
||||
decidePolicyFor navigationAction: WKNavigationAction,
|
||||
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
|
||||
) {
|
||||
guard let url = navigationAction.request.url else {
|
||||
decisionHandler(.cancel)
|
||||
return
|
||||
}
|
||||
|
||||
if shouldOpenExternally(url: url, navigationType: navigationAction.navigationType) {
|
||||
UIApplication.shared.open(url)
|
||||
decisionHandler(.cancel)
|
||||
return
|
||||
}
|
||||
|
||||
decisionHandler(.allow)
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
||||
showLoadFailure(error)
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
|
||||
showLoadFailure(error)
|
||||
}
|
||||
|
||||
private func shouldOpenExternally(url: URL, navigationType: WKNavigationType) -> Bool {
|
||||
guard let scheme = url.scheme?.lowercased() else {
|
||||
return false
|
||||
}
|
||||
|
||||
if ["http", "https"].contains(scheme) {
|
||||
return false
|
||||
}
|
||||
|
||||
if ["mailto", "tel", "sms"].contains(scheme) {
|
||||
return true
|
||||
}
|
||||
|
||||
return navigationType == .linkActivated
|
||||
}
|
||||
}
|
||||
|
||||
extension DreamioWebViewController: WKUIDelegate {
|
||||
func webView(
|
||||
_ webView: WKWebView,
|
||||
createWebViewWith configuration: WKWebViewConfiguration,
|
||||
for navigationAction: WKNavigationAction,
|
||||
windowFeatures: WKWindowFeatures
|
||||
) -> WKWebView? {
|
||||
if navigationAction.targetFrame == nil {
|
||||
webView.load(navigationAction.request)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
38
Dreamio/Info.plist
Normal file
38
Dreamio/Info.plist
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<false/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default Configuration</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UILaunchScreen</key>
|
||||
<dict/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
20
Dreamio/SceneDelegate.swift
Normal file
20
Dreamio/SceneDelegate.swift
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import UIKit
|
||||
|
||||
final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
var window: UIWindow?
|
||||
|
||||
func scene(
|
||||
_ scene: UIScene,
|
||||
willConnectTo session: UISceneSession,
|
||||
options connectionOptions: UIScene.ConnectionOptions
|
||||
) {
|
||||
guard let windowScene = scene as? UIWindowScene else {
|
||||
return
|
||||
}
|
||||
|
||||
let window = UIWindow(windowScene: windowScene)
|
||||
window.rootViewController = DreamioWebViewController()
|
||||
window.makeKeyAndVisible()
|
||||
self.window = window
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue