iOS
Create a view controller with a WKWebview
and set its class to EGreetingButtonViewController
. Assign the webView
’s Outlet
to the view controller’s WKWebview
.
EGreetingButtonViewController.swift
import UIKit
import WebKit
class EGreetingButtonViewController: UIViewController, WKScriptMessageHandler {
@IBOutlet weak var webView: WKWebView!
let jwt = /* supplied by FI */
let cid = /* Partner-supplied Client ID property */
let baseUrl = /* supplied by FI */
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "\(baseURL)/#tkn=\(jwt)&cid=\(cid)&action=%2Fpersonalize")!
webView.configuration.userContentController.add(self, name: "appInterface")
webView.load(URLRequest(url: url))
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let messageString = message.body as? String,
let data = messageString.data(using: .utf8),
let eventDictionary = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
if eventDictionary["event"] as? String == "PERSONALIZE" {
// get the action
guard let action = eventDictionary["actions"]["personalize"] as? String else {
return
}
let eCardViewController = // instantiate view controller
eCardViewController.action = action
present(activityVC, animated: true)
}
}
}
}
Create a view controller with a WKWebview
and set its class to EGreetingViewController
. Assign the webView
’s Outlet
to the view controller’s WKWebview
.
EGreetingViewController.swift
import UIKit
import MessageUI
import WebKit
class EGreetingViewController: UIViewController, UIActivityItemSource, WKScriptMessageHandler {
@IBOutlet weak var webView: WKWebView!
let verifiedHost: String = ""// supplied by the FI
let jwt = /* supplied by FI */
let cid = /* Partner-supplied Client ID property */
let baseUrl = /* supplied by FI */
var action: String?
var redemptionUrl = "" /* initialize */
var envelopeUrl = "" /* initialize */
var logoUrl = "" /* initialize */
var messageTitle = "" /* initialize */
var messageDescription = "" /* initialize */
override func viewDidLoad() {
super.viewDidLoad()
var urlString = "\(baseURL)/#tkn=\(jwt)&cid=\(cid)"
if let action = action {
urlString = urlString + "&action=\(action)"
}
let url = URL(string: urlString)!
webView.configuration.userContentController.add(self, name: "appInterface")
webView.load(URLRequest(url: url))
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let messageString = message.body as? String,
let data = messageString.data(using: .utf8),
let eventDictionary = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
if eventDictionary["event"] as? String == "VOUCHER_CREATED" {
guard let urlString = eventDictionary["url"] as? String else { return }
guard let shareInfo = eventDictionary["shareInfo"] as? [String: Any], let
envelopeUrl = shareInfo["packagingImage"] as? String, let logoUrl = shareInfo["favIcon"] as? String, let messageTitle = shareInfo["title"] as? String, let messageDescription = shareInfo["description"] as? String else {
return
}
// store the values for iOS sharing
self.redemptionUrl = urlString
self.envelopeUrl = envelopeUrl
self.logoUrl = logoUrl
self.messageTitle = messageTitle
self.messageDescription = messageDescription
// validate url
guard redemptionUrl.scheme == "https" && redemptionUrl.host == verifiedHost else {
print("invalid url")
return
}
// handle url e.g. present the share sheet
let items = [self]
let activityVC = UIActivityViewController(activityItems: items, applicationActivities: nil)
// IPAD sharesheet requirement
activityVC.excludedActivityTypes = [.airDrop]
if let popoverController = activityVC.popoverPresentationController {
popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
popoverController.sourceView = self.view
popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}
present(activityVC, animated: true)
}
}
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return self.activityViewController(activityViewController, itemForActivityType: UIActivity.ActivityType.message) ?? ""
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
let buttonText = "Open"
let footerMessage = "Brought to you by Vouchr!"
let backgroundColor = "#0c2da1"
let textColor = "white"
let buttonColor = "#007aff"
let buttonTextColor = "white"
// Apple Mail HTML
let htmlString = """
<html>
<body style="font-family: sans-serif">
<table
class="main"
style="
background-color: \(backgroundColor);
color: \(textColor);
margin: auto;
min-width: 500px;
padding-top: 32px;
padding-bottom: 32px;
text-align: center;
width: 500px;
"
>
<tr>
<td>
<img
class="logo"
src="\(self.logoUrl)"
style="height: 48px"
/>
<h1>\(self.messageTitle)</h1>
<p>\(self.messageDescription)</p>
<img
class="envelope"
src="\(self.envelopeUrl)"
style="padding: 20px 0px 20px 0px"
/>
<div>
<a
href="\(self.redemptionUrl)"
target="_blank"
>
<button
style="
background: \(buttonColor);
border-color: \(buttonColor);
border-radius: 999px;
border-style: solid;
color: \(buttonTextColor);
font-size: large;
height: 40px;
width: 200px;
"
>
\(buttonText)
</button>
</a>
</div>
</td>
</tr>
</table>
<table
class="footer"
style="
border: 1px solid #e0e0e088;
margin: auto;
min-width: 500px;
padding: 24px 0px 24px 0px;
width: 500px;
"
>
<tr>
<td>
<p
class="footerMessage"
style="margin: auto; text-align: center; width: 70%;"
>
\(footerMessage)
</p>
</td>
</tr>
</table>
</body>
</html>
"""
if (activityType == .mail) {
return htmlString
}
return redemptionUrl
}
func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String {
// Apple Mail Subject line
return "Check out this eCard!"
}
/*
* Connect this IBAction method to a separate back button if desired (optional)
*/
@IBAction func browserBack() {
if (self.webview.canGoBack){
self.webview.goBack()
}
}
}
%}
ChangeLog
v1.4.3 - May 18, 2023
- Separated full iOS example