APICloud is an excellent cross-platform development tool. It also has a rich modular market that can meet almost all the needs of daily development. There is a method in it which I think is very interesting, is api.require(), this method returns a JS object at the same time will satisfy the jS object directly call the iOS native method of the same name, took half a day, simple simulation of such a function, the following is the general idea and part of the code. If the gods have a better idea, give more advice.
Step 1: Take a look at the simple logic in a custom HTML page
This directly initializes an API object and creates an ApiReady method in JS. If you know about APICloud, this is the default method of APICloud. The API Object provides rich methods to implement various logic. Here, an Object Object is simply initialized to imitate. The apiReady method is called after the API object has been successfully initialized; The end result is to create a log object from our custom API object as shown in the figure, and this log object can directly call the native method of the same name for the log class.
Step 2. Look again at the method of the instance that needs to be invoked in the native context
Create a “WSLApiWebLog” class in the native project and create an instance method of “log”.
Step 3. Create WKWebView and bridge JS and OC
Just to imitate apiCloud, I put the api.require method in HTML under OC to create it.
Add logic to webView proxy method, add require method to API JS object in HTML. The attribute api.require is caused by a function, but it does not affect the logic behind it. Baidu has been at a loss for some time and hopes to give advice.
Two important JS methods are used here: window.prompt and eval;
For the first time, the window.prompt method is called because api.require needs to return a JS object, so WKWebView needs to accept a JS synchronization method and report it back to JS after executing the native logic.
So, how to accept?
WKWebView proxy method
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler
This synchronization method is accepted in WKWebView’s proxy method, and at the end of the method there is a callback completionHandler that returns a string; Create instances and save the iOS js needed here to saveDynamicClassInstanceArr array; This way we can call the closure after processing the native logic, but the return value needs to be a string. What string is created?
Remember that api.require needs to return a JS object, and there is an important JS method eval; Eval is a JS method that can run strings directly; In this case, the API. Require method returns a JS object by passing in a string that initializes the logic of the JS object in the completionHandler callback to the WKWebView synchronization method, and then executing the string through eval.
Step 4. Create a string that initializes the js object logic.
The API. Require method is to pass an iOS class name string, this is a simple bridge class method, accept the parameter is passed by the JS side, here directly to find the native class below the instance method, and then according to the JS logic rules to generate the corresponding string. Example: {OCMethod: function (param) {window. Its. MessageHandlers. InitNative. PostMessage}}.
Window. Its. MessageHandlers window. The difference between this method and the above prompt method, it just call, do not need the callback, trigger native executable logic can, therefore, this method is suitable for js object call OC method under the same name.
Well, here the api.require method returns a JS object with the same method name as the OC object.
Step 5. Call the apiReady method
This method can be executed after the native API object initialization logic is complete (appropriate call means when you think it is ready), and the HTML API API ready does the calling.
Step 6. The native instance executes the related methods
WKWebView proxy method
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message
This will get the corresponding class name + method name + parameter, can be executed.
Step 7. Test results
Finally, the log js object in the APIReady method calls the WSLApiWebLog native object log in iOS and passes in a JSON object.
Conclusion: Here is the end of the basic idea, there is no too complex logic, expression ability is limited. Hope to be helpful to everyone, but also accept the gods of criticism, common progress.