填平macOS和iOS之间的鸿沟

tags:开发随笔

mac and iOS

虽然mac存在了很多年之后才有了iOS,但是对很多程序员而言,可能是先熟悉了 UIKit之后才去熟悉AppKit。

我自己也是这样。在开发了MarkNote之后,我想把MarkNote的笔记体验延伸到mac。

有没有工具或者库可以直接将iOS应用转换为macOS应用

最初我只是想让iOS版本的MarkNote照搬过来,于是我想看看是否有捷径可走。最理想的情况下,有一个工具,直接把iOS上的代码转换一下,就可以在mac下运行。或者直接在mac上给iOS应用提供一个runtime?

查了一下之后,发现真有人有类似的想法。

  • chameleon将UIKit移植到OS X。然而,这个库只实现了UIKit中的大部分API。更可惜的是,这个库三年前就停止更新了。
  • UMEKit也做了类似的事,然而,实现的更少。而且,7年前就停了。

这些库之所以夭折,在很大程度上是因为其复杂程度远远超过看起来的那样。桌面应用和移动应用的机制有很大的不同。虽然UIKit和AppKit共享了很多概念,但是API依然有很大的不同。比如UIView和 NSView虽然看起来很像,但是实现细节和使用上有很多不同。

MarkNote的macOS实现策略

虽然Chameleon看起来很有意思,但是我最终没有采用这个方案。一来我担心其局限性的制约,二来我找到了现在看来效果非常好的策略。

我的设计策略总结起来是以下两点:

  • 正视macOS和iOS的不同。 mac有mac擅长的地方,在很多方面受的局限更小,应用之可以获得更好的用户体验。比如这篇文字,虽然在iOS上也可以撰写,还是不如mac上写起来畅快淋漓。
  • 尽量在2个平台间复用代码。对于MarkNote而言,我希望核心的代码是完全通用的。比如markdown解析,笔记管理等等。

我采用了以下的办法来提高复用:

  • 业务逻辑和UI操作彻底分离。 核心的业务逻辑在理想情况下应该只依赖于 Foundation 而不依赖于 Cocoa 或者UIKit。比如Markdown解析,就仅仅依赖于Foundation。
  • 将通用的代码单独建project并打包为framewok。MarkNote的工程视图如下:
project

其中:
MarkNoteParserOC 是Obj-C版的markdown 解析器,已经开源
MarkEditor是语法高亮编辑器,支持iOS和macOS。不仅为mac版和iOS版的MarkNote使用,同时也是�InstantCoder的代码编辑器。其一个早期版本也已经开源
MarkNoteEngine是笔记管理和�iCloud同步的核心库,为mac版和iOS版的MarkNote使用。
MarkNotes是mac版的MarkNote。
MarkNote是iOS版的MarkNote。

  • 一个Framework,两个target
    在同一个工程中,分别给macOS和iOS创建不同的target。
target
  • 使用宏来区分不同的版本
    虽然代码很多相同,但是还是有很多系统之间的差异。这个时候可以用宏来处理。比如我需要给mac版的加openWithCompletionHandler,而无需给iOS版添加它,就可以用类似下面的代码:
#if !TARGET_OS_IPHONE
- (void)openWithCompletionHandler:(void (^)(BOOL success))completionHandler;
#endif
  • 使用宏来融合UIKit和AppKit的不同
    AppKit和UIKit中很多API都是相似的。比如NSColor和UIColor,NSView和UIView,等等。这个时候,用宏定义一个别名,可能是融合使用的一个好办法。
    比如,我的文本编辑器在本质上只是NSTextView或者 UITextViewUI的一个category。
    因此我定义了一个宏BaseTextView来分别在macOS上指向NSTextView,而在iOS上指向UITextView:
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#define BaseTextView UITextView
#else
#import <Cocoa/Cocoa.h>
#define BaseTextView NSTextView
#endif

这样,我后面也就直接用BaseTextView好了。比如

@interface BaseTextView(Editor)

MarkNote IOS版在2015年5月上线,mac版在2015年11月上线。之后两个版本都分别更新了十多次。上面所描述的策略和方法,使得我的代码维护起来清晰而简单。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容