#core-data #swiftui #wkwebview
#core-data #swiftui #wkwebview
Вопрос:
У меня есть WKWebView, который воспроизводит видео на YouTube. Я собрал функциональность воспроизведения / паузы и многое другое. В настоящее время я пытаюсь реализовать CoreData и пытаюсь сохранить информацию о видео YT, которые воспроизводятся в данный момент, например, название видео и идентификатор видео и многое другое.
Я могу сохранить данные, и я также могу видеть свои сохраненные данные, и я могу их удалить. Однако я заметил, что при попытке сохранить видео моя кнопка воспроизведения / паузы больше не работает. Я обнаружил проблему в своих действиях WKWebView, которые больше не работают после сохранения в CoreData, но они работают, пока я не попытаюсь сохранить.
Вызываются функции playVideo и pauseVideo, но кажется, что WKWebView больше не отвечает по какой-то странной причине
Итак, моя проблема в том, почему мой WKWebView больше не отвечает?
Вот как я реализовал свой WKWebView
var webview: WKWebView?
var videoID: String
let hardcodedPlaylist: [String] = ["EQIh607kd0Y", "A5kGigZHed4", "MLJyFzdQfK8", "Trfxm0TJwuQ", "nVVr7gJNny8", "XqZsoesa55w"]
func createEmbededHtml(videoID: String, playlist: String) -> String {
return """
<!DOCTYPE html>
<html>
<style>
* { margin: 0; padding: 0; }
html, body { width: 100%; height: 100%; }
</style>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player" ></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '100%',
width: '100%',
videoId: '(videoID)',
playerVars: {
controls: 0,
rel: 0,
modestbranding: 1,
playsinline: 1,
enablejsapi: 1,
playlist: '(playlist)'
},
events: {
'onReady': onPlayerReady
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
player.playVideoAt(1);
}
</script>
</body>
</html>
"""
}
init(web: WKWebView?, videoID: String) {
let configuration = WKWebViewConfiguration()
configuration.allowsInlineMediaPlayback = true
configuration.mediaTypesRequiringUserActionForPlayback = []
self.webview = WKWebView(frame: .zero, configuration: configuration)
self.videoID = videoID
}
func makeUIView(context: Context) -> WKWebView {
let embededHtmlString = createEmbededHtml(videoID: videoID, playlist: hardcodedPlaylist.joined(separator: ", "))
self.webview?.navigationDelegate = context.coordinator
webview?.isUserInteractionEnabled = false
webview?.isOpaque = false
webview?.loadHTMLString(embededHtmlString, baseURL: nil)
return webview!
}
func updateUIView(_ uiView: WKWebView, context: Context) {
}
class Coordinator: NSObject, WKNavigationDelegate {
private var webViewModel: WebViewModel
init(_ webViewModel: WebViewModel) {
self.webViewModel = webViewModel
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("webview has loaded")
self.webViewModel.didFinishLoading = true
}
}
func makeCoordinator() -> Webview.Coordinator {
Coordinator(webViewModel)
}
func playVideo() {
webview?.evaluateJavaScript("player.playVideo()")
print("playing...")
}
func pauseVideo() {
webview?.evaluateJavaScript("player.pauseVideo()")
print("pauseing...")
}
Этот код находится в классе с именем Webview, чтобы показать как можно меньше кода, я не буду показывать, как я вызываю свой Webview, я не думаю, что это будет служить цели.
Вот фрагмент с кодом моей кнопки, которая используется для сохранения видео, я также включил код для saveVideo и saveContext
Button(action: {
print("saving button pressed")
let currentIndex = webViewModel.playlistIndex - 1
saveVideo(videoID: videoIDFetcherInfo.videoIDs[webViewModel.playlistIndex] ,title: videoIDFetcherInfo.videoTitles[currentIndex], thumbnailUrlString: videoIDFetcherInfo.VideoThumbnailsUrl[currentIndex])
}, label: {
Image(videoSaved.isVideoSaved ? "bookmark-border-filled" : "bookmark-border")
.sizeShadowModifier(size: 44, shadowRadius: 12, shadowX: 2, shadowY: 6)
})
func saveVideo(videoID: String, title: String, thumbnailUrlString urlString: String) {
let newVideo = Video(context: managedObjectContext)
newVideo.thumbnailUrlString = urlString
newVideo.title = title
newVideo.videoID = videoID
newVideo.createdAt = Date()
print("Saving Video")
saveContext()
}
func saveContext() {
do {
try managedObjectContext.save()
} catch {
//TODO: add alert instead
print("There was an error saving")
}
}
После вызова saveVideo моя кнопка для воспроизведения / приостановки больше не работает, но видео сохраняется, и я вижу, что также соответствующая функция вызывается внутри Webview. Также я разрабатываю для iOS 14 и использую Xcode 12.3 и использую только SwiftUI