2016-11-23 23 views
5

Tôi đang cố thực hiện cuộc gọi từ một hàm javascript trong UIWebView sang Swift trong iOS 10. Tôi đã thiết lập một dự án rất cơ bản chỉ để thử và làm việc này, mã bên dưới.Cuộc gọi Javascript tới Swift từ UIWebView

import UIKit 

class ViewController: UIViewController, UIWebViewDelegate {  
    @IBOutlet var webView: UIWebView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let url = Bundle.main.url(forResource: "products", withExtension: "html") 
     let request = NSURLRequest(url: url! as URL) 
     webView.loadRequest(request as URLRequest) 
    } 

    @IBAction func closeDocumentViewer() { 
     displayView.isHidden = true; 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 
} 

Nếu tôi chỉ nhận một chuỗi từ chức năng javascript, tôi sẽ phải thêm gì vào phần trên?

Trả lời

1

Bạn phải một tùy chỉnh URL Scheme như myawesomeapp và đánh chặn các yêu cầu để nó sử dụng:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool 

cháy một cuộc gọi đến mã nguồn gốc sử dụng window.location=myawesomeapp://hello=world, và nhận được truy vấn params bạn vượt qua từ request.URL.query trong mã nguồn gốc.

Để biết thêm thông tin, xem câu hỏi của tôi về UIWebView s ở đây: JavaScript synchronous native communication to WKWebView

9

tôi sẽ đề nghị xem xét sử dụng WKWebView thay UIWebView. Sau đó, bạn sẽ không cần đăng ký lược đồ URL tùy chỉnh. Ngoài ra, UIWebView đã lỗi thời và WKWebView có rất nhiều lợi thế, đáng chú ý nhất là hiệu năng và hiển thị khi nó chạy trong một quá trình riêng biệt.

Liên kết đến tài liệu Apple và khuyến cáo sử dụng WKWebView https://developer.apple.com/reference/webkit/wkwebview/

quan trọng

Bắt đầu từ iOS 8.0 và OS X 10.10, sử dụng WKWebView để thêm nội dung web để bạn> ứng dụng. Không sử dụng UIWebView hoặc WebView.

Điều đó nói rằng, nó rất đơn giản để thiết lập một quê hương để cầu javascript:

import WebKit 

class ViewController: UIViewController, WKScriptMessageHandler { 
    var webView: WKWebView? 
    override func loadView() { 
     super.loadView() 

     webView = WKWebView(frame: self.view.frame) 
     webView?.configuration.userContentController.add(self, name: "scriptHandler") 

     self.view.addSubview(webView!) 
    } 

    public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { 
     print("Message received: \(message.name) with body: \(message.body)") 
    } 
// rest of code 
} 

Sau đó trong mã javascript của bạn, gọi nó là:

window.webkit.messageHandlers["scriptHandler"].postMessage("hello"); 

Tôi đã viết một thư viện đó thúc đẩy điều này và thêm một số cú pháp javascript ưa thích. https://github.com/tmarkovski/BridgeCommander

Để sử dụng nó, chỉ cần tham khảo dự án (hoặc thêm nhanh chóng và các tập tin javascript để dự án Xcode của bạn) và gọi

webView = WKWebView(frame: self.view.frame) 
    let commander = SwiftBridgeCommander(webView!) 

    commander.add("echo") { 
     command in 
     command.send(args: "You said: \(command.args)") 
    } 

Sau đó, bạn sẽ có thể sử dụng cú pháp gọi lại trong javascript như

này
var commander = new SwiftBridgeCommander(); 
commander.call("echo", "Hello", function(args) { 
     // success callback 
    }, function(error) { 
     // error callback 
}); 
+0

tôi đã sử dụng wkwebview, nhưng wkwebview có thể dẫn đến kết thúc chết. Giống như nó không đồng bộ cookie với nshttpcookiestrorage – Atif

+0

Yup, đó là một nhược điểm của WKWebView. Nó chạy các công cụ web trong quá trình cô lập và không có quyền truy cập vào bộ nhớ thời gian chạy của bạn. –

+0

Kiểm tra tài liệu WKWebsiteDataStore để quản lý cookie bằng WKWebView - https://developer.apple.com/documentation/webkit/wkwebsitedatastore –

Các vấn đề liên quan