最近在写的App是这种类型的,总结了总结,写了这篇博文,在掘金中没有客户端分类 我不知道该放到那个分类里 就放在iOS里吧html
本文旨在介绍如何实现 基于文档的Mac App 如有描述不许确或错误的地方 还望多多指正,共同窗习(๑•ᴗ•๑)api
实现的效果也就是 在文档的打开方式中有本身的App可选,将文件拖拽至Dock栏中能够打开~bash
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))
}
}
复制代码
顾名思义是负责对Document
进行管理,是一个单例~ 方法也就主要是下面这些~学习
NSDocumentController.shared.newDocument(nil)
//也能够直接init一个Document,而后加进去
复制代码
//用户经过面板打开一个新的Document
NSDocumentController.shared.openDocument(nil)
//这里也能够使用NSDocument的init方法建立(使用的重载方法不一样),可是这样建立的对象再也不NSDocumentController的管理内~ 能够手动加入其中
复制代码
//保存全部文档
NSDocumentController.shared.saveAllDocuments(nil)
//也能够调用NSDocument的save方法
复制代码
这里应该调用的是 Document的 saveAs()/saveTo() 方法, 为了工整一些 我就放在这里了~
复制代码
对NSDocument
类支持的文档类型和导出的文档类型是在 info.plist
中存储的~ 咱们能够在Targets->info中进行设置~ 须要对Document Type和Export UTIs进行设置~~ui
这里就引入了一个概念UTI,它是Apple系统处理文档文件等数据的统一类型标识符,也能够把它理解为苹果爸爸对其余各种文档数据的别名,你们叫jpg
,苹果爸爸叫它public.jpeg
.除去UTI中约定好的部分,对于 咱们自创的类型,则能够设置自创的别名~ 在这里我就使用已有类型了jpg
其余的UTI看这里Uniform Type Identifiesspa
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上时,在新建的文档保存/导出时,会让咱们选择格式~
如果App只是使用已有的文档类型如jpg
,则是在Document Types中设置就已经足够了,可是若要试用自定义类型的话,则须要用到
Description
外都是必填的~
identifer和Extension这里是自定以的~怎么写都好~ 可是上下要一致
Conforms To这里我填写的是public.data
,这里到底写什么,能够在UTIs中按需选择~
效果以下~~
有些时候,咱们的文档并不是只是一个文档,还有相似于bundle
这种类型的文档包,(在这里吐槽一句,其实MarkDown也应该作成文档包这种样式就行了~) 效果以下
配置FileWrapper和上面略有不一样~
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时~
若上文有不许确的地方 还望多多指正 共同窗习 (๑•ᴗ•๑)