填平macOS和iOS之間的鴻溝

tags:開(kāi)發(fā)隨筆

mac and iOS

雖然mac存在了很多年之后才有了iOS,但是對(duì)很多程序員而言,可能是先熟悉了 UIKit之后才去熟悉AppKit。

我自己也是這樣瓮增。在開(kāi)發(fā)了MarkNote之后,我想把MarkNote的筆記體驗(yàn)延伸到mac哩俭。

有沒(méi)有工具或者庫(kù)可以直接將iOS應(yīng)用轉(zhuǎn)換為macOS應(yīng)用

最初我只是想讓iOS版本的MarkNote照搬過(guò)來(lái)绷跑,于是我想看看是否有捷徑可走。最理想的情況下凡资,有一個(gè)工具你踩,直接把iOS上的代碼轉(zhuǎn)換一下,就可以在mac下運(yùn)行讳苦。或者直接在mac上給iOS應(yīng)用提供一個(gè)runtime吩谦?

查了一下之后鸳谜,發(fā)現(xiàn)真有人有類(lèi)似的想法。

  • chameleon將UIKit移植到OS X式廷。然而咐扭,這個(gè)庫(kù)只實(shí)現(xiàn)了UIKit中的大部分API。更可惜的是滑废,這個(gè)庫(kù)三年前就停止更新了蝗肪。
  • UMEKit也做了類(lèi)似的事,然而蠕趁,實(shí)現(xiàn)的更少薛闪。而且,7年前就停了俺陋。

這些庫(kù)之所以夭折豁延,在很大程度上是因?yàn)槠鋸?fù)雜程度遠(yuǎn)遠(yuǎn)超過(guò)看起來(lái)的那樣昙篙。桌面應(yīng)用和移動(dòng)應(yīng)用的機(jī)制有很大的不同。雖然UIKit和AppKit共享了很多概念诱咏,但是API依然有很大的不同苔可。比如UIView和 NSView雖然看起來(lái)很像,但是實(shí)現(xiàn)細(xì)節(jié)和使用上有很多不同袋狞。

MarkNote的macOS實(shí)現(xiàn)策略

雖然Chameleon看起來(lái)很有意思焚辅,但是我最終沒(méi)有采用這個(gè)方案。一來(lái)我擔(dān)心其局限性的制約苟鸯,二來(lái)我找到了現(xiàn)在看來(lái)效果非常好的策略同蜻。

我的設(shè)計(jì)策略總結(jié)起來(lái)是以下兩點(diǎn):

  • 正視macOS和iOS的不同。 mac有mac擅長(zhǎng)的地方倔毙,在很多方面受的局限更小埃仪,應(yīng)用之可以獲得更好的用戶(hù)體驗(yàn)。比如這篇文字陕赃,雖然在iOS上也可以撰寫(xiě)卵蛉,還是不如mac上寫(xiě)起來(lái)暢快淋漓。
  • 盡量在2個(gè)平臺(tái)間復(fù)用代碼么库。對(duì)于MarkNote而言傻丝,我希望核心的代碼是完全通用的。比如markdown解析诉儒,筆記管理等等葡缰。

我采用了以下的辦法來(lái)提高復(fù)用:

  • 業(yè)務(wù)邏輯和UI操作徹底分離。 核心的業(yè)務(wù)邏輯在理想情況下應(yīng)該只依賴(lài)于 Foundation 而不依賴(lài)于 Cocoa 或者UIKit忱反。比如Markdown解析泛释,就僅僅依賴(lài)于Foundation。
  • 將通用的代碼單獨(dú)建project并打包為framewok温算。MarkNote的工程視圖如下:
project

其中:
MarkNoteParserOC 是Obj-C版的markdown 解析器怜校,已經(jīng)開(kāi)源
MarkEditor是語(yǔ)法高亮編輯器注竿,支持iOS和macOS茄茁。不僅為mac版和iOS版的MarkNote使用,同時(shí)也是?InstantCoder的代碼編輯器巩割。其一個(gè)早期版本也已經(jīng)開(kāi)源裙顽。
MarkNoteEngine是筆記管理和?iCloud同步的核心庫(kù),為mac版和iOS版的MarkNote使用宣谈。
MarkNotes是mac版的MarkNote愈犹。
MarkNote是iOS版的MarkNote。

  • 一個(gè)Framework闻丑,兩個(gè)target甘萧。
    在同一個(gè)工程中萝嘁,分別給macOS和iOS創(chuàng)建不同的target。
target
  • 使用宏來(lái)區(qū)分不同的版本扬卷。
    雖然代碼很多相同牙言,但是還是有很多系統(tǒng)之間的差異。這個(gè)時(shí)候可以用宏來(lái)處理怪得。比如我需要給mac版的加openWithCompletionHandler咱枉,而無(wú)需給iOS版添加它,就可以用類(lèi)似下面的代碼:
#if !TARGET_OS_IPHONE
- (void)openWithCompletionHandler:(void (^)(BOOL success))completionHandler;
#endif
  • 使用宏來(lái)融合UIKit和AppKit的不同徒恋。
    AppKit和UIKit中很多API都是相似的蚕断。比如NSColor和UIColor,NSView和UIView入挣,等等亿乳。這個(gè)時(shí)候,用宏定義一個(gè)別名径筏,可能是融合使用的一個(gè)好辦法葛假。
    比如,我的文本編輯器在本質(zhì)上只是NSTextView或者 UITextViewUI的一個(gè)category滋恬。
    因此我定義了一個(gè)宏BaseTextView來(lái)分別在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月上線(xiàn)带斑,mac版在2015年11月上線(xiàn)。之后兩個(gè)版本都分別更新了十多次勋拟。上面所描述的策略和方法勋磕,使得我的代碼維護(hù)起來(lái)清晰而簡(jiǎn)單。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末敢靡,一起剝皮案震驚了整個(gè)濱河市朋凉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌醋安,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墓毒,死亡現(xiàn)場(chǎng)離奇詭異吓揪,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)所计,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)柠辞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人主胧,你說(shuō)我怎么就攤上這事叭首∠扒冢” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵焙格,是天一觀的道長(zhǎng)图毕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)眷唉,這世上最難降的妖魔是什么予颤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮冬阳,結(jié)果婚禮上蛤虐,老公的妹妹穿的比我還像新娘。我一直安慰自己肝陪,他們只是感情好驳庭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著氯窍,像睡著了一般饲常。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荞驴,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天不皆,我揣著相機(jī)與錄音,去河邊找鬼熊楼。 笑死霹娄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鲫骗。 我是一名探鬼主播犬耻,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼执泰!你這毒婦竟也來(lái)了枕磁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤术吝,失蹤者是張志新(化名)和其女友劉穎计济,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體排苍,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沦寂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了淘衙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片传藏。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出毯侦,到底是詐尸還是另有隱情哭靖,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布侈离,位于F島的核電站试幽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏霍狰。R本人自食惡果不足惜抡草,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蔗坯。 院中可真熱鬧康震,春花似錦、人聲如沸宾濒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)绘梦。三九已至橘忱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卸奉,已是汗流浹背钝诚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留榄棵,地道東北人凝颇。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像疹鳄,于是被迫代替她去往敵國(guó)和親拧略。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容