質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1038閲覧

iOSアプリのwebViewで、GoogleMapsEmbedAPIで生成された地図からGoogleMapアプリを開きたい

koikuti

総合スコア50

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2022/08/29 11:03

前提

iOSアプリ上で開いたWebView上に表示されているGoogleMapsEmbedAPIで生成された地図をクリックしたとき、
端末にインストールされているGoogleMapアプリが立ち上がるようにしたい。

この地図は、GoogleMapsEmbedAPIで生成されており以下のスクショのように表示されています。イメージ説明

このとき、左上の拡大地図を表示ボタンをタップした場合、端末にインストールされているGoogleMapアプリが立ち上がる
(インストールされていない場合、Safariのアプリが立ち上がりGoogleMapが表示される。)
のですが、地図上(例えば東京駅の部分)をタップした場合、そのままWebView上でブラウザ版(?)のGoogleMapが表示されてしまいます。

地図上をタップした場合も、拡大地図を表示と同じ挙動にしたいのですが、方法が分からない状態です。

WebViewに表示されるWeb側は、React/Typescriptで作成しています。

実現したいこと

  • 地図上をタップした場合も、拡大地図を表示と同じ挙動にしたい。

該当のソースコード

TypeScript/React

1<iframe 2 src={`https://www.google.com/,aps/embed/v1/place?key=API_KEY&q=0.000,0.000`} 3/>

試したこと

  • よくあるアプリを立ち上げる方法のURLスキーム(<a href="maps:q=0.000,0.000">Mapアプリで開く</a>みたいな)の書き方をすれば良いと思ったのですが、googleのAPIによって自動的に生成される部分であり、自分で書き換えられないと思っています。
  • 試しに、デベロッパーツールから、Htmlを直接書き換えて、hrerfの内容をmaps:に書き換えてとりあえず挙動だけでも確認しようと思ったのですが、こちらもうまく行かず、WebView上でそのままGoogleMapが表示されてしまいました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koikuti

2022/09/06 07:40

hoshi-takanorさん 情報ありがとうございます。 そちらのページを参考に、リクエストURLを検証して、GoogleMapのものだった場合、 maps:緯度経度 に置き換え、 ``` UIApplication.shared.open(url) decisionHandler(.cancel) return ``` と処理するような方法など、色々試してなんとか解決しました。 (Swiftの文字列切り出しなどがチョット大変だったのは、また別のお話)
guest

回答1

0

自己解決

最終的に以下のように解決しました。

Swift

1public func webView(_ webView: WKWebview, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { 2 // リンク先のURLの文字列を取得 3 guard let url = navigationAction.request.url, !url.isFileURL else { 4 decisionHandler(.cancel) 5 return 6 } 7 let urlString = url.absoluteString 8 9 // ※1 10 // 自ドメイン内の遷移以外の、Mainframeで処理するものは外部アプリなどで開く 11 // = 外部のURLをwebView上で開こうとする場合 12 // 例えば、各種URLスキーム(tel: など)、外部サイトへのリンク、GoogleMap内のタップや『拡大地図を表示』ボタン、などなど 13 if !urlString.hasPrefix(myDomain) { 14 if navigationAction.targetFrame == nil || navigationAction.targetFrame!.isMainFrame { 15 UIApplication.shared.open(url) 16 decisionHandler(.cancel) 17 return 18 } 19 } 20 21 // 上記以外は、内部で処理する 22 // 自ドメイン内の遷移、GoogleMapを表示するiframeのsrcで呼ばれる、GoogleMapEmbedAPI、など 23 decisionHandler(.allow) 24 return 25 26}

GoogleMapEmbedAPIのリクエストはwebView上で処理したく(画面の変化はない裏で走るため)、外部のアプリで処理して欲しくないもので、このリクエストが、
自ドメインでない、navigationAction.targetFrame!.isMainFrame = falseとなるため
※1の判定をするに至りました。

navigationAction.targetFrame!.isMainFrame
が、どんなときにどんな値になるのか、公式のリファレンスを見ても、Swiftの書籍を見ても、明確には確認できなかったため、実際にアプリを動かしてそれぞれ確認して今の判定となりました。
(この判定で不都合が出ればその時に改修する方針)

参考までに

  • tel: スキーム
    • isMainFrame = true
  • 外部リンク
    • isMainFrame = true
  • GoogleMapの『拡大地図を表示』ボタンをクリック
    • そもそもnavigationAction.targetFramenil
  • GoogleMapの地図上自体をクリック
    • isMainFrame = true

という実行結果でした。

投稿2022/09/06 08:20

編集2022/09/06 08:22
koikuti

総合スコア50

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問