Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ブラウザアプリを自作してわかったWebViewの扱い方/iOS Meetup in 福岡

ブラウザアプリを自作してわかったWebViewの扱い方/iOS Meetup in 福岡

Kyome (Takuto Nakamura)

March 24, 2023
Tweet

More Decks by Kyome (Takuto Nakamura)

Other Decks in Programming

Transcript

  1. GitHubΛړ͍ͬͯΔͱΑ͘ݟΔख๏ enumͷϓϩύςΟΛ؂ࢹͯ͠WKWebViewͷΞΫγϣϯΛ੍ޚ͢Δ UIViewRepresentableͷCoordinatorͰWKWebViewͷঢ়ଶΛ؂ࢹ͢Δ SwiftUIͰWKWebViewΛѻ͏ func updateUIView(_ webView: WKWebView, context: Context)

    { switch action { case .none: break case .search(let searchText): context.coordinator.search(text: searchText) action = .none } } action͕searchʹͳͬͨΒcoordinatorΛհͯ͠
 WKWebViewͷload(request:)Λୟ͘ actionΛ࢖͍ऴΘͬͨΒ.noneʹ໭͢
  2. GitHubΛړ͍ͬͯΔͱΑ͘ݟΔख๏ enumͷϓϩύςΟΛ؂ࢹͯ͠WKWebViewͷΞΫγϣϯΛ੍ޚ͢Δ UIViewRepresentableͷCoordinatorͰWKWebViewͷঢ়ଶΛ؂ࢹ͢Δ SwiftUIͰWKWebViewΛѻ͏ struct WrappedWKWebView: UIViewRepresentable { @Binding private

    var progress: Double private let webView = WKWebView() func makeCoordinator() -> Coordinator { return Coordinator(webView: webView, progress: $progress) } coordinatorʹwebViewͱBinding͍ͨ͠ϓϩύςΟΛ౉͢
  3. GitHubΛړ͍ͬͯΔͱΑ͘ݟΔख๏ enumͷϓϩύςΟΛ؂ࢹͯ͠WKWebViewͷΞΫγϣϯΛ੍ޚ͢Δ UIViewRepresentableͷCoordinatorͰWKWebViewͷঢ়ଶΛ؂ࢹ͢Δ SwiftUIͰWKWebViewΛѻ͏ class Coordinator { init(webView: WKWebView, progress:

    Binding<Double>) { // ॳظԽ͸লུ self.webView 
 .publisher(for: \.estimatedProgress) .sink { [weak self] value in self?.progress = value } .store(in: &cancellables) } } WKWebViewͷঢ়ଶΛ؂ࢹͯ͠Bindingʹྲྀ͢
  4. 💡ղܾࡦ UIViewRepresentableͷ֎ʹWKWebViewͷΠϯελϯεΛ࣋ͨͤɺ
 ͦͪΒͰঢ়ଶͷ؂ࢹͱ੍ޚΛߦ͏ SwiftUIͰWKWebViewΛѻ͏ struct WrappedWKWebView: UIViewRepresentable { let setWebViewHandler:

    (WKWebView) -> Void func makeUIView(context: Context) -> some WKWebView { let webView = WKWebView() setWebViewHandler(webView) return webView } func updateUIView(_ uiView: UIViewType, context: Context) {} } WKWebViewΛ֎ʹ࣋ͪग़͢΍ͭ Կ΋͠ͳ͍
  5. 💡ղܾࡦ UIViewRepresentableͷ֎ʹWKWebViewͷΠϯελϯεΛ࣋ͨͤɺ
 ͦͪΒͰঢ়ଶͷ؂ࢹͱ੍ޚΛߦ͏ SwiftUIͰWKWebViewΛѻ͏ class WebViewModel: ObservableObject { private weak

    var webView: WKWebView? func setWebView(_ webView: WKWebView) { self.webView = webView // webViewͷঢ়ଶΛ؂ࢹ(ߪಡ)ͯ͠PublishedͳϓϩύςΟʹྲྀ͢ } func search() { // URLRequestΛ࡞ͬͯ webView?.load() Λୟ͘ } }
  6. 💡ղܾࡦ UIViewRepresentableͷ֎ʹWKWebViewͷΠϯελϯεΛ࣋ͨͤɺ
 ͦͪΒͰঢ়ଶͷ؂ࢹͱ੍ޚΛߦ͏ SwiftUIͰWKWebViewΛѻ͏ struct WebView: View { @StateObject private

    var webViewModel = WebViewModel() var body: some View { VStack(spacing: 0) { SearchBar(inputText: $webViewModel.inputText) .onSubmit { webViewModel.search() } ProgressView(value: webViewModel.progress) WrappedWKWebView(setWebViewHandler: { webView in webViewModel.setWebView(webView) }) } } } Modelͷsearch()Λୟ͘ WKWebViewͷΠϯελϯεΛModelʹ౉͢
  7. 💡ղܾࡦ UIViewRepresentableͷ֎ʹWKWebViewͷΠϯελϯεΛ࣋ͨͤɺ
 ͦͪΒͰঢ়ଶͷ؂ࢹͱ੍ޚΛߦ͏ SwiftUIͰWKWebViewΛѻ͏ struct WebView: View { @StateObject private

    var webViewModel = WebViewModel() var body: some View { VStack(spacing: 0) { SearchBar(inputText: $webViewModel.inputText) .onSubmit { webViewModel.search() } ProgressView(value: webViewModel.progress) WrappedWKWebView(setWebViewHandler: { webView in webViewModel.setWebView(webView) }) } } } Modelͷsearch()Λୟ͘ WKWebViewͷΠϯελϯεΛModelʹ౉͢ Q, Կ౓΋ݺͼग़͞Εͯ͠·͏ͷͰ͸ʁ A, UIViewRepresentableͷmakeUIView() ͸ 
 Ұ౓͔͠ݺ͹Εͳ͍ͷͰ໰୊ͳ͍
  8. 💡ղܾࡦ UIViewRepresentableͷ֎ʹWKWebViewͷΠϯελϯεΛ࣋ͨͤɺ
 ͦͪΒͰঢ়ଶͷ؂ࢹͱ੍ޚΛߦ͏ SwiftUIͰWKWebViewΛѻ͏ struct WebView: View { @StateObject private

    var webViewModel = WebViewModel() var body: some View { VStack(spacing: 0) { SearchBar(inputText: $webViewModel.inputText) .onSubmit { webViewModel.search() } ProgressView(value: webViewModel.progress) WrappedWKWebView(setWebViewHandler: { webView in webViewModel.setWebView(webView) }) } } } Modelͷsearch()Λୟ͘ WKWebViewͷΠϯελϯεΛModelʹ౉͢ Q, Կ౓΋ݺͼग़͞Εͯ͠·͏ͷͰ͸ʁ A, UIViewRepresentableͷmakeUIView() ͸ 
 Ұ౓͔͠ݺ͹Εͳ͍ͷͰ໰୊ͳ͍