iOSアプリからWebにアクセスしたいときは、SFSafariView, WKWebView, (UIWebView)などを使うと可能です。あるいはSafariに投げてしまうこともできます。
Xcode 11.3.1
WebView
Webページを表示する方法はいくつかあります。他のブラウザアプリ、Safariなどへ渡してしまったり、ある程度標準的なUIが付随しているSFSafariViewControllerを使うこともできます。またWKWebViewを使ってカスタマイズすることも可能です。
今まであったUIWebViewは推奨されていません。UIWebViewでは通信関連APIが操作される可能性があり、セキュリティ上好ましくないのと、クラッシュ率が高いという理由からWKWebViewあるいはSFSafariViewControllerを使う方がいいようです。
UIApplication を使って Safari へ渡す
Safari に代行してもらうという安易ですが安全かもしれない方法です。
アプリからちょっとWeb アクセスしたいだけなのに、「戻る」だの、「ダウンロード中」の表示だの考えなくていいので簡単です。
その辺を適当にやるとAppleの申請で Regect になる可能性があります。
UIApplicationクラスを使います
ViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import UIKit class ViewController: UIViewController , UIWebViewDelegate { override func viewDidLoad() { super.viewDidLoad() // URLを指定 let url = URL(string: "https://i-app-tec.com/")! if #available(iOS 10.0, *) { UIApplication.shared.open(url, options: [:], completionHandler: nil) } else { UIApplication.shared.openURL(url) } } } |
コードはこれだけです。
SafariでWebに移動する場合は自分のアプリから外れるのでパラメータの扱いは工夫が必要です。
SFSafariViewController を使う
iOS9(iOS8)からはSFSafariViewControllerを使うことができるようになりました。Safariに渡してしまうのではなく、あくまでアプリの一部のViewControllerとして扱えます。
また、ブラウザに必要なボタン等が標準で付いていてお手軽です。カスタマイズしたいのであれば、後出のWKWebViewを使います。
UIViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import UIKit import SafariServices class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func viewDidAppear(_ animated: Bool) { let webPage = "https://i-app-tec.com/" let safariVC = SFSafariViewController(url: NSURL(string: webPage)! as URL) present(safariVC, animated: true, completion: nil) } } |
WKWebView を使う
アプリの中にWebページを挿入するなどのカスタマイズをしたい場合に使います。
SafeArea:
何も考えずに今まで通りに画面いっぱいにしているとSafeAreaの問題がiPhone X系で起きます。この場合はステータスバーにWebの内容が被ってしまいます。
topPaddingを計算してSafeAreaの上部にUIWebViewが被らないようにします。下部はボタンを出すときは考慮する必要がありますが、そうでない場合はむしろ見せるというスタンスのようです(面倒ですが)とりあえずportraitの場合だけ考えてみます。(Landscapの場合は両サイドとホームインジケータに注意を払わないといけませんが)
UIViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import UIKit import WebKit class ViewController: UIViewController { var webView: WKWebView! // adjust SafeArea top space // portrait のみを想定 var topPadding:CGFloat = 0 override func viewDidAppear(_ animated: Bool){ print("viewDidAppear") let screenWidth:CGFloat = view.frame.size.width let screenHeight:CGFloat = view.frame.size.height // iPhone X , X以外は0となる if #available(iOS 11.0, *) { // 'keyWindow' was deprecated in iOS 13.0: Should not be used for applications let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first topPadding = window!.safeAreaInsets.top } // Webページの大きさを画面に合わせる let rect = CGRect(x: 0, y: topPadding, width: screenWidth, height: screenHeight - topPadding) let webConfiguration = WKWebViewConfiguration() webView = WKWebView(frame: rect, configuration: webConfiguration) let webUrl = URL(string: "https://i-app-tec.com/")! let myRequest = URLRequest(url: webUrl) webView.load(myRequest) // インスタンスをビューに追加する self.view.addSubview(webView) } } |
カスタマイズなので「戻る」や「リロード」ボタンなどもそれぞれ作る必要があります。
UIWebView クラス
昔からあるものですがサポート終了です。iOS12以上ではWKWebViewを推奨しています。
ViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
import UIKit class ViewController: UIViewController, UIWebViewDelegate { let webView : UIWebView = UIWebView() // adjust SafeArea top space // portrait のみを想定 var topPadding:CGFloat = 0 override func viewDidLoad() { super.viewDidLoad() // Delegate設定 webView.delegate = self } // iPhone X のSafeArea調整のため override func viewDidAppear(_ animated: Bool){ let screenWidth:CGFloat = view.frame.size.width let screenHeight:CGFloat = view.frame.size.height // iPhone X , X以外は0となる if #available(iOS 11.0, *) { let window = UIApplication.shared.keyWindow topPadding = window!.safeAreaInsets.top } // Webページの大きさを画面に合わせる let rect = CGRect(x: 0, y: topPadding, width: screenWidth, height: screenHeight - topPadding) webView.frame = rect webView.scalesPageToFit = true // インスタンスをビューに追加する self.view.addSubview(webView) // URLを指定 let url = URL(string: "https://i-app-tec.com/")! let request: URLRequest = URLRequest(url: url) // リクエストを投げる webView.loadRequest(request) } // ロード時にインジケータをまわす func webViewDidStartLoad(_ webView: UIWebView) { UIApplication.shared.isNetworkActivityIndicatorVisible = true print("indicator on") } // ロード完了でインジケータ非表示 func webViewDidFinishLoad(_ webView: UIWebView) { UIApplication.shared.isNetworkActivityIndicatorVisible = false print("indicator off") } } |
References:
UIApplication – UIKit | Apple Developer Documentation
WKWebView – WebKit | Apple Developer Documentation
SFSafariViewController – SafariServices | Apple Developer Documentation
UIWebView – UIKit | Apple Developer Documentation