Swift iOS : 在webview的當前網頁上提取資訊的方法

RecoReco發表於2017-07-20

廣告

Swift iOS開發小書 ,幫你快速上手開發 epub.ituring.com.cn/946

正文

使用UIWebView裝載一個網頁後,可能需要提取其內的資訊,比較好的方法是使用JavaScript。方法UIWebView.stringByEvaluatingJavaScript可以執行一個指令碼。

提取頁面資訊

執行如下程式碼,點選頁面左上方的run js按鈕,可以顯示一個對話方塊,內容為當前網頁的標題(title):

import UIKit
class Page: UIViewController{
    var c : UIWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        c = UIWebView()
        c.frame = super.view.frame
        view.addSubview(c)
        c.frame.origin.y += 100
        c.frame.size.height = 300
        let url = URL(string:"http://apple.com")
        let ro = URLRequest(url:url!)
        c.loadRequest(ro)
        let button = UIButton()
        button.setTitle("run js", for: .normal)
        button.addTarget(self, action: #selector(tap), for: .touchDown)
        button.frame = CGRect(x: 0, y: 70, width: 100, height: 20)
        view.addSubview(button)
    }
    func tap(){
        c.stringByEvaluatingJavaScript(from: "function showtitle(){alert(document.title)};showtitle()")
    }
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window!.rootViewController = Page()
        self.window?.makeKeyAndVisible()
        return true
    }
}複製程式碼

如果javas使用的函式或者模組比較大,可以把它們放到一個檔案內,作為資源包含,啟動時載入並求值。這樣是很方便的。接下來的案例,把上面案例的js函式showtitle()作為資原始檔。首先func tap內修改為從資源中載入:

    func tap(){
        let jsCode = try! String(contentsOf: URL(fileURLWithPath: Bundle.main.path(forResource: "pack", ofType: "js")!))
        c.stringByEvaluatingJavaScript(from: jsCode)
        c.stringByEvaluatingJavaScript(from: "showtitle()")
    }複製程式碼

其次,建立一個資原始檔,名為pack.js ,內容為:

  function showtitle(){alert(document.title)};複製程式碼

程式碼執行後,點選run js按鈕,效果和前一個案例相同。

提取圖片資訊

有時候,需要截獲WebView的手勢操作到當前程式碼內,在此程式碼中獲取當前手勢觸控的位置上的元素。這個場景下,就可以把js模組程式碼放到資原始檔內,在觸控程式碼中對此js呼叫和求值,獲得它的輸出:

import UIKit
class Page: UIViewController,UIGestureRecognizerDelegate{
    var c : UIWebView!
    var tapGesture : UITapGestureRecognizer!
    override func viewDidLoad() {
        super.viewDidLoad()
        c = UIWebView()
        c.frame = super.view.frame
        view.addSubview(c)
        c.frame.origin.y += 100
        c.frame.size.height = 300
        let url = URL(string:"https://httpbin.org/image/png")//must be a https url ,otherwise iOS will fobidden it 
        let ro = URLRequest(url:url!)
        c.loadRequest(ro)
        let button = UIButton()
        button.setTitle("run js", for: .normal)
        button.addTarget(self, action: #selector(tap), for: .touchDown)
        button.frame = CGRect(x: 0, y: 70, width: 100, height: 20)
        view.addSubview(button)
        tapGesture = UITapGestureRecognizer(target: self, action:#selector(tapHandler(_:)))
        self.tapGesture!.delegate = self
        self.c.addGestureRecognizer(self.tapGesture!);
    }
    func tap(){
        let jsCode = try! String(contentsOf: URL(fileURLWithPath: Bundle.main.path(forResource: "pack", ofType: "js")!))
        c.stringByEvaluatingJavaScript(from: jsCode)
        c.stringByEvaluatingJavaScript(from: "showtitle()")
    }
    func gestureRecognizer(_: UIGestureRecognizer,  shouldRecognizeSimultaneouslyWith shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool
    {
        return true
    }
    func tapHandler(_ tap :UITapGestureRecognizer){
        let tapPoint = tap.location(in: tap.view)
        print(tapPoint)
        let script = String(format: "getHTMLElementAtPoint(%i,%i)", Int(tapPoint.x),Int(tapPoint.y))
        let imgSrc = self.c.stringByEvaluatingJavaScript(from: script)
        print(imgSrc)
    }
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window!.rootViewController = Page()
        self.window?.makeKeyAndVisible()
        return true
    }
}複製程式碼

執行程式碼,點選頁面的圖片,就可以看到控制檯上的輸出:

(168.0, 65.0)
Optional("https://httpbin.org/image/png,100,100,110,0")複製程式碼

委託方法 gestureRecognizer(:shouldRecognizeSimultaneouslyWith)是非常必要的,沒有它的話,WebView會自己處理手勢,而不是轉移控制器給tapHandler(:)。

相關文章