May 30

初学纯代码MAC应用开发小记

Lrdcq , 2018/05/30 21:43 , 程序 , 閱讀(4274) , Via 本站原創
由于工具应用的开发需求,稍微尝试了一下更加工程化的MAC开发。按传统的做法,依赖AppKit开发普通桌面应用会大量使用xib/storyboard等工具,不过考虑到目前写的东西的方案会往sketch插件或者别的工具和平台上移植,并且从团队技术栈上来看大家也更习惯纯代码frame+Masonry的开发手段,同时也有程序本身设计动态化窗口/菜单的缘故,因此尝试探索了几乎纯代码开发mac应用的方式。

點擊在新視窗中瀏覽此圖片

● 从零创建一个mac程序项目,会包含一个主xib,其中包含一个NSWindow窗口与我们的顶部菜单。这一套xib完全可以删除。

  - 其中窗口直接新建NSWindow并且[window makeKeyAndOrderFront:self]就可以展示出来了

  - 菜单需要自己组合创建复杂的NSMenu与NSMenuItem对象,并设置到[[NSApplication sharedApplication] mainMenu]即可

● 控制一个手工创建的NSWindow的效果常用的地方有好几处

  - 一个是构造器- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag中NSWindowStyleMask部分,对应的xib编辑面板窗口option那一部分,计划所有常见功能如无边框,禁止放大缩小等,对于自定义界面的程序,都会用到

  - 属性level,定义窗口在系统中的层次,最高可以到NSScreenSaverWindowLevel屏保层,这次做的悬浮框应用是相当有用的。

  - 属性collectionBehavior,定义窗口在桌面集合工具,比如dock,手势集合面板上的表现,由于默认表现受上面两个属性的影响,所有有必要单独设置,

● 纯代码创建的NSWindow在使用时有一些坑

  - 注意到和iOS开发的区别,iOS中初始化的window在最顶层的只有一个,每次makeKeyAndVisible就可以了。而NSWindow在mac程序中往往有复数个,到底是否只是出现还是提高到某一个层次还是直接夺得焦点,需要我们自己根据使用场景来定夺,相关的方法也是相当丰富的。

  - 和iOS不一样的是,mac应用一般就需要考虑多屏幕的适配,因此需要通过[NSScreen mainScreen]拿到当前的主要屏幕,并且通过visibleFrame属性去检查实际展示的区域,从而去初始化当前window的位置。同时,也要考虑subwindow的情况。

  - 如果要考虑桌面多个工作台转移的情况,需要通过[[NSWorkspace sharedWorkspace] notificationCenter]监听NSWorkspaceActiveSpaceDidChangeNotification通知并且在发生变化的时候重新展示window。当然,直接设置windows的NSWindowCollectionBehaviorMoveToActiveSpace或者NSWindowCollectionBehaviorCanJoinAllSpaces就能应付绝大部分需要挪动位置的场景。

  - 手工创建的NSWindow在arc销毁时,AppKit有bug会重复释放,需要在释放前设置releasedWhenClosed=NO。

● 数据架构选择上的考虑

  - 说到苹果开发,一上来就是NSViewController的mvc开发模式,不过和ios开发不同,mac开发中NSViewController看起来并没有那么重要。

  - 一个是从NSViewController和UIViewController在对应框架中的作用来看,UIViewController是整个界面的根基,整个界面树不可或缺的一环,而NSViewController在实际使用中并不在树上,它真的就是一个附属类,老老实实的完成controller的任务,换句话说,一个controller它到底是不是NSViewController并不重要。

  - 同时,从app和桌面程序的程序形态来看。iOS应用一般只有一个UIWindow,因此需要在window中通过大量子容器即UIViewController来实现流程和功能的切换。而桌面程序一般通过NSWindow开窗口来聚焦核心功能,分支流程通过大量子窗口的串接来完成,因此NSViewController在mac应用开发中并不重要。

  - 另外,作为近两年的iOS开发,我们已经有一套自有的完整的数据框架:比如MVP,MVVM,flow等,他们的特点是,UIViewController在他们中并不重要,数据流冗余,甚至鸡肋。比如对于MVVM来说,我们每一个NSView对应一个ViewModel即可完成整个数据流程,NSView自己执行数据绑定过程已经不需要NSViewController了。并且整个数据框架可以完整的组合成中大型项目。

  - 因此,对于纯手工建的代码布局来说,既然没有xib,我也就不需要NSViewController了,直接通过NSWindow的contentView绑定上携带数据源的NSView就可以构成整个应用了

● 对于其他第三方库的选择,其实限制并不多,类似于基础的libextobjc,常用的AFNetworking,Masonry,ReactiveCocoa之类的功能型库,基本上可以直接使用,可以保障iOS开发习惯继续延续。

● 另外,如果保持较为精简的原生AppKit开发方式,可以直接开发为framework甚至直接迁移代码为比如skecth插件等第三方工具开发提供帮助,这也是非常流畅的组合开发方式。
关键词:appkit , osx
logo