1. 程式人生 > >iOS--CFMessagePort實現程序間通訊

iOS--CFMessagePort實現程序間通訊

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;
}


程式碼下載地址:http://download.csdn.net/detail/qqmcy/9450336