如何在Swift中从.js文件调用JavaScript函数

3
我尝试使用以下代码从Swift调用Javascript函数,但无法访问Javascript函数。
这是我创建Javascript上下文对象的方法:
lazy var context: JSContext? = {
        let context = JSContext()

        guard let
            JSPath = Bundle.main.path(forResource: "IAV", ofType: "html")
            else {
                print("Unable to read resource files.")
                return nil
        }


        do {
            let iav = try String(contentsOfFile: JSPath, encoding: String.Encoding.utf8)
            _ = context?.evaluateScript(iav)
        } catch (let error) {
            print("Error while processing script file: \(error)")
        }

        return context
    }()

//设置js的值

func setToken(Token:String)
    {
        let jsmethod = context?.objectForKeyedSubscript("setIAVToken")
        let passParameter = jsmethod?.call(withArguments: [Token])
    }

HTML文件的内容为:



sample IAV form

</head>  


<body > <header> </header> <main>
<h1>Registration Form</h1>  
<form id="myform" method="post">  
 <div id="mainContainer">   <input type="button" id="start" value="Add Bank"> </div>  

var value="dhjhsd";

var setIAVToken = function(token) {
value= token;
}


$('#start').click(function() {
var iavToken = value;
alert(iavToken)
dwolla.configure('uat');
dwolla.iav.start('iavContainer', iavToken, function(err, res) {
console.log('Error: ' + JSON.stringify(err) + ' -- Response: ' + JSON.stringify(res));
});
}); </script> </html>

您也可以查看https://www.raywenderlich.com/124075/javascriptcore-tutorial。 - Hrishikesh
已经检查过了,在方法let parseFunction = context.objectForKeyedSubscript("parseJson")中出现错误 请注意,如果无法将response解析为JSON,则会打印“无法解析JSON”并返回空数组。 因此,您得到了print("Unable to parse JSON")消息。 - rajes
3个回答

4

如果您想要在iOS中加载 Web 内容,建议使用 WKWebView(这是一种新的方式,因为它使用了 WebKit 并且有很多改进,例如比起 WebView 更好的内存分配)。

在 iOS 的 Swift 文件 WebviewBridging.swift 中,可以编写如下内容:

import UIKit
import WebKit

class WebviewBridging: UIViewController, WKNavigationDelegate {

    var webView: WKWebView?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create a WKWebView instance
        webView = WKWebView (frame: self.view.frame, configuration: webConfig)
        view.addSubview(webView!)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let url = Bundle.main.url(forResource: "index", withExtension: "html")!
        webView!.loadFileURL(url, allowingReadAccessTo: url)
    }

    func callJSFunctionFromSwift(){
        webView!.evaluateJavaScript("changeBackgroundColor('red')", completionHandler: nil)
    }
}

在你的iOS项目文件夹中的index.html文件中,你可能会有如下内容:
<html>
    <head>
    </head>
    <body>
    <script>
    function changeBackgroundColor(colorText) {
        document.body.style.background = colorText;
    }
    </script>
    </body>
</html> 

无论何时你在swift中调用callJSFunctionFromSwift(),它都会通过XPC通信与WKWebView进行通信并评估你的javascript代码,从而触发index.html中的javascript函数。

3

对于Objective C,请按照以下步骤进行操作:

  • 在头文件中添加#import <JavaScriptCore/JavaScriptCore.h>

  • 接下来,在viewcontroller内使用以下代码:

NSString *jsPath = [[NSBundle mainBundle] pathForResource:@"JSFileName" ofType:@"js"];

NSString *scriptString = [NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:nil];

JSContext *context = [[JSContext alloc] init];
    context = [[JSContext alloc] init];
    [context evaluateScript:scriptString];
    JSValue *function = context[@"setMessage"];
    JSValue* result = [function callWithArguments:@[@"your custom string"]]; //pass the string whatever you want.
    [result toString]; // This will give the value in string format.

@rajes:那问题在哪里?这是从iOS调用JS函数的正确方式。 - Poles
我的目标是在Web视图上加载具有动态值的JS,这可能吗? - rajes
好的。你能告诉我你正在加载的HTML文件是来自捆绑包还是使用了HTML字符串吗? - Poles
在 HTML 文件中添加了 <script src="alertfile.js"></script>。 - rajes
好的。在浏览器中尝试一次。 - Poles
显示剩余9条评论

0

编辑HTML,使用<input type="button" id="start" value="Add Bank" onClick="setMessage()">代替<input type="button" id="start" value="Add Bank">

同时在表单内添加<input type="hidden" id="token" value="Token value">以传递令牌值。

在JavaScript方法中:

<script>
  function setMessage() {
  var iavToken = document.getElementById("token").value;
  alert(iavToken)
  dwolla.configure('uat');
  dwolla.iav.start('iavContainer', iavToken, function(err, res) {
  console.log('Error: ' + JSON.stringify(err) + ' -- Response: ' +  JSON.stringify(res));
  });
  } 
</script>

接下来使用以下 Objective-C 调用 JavaScript 函数。

NSString * jsCallBack = [NSString stringWithFormat:@"setMessage()"]; 
 [webView stringByEvaluatingJavaScriptFromString:jsCallBack];

提示:您需要在HTML中添加<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>(如果您有本地的JS文件,请添加它)以便与JS一起使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接