MacOS XPC的使用入門

MacOS:10.14,Xcode:11.0


1、隨意創建一個工程,可以是App project
Xcode -> File -> New -> Project... -> macOS -> Application -> App -> click Next
填寫Product Name(XPCDemo) -> 選擇或者不選擇Team賬號 -> click Next -> click create, 創建一個工程


2、創建xpc service

選中project -> 顯示targets欄 -> 點擊"+"號



選擇macOS -> 篩選框中輸入xpc -> 選擇XPC Service -> click Next


填寫Product Name -> 設置 Bundle Identifer -> click Finish完成創建
 
 


3、檢查和設置
創建完成後,檢查下TARGETS -> XPCDemo -> Build Phases中,有增加一項 Embed XPC Services
這個功能現在在我的Xcode 11.0是自動添加的,但很早以前的版本好像還要自己添加才行


檢查或設置xpc的bundle identifer,在調用xpc時使用

 


4、文件說明:
XPC 創建後,在工程中會生成4個文件,


XPCServiceProtocol.h聲明一些函數,

// XPCServiceProtocol.h文件
#import <Foundation/Foundation.h>

@protocol XPCServiceProtocol
- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply;    
@end

XPCService.h聲明繼承了協議,

// XPCService.h文件
#import <Foundation/Foundation.h>
#import "XPCServiceProtocol.h"
@interface XPCService : NSObject <XPCServiceProtocol>
@end

XPCService.m中實現這些協議方法

// XPCService.m文件
#import "XPCService.h"

@implementation XPCService
// XPCServiceProtocol.h中聲明的方法的實現
- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply {
    NSString *response = [aString uppercaseString];
    reply(response);
}

@end

這個函數是xcode自動生成的示例代碼,可直接用來測試。在main.m文件中也有很多代碼,都是自動生成的,暫且不管
調用XPC的時候,調用Protocol中聲明的方法,Protocol是內外使用方法的橋樑

 


5、XPC啓動和方法調用
在XPCServiceProtocol.h中也給出瞭如何使用xpc的一個示例代碼
示例中給出了建立連接、運行方法、清除連接的方法

/*
 To use the service from an application or other process, use NSXPCConnection to establish a connection to the service by doing something like this:

     _connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"com.company.XPCService"];
     _connectionToService.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCServiceProtocol)];
     [_connectionToService resume];

Once you have a connection to the service, you can use it like this:

     [[_connectionToService remoteObjectProxy] upperCaseString:@"hello" withReply:^(NSString *aString) {
         // We have received a response. Update our text field, but do it on the main thread.
         NSLog(@"Result string was: %@", aString);
     }];

 And, when you are finished with the service, clean up the connection like this:

     [_connectionToService invalidate];
*/

storyboard -> View Controller Scene -> 添加button -> ctrl+鼠標,將button在ViewController中建立個action連接
ViewController.h中引入頭文件:

// ViewController.h文件
#import <Cocoa/Cocoa.h>
#import "XPCServiceProtocol.h"
#import "XPCService.h"
@interface ViewController : NSViewController

@end

ViewController.m文件內容:

// ViewController.m文件
#import "ViewController.h"
@interface ViewController(){
    NSXPCConnection *_connectionToService; //私有變量
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //建立xpc連接並啓動
    _connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"com.company.XPCService"];
    _connectionToService.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCServiceProtocol)];
    [_connectionToService resume];
}

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}
- (IBAction)XPCTest:(id)sender {
    // XPC中運行方法
    [[_connectionToService remoteObjectProxy] upperCaseString:@"hello" withReply:^(NSString *aString) {
        NSLog(@"Result string was: %@", aString);
    }];
}
@end

執行結果(XPC執行方法upperCaseString,輸出結果):

 
 


github XPCDemo:https://github.com/auspark/XPCDemo


Apple Documentation:

Apple XPC
Creating XPC Services
Efficient Design with XPC Videos
Kernel and Device Drivers Layer

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章