iOS Dev. Lesson 11

---

Agenda

  1. Showing external website with SFSafariController
  2. Loading web pages in WKWebView.
  3. Controlling and interacting with the web page loaded.

SFSafariController

 

import SafariServices

@IBAction func tapDetails(_ sender: Any) {
    guard let url = URL(string: "https://www.smg.gov.mo/") else {
      return
    }
    let vc = SFSafariViewController(url: url)
    self.show(vc, sender: false)
}

WKWebView

 

webview.load(...)

webview.load(
  URLRequest(url: 
             URL(string: "https://example.com")!
            )
)

WKWebView

 

  1. WKNavigationDelegate
  2. WKUIDelegate

The Swift part

// Setup webview

// Session
let configuration = WKWebViewConfiguration()
configuration.processPool = GlobalSession.shared.processPool

// Message handler
let userContentController = WKUserContentController()

// the name has to match the JavaScript part.
userContentController.add(self, name: "notification")

configuration.userContentController = userContentController

// Init the webview
let webview = WKWebView.init(frame: .zero, configuration: configuration)
webview.customUserAgent = "Demo App iOS, version 1.0 build 2021.05"


// Finally, we load the URL
webview.load(URLRequest(url: URL(string: "https://in200-demo.netlify.com/app.html")!))



webview.navigationDelegate = self


// Make sure we add the new web view into the view hierarchy.
stackView.addArrangedSubview(webview)

WKWebView

Demo Web App URL:

https://in200-demo.netlify.app/app.html

 

The HTML part

<head>
  <!-- Please make sure user-scalable=no is only used carefully -->
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <style>
	
	body {
	  font: -apple-system-body;
	  padding: 16px;
	  margin: 0;
	}
	footer {
	  font: -apple-system-footnote;
	}
	label {
	  display: block;
	  margin-bottom: 1em;
	}
	input {
	  display: block;
	  width: 100%;
	  padding: .5em;
	  border: 1px solid #e0e0e0;
	  border-radius: 4px;
	  font-size: inherit;
	}
  </style>
</head>
<body>
  <h1>Demo</h1>
  <form id="form" action="">
	<label>Name:
	  <input type="text" id="name" name="name">
	</label>
	
	<label>Home Tel:
	  <input type="tel" id="tel" name="tel">
	</label>
	
	<label>Mobile Tel:
	  <input type="tel" id="mobile-tel" name="mobile-tel">
	</label>
	
	<label>Income
	  <input type="number" id="income" pattern="[0-9]*" name="income">
	</label>
	
	<label>
	  <input type="button" id="send-back" value="Send back to iOS">
	</label>
	
  </form>
  
  <p>Debug: <span id="preferredContentSizeCategory"></span></p>
  
  <footer>Footer placeholder.</footer>
  
  <script src="https://code.jquery.com/jquery.min.js"></script>
  <script>
	// document.write(window.navigator.userAgent);
	
	let userAgent = window.navigator.userAgent;
	
	if (userAgent.indexOf("Demo App iOS") >= 0) {
	  $("h1").hide();
	}
	
	function fillInForm(name, tel, mobileTel) {
	  $("#name").val(name);
	  $("#tel").val(tel);
	  $("#mobile-tel").val(mobileTel);  
	  return "Form filled by JavaScript."
	}
	
	function setAccessibilityFontSize(size) {
	  $("#preferredContentSizeCategory").text(size);
	}
	
	$("#send-back").on('click', function(){
	  var data = {
		'name': $("#name").val(),
		'tel': $("#tel").val(),
		'mobileTel': $("#mobile-tel").val(),
		'income': $("#income").val()
	  }
	  
	  // The "notification" has to match the name of userContentController in Swift.
	  window.webkit.messageHandlers.notification.postMessage({ hello: "world from web/JS", data: data} );
	});
  </script>
</body>

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

font: -apple-system-body;

let userAgent = window.navigator.userAgent;
	
if (userAgent.indexOf("Demo App iOS") >= 0) {
  $("h1").hide();
}
window.webkit.messageHandlers.notification.postMessage(
  { hello: "world from web/JS", data: data} 
);

Passing data between Swift and JavaScript

1. Passing data from Swift to JavaScript

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
	let name = "Thomas Mak"
	let tel = "28123123"
	let mobileTel = "66661234"
	let script = "fillInForm('" + name + "', '" + tel + "', '" + mobileTel + "')"
	webView.evaluateJavaScript(script)
	
	// OR:
	
	webView.evaluateJavaScript(script) { (returnedResult, error) in
		print("Returned: ")
		print(returnedResult)
	}
	
	print(UIApplication.shared.preferredContentSizeCategory.rawValue )
	webView.evaluateJavaScript("setAccessibilityFontSize('" + UIApplication.shared.preferredContentSizeCategory.rawValue + "')")
}

2. Passing data from JavaScript to Swift

// JavaScript

$("#send-back").on('click', function(){
  var data = {
	'name': $("#name").val(),
	'tel': $("#tel").val(),
	'mobileTel': $("#mobile-tel").val(),
	'income': $("#income").val()
  }
  
  // The "notification" has to match the name of userContentController in Swift.
  window.webkit.messageHandlers.notification.postMessage({ hello: "world from web/JS", data: data} );
});

iOS Dev Lesson 11

By makzan

iOS Dev Lesson 11

  • 357