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时~

若上文有不许确的地方 还望多多指正 共同窗习 (๑•ᴗ•๑)

相关文章
相关标签/搜索