如何在swift中从.js文件中调用javascript函数

Posted

技术标签:

【中文标题】如何在swift中从.js文件中调用javascript函数【英文标题】:How to call javascript function from .js file in swift 【发布时间】:2016-12-27 08:00:32 【问题描述】:

我尝试使用以下代码从 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文件的内容是

示例 IAV 表单

</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>

【问题讨论】:

也可以查看raywenderlich.com/124075/javascriptcore-tutorial 已经检查过了,方法有错误 let parseFunction = context.objectForKeyedSubscript("parseJson") guard let parsed = parseFunction?.call(withArguments: [response]).toArray() else print( "无法解析 JSON") 返回 [] 得到 print("无法解析 JSON") 消息 【参考方案1】:

您可能应该使用WKWebView(这是在ios 的webview 中加载Web 内容的新方法,因为它使用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 函数。

【讨论】:

【参考方案2】:

如果是目标 c,请执行以下操作:

#import &lt;JavaScriptCore/JavaScriptCore.h&gt; 在头文件中。

接下来在 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.

【讨论】:

我也做同样的事情 swift :let JSPath = Bundle.main.path(forResource: "jsfile", ofType: "js") let alert = try String(contentsOfFile: JSPath, encoding: String. Encoding.utf8) _ = context?.evaluateScript(alert) let jsmethod = context?.objectForKeyedSubscript("jsfunctionName") let passParameter = jsmethod?.call(withArguments: [message]) @rajes :那有什么问题呢?从ios调用js函数才是正确的方法。 我在js文件的setmessage函数里面显示alert(message),但是执行时不能显示alert UIWebView 的 js,在 webViewDidStartLoad 内部执行 用动态值在网页视图上加载 js 我的目标可能吗?【参考方案3】:

编辑html,使用 &lt;input type="button" id="start" value="Add Bank" onClick="setMessage()"&gt; 而不是 &lt;input type="button" id="start" value="Add Bank"&gt;

还要在表单中添加&lt;input type="hidden" id="token" value="Token value"&gt; 以传递令牌值。

在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>

接下来使用以下目标 c 调用 javascript 函数。

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

P.S:你需要在html中添加&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"&gt;&lt;/script&gt;(或者如果你有本地的js文件添加它。)在html中使用js。

【讨论】:

以上是关于如何在swift中从.js文件中调用javascript函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中从文件扩展名中拆分文件名?

如何在swift中从文档目录中获取特定文件的NSURL

如何在 Swift 中从文件夹中获取 UIImage 数组?

如何在swift3中从库的PHAsset中获取图像文件名

如何在 Swift 中从服务器下载 zip 文件?

如何在 swift 5.3 中从 m4a 音频文件中获取 Track Id