I am currently trying to create an IOS app that mirrors the one I have developed on Android. I am new to Swift, but had little trouble learning some of the basics. My app has a separate class that outputs html. I use the output html to be run using the loadHTMLString(html, baseURL) to display on the app. The user use pickers to select different parameters, but after selecting the parameters, the webView does not update the html. Using the print() method show that the new parameters get called.
Here is the WKWebview struct, called Distance List
import WebKit
import SwiftUI
struct DistanceList: UIViewRepresentable {
//Parameters for html String to update
var jump1type: String
var jump2type: String
//More parameters to come
//Create webview
var distanceList = WKWebView()
func makeUIView(context: Context) -> some WKWebView {
return distanceList
}
func updateUIView(_ uiView: UIViewType, context: Context) {
print("DistanceList.updateUIView(" + uiView.description + ", context) \njump1Type: " + jump1type)
//Invoke WKWebview extension method updateValues
distanceList.updateValues(jump1type: jump1type, jump2type: jump2type)
}
} // - struct DistanceList: UIViewRepresentable
extension WKWebView{
/**
* updates the HTML string and then calls it to be reloaded
*/
func updateValues(jump1type: String, jump2type: String){
//Check that this method has been invoked correctly
print("DistanceList.udateValues("+jump1type+", " + jump2type + ") ")
//Creates a new HTML String from a static method in class Utils
let html: String = Utils.getDistance(jumpType1: jump1type, jumpType2: jump2type, lineType: "Jumping Round", horseType: "Horse", height1: 1.10, height2: 1.10, slope: "Flat")
//Load update html
loadHTMLString(html, baseURL: Bundle.main.resourceURL)
//Clean and clear cache
clean()
}
func clean() {
guard #available(iOS 9.0, *) else {return}
HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)
WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
records.forEach { record in
WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: {})
#if DEBUG
print("WKWebsiteDataStore record deleted:", record)
#endif
}
}
}
}
And here is the ContentView:
import SwiftUI
import UIKit
import WebKit
struct ContentView: View {
//Selection variables for Pickers
@State var jump1Selection = 0
@State var jump2Selection = 0
@State var useSelection = 0
@State var horseSizeSelection = 0
@State var height1Selection = 0
@State var height2Selection = 0
@State var slopeSelection = 0
//Arrays for Picker content
var jumps = [String](arrayLiteral: "Vertical", "Oxer", "Triple", "Wall", "Pole", "Cavalletti")
var uses = [String](arrayLiteral: "Jumping ", "Schooling Exercise", "From Trot")
var horseSizes = [String](arrayLiteral: "Horse", "Pony (large)", "Pony (medium)", "Pony (small)")
var jumpHeights = [String](arrayLiteral: "1.10m", "<0.50m", "0.60m", "0.70m", "0.80m", "0.90m", "1.00m", "1.10m", "1.20m", "1.30m", "1.40m", "1.50m", ">1.50m")
var slopes = [String](arrayLiteral: "Flat", "Downhill", "Uphill")
var body: some View {
VStack{
Text("Strides Distance Calculator")
//Jump 1
Picker(selection: self.$jump1Selection, label: Text("Jump 1")){
ForEach(0 ..< self.jumps.count){ index in
Text("\(self.jumps[index])").tag(index)
}
}
//Jump 2
Picker(selection: self.$jump2Selection, label: Text("Jump 2")){
ForEach(0 ..< self.jumps.count){ index in
Text("\(self.jumps[index])").tag(index)
}
}
//Line use
Picker(selection: self.$useSelection, label: Text("Use")){
ForEach(0 ..< self.uses.count){ index in
Text("\(self.uses[index])").tag(index)
}
}
//Horse size
Picker(selection: self.$horseSizeSelection, label: Text("Horse Size")){
ForEach(0 ..< self.horseSizes.count){ index in
Text("\(self.horseSizes[index])").tag(index)
}
}
//Fence 1 height
Picker(selection: self.$height1Selection, label: Text("1st Fence Height")){
ForEach(0 ..< self.jumpHeights.count){ index in
Text("\(self.jumpHeights[index])").tag(index)
}
}
//Fence 2 height
Picker(selection: self.$height2Selection, label: Text("2nd Fence Selection")){
ForEach(0 ..< self.jumpHeights.count){ index in
Text("\(self.jumpHeights[index])").tag(index)
}
}
//Ground slope
Picker(selection: self.$slopeSelection, label: Text("Slope")){
ForEach(0 ..< self.slopes.count){ index in
Text("\(self.slopes[index])").tag(index)
}
}
//Display webview
//Only using two selections at present
DistanceList(jump1type: self.jumps[self.jump1Selection], jump2type: self.jumps[self.jump2Selection])
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
}
}
}
When I run this app, the initial html String is loaded as it should, but the loadHTMLString method does not update to the new html String is loaded. After the second picker is loaded I get the following error code:
i022-06-25 09:07:23.333657+1200 Strides Distance Calculator[23957:1326393] [ProcessSuspension] 0x10f005e60 - ProcessAssertion: Failed to acquire RBS assertion 'ConnectionTerminationWatchdog' for process with PID=23972, error: Error Domain=RBSServiceErrorDomain Code=1 "target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit"
Can someone let me know what I am missing or where I am going wrong?