iOS--CFMessagePort實現程序間通訊
阿新 • • 發佈:2018-11-01
CFMessagePort屬於CoreFoundation框架中的類。因此可以在http://opensource.apple.com/tarballs/CF/CF-855.17.tar.gz中在原始碼,如果感興趣可以去看看。
下面說下CFMessagePortRef的具體使用。
首先建立一個工程作為訊息的接受者。
#import "ViewController.h" #define LOCAL_MACH_PORT_NAME "com.message.demo" @interface ViewController () { CFMessagePortRef mMsgPortListenner; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. UIButton *startPortButton = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 120, 40)]; [startPortButton setTitle:@"Start " forState:UIControlStateNormal]; startPortButton.backgroundColor = [UIColor grayColor]; [startPortButton addTarget:self action:@selector(start) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:startPortButton]; UIButton *endPortButton = [[UIButton alloc] initWithFrame:CGRectMake(100, 300, 120, 40)]; [endPortButton setTitle:@"End " forState:UIControlStateNormal]; endPortButton.backgroundColor = [UIColor grayColor]; [endPortButton addTarget:self action:@selector(end) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:endPortButton]; } CFDataRef onRecvMsgCallBack(CFMessagePortRef local,SInt32 msgid,CFDataRef cfData,void *info) { NSLog(@"local = %@",local); NSLog(@"msgid = %d",msgid); NSString *strData = nil; if (cfData) { const UInt8 * recvedMsg = CFDataGetBytePtr(cfData); strData = [NSString stringWithCString:(char *)recvedMsg encoding:NSUTF8StringEncoding]; /** 實現資料解析操作 **/ NSLog(@"receive message:%@",strData); } //為了測試,生成返回資料 NSString *returnString = [NSString stringWithFormat:@"i have receive:%@",strData]; const char* cStr = [returnString UTF8String]; NSUInteger ulen = [returnString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; CFDataRef sgReturn = CFDataCreate(NULL, (UInt8 *)cStr, ulen); return sgReturn; } - (void)start { if (0 != mMsgPortListenner && CFMessagePortIsValid(mMsgPortListenner)) { CFMessagePortInvalidate(mMsgPortListenner); } mMsgPortListenner = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR(LOCAL_MACH_PORT_NAME), onRecvMsgCallBack, NULL, NULL); CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, mMsgPortListenner, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes); NSLog(@"start"); }
解釋下面接收接收方法引數的意思
CFMessagePortRef 指接受訊息物件的相關資訊
例如:
local = <CFMessagePort 0x7f8391c0a110 [0x10800c7b0]>{locked = Maybe, valid = Yes, remote = No, name = com.message.demo, source = 0x7f8391d08240, callout = onRecvMsgCallBack (0x107362440), context = <CFMessagePort context 0x0>}
SInt32 msgid 給單條訊息的標記
CFDataRef data 是訊息傳送的內容
void *info 可以攜帶其他資料物件進行傳遞,通常為空。
接下來再建立一個工程作為訊息的傳送者
#import "ViewController.h" @interface ViewController () { UITextField *textField; } @end #define MSG_PORT "com.message.demo" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 100, 100, 30)]; textField.backgroundColor = [UIColor grayColor]; [self.view addSubview:textField]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; [btn setTitle:@"Send" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(sendMethod) forControlEvents:UIControlEventTouchUpInside]; btn.frame = CGRectMake(50, 150, 100, 50); [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [self.view addSubview:btn]; } - (void)sendMethod { [self sendMessageToDameonWith:textField.text msgID:101]; } - (NSString *)sendMessageToDameonWith:(id)msgInfo msgID:(SInt32)msgid { CFMessagePortRef bRemote = CFMessagePortCreateRemote(kCFAllocatorDefault, CFSTR(MSG_PORT)); if (nil == bRemote) { NSLog(@"bRemote create failed"); return nil; } NSString *msg = [NSString stringWithFormat:@"%@",msgInfo]; NSLog(@"send msg is :%@",msg); const char *message = [msg UTF8String]; CFDataRef data,recvData = nil; data = CFDataCreate(NULL, (UInt8 *)message, strlen(message)); /* 傳送訊息 */ CFMessagePortSendRequest(bRemote, msgid, data, 0, 100, kCFRunLoopDefaultMode, &recvData); if (nil == recvData) { NSLog(@"recvData data is nil."); CFRelease(data); CFMessagePortInvalidate(bRemote); CFRelease(bRemote); return nil; } const UInt8 *recvedMsg = CFDataGetBytePtr(recvData); if (nil == recvedMsg) { NSLog(@"receive data err."); CFRelease(data); CFMessagePortInvalidate(bRemote); CFRelease(bRemote); return nil; } NSString *strMsg = [NSString stringWithCString:(char *)recvedMsg encoding:NSUTF8StringEncoding]; NSLog(@"%@",strMsg); CFRelease(data); CFMessagePortInvalidate(bRemote); CFRelease(bRemote); CFRelease(recvData); return nil; }