0

Preview documents with Quick Look Framework

iOS có những framework tuyệt vời nhưng lại không được nhiều người biết đến, nó có thể giúp bạn tiết kiệm hàng giờ và vô cùng hữu ích đối với lập trình viên. Quick Look framework là một trong số đó, nó cung cấp chức năng xem trước những tài liệu mà app xử lý.

Quick Look framework được dùng để xem trước nội dung của một số loại tài liệu như iWork (Pages, Numbers, Keynote), file Microsoft Office, file PDF, ảnh, file text, file rich-text format, file comma-separated value (csv).

Ngoài khả năng cho phép xem trước, framework này còn cung cấp chức năng chia sẻ tài liệu.

Quick Look framework chứa QLPreviewController, được dùng để xem trước nội dung của tài liệu. View controller này sẽ được xuất hiện trong app theo kiểu modally hoặc navigation. Nó là thành phần chính tạo nên framework, cùng với chức năng xem trước, ta có thể chia sẻ, chuyển sang xem file mới nhờ hiển thị một danh sách các tài liệu có sẵn.

Demo

Để hiểu rõ hơn về Quick Look framework, hãy cùng tạo một demo, liệt kê ra các tài liệu được lưu trong app bundle và xem trước nội dung của các tài liệu này.

Trước tiên hãy tạo một project mới đặt tên là QuickLookDemo, sau đó tạo một tableview FileListViewController và FileListCell.xib định nghĩa một tableview cell gồm title và detail label.

Hãy kéo vào app bundle những file mà bạn muốn preview (pdf, image, keynote, pages, text..). Bước tiếp theo chúng ta sẽ cùng hiển thị danh sách các file này vào table view. Project lúc này sẽ có cấu trúc như sau:

Screen Shot 2016-09-24 at 10.22.48 AM.png

Tạo files và files URL

Để hiển thị các file này, ta sẽ tạo một array chứa file name của các sample files trên, việc này không chỉ giúp ta hiển thị các file trong tableview mà quan trọng hơn, nó tạo ra một danh sách các NSURL objects được cung cấp như là datasource cho Quick Look framework.

Định nghĩa array này trong FileListViewController:

let fileNames = ["SycamoreTree_Keynote.key", "SycamoreTree_Pages.pages", "SycamoreTree_Pdf.pdf", "SycamoreTree_Text.txt", "SycamoreTree_Image.jpg"]

Trong demo này, do các file data đã được chúng ta biết trước nên việc tạo ra một array chứa filename của files khá dễ dàng. Tuy nhiên, đối với các app thực tế, nếu các file được download từ bên ngoài về thì rất khó để tạo array, vì vậy ta cần khai báo dynamic array để có thể dễ dàng thêm một hoặc nhiều file mới vào.

var fileURLs = [NSURL]()

Array trên đóng vai trò là datasource cho cả QuickLook framework và tableview.

Tiếp theo, hãy tạo ra những NSURL object mới từ array filesName và add vào fileURLs chúng ta vừa tạo ra:

func createFileURLs() {
        for file in fileNames {
            let fileParts = file.componentsSeparatedByString(".")
            guard let fileURL = NSBundle.mainBundle().URLForResource(fileParts[0], withExtension: fileParts[1]) else {
                continue
            }

            if NSFileManager.defaultManager().fileExistsAtPath(fileURL.path!) {
                fileURLs.append(fileURL)
            }
        }
    }

Hãy gọi function này trong viewDidLoad của FileListViewController.

Hiển thị files

Ta sẽ hiển thị danh sách các files trong tableview với title là tên file và thông tin detail là loại files. Tên file và loại file sẽ đc tách ra và trả vể từ fileURL ta đã tạo ra từ trước:

func extractFilename(fileURL: NSURL) -> (fileName: String, fileExtension: String) {
        let fileURLParts = fileURL.path!.componentsSeparatedByString("/")
        let fileName = fileURLParts.last
        let filenameParts = fileName?.componentsSeparatedByString(".")

        // Return file name and file extension
        return (filenameParts![0], filenameParts![1])
    }

Và hiển thị tên file lên tableview:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("idCellFile", forIndexPath: indexPath)

        let currentFileParts = extractFilename(fileURLs[indexPath.row])

        cell.textLabel?.text = currentFileParts.fileName

        return cell
    }

Tiếp theo ta chuyển đổi loại file sang chuỗi string dễ đọc hơn:

func getFileTypeFromFileExtension(fileExtension: String) -> String {
    var fileType = ""

    switch fileExtension {
    case "docx":
        fileType = "Microsoft Word document"

    case "pages":
        fileType = "Pages document"

    case "jpeg":
        fileType = "Image document"

    case "key":
        fileType = "Keynote document"

    case "pdf":
        fileType = "PDF document"

    default:
        fileType = "Text document"

    }

    return fileType
}

Và thêm vào function cellForRowAtIndexPath dòng code sau để hiện thị loại file trong detail text của table cell:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("idCellFile", forIndexPath: indexPath)

        let currentFileParts = extractFilename(fileURLs[indexPath.row])

        cell.textLabel?.text = currentFileParts.fileName
        cell.detailTextLabel?.text = getFileTypeFromFileExtension(currentFileParts.fileExtension)

        return cell
    }

Bước cuối cùng, hãy trả về số dòng của tableview chính bằng số phần tử của aray fileURLs:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return fileURLs.count
    }

Kết quả sau khi chạy app ta sẽ được một danh sách như sau:

Screen Shot 2016-09-24 at 11.33.41 AM.png

Quick Look Preview Controller Datasource

Để sử dụng Quick Look framework, hãy import nó vào FileListViewController và khai báo một biến mới thuộc class QLPreviewController:

import QuickLook

let quickLookController = QLPreviewController()

Class FileListViewController cần implement QLPreviewControllerDataSource để có thể sử dụng framework:

extension FileListViewController: QLPreviewControllerDataSource {}

Thêm vào hai method sau để báo với Quick Look có bao nhiêu tài liệu cần preview và phải preview document nào trong mảng fileURLs:

func numberOfPreviewItemsInPreviewController(controller: QLPreviewController) -> Int {
        return fileURLs.count
}

func previewController(controller: QLPreviewController, previewItemAtIndex index: Int) -> QLPreviewItem {
        return fileURLs[index]
}

Cuối cùng, hãy set datasource cho quickLookController trong viewDidLoad method:

quickLookController.dataSource = self

Preview tài liệu

Để app mở preview của tài liệu được chọn, ta cần thực thi method didSelectRowAtIndexPath của tableview. Quick Look cung cấp phương thức canPreviewItem để kiểm tra xem một loại tài liệu có được hỗ trợ để mở hay không. Nếu có, gọi navigationController để mở quickLookController:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if QLPreviewController.canPreviewItem(fileURLs[indexPath.row]) {
        quickLookController.currentPreviewItemIndex = indexPath.row
        navigationController?.pushViewController(quickLookController, animated: true)
    }    
}

Chạy demo và bây giờ ta đã có thể preview được cây sycamore tuyệt đẹp vào mùa thu.

Screen Shot 2016-09-24 at 3.26.15 PM.png

Các bạn có thể sử dụng tính năng chia sẻ ở góc dưới màn hình của Quick Look:

Screen Shot 2016-09-24 at 3.26.29 PM.png

Ngoài ra, button ở góc dưới bên phải giúp mở ra một danh sách các files có trong datasource, và ta có thể dễ dàng chọn bất cứ một file nào để xem, hoặc bạn có thể chỉ đơn giản swipe phải để preview tài liệu tiếp theo.

Screen Shot 2016-09-24 at 3.32.44 PM.png

Quick Look Preview Controller Delegate

Ngoài hai delegate methods trên của Quick Look, ta có thể implement thêm một số delegate methods khác để điều khiển preview controller tốt hơn. Các method này thuộc về protocol QLPreviewControllerDelegate:

func previewControllerWillDismiss(controller: QLPreviewController) {
        print("The Preview Controller will be dismissed")
    }

func previewControllerDidDismiss(controller: QLPreviewController) {
        tblFileList.deselectRowAtIndexPath(tblFileList.indexPathForSelectedRow!, animated: true)
        print("The Preview Controller has been dismissed.")
    }

Ngoài ra, ta có thể định nghĩa file nào được phép preview, file nào không bằng method sau:

func previewController(controller: QLPreviewController, shouldOpenURL url: NSURL, forPreviewItem item: QLPreviewItem) -> Bool {
    if item as! NSURL == fileURLs[0] {
        return true
    }
    else {
        print("Will not open URL \(url.absoluteString)")
    }
 
    return false
}

Kết luận

Quick Look framework thực sự là một framework hữu ích nếu ta muốn preview tài liệu một cách nhanh chóng và không tốn nhiều công sức. Framework này hầu như cung cấp đầy đủ những phương thức cần thiết để preview tài liệu. Thông qua bài viết này, hy vọng các bạn có được cái nhìn tổng quát về Quick Look và sẽ có thể sử dụng nó sau này. Demo project có thể download tại đây.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí