• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ObjectiveCXPC初步学习二

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前面有对xpc进行一些学习了解,这篇主要是记录下xpc的创建以及使用过程。

一、创建xpc target

新建project-->targets,左下角点➕搜索xpc,点击next添加即可,设定xpc bundle 名称,后面需要bind 连接。

二、代码实现

添加完xpc之后,项目内会出现xpc service的source 包,这里用来实现你的xpc功能需求,我这边新增了一个client 应来处理sevice的响应,代码如下:

Sevice端:

main.m


#import <Foundation/Foundation.h>
#import "xpcService.h"
#import "xpcClient.h"

@interface ServiceDelegate : NSObject <NSXPCListenerDelegate>
@end

@implementation ServiceDelegate

- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
    // This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection.
    
    // Configure the connection.
    // First, set the interface that the exported object implements.
    //设置service端接收消息的配置
    newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(xpcServiceProtocol)];
    
    // Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object.
    xpcService *exportedObject = [xpcService new];
    newConnection.exportedObject = exportedObject;
    
    
    newConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(xpcClientProtocol)];
    exportedObject.xpcConnect = newConnection;
    // Resuming the connection allows the system to deliver more incoming messages.
    [newConnection resume];

    
    // Returning YES from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call -invalidate on the connection and return NO.
    return YES;
}


@end

int main(int argc, const char *argv[])
{
    // Create the delegate for the service.
    ServiceDelegate *delegate = [ServiceDelegate new];
    
    // Set up the one NSXPCListener for this service. It will handle all incoming connections.
    NSXPCListener *listener = [NSXPCListener serviceListener];
    listener.delegate = delegate;
    
    // Resuming the serviceListener starts this service. This method does not return.
    [listener resume];
    return 0;
}

xpcServiceProtocol.h


#import <Foundation/Foundation.h>

// The protocol that this service will vend as its API. This header file will also need to be visible to the process hosting the service.
@protocol xpcServiceProtocol

// Replace the API of this protocol with an API appropriate to the service you are vending.
- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply;
    
- (void)sendToClient:(NSString *)info withReply:(void (^)(NSString *))reply;

@end

xpcService.h

#import <Foundation/Foundation.h>
#import "xpcServiceProtocol.h"
#import "xpcClient.h"
// This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection.
@interface xpcService : NSObject <xpcServiceProtocol>
@property(nonatomic,strong) id<xpcClientProtocol> service;

@property NSXPCConnection *xpcConnect;

@end

xpcService.m

#import "xpcService.h"

@implementation xpcService

// This implements the example protocol. Replace the body of this class with the implementation of this service's protocol.
- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply {
    NSString *response = [aString uppercaseString];
    reply(response);
}

- (void)sendToClient:(NSString *)info withReply:(void (^)(NSString *))reply {
    reply(@"[Server]:");
    [[_xpcConnect remoteObjectProxy] getMsgFromService:@"this is ping test from server"];
}


@end

Client端:

xpcClientProtocol.h

-->协议的创建,点击项目里面,command+n或者右键新增,选择objectivec-c file,选择类型为protocol

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@protocol xpcClientProtocol <NSObject>

- (void)getMsgFromService:(NSString *)message;

@end

NS_ASSUME_NONNULL_END

xpcClient.h

#import <Foundation/Foundation.h>
#import "xpcClientProtocol.h"
#import "xpcServiceProtocol.h"


NS_ASSUME_NONNULL_BEGIN

@interface xpcClient : NSObject<xpcClientProtocol>
@property NSXPCConnection *connectionToService;
@property (nonatomic,strong) id<xpcServiceProtocol> service;



@end

NS_ASSUME_NONNULL_END

xpcClient.m


#import "xpcClient.h"

@implementation xpcClient

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self createConnect];
    }
    return self;
}

-(void)createConnect{
       _connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"xiaoqiang.xpcService"];
       _connectionToService.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(xpcServiceProtocol)];
       _connectionToService.exportedObject = self;
       _connectionToService.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(xpcClientProtocol)];
       _service = [self.connectionToService remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
             //这里面是错误处理的代码
         }];
    
    //可以通过remoteObjectProxy获得protocol
    [[_connectionToService remoteObjectProxy] upperCaseString:@"hello ,xiaoqiang" withReply:^(NSString* reply){
        NSLog(@"result from server: %@", reply);
    }];
    
    [_connectionToService resume];

}
- (void)getMsgFromService:(nonnull NSString *)message {
     NSLog(@"server Reply:%@",message);
}


@end

ViewController.m


#import "ViewController.h"
#import "xpcClient.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    xpcClient *xpc = [[xpcClient alloc]init];
    [xpc.service upperCaseString:@"hello,world" withReply:^(NSString * reply){
        NSLog(@"result :%@",reply);
    }];
    [xpc.service sendToClient:@"Receive:" withReply:^(NSString *reply){
        NSLog(@"----->%@",reply);

    }];
    // Do any additional setup after loading the view.
}


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

    // Update the view, if already loaded.
}

最后编译执行,你就会看到sevice 呼叫,client接收的信息。

2020-07-21 14:29:45.373534+0800 XpcTest[10121:122917] result from server: HELLO ,XIAOQIANG
2020-07-21 14:29:45.373713+0800 XpcTest[10121:122917] result :HELLO,WORLD
2020-07-21 14:29:45.373856+0800 XpcTest[10121:122917] ----->[Server]:
2020-07-21 14:29:45.373930+0800 XpcTest[10121:122917] server Reply:this is ping test from server

XPC 属性

前面如果看的不是很明白的话,在来解释下xpc的应用过程

前面用到了2种方法来调用远端方法

1.xpcServiceProtocol 属性

@property (nonatomic,strong) id<xpcServiceProtocol> service;
-->
xpcClient *xpc = [[xpcClient alloc]init];
[xpc.service upperCaseString:@"hello,world" withReply:^(NSString * reply){
    NSLog(@"result :%@",reply);
}];

2.NSXPCConnection 属性remoteObjectProxy调用远端方法

@property NSXPCConnection *connectionToService;
-->
[[_connectionToService remoteObjectProxy] upperCaseString:@"hello ,xiaoqiang" withReply:^(NSString* reply){
      NSLog(@"result from server: %@", reply);
  }];

根据这张图,来解析一下client和main.m所做的事情:

过程:

Service端:
1.首先,设置导出对象实现的接口,也就是service协议
-->newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(xpcServiceProtocol)];

2.接下来,设置连接导出的对象。在与此服务的连接上发送的所有消息都将发送到导出的对象进行处理(xpcService)。连接保留导出的对象。
 --> xpcService *exportedObject = [xpcService new];
    newConnection.exportedObject = exportedObject;
    newConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(xpcClientProtocol)];
    exportedObject.xpcConnect = newConnection;

3.恢复连接允许系统传递更多的传入消息。
 -->[newConnection resume];

Client端:
@property NSXPCConnection *connectionToService;
1.设定当前xpc服务名称,并设定远端service接口,也就是sevice协议。
_connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"xiaoqiang.xpcService"];

_connectionToService.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(xpcServiceProtocol)];

2.将自己设置为导出对象,目的是为了在当前同一xpcConnection属性下供对方获得接口内容(这里的client有定义一个协议方法,暴露给remote sevice)。  
_connectionToService.exportedObject = self;
_connectionToService.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(xpcClientProtocol)];

3.这一步很重要,通过remoteObjectProxyWithErrorHandler返回一个代理对象,如果连接发生错误,它将调用错误处理块。如果发送给代理的消息具有reply处理程序,则错误处理程序或reply处理程序将仅被调用一次.
_service = [self.connectionToService remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
             //错误处理的代码
 }];

4.通过remoteObjectProxy获得protocol方法实现,最后resume整个xpc 连接.
[[_connectionToService remoteObjectProxy] upperCaseString:@"hello ,xiaoqiang" withReply:^(NSString* reply){
    NSLog(@"result from server: %@", reply);
}];
    
[_connectionToService resume];
    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Objective-CAVPlayer播放视频的使用与封装发布时间:2022-07-12
下一篇:
ObjectiveC语言中nil、Nil、NULL、NSNull的区别发布时间:2022-07-12
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap