Diverse Advent Calendar の22日目の記事です。
おはこんばんちわ。
ドーモ。窓際エンジニア=デス
今日はWebViewでスマートフォン向けのWebページを見ながらOGPの情報を取得する方法を紹介します。
OGPのタグはスマートフォン向けのページには書かれることはほとんど無く、大抵の場合はPC向けのページのみに書かれています。
OGP情報を取るだけのためにPCページを表示したくないときに利用すると良い感じです。
今回の方法
- 
AFNetworkingを使ってカスタムUAを設定したリクエストを飛ばす
- レスポンスからOGP情報を取得する
見ているページにカスタムUAを設定したリクエストを送る
今回はボタンを押したときにOGPを取得することを想定します。
利用の際は、適当なタイミングでリクエストを送ってください。
HTMLからmetaタグを取り出すのはHTMLReaderを利用してます。
dict に取得したOGP情報を格納しています。
class ViewController: UIViewController, UIWebViewDelegate {
    let webView = UIWebView()
    let button = UIButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.frame = view.frame
        webView.delegate = self
        view.addSubview(webView)
        
        button.frame = CGRectMake(100, 100, 120, 60)
        button.addTarget(self, action: "onClickButton", forControlEvents: .TouchUpInside)
        view.addSubview(button)
        
        let url = NSURL(string: "http://diverse-inc.co.jp/")
        let urlRequest = NSURLRequest(URL: url!)
        webView.loadRequest(urlRequest)
    }
    
    func onClickButton() {
        // 見ているページの取得
        let urlString = webView.stringByEvaluatingJavaScriptFromString("document.URL")
        
        let manager = AFHTTPRequestOperationManager()
        let request = manager.requestSerializer.requestWithMethod("GET", URLString: urlString, parameters: nil)
        
        // カスタムUAの設定
        request.setValue("CustomUserAgent", forHTTPHeaderField: "User-Agent")
        
        let operation = manager.HTTPRequestOperationWithRequest(request, success: {
            (requestOperation: AFHTTPRequestOperation!, responseObject: AnyObject!) in
            if let data = responseObject as? NSData {
                if let htmlString = String(data: data, encoding: NSUTF8StringEncoding) {
                    self.extractOGP(htmlString)
                }
            }
            }, failure: {
                (requestOperation: AFHTTPRequestOperation!, error: NSError!) in
                // error handling
        })
        
        operation.responseSerializer = AFHTTPResponseSerializer()
        operation.responseSerializer.acceptableContentTypes = NSSet(object: "text/html") as Set<NSObject>
        manager.operationQueue.addOperation(operation)
    }
    
    // htmlからOGPを取得する
    func extractOGP(htmlString: String) {
        var dict = [String:String]()
        
        // HTMLReaderを利用してogタグを取得する
        let html = HTMLDocument(string: htmlString)
        guard let ogTags: [AnyObject] = html.nodesMatchingSelector("meta[property^=\"og:\"]") else {
            // ogタグが無かったときの処理
            return
        }
        
        for tag in ogTags {
            if let key = tag.attributes?["property"] as? String, let value = tag.attributes?["content"] as? String {
                // ogタグを辞書に入れる
                dict[key] = value                                                    
            }
        }
    }
}
ボタンを押した際にPC向けのサイトにリクエストを送り、レスポンスからOGP情報を取得することができます。
まとめ
見ているページのURLへカスタムなUAを設定したリクエストを送り、レスポンスからOGP情報を取得しました。
スマートフォン向けのページを見たまま、裏側でOGP情報を取得したいときなどに使えます。
