12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SpeakerDeckのスライドをPDF形式で表示できるiOSアプリを作った

Last updated at Posted at 2017-05-20

SpeakerDeckのスライドをPDF形式で表示できるiOSアプリを作った

背景

IMG_6577.PNG

勉強会のスライドなど、Speaker Deckに掲載されているスライドをよく閲覧するのですが、1ページずつしか進めないし、数ページ前に戻りたくても1ページずつしか戻れないし...なにより保存できないし...
もう少しスマートに閲覧したいと思い、PDF形式で保存・表示できるアプリをRxSwiftの練習を兼ねて作ってみました。

作ったもの

IMG_6577.gif Speaker Deckの`ユーザ名 / スライド名`もしくは`スライドURL`を入力したら、 スライド情報を保存してPDF表示できるものを作ってみました。

やったこと

スライドのURLを入力

Kanna を用いてスクレイピング

スライドIDなどの情報を保存

webViewでPDFを表示

スライドURLの入力

URLTextField.rx.controlEvent([.editingDidEnd])
    .flatMap({
        self.URLTextField.text.flatMap(Observable.just) ?? Observable.empty()
    })
    .bind(to: viewModel.urlString)
    .addDisposableTo(disposeBag)

textFieldの入力終了後に、textFieldに入力されているtextの内容をviewModelのurlStringに渡すようにしました。

Kannaを用いたスクレイピング

今回、Swift製のHTMLパーサKannaを使用してスクレイピングを行いました。

Swift製HTMLパーサ「Kanna」
詳しい使い方はこちらを参考にしてください。

//HTMLソースをData形式で取得
let data = try FetchSlideRequest.getHTML(path: path)
//HTMLDocument形式に変換
let doc = HTML(html: data, encoding: String.Encoding.utf8)
guard let details = doc?.body?.css("div#talk-details").first else { return }

//スライドのタイトルを取得
guard let title = details.css("h1").first?.innerHTML else { return }
//スライドの作者を取得
guard let author = details.css("a").first?.innerHTML else { return }
//PDF形式のスライドのURLを取得
guard let pdfURL = doc?.body?.css("#share_pdf").first?["href"] else { return }

スライドIDなどの情報を保存

 var importSlide: Observable<Void> {
    return Observable
        .zip(slideTitle, slideAuthor, slideId, pdfURL, importTrigger) { slideTitle, slideAuthor, slideId, pdfURL, importTrigger -> Void in
            let slide = Slide()
            slide.title = slideTitle
            slide.author = slideAuthor
            slide.id = slideId
            slide.pdfURL = pdfURL
            let realm = try! Realm()
            try? realm.write {
                realm.add(slide, update: true)
            }
    }
}

importTriggerが発火したときに、取得していたタイトルや作者などをRealmに保存するようにしてみました。

PDFの表示

WebViewを使用することでPDFビューワーを実装しなくても済むようにしました。
URLRequestのキャッシュを使用しているので、PDFファイル自体は保存していません。

guard let url = URL(string: slide.pdfURL) else {
     return
}
self.WKView.load(URLRequest(url: url))

今回、プログレスバーを使用したかったため、WKWebViewを使用しました。

self.WKView.rx.estimatedProgress.bind(onNext: {
    self.navigationController?.setProgress(Float($0), animated: false)
}).addDisposableTo(disposeBag)

RxSwiftを使用していたので、こんな感じに書けました。
Rx+WebKit.swift : WebKitのRxExtensionを使用させてもらいました。

まとめ

個人的に結構使い勝手がいいです。
Safariから直接アプリに取り込めるようにしたい!

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?