Загрузка JavaScript в UIWebView из ресурсов
Мне нужно загрузить файлы JavaScript из папки ресурсов моих приложений. На данный момент он прекрасно читает изображения с ресурсов, но почему-то не читает javascripts.
Я смог отобразить HTML-документы, которые ссылаются на эти javascripts, если сами html-файлы записаны в ресурсы, но я хотел бы отобразить html/js, установив html для UIWebView, чтобы он мог быть динамическим.
Вот что я делаю:
NSString * html = @"<!DOCTYPE html><html><head><title>MathJax</title></head><body><script type=\"text/x-mathjax-config\">MathJax.Hub.Config({tex2jax: {inlineMath: [[\"$\",\"$\"],[\"\\(\",\"\\)\"]]}});</script><script type=\"text/javascript\" src=\"/MathJax/MathJax.js\"></script>$$\\int_x^y f(x) dx$$<img src=\"coffee.png\"></body></html>";
NSString * path = [[NSBundle mainBundle] resourcePath];
path = [path stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
path = [path stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
NSString * resourcesPath = [[NSString alloc] initWithFormat:@"file://%@/", path];
[webview loadHTMLString:html baseURL:[NSURL URLWithString:resourcesPath]];
Теперь, если я изменю базовый URL на мой сервер, на котором также есть необходимые файлы, он загружается правильно. Было бы здорово не требовать подключения к интернету. Любая помощь приветствуется!!!;)
Я нашел это полезным для получения изображений для отображения: iPhone Dev: UIWebView baseUrl для ресурсов в папке "Документы", а не в комплекте приложений
Редактировать:
Вместо замены строки и кодирования URL я смог получить изображения, просто вызвав resourceURL в mainBundle, но все еще не выполняя javascript.
NSString * setHtml = @"<!DOCTYPE html><html><head><title>MathJax</title></head><body><script type=\"text/x-mathjax-config\">MathJax.Hub.Config({tex2jax: {inlineMath: [[\"$\",\"$\"],[\"\\(\",\"\\)\"]]}});</script><script type=\"text/javascript\" src=\"/MathJax/MathJax.js\"></script>$$\\int_x^y f(x) dx$$<img src=\"images/test.png\"></body></html>";
[webview loadHTMLString:setHtml baseURL:[[NSBundle mainBundle] resourceURL]];
РЕДАКТИРОВАТЬ
Если вы хотите помочь в этом, я помог вам, создав пример проекта!
https://github.com/pyramation/math-test
git clone git@github.com:pyramation/math-test.git
4 ответа
Здесь мы идем с простой настройкой.
Создайте следующую структуру папок в папке "Ресурсы".
Обратите внимание, что синие папки являются ссылочными
CSS просто конфетка:) В lib.js находится ваш код JavaScript, который вы хотели бы использовать.
index.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/standard.css">
<script src="js/lib.js" type="text/javascript" />
</head>
<body>
<h2>Local Javascript</h2>
<a href="javascript:alert('Works!')">Test Javascript Alert</a>
<br/>
<br/>
<a href="javascript:alertMeWithMyCustomFunction('I am');">External js test</a>
</body>
</html>
lib.js
function alertMeWithMyCustomFunction(text) {
alert(text+' -> in lib.js');
}
Загрузка контента в веб-просмотр
Примечание: webView - это свойство, представление создается с помощью компоновщика экземпляров.
- (void)viewDidLoad
{
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"index"
ofType:@"html"
inDirectory:@"/htdocs" ];
NSString *html = [NSString stringWithContentsOfFile:htmlPath
encoding:NSUTF8StringEncoding
error:nil];
[webView loadHTMLString:html
baseURL:[NSURL fileURLWithPath:
[NSString stringWithFormat:@"%@/htdocs/",
[[NSBundle mainBundle] bundlePath]]]];
}
И это должны быть результаты:
РЕДАКТИРОВАТЬ:
Snowman4415 упомянул, что iOS 7 не любит самозакрывающиеся теги сценариев тегов, поэтому, если что-то не работает в iOS 7, вам может потребоваться закрыть тег с помощью </script>
Вот еще один способ внедрить локальный файл JavaScript в DOM веб-представления. Вы загружаете содержимое файла JS в строку, а затем используете stringByEvalutatingJavaScriptFromString
:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *jsFile = @"jquery-1.8.2.min.js";
NSString *jsFilePath = [[NSBundle mainBundle] pathForResource:jsFile ofType:nil];
NSURL *jsURL = [NSURL fileURLWithPath:jsFilePath];
NSString *javascriptCode = [NSString stringWithContentsOfFile:jsURL.path encoding:NSUTF8StringEncoding error:nil];
[webView stringByEvaluatingJavaScriptFromString:javascriptCode];
// ...
}
Это особенно полезно, если у вас нет *.html/xhtml файлов, которые вы отображаете (например, ePub reader или агрегатор новостей). Это помогает вам не беспокоиться об относительных путях из вашего файла xhtml в файл js.
Вот как я это сделал, используя Webview и локальный JS. Положив несколько снимков здесь пример проекта здесь
// Get the path for index.html, where in which index.html has reference to the js files, since we are loading from the proper resource path, the JS files also gets picked up properly from the resource path.
func loadWebView(){
if let resourceUrl = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "WebDocs2"){
let urlRequest = URLRequest.init(url: resourceUrl)
myWebView.loadRequest(urlRequest)
}
}
// Load the JS from resources
func jsScriptText() -> String? {
guard let jsPath = Bundle.main.path(forResource: "hello", ofType: "js", inDirectory: "WebDocs2/scripts") else {
return nil
}
do
{
let jsScript = try String(contentsOfFile: jsPath, encoding: String.Encoding.utf8)
return jsScript
}catch{
print("Error")
return nil
}
}
// Run the java script
func runJS(){
if let jsScript = jsScriptText(){
let jsContext = JSContext()
_ = jsContext?.evaluateScript(jsScript)
let helloJSCore = jsContext?.objectForKeyedSubscript("helloJSCore")
let result = helloJSCore?.call(withArguments: [])
print(result?.toString() ?? "Error")
}
}
В Swift 3.x мы можем использовать loadHTMLString(_ string: String, baseURL: URL?)
функция, которая используется для отображения скрипта в UIWebview
@IBOutlet weak var webView : UIWebView!
class ViewController: UIViewController,UIWebViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
}
func loadWebView() {
webView.loadHTMLString("<p>Hello, How are you doing?.</p>" , baseURL: nil)
}
func webViewDidFinishLoad(_ webView: UIWebView) {
webView.frame.size.height = 1
webView.frame.size = webView.sizeThatFits(.zero)
}
}
Примечание:- Мы можем установить высоту UIWebView, как я упоминал выше в методе webViewDidFinishLoad
строгий текст Мы можем запустить собственный JavaScript в UIWebView с помощью метода stringByEvaluatingJavaScriptFromString(). Этот метод возвращает результат выполнения сценария JavaScript, переданного в параметре сценария, или nil в случае сбоя сценария.
Swift
Загрузить скрипт из строки
webview.stringByEvaluatingJavaScriptFromString(“alert(‘This is JavaScript!’);”)
Загрузить скрипт из локального файла
//Suppose you have javascript file named "JavaScript.js" in project.
let filePath = NSBundle.mainBundle().pathForResource("JavaScript", ofType: "js")
do {
let jsContent = try String.init(contentsOfFile: filePath!, encoding:
NSUTF8StringEncoding)
webview.stringByEvaluatingJavaScriptFromString(jsContent)
}
catch let error as NSError{
print(error.debugDescription)
}
Цель-C
Загрузить скрипт из строки
[webview stringByEvaluatingJavaScriptFromString:@”alert(‘This is JavaScript!’);”];
Загрузить скрипт из локального файла
//Suppose you have javascript file named "JavaScript.js" in project.
NSString *filePath = [[NSBundle mainBundle] pathForResource:@”JavaScript” ofType:@”js”];
NSString *jsContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[webview stringByEvaluatingJavaScriptFromString:jsContent];
Примечание. Метод stringByEvaluatingJavaScriptFromString: синхронно ожидает завершения оценки JavaScript. Если вы загружаете веб-контент, код JavaScript которого вы не проверили, вызов этого метода может привести к зависанию вашего приложения. Лучше всего принять класс WKWebView и вместо него использовать его метод AssessmentJavaScript:completionHandler:. Но WKWebView доступен в iOS 8.0 и новее.