SpeakerDeck의 슬라이드를 PDF 형식으로 표시할 수 있는 iOS 앱을 만들었다

SpeakerDeck의 슬라이드를 PDF 형식으로 표시할 수 있는 iOS 앱을 만들었다



배경





공부회의 슬라이드 등 Speaker Deck에 게재되어 있는 슬라이드를 자주 열람합니다만, 1페이지씩 밖에 진행할 수 없고, 몇 페이지 전에 돌아가고 싶어도 1페이지씩 밖에 돌아갈 수 없고... 무엇보다 저장 할 수 없고 ...
좀 더 스마트하게 열람하고 싶고, PDF 형식으로 보존·표시할 수 있는 앱을 RxSwift의 연습을 겸해 만들어 보았습니다.

만든 것




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에서 직접 앱으로 가져올 수 있기를 원합니다!

좋은 웹페이지 즐겨찾기