macOS.XPC

XPC 是 macOS 里經(jīng)常用到的進程間通信機制。本文不關(guān)注 XPC 的內(nèi)部機制,而是一篇教你如何上手 XPC 的文章。

  1. 創(chuàng)建 macOS 工程 'FRTestXPC',選擇 Cocoa App Template。

  2. 在工程 'FRTestXPC' 里點擊增加 Target,在彈出框搜索 XPC, 選擇搜索結(jié)果中的 XPC Service,然后命名 Target 為 'FRTestXPC_Helper' 并將 target 對應(yīng)的 info.plist 文件中 bundle id 修改為 'com.frank.xpchelper'

  3. 選擇 'FRTestXPC' Target -> Build Phases 然后新增 CopyFiles 項目,將剛剛的 FRTestXPC_Helper.xpc 加進去,注意 Destination 必須要選擇 XPC Services。否則后續(xù)主程序和 XPC 會無法建立連接。

  4. 回過頭來看工程目錄里 FRTestXPC_Helper -> main.m 文件,這里 main 函數(shù)是 XPC 程序的入口函數(shù)。可以看到 Xcode 已經(jīng)幫助生成很多 demo code。我們已經(jīng)不需要做太多。

  5. 在主程序的窗口里增加一個 button,在點擊方法里實現(xiàn)如下代碼

    • NSXPCConnection *con = [[NSXPCConnection alloc] initWithServiceName:@"com.frank.xpchelper"];
      NSXPCInterface *remoteInterface = [NSXPCInterface interfaceWithProtocol:@protocol(FRTestXPC_HelperProtocol)];
      con.remoteObjectInterface = remoteInterface;
      [[con remoteObjectProxy]  upperCaseString:@"hello" withReply:^(NSString *reply) {
         NSLog(@"reply = %@",reply);
          }];
      [con resume];
      
  6. 啟動程序,點擊 button,觀察終端輸出為 HELLO

一些說明

  1. Tips :作為 demo 可以刪除掉 Project 里的各種 Test Target 和 Test 文件,保持工程清爽直觀。
  2. 我用的是 Xcode9.1版本,創(chuàng)建好的 XPC 中的代碼完全為 Xcode 自動生成的,(void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply;這個協(xié)議也是 Xcode 生成的,所以看上面代碼不要太突兀,你自己試試就知道了。
  3. 初始化主程序 NSXPCConnection 的時候必須寫正確 XPC 的 service name.

一些 QA

Q: 什么場景下會用到 XPC? 具體到項目中說一下。

A: 我覺得用到 XPC 的地方主要還是希望讓別的進程分擔(dān)自己的任務(wù),同時又能夠及時的和主進程進行通信。(比如一些網(wǎng)絡(luò)處理的服務(wù))

  • #Offcial Note# Apple WWDC 的講解也是這么說的 So if you just have some background piece of work that needs to happen every so often, you can use XPC to talk to it, initiate it, and get it running.

? 其次是考慮一些其他因素,比如

  • 增加程序穩(wěn)定性(XPC Service crash 但主程序不 crash).
  • XPC 服務(wù)處理一些不夠安全的東西,這時候我們不提供 XPC 任何權(quán)限,比如網(wǎng)絡(luò)訪問,文件訪問等,但是主程序還是保留所有的權(quán)限。
    • #Fan's Note# 相當(dāng)于讓小弟干活兒,但是不給小弟太多權(quán)利,干的了就干,干不了就別干…..
  • 很重要一點:是這是 App Store 允許的多進程的方式。

Q: XPC 服務(wù)有界面嗎?

A: 一般都是后臺進程。沒見過有人用 XPC 搭建界面的。

Q: 系統(tǒng)是怎么通過以下這些 API 方法找到 XPC 服務(wù)的 ?

  • NSXPCInterface *myCookieInterface = [NSXPCInterfaceinterfaceWithProtocol:@protocol(XPC_HelperProtocol)];
    NSXPCConnection *myConnection = [[NSXPCConnection alloc]  initWithServiceName:@"com.frank.xpchelper"];
    

A: 當(dāng) app 啟動的時候,系統(tǒng)自動注冊 app 中可見的 XPC 服務(wù),當(dāng) app 與某個 XPC 服務(wù)建立連接,然后向他發(fā)送包含事件服務(wù)的消息。

? When the app is launched, the system automatically registers each XPC service it finds into the namespace visible to the app. An app establishes a connection with one of its XPC services and sends it messages containing events that the service then handles

一個 Demo

以上的 demo 是最簡單的,一般 XPC 用來做后臺下載處理比較合適,所以寫了一個比上面代碼復(fù)雜一點點(不過還是很簡單)的 demo 放到 github 上,這個 demo 是 XPC 雙向同步的。即 XPC Service 可以不依賴于代理方法的回調(diào)而是直接給 Client app 發(fā)送消息。

NSXPCConnection 是最主要的 API,其余的 API 比如 NSXPCInterface,都是依附于 Connection。構(gòu)建雙向通信的 XPC Demo 在 ClientApp 和 XPC 里有一些代碼非常相似。即互相暴露接口,互相暴露交接的對象。Demo 也提供了一些非常實用的構(gòu)建 XPC 時用的 API。

Demo 地址: https://github.com/fanxiushan/Demo.XPCTestDemo

參考:

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

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,532評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • 1:InputChannel提供函數(shù)創(chuàng)建底層的Pipe對象 2: 1)客戶端需要新建窗口 2)new ViewRo...
    自由人是工程師閱讀 5,403評論 0 18
  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,552評論 5 6
  • 他丟出一枚硬幣, 他的信仰沒有光環(huán), 他在雨夜里彷徨 不敢承認。 人群聚了又散, 剩他一人昏昏沉沉, 借的誰的故事...
    汀白白閱讀 290評論 0 3