Pages

2011-07-05

SafariというかWebKitのWebArchiveについて

Safariで閲覧中のページを保存しようとしたとき、保存形式に「Webアーカイブ」ってのが選べますよね。そのページで利用されているリソース一式が1つのファイルを保存できる便利なアレです。

CocoaでWebアーカイブを扱う方法

そのWebアーカイブをCocoaで扱うには、WebKitのWerArchiveというドンピシャな名前のクラスを使います。次のようにすることでWebViewで表示中のページのWebアーカイブを取り出すことができます。

WebArchive *archive = [[[webView mainFrame] dataSource] webArchive];

ここで得られたWebArchiveオブジェクトは- dataというインスタンスメソッドを持っていて、そこで返されるNSDataオブジェクトをファイルに書き込むことでWebアーカイブファイルを作成することができます(拡張子を.webarchiveにすればSafariでちゃんと開けます!)。

また、WebアーカイブファイルをNSDataとして読み込めば、そこからWebArchiveオブジェクトを生成してWebViewに読み込ませることができます。

WebArchive *archive = [[[WebArchive alloc] initWithData:webArchiveFileData] autorelease];
[[webView mainFrame] loadArchive:archive];

Webアーカイブの中身

Webアーカイブの中身はバイナリplistです。試しに.webarchiveファイルをProperty List Editorにドロップしてみればちゃんと中身を見ることができます。plistということは、中の構造さえわかってしまえばWebKitを使わなくてもCocoaからあんなことやこんなことができちゃうわけです。というわけでplistの内容をチェックしていきましょう。WebアーカイブplistのルートはDictionaryになっています。

WebMainResource
Dictionary。周辺リソースではなくそのページ本体について、以下のキーをもちます。
WebResourceData
Data。本体のデータです。HTMLページの場合はそのHTMLをNSData形式にしたものが入ります。
WebResourceFrameName
String。ここでは空欄。WebSubframeArchives絡み(後述)で使います
WebResourceMIMEType
String。そのまま。text/htmlとか。
WebResourceTextEncodingName
String。UTF-8とか。
WebResourceURL
String。その本体リソースが本来あったURL。
WebSubframeArchives
Array。後述。
WebSubresources
Array。ページに埋め込まれている画像やスクリプト等の外部リソースについて、(WebMainResourceと同じように)WebResourceData、WebResourceMIMEType、WebResourceURLのキーを使ってDIctionaryを作り、Arrayに追加していきます。SafariやWebKitが作ったWebアーカイブにはこれらの他にもリソース取得時のNSHTTPURLResponseインスタンスがWebResourceResponseというキーでアーカイブされているのですが、これを消しても正常に表示できるようなので、要調査。

WebSubframeArchivesは、frame、iframe、objectといった要素で埋め込まれた外部ページのWebアーカイブをそのまま追加します。つまり、a.htmlの中のフレームにb.htmlが読み込まれている場合、a.htmlのWebアーカイブしようとする場合には先にb.htmlのWebアーカイブを作成し、その結果をこのWebSubframeArchivesのArrayの要素として追加する必要があります。このときのb.htmlのアーカイブは、さっきは空欄にしたWebResourceFrameNameにa.htmlでのフレーム名が入ります。

おわりに

上で見たように、WebアーカイブはただのplistなのでCocoaから簡単にいじることができるので、単なるファイル保存用途にとどまらず、いろいろな活用法があるかもしれません。CocoaじゃなくてもWindowsならCFLiteを使えば多分plistを扱えるとおもうので、ここはおひとつ試してみてはいかがでしょうか。

0 件のコメント:

コメントを投稿