填平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月上線。之后兩個版本都分別更新了十多次。上面所描述的策略和方法,使得我的代碼維護起來清晰而簡單。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容