Mac開發---NSDocument

簡述

最近在寫的App是這種類型的,總結了總結,寫了這篇博文,在掘金中沒有客戶端分類 我不知道該放到那個分類裏 就放在iOS裏吧html

本文旨在介紹如何實現 基於文檔的Mac App 如有描述不許確或錯誤的地方 還望多多指正,共同窗習(๑•ᴗ•๑)api

實現的效果也就是 在文檔的打開方式中有本身的App可選,將文件拖拽至Dock欄中能夠打開~bash

NSDocument

NSDocument類至關於一層封裝~ ,相似於UIImage,不管是jpg格式仍是png格式都以UIImage對象進行調用~app

NSDocument則不只能夠對外持有 文檔數據, 對內能夠綁定 窗口控制器~.當打開文檔時自動建立並展現與其綁定的窗口控制器~dom

Xcode提供的Document模板大概就是下面這個樣子~ide

import Cocoa

class Document: NSDocument {
    var saveData:Data!

    //是否自動保存(出用戶選擇外的全部保存方式 都是非自動保存,像按鈕..點擊的方法中能夠保存,其餘的不能)
    override class var autosavesInPlace: Bool {
        return true
    }

    //用於爲Document綁定WindowController,當打開新的Document時,對應的WindowController就會被打開~(不綁定也是能夠的)
    override func makeWindowControllers() {
        let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
        let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController
        self.addWindowController(windowController)
    }

    //將當前文檔保存時調用
    override func data(ofType typeName: String) throws -> Data {
        Swift.print("保存文件")
        return saveData
    }

    //當讀取新的數據時調用
    override func read(from data: Data, ofType typeName: String) throws {
        saveData = data
        Swift.print("讀取內容 來自\(self.fileURL)")
    }
    
    //自動保存時調用的方法~ 當前是否能判斷是否
    override func autosave(withImplicitCancellability autosavingIsImplicitlyCancellable: Bool, completionHandler: @escaping (Error?) -> Void) {
        Swift.print("調用自動保存")

        //completionHandler(nil)
        completionHandler(NSError.init(domain: "錯誤提示", code: 0, userInfo: nil))
    }
}
複製代碼

NSDocumentController

顧名思義是負責對Document進行管理,是一個單例~ 方法也就主要是下面這些~學習

新建

NSDocumentController.shared.newDocument(nil)
//也能夠直接init一個Document,而後加進去
複製代碼

打開

//用戶經過面板打開一個新的Document 
NSDocumentController.shared.openDocument(nil)

//這裏也能夠使用NSDocument的init方法建立(使用的重載方法不一樣),可是這樣建立的對象再也不NSDocumentController的管理內~ 能夠手動加入其中

複製代碼

保存

//保存全部文檔
NSDocumentController.shared.saveAllDocuments(nil)

//也能夠調用NSDocument的save方法
複製代碼

導出

這裏應該調用的是 Document的 saveAs()/saveTo() 方法, 爲了工整一些 我就放在這裏了~
複製代碼

info.plist配置

NSDocument類支持的文檔類型和導出的文檔類型是在 info.plist中存儲的~ 咱們能夠在Targets->info中進行設置~ 須要對Document TypeExport UTIs進行設置~~ui

這裏就引入了一個概念UTI,它是Apple系統處理文檔文件等數據的統一類型標識符,也能夠把它理解爲蘋果爸爸對其餘各種文檔數據的別名,你們叫jpg,蘋果爸爸叫它public.jpeg.除去UTI中約定好的部分,對於 咱們自創的類型,則能夠設置自創的別名~ 在這裏我就使用已有類型了jpg 其餘的UTI看這裏Uniform Type Identifiesspa

Document Types

Name: 文檔的類型名稱,可爲空~設計

identifer: 文檔標識,如果用自定義的類型,這裏能夠寫自定義的類型.如果針對已有類型能夠在UTI中找~

Class: 標識該類型對應在項目中的Document類,我使用的繼承NSDocument的子類 MK_Document,因此這裏填 $(PRODUCT_MODULE_NAME).MK_Document

Roler: 這裏表示應用對文檔的處理權限, Editor(讀寫),Viewer(只讀).

Extensions: 文檔後綴,不區別大小寫~

Icon: 自定義類型在Finder中顯示的樣子(有時候能夠,有時候不行,就和我用Movist看mkv視頻,有時候能夠帶上Movist圖標,有時候不行~ 要有懂這個圖片設置的老鐵 分享一蛤~)

至於其餘的一些選項,我沒用到

至於下面那個additional document type properties是設置額外的文檔屬性,在舊版Xcode中Document Types在這裏的選項並無這麼多,那個時候須要用它設置額外的一些屬性,我用的Xcode9上面提供的選項已經夠用了~~

當咱們設置多個Document Type且綁定至同一個Document上時,在新建的文檔保存/導出時,會讓咱們選擇格式~

Export UTLs

如果App只是使用已有的文檔類型如jpg,則是在Document Types中設置就已經足夠了,可是若要試用自定義類型的話,則須要用到

這裏就簡單展現了一下自定義類型,須要注意的是 上面除了 Description外都是必填的~

identiferExtension這裏是自定以的~怎麼寫都好~ 可是上下要一致

Conforms To這裏我填寫的是public.data,這裏到底寫什麼,能夠在UTIs中按需選擇~

效果以下~~

FileWrapper

有些時候,咱們的文檔並不是只是一個文檔,還有相似於bundle這種類型的文檔包,(在這裏吐槽一句,其實MarkDown也應該作成文檔包這種樣式就行了~) 效果以下

配置FileWrapper和上面略有不一樣~

infor配置

主要就是將 Conforms To改一下~ 而後在 Document中實現對應的 NSFileWrape方法 其餘地方也就是換湯不換藥

//保存時調用
    override func fileWrapper(ofType typeName: String) throws -> FileWrapper {
        let  fileWrappers  = FileWrapper(directoryWithFileWrappers: [:])

        return fileWrappers
    }

    //讀取時調用~ 包中的數據能夠經過 filleWraper獲取
    override func read(from fileWrapper: FileWrapper, ofType typeName: String) throws {
        for item in fileWrapper.fileWrappers! {
            Swift.print("得到\(item.key)")
        }
    }
複製代碼

總結

NSDocument是 對文檔的封裝,不管面對什麼樣的文檔 都是NSDocument對象,和 NSData同樣~ 這種設計方案是是值得咱們借鑑的 尤爲是在寫SDK時~

若上文有不許確的地方 還望多多指正 共同窗習 (๑•ᴗ•๑)

相關文章
相關標籤/搜索