The WkWebView Message handler fails to return the value of the textbox initially, but successfully does so after pressing the button a second time

Having an HTML form embedded in a WKWebView in my Swift app poses a problem when trying to extract the textbox content using a message handler. The issue arises when pressing the Register button, which triggers a JavaScript function to retrieve the values of the textboxes. Strangely, the first result is empty, just a space character.

Upon pressing the button again, the actual content of the textboxes is successfully obtained. I've experimented with using the evaluateJavascript function to target elements by ID, but encountered the same behavior – blank response on the first attempt, followed by the expected values on subsequent tries.

The code snippet from my ViewController:

private var webkitview: WKWebView!
    var lsusername = "";
    var lspassword = "";

    @IBOutlet weak var baseview: UIView!
    @IBOutlet weak var registerAccountButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.webkitview = WKWebView(frame: self.baseview.bounds, configuration: self.getWKWebViewConfiguration())
        baseview.addSubview(self.appvalleyRegistration)
        baseview.translatesAutoresizingMaskIntoConstraints = false;

        let url = URL(string: "https://redacted.com/registrationform.php")!
        webkitview.load(URLRequest(url: url))

    }
    
    //Remaining view controller code...

When triggering the showUser() alert method, it displays nothing initially, only revealing the correct username and password fetched via WebKit after the second button press.

Excerpt from my form's script:

<body>
<script type="text/javascript">
          function submitForm() {
              var message = {
                passw: document.getElementById("passw").value,
                email: document.getElementById("email").value
              };
              window.webkit.messageHandlers.observer.postMessage(message);
          }
</script>>
  <div class="container">
    <h1>Welcome to my site</h1>
    <p>Let's set up your account</p>
    <hr>

    <label for="email"><b>Email</b></label>
    <input type="text" placeholder="Enter Email" name="email" id="email" required>

    <label for="psw"><b>Password</b></label>
    <input type="password" placeholder="Enter Password" name="passw" id="passw" required>

    <label for="psw-repeat"><b>Repeat Password</b></label>
    <input type="password" placeholder="Repeat Password" name="psw-repeat" id="psw-repeat" required>
  </div>
</body>

Unable to comprehend why functionality behaves inconsistently between first and subsequent attempts, I even tried introducing a sleep() delay to no avail.

Answer №1

evaluateJavascript operates asynchronously. You may want to consider incorporating a completion block and invoking showUser within it (ensuring that UI updates are executed on the main thread). This adjustment should help address your immediate issue:

webkitview.evaluateJavaScript("submitForm()") { [weak self] (_, _) in
    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }
        self.showUser(email: self.lsusername, name: self.lspassword)
    }
}

From a broader perspective, would it be more logical to trigger showUser from the didReceive method of the WKUserContentController? My experience with this area is limited, so I could be mistaken.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Limit the input to a specific format

Currently developing a JavaScript application, but having some confusion with Regular Expressions. The main goal is to allow users to input a specific format of strings in a text area for the application to process accordingly, thus requiring restriction o ...

Dealing with delays in rendering certain values with Angular interpolation & ways to eliminate an element from an array of TypeScript objects

I am currently developing a web application using ASP.NET Core - Angular. The app allows users to select a customer as the starting point and then calculates the distance & duration to other customers using Google Maps Distance Matrix Service. Although I a ...

Switching a material-ui input control instead of a textfield for materials-ui-datepicker: the ultimate guide

Within my React application (v16.3), I am utilizing the DatePicker component from the material-ui-pickers library to render date-picker controls. This particular component renders a Material-UI TextField. However, I am interested in modifying it to only di ...

Troubleshooting issue with Rails 5.2.3 AJAX request: JSON key-value pairs containing the plus sign are not being received

In my Rails 5.2.3 project, I am attempting to send an AJAX request that includes a JSON representation of a callflow object (the specifics of which are not relevant). This JSON representation is located within a textarea with the id "newCallflowJsonDisplay ...

Having trouble binding form data to a React component with the onChange() method?

I've been working on developing an email platform exclusively for myself and encountered a roadblock with this React form not updating state when data is entered. After identifying the issue, it appears that the main problem lies in the React form not ...

Difficulty displaying images on an HTML canvas

Currently, I have a function named next that is designed to retrieve the time (just the hours) and then compare the hours using an if statement to determine which clock image to load into the imageURLs[] array. Based on my observations, this part seems t ...

Changing the direction of the cursor to move opposite of the mouse's input

I'm currently working on a unique webpage with an unconventional navigation method. The concept involves the cursor moving in the opposite direction of mouse movement input. To achieve this effect, I decided to hide the actual cursor and use JavaScri ...

Contrasting the uses of element(...) versus element(...).getWebElement() in Protractor

What is the advantage of using element(...).getWebElement() instead of element(...) when they both perform similarly? Why are there two different APIs for the same purpose? ...

Creating a fantastic Image Gallery in JavaScript

As I work on creating a basic gallery page with html and css, everything seemed to be running smoothly. However, upon testing it in Google Chrome and IE, the onmouseover function is not responding as expected. The idea is for a larger image to display in t ...

Error encountered: Attempting to spread non-iterable object, resulting in an invalid action

Whenever I attempt to add an item to the cart, I encounter this error. Unhandled Runtime Error. TypeError: Invalid attempt to spread non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() method. import { creat ...

Neglect to notify about the input text's value

Having trouble retrieving the text from a simple <input id="editfileFormTitleinput" type="text>. Despite my efforts, I am unable to alert the content within the input field. This is the code snippet I've attempted: $('#editfileFormTitleinp ...

Ways to retrieve form data following a post request using JavaScript

Does anyone know how to read form data from testPage.html in testPageResult.html? I have created a html page called testPage.html with a form that has a post action like the following: <h2>HTML Forms</h2> <form action="http://test.com/tes ...

What is the most effective method for enlarging elements using Javascript?

I have come across many different methods for expanding elements on webpages, such as using divs with javascript and jquery. I am curious to know what the most optimal and user-friendly approach is in terms of performance, among other things. For instance ...

Using Javascript and Node.js, a child class instance in ES5 can access a method belonging to its parent

I am facing an issue while trying to call a parent's method from child's constructor. Below is the code snippet: parentClass.js var ParentClass = function(arg) { this.arg = arg; this.result = {}; }; ParentClass.prototype = { constr ...

The Facebook like button is mysteriously absent on all browsers except Chrome

After embedding the Facebook like button using an iframe code on a website I am working on, I noticed that it only displays correctly on Chrome, while other browsers do not show it. I attempted to use html5 and xfbml methods, but the button still did not ...

Counting Clicks with the Button Counter

I'm having an issue with my jQuery code that is supposed to count button clicks - it stops after just one click. I need help fixing this problem. $(function() { $('.btn').click(function() { $(this).val(this.textContent + 1); }); } ...

Is there a way to iterate through objects and add new properties to them?

I am trying to achieve the following object: let newPost = { title: "Post 1", Content: "New content" } with the code below: let newPost = {}; let postData = $(".post-data").each (function(index) { newPost.title = $ ...

Invoke the parent function when extending javascript prototype

Below is the Meta-Code I am currently working with: var Parent = function(){} Parent.prototype.doSomething = function(){ console.log("As a parent I did like a parent"); } var Child = function(){} Child.prototype = new Parent(); Child.prototype.doSometh ...

Looking for a way to go through a set of documents in an array and calculate the sum of a specific property in JSON using the $cond

Here's an array of JSON data: let x = [{"Data":"Chocolate","Company":"FiveStar"},{"Data":"Biscuit","Company":"Parle"},{"Data":"Chocolate","Company ...

Tap twice to enlarge or reduce the view

I am currently working on an app that features a collection of images displayed when the user taps a button on a text list view screen. I have implemented a specific subclass that enables the user to pinch and zoom, but I am interested in finding out the ...