2011-12-26 4 views
18

ऐप्पल के अनुसार, शेर में पेश की गई नई एक्सपीसी सेवा एपीआई, ग्रैंड सेंट्रल डिस्पैच (जीसीडी) के साथ एकीकृत बुनियादी इंटरप्रोसेस संचार के लिए हल्के तंत्र प्रदान करती है और लॉन्च की जाती है।प्रक्रियाओं के बीच संदेशों का आदान-प्रदान करने के लिए आईपीसी जैसे मैक ओएस एक्स एक्सपीसी का उपयोग करना संभव है? कैसे?

ऐसा लगता है कि इस एपीआई को एक प्रकार के आईपीसी के रूप में उपयोग करना संभव है, जैसे पॉज़िक्स आईपीसी, हालांकि, मुझे यह नहीं पता कि यह कैसे किया जाए।

मैं XPC API का उपयोग करके दो प्रक्रियाओं को संवाद करने की कोशिश कर रहा हूं, इसलिए मैं उनके बीच संदेश भेज सकता हूं लेकिन मुझे सर्वर पक्ष में हमेशा "XPC कनेक्शन अमान्य" त्रुटि मिलती है।

मुझे एक XPC सेवा नहीं चाहिए, मैं सिर्फ क्लाइंट-सर्वर आर्किटेक्चर का उपयोग करके संदेशों का आदान-प्रदान करना चाहता हूं।

मैं दो बीएसडी की तरह प्रक्रियाओं का उपयोग कर रहा है, तो कोई Info.plist या जो कुछ भी ...

मैं इस चर्चा http://lists.macosforge.org/pipermail/launchd-dev/2011-November/000982.html निम्नलिखित किया गया है लेकिन इस विषय थोड़ा अस्पष्ट और गैर-दस्तावेजी लगता है।

धन्यवाद!

+0

ऐसा लगता है कि किसी ने ऐसा करने के लिए हासिल किया है ... http: //stackoverflow.com/questions/8491361/exc-bad-instruction-when-sending-message-to-xpc-service – poorDeveloper

+0

हालांकि अभी भी यह नहीं पता कि इसे कैसे करें ... – poorDeveloper

+0

यदि आपके पास वास्तव में कोई है अभिभावक-बाल संबंध, तो XPC आपके लिए है, लेकिन यदि आपके पास दो स्वतंत्र प्रक्रियाएं हैं, तो XPC जाने का कोई तरीका नहीं है। मैक माइक्रोस्कोनल पर मैकोज़ बेस और इसलिए इसमें एक बहुत ही शक्तिशाली आईपीसी तंत्र है, जो कि किसी भी चीज़ से तेज़ तरीका है: मैक संदेश। यह सॉकेट पर डेटा भेजने की तरह थोड़ा काम करता है लेकिन आप इसे आपके लिए साझा मेमोरी के माध्यम से डेटा स्थानांतरित कर सकते हैं (जो लिखने पर प्रतिलिपि होगी)। यह थोड़ा खराब दस्तावेज है और अवधारणाएं पहले जटिल हैं, लेकिन यह सीखने लायक है।मैकोज़ में अन्य सभी आईपीसी वास्तव में मैक संदेशों के शीर्ष पर लागू किए गए हैं। – Mecki

उत्तर

16

हां, यह संभव है, लेकिन जिस तरह से आप उम्मीद करेंगे।

आप पर एक (गैर लॉन्च) प्रक्रिया एक सेवा बना सकते हैं। यह सुरक्षा कारणों से है, क्योंकि इससे मैन-इन-द-बीच हमले करना आसान हो जाएगा।

आप अभी भी जो भी चाहते हैं उसे प्राप्त कर सकते हैं, हालांकि: आपको एक लॉन्च सेवा स्थापित करना है जो XPC/mach सेवा को वेंड करता है। ए और बी दोनों प्रक्रियाएं तब आपके लॉन्च की गई सेवा से जुड़ती हैं। प्रक्रिया ए फिर एक तथाकथित अज्ञात कनेक्शन बना सकता है और इसे लॉन्च की गई सेवा में भेज सकता है जो बी को संसाधित करने के लिए अग्रेषित करेगा। एक बार ऐसा हुआ है, प्रक्रिया ए और बी सीधे उस कनेक्शन के माध्यम से एक दूसरे से बात कर सकती है (यानी लॉन्च सेवा कनेक्शन तोड़ने के बिना बाहर निकल सकते हैं)।

यह चारों ओर प्रतीत हो सकता है, लेकिन सुरक्षा कारणों से यह आवश्यक है।

अज्ञात कनेक्शन के बारे में विवरण के लिए xpc_object(3) मैन पेज देखें।

यह थोड़ा सा अंतर्ज्ञानी है, क्योंकि प्रक्रिया ए श्रोता ऑब्जेक्ट xpc_connection_create() के साथ बना देगा। ए एंडपॉइंट श्रोता से xpc_endpoint_create() के साथ ऑब्जेक्ट बनाता है और बी बी को संसाधित करने के लिए तार (XPC से अधिक) पर उस एंडपॉइंट को भेजता है, फिर उस ऑब्जेक्ट को xpc_connection_create_from_endpoint() के साथ कनेक्शन में बदल सकता है। श्रोता के लिए ए इवेंट हैंडलर को xpc_connection_create_from_endpoint() के साथ बनाए गए कनेक्शन से मेल खाने वाला एक कनेक्शन ऑब्जेक्ट प्राप्त होगा। यह इस तरह काम करता है कि xpc_connection_create_mach_service() के इवेंट हैंडलर क्लाइंट कनेक्ट करते समय कनेक्शन ऑब्जेक्ट प्राप्त करेंगे।

+0

क्या होगा यदि मैं प्रक्रिया बी से सेवा से कनेक्ट नहीं करना चाहता हूं? मान लीजिए, उदाहरण के लिए, बी बी एक बैश स्क्रिप्ट या पहले से संकलित सी प्रोग्राम है, क्या यह XPC के माध्यम से "क्लासिक" आईपीसी प्राप्त करना संभव है? या, वैकल्पिक रूप से, क्या मैं किसी भी तरह से XPC को बाईपास कर सकता हूं ('NSPipe' या उस तरह कुछ) का उपयोग कर? – Saphrosit

+0

आपको XPC का उपयोग करने की आवश्यकता नहीं है, लेकिन यदि आप XPC का उपयोग कर रहे हैं, तो आप XPC का उपयोग कर रहे हैं। आप एक XPC क्लाइंट लिख सकते हैं जिसे आप कमांड लाइन से निष्पादित कर सकते हैं, हालांकि, अगर आपको इसकी आवश्यकता है। यह कहना मुश्किल है कि सबसे अच्छा समाधान बिना किसी विवरण के क्या है। –

+0

शायद स्पष्ट रूप से पूछना अच्छा नहीं है, लेकिन अगर आप एक नजर डालना चाहते हैं तो यहां मेरा प्रश्न है: http://stackoverflow.com/questions/9742937/interprocess-communication-on-macosx-lion – Saphrosit

11

यहां बताया गया है कि मैं XPC का उपयोग करके द्वि-दिशात्मक आईपीसी कैसे कर रहा हूं।

हेल्पर (लॉगिन आइटम) सर्वर या श्रोता है। मुख्य ऐप या कोई अन्य ऐप ग्राहकों को माना जाता है।

हैडर:

मैं निम्नलिखित प्रबंधक बनाया

@class CommXPCManager; 

typedef NS_ENUM(NSUInteger, CommXPCErrorType) { 

    CommXPCErrorInvalid  = 1, 
    CommXPCErrorInterrupted = 2, 
    CommXPCErrorTermination = 3 
}; 

typedef void (^XPCErrorHandler)(CommXPCManager *mgrXPC, CommXPCErrorType errorType, NSError *error); 
typedef void (^XPCMessageHandler)(CommXPCManager *mgrXPC, xpc_object_t event, NSDictionary *message); 
typedef void (^XPCConnectionHandler)(CommXPCManager *peerConnection); 

@interface CommXPCManager : NSObject 

@property (readwrite, copy, nonatomic) XPCErrorHandler errorHandler; 
@property (readwrite, copy, nonatomic) XPCMessageHandler messageHandler; 
@property (readwrite, copy, nonatomic) XPCConnectionHandler connectionHandler; 

@property (readonly, nonatomic) BOOL clientConnection; 
@property (readonly, nonatomic) BOOL serverConnection; 
@property (readonly, nonatomic) BOOL peerConnection; 

@property (readonly, nonatomic) __attribute__((NSObject)) xpc_connection_t connection; 

@property (readonly, strong, nonatomic) NSString *connectionName; 
@property (readonly, strong, nonatomic) NSNumber *connectionEUID; 
@property (readonly, strong, nonatomic) NSNumber *connectionEGID; 
@property (readonly, strong, nonatomic) NSNumber *connectionProcessID; 
@property (readonly, strong, nonatomic) NSString *connectionAuditSessionID; 

- (id) initWithConnection:(xpc_connection_t)aConnection; 
- (id) initAsClientWithBundleID:(NSString *)bundleID; 
- (id) initAsServer; 

- (void) suspendConnection; 
- (void) resumeConnection; 
- (void) cancelConnection; 

- (void) sendMessage:(NSDictionary *)dict; 
- (void) sendMessage:(NSDictionary *)dict reply:(void (^)(NSDictionary *replyDict, NSError *error))reply; 
+ (void) sendReply:(NSDictionary *)dict forEvent:(xpc_object_t)event; 

@end 

कार्यान्वयन:

@interface CommXPCManager() 
@property (readwrite, nonatomic) BOOL clientConnection; 
@property (readwrite, nonatomic) BOOL serverConnection; 
@property (readwrite, nonatomic) BOOL peerConnection; 
@property (readwrite, strong, nonatomic) __attribute__((NSObject)) dispatch_queue_t dispatchQueue; 
@end 

@implementation CommXPCManager 

@synthesize clientConnection, serverConnection, peerConnection; 
@synthesize errorHandler, messageHandler, connectionHandler; 
@synthesize connection = _connection; 
@synthesize dispatchQueue = _dispatchQueue; 

#pragma mark - Message Methods: 

- (void) sendMessage:(NSDictionary *)dict { 

    dispatch_async(self.dispatchQueue, ^{ 

     xpc_object_t message = dict.xObject; 
     xpc_connection_send_message(_connection, message); 
     xpc_release(message); 
    }); 
} 

- (void) sendMessage:(NSDictionary *)dict reply:(void (^)(NSDictionary *replyDict, NSError *error))reply { 

    dispatch_async(self.dispatchQueue, ^{ 

     xpc_object_t message = dict.xObject; 
     xpc_connection_send_message_with_reply(_connection, message, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(xpc_object_t object) { 

      xpc_type_t type = xpc_get_type(object); 

      if (type == XPC_TYPE_ERROR) { 

       /*! @discussion Reply: XPC Error */ 
       reply([NSDictionary dictionary], [NSError errorFromXObject:object]); 

      } else if (type == XPC_TYPE_DICTIONARY) { 

       /*! @discussion Reply: XPC Dictionary */ 
       reply([NSDictionary dictionaryFromXObject:object], nil); 
      } 
     }); xpc_release(message); 
    }); 
} 

+ (void) sendReply:(NSDictionary *)dict forEvent:(xpc_object_t)event { 

    xpc_object_t message = [dict xObjectReply:event]; 
    xpc_connection_t replyConnection = xpc_dictionary_get_remote_connection(message); 
    xpc_connection_send_message(replyConnection, message); 
    xpc_release(message); 
} 

#pragma mark - Connection Methods: 

- (void) suspendConnection { 

    dispatch_async(self.dispatchQueue, ^{ xpc_connection_suspend(_connection); }); 
} 

- (void) resumeConnection { 

    dispatch_async(self.dispatchQueue, ^{ xpc_connection_resume(_connection); }); 
} 

- (void) cancelConnection { 

    dispatch_async(self.dispatchQueue, ^{ xpc_connection_cancel(_connection); }); 
} 

#pragma mark - Accessor Overrides: 

- (void) setDispatchQueue:(dispatch_queue_t)queue { 

    if (queue) dispatch_retain(queue); 
    if (_dispatchQueue) dispatch_release(_dispatchQueue); 
    _dispatchQueue = queue; 

    xpc_connection_set_target_queue(self.connection, self.dispatchQueue); 
} 

#pragma mark - Getter Overrides: 

- (NSString *) connectionName { 

    __block char* name = NULL; 
    dispatch_sync(self.dispatchQueue, ^{ name = (char*)xpc_connection_get_name(_connection); }); 

    if(!name) return nil; 
    return [NSString stringWithCString:name encoding:[NSString defaultCStringEncoding]]; 
} 

- (NSNumber *) connectionEUID { 

    __block uid_t uid = 0; 
    dispatch_sync(self.dispatchQueue, ^{ uid = xpc_connection_get_euid(_connection); }); 
    return [NSNumber numberWithUnsignedInt:uid]; 
} 

- (NSNumber *) connectionEGID { 

    __block gid_t egid = 0; 
    dispatch_sync(self.dispatchQueue, ^{ egid = xpc_connection_get_egid(_connection); }); 
    return [NSNumber numberWithUnsignedInt:egid]; 
} 

- (NSNumber *) connectionProcessID { 

    __block pid_t pid = 0; 
    dispatch_sync(self.dispatchQueue, ^{ pid = xpc_connection_get_pid(_connection); }); 
    return [NSNumber numberWithUnsignedInt:pid]; 
} 

- (NSNumber *) connectionAuditSessionID{ 

    __block au_asid_t auasid = 0; 
    dispatch_sync(self.dispatchQueue, ^{ auasid = xpc_connection_get_asid(_connection); }); 
    return [NSNumber numberWithUnsignedInt:auasid]; 
} 

#pragma mark - Setup Methods: 

- (void) setupConnectionHandler:(xpc_connection_t)conn { 

    __block CommXPCManager *this = self; 

    xpc_connection_set_event_handler(conn, ^(xpc_object_t object) { 

     xpc_type_t type = xpc_get_type(object); 

     if (type == XPC_TYPE_ERROR) { 

      /*! @discussion Client | Peer: XPC Error */ 

      NSError *xpcError = [NSError errorFromXObject:object]; 

      if (object == XPC_ERROR_CONNECTION_INVALID) { 

       if (this.errorHandler) 
        this.errorHandler(this, CommXPCErrorInvalid, xpcError); 

      } else if (object == XPC_ERROR_CONNECTION_INTERRUPTED) { 

       if (this.errorHandler) 
        this.errorHandler(this, CommXPCErrorInterrupted, xpcError); 

      } else if (object == XPC_ERROR_TERMINATION_IMMINENT) { 

       if (this.errorHandler) 
        this.errorHandler(this, CommXPCErrorTermination, xpcError); 
      } 

      xpcError = nil; return; 

     } else if (type == XPC_TYPE_CONNECTION) { 

      /*! @discussion XPC Server: XPC Connection */ 

      CommXPCManager *xpcPeer = [[CommXPCManager alloc] initWithConnection:object]; 

      if (this.connectionHandler) 
       this.connectionHandler(xpcPeer); 

      xpcPeer = nil; return; 

     } else if (type == XPC_TYPE_DICTIONARY) { 

      /*! @discussion Client | Peer: XPC Dictionary */ 

      if (this.messageHandler) 
       this.messageHandler(this, object, [NSDictionary dictionaryFromXObject:object]); 
     } 

    }); 
} 

- (void) setupDispatchQueue { 

    dispatch_queue_t queue = dispatch_queue_create(xpc_connection_get_name(_connection), 0); 
    self.dispatchQueue = queue; 
    dispatch_release(queue); 
} 

- (void) setupConnection:(xpc_connection_t)aConnection { 

    _connection = xpc_retain(aConnection); 

    [self setupConnectionHandler:aConnection]; 
    [self setupDispatchQueue]; 
    [self resumeConnection]; 
} 

#pragma mark - Initialization: 

- (id) initWithConnection:(xpc_connection_t)aConnection { 

    if (!aConnection) return nil; 

    if ((self = [super init])) { 

     self.peerConnection = YES; 
     [self setupConnection:aConnection]; 

    } return self; 
} 

- (id) initAsClientWithBundleID:(NSString *)bundleID { 

    xpc_connection_t xpcConnection = xpc_connection_create_mach_service([bundleID UTF8String], nil, 0); 

    if ((self = [super init])) { 

     self.clientConnection = YES; 
     [self setupConnection:xpcConnection]; 
    } 

    xpc_release(xpcConnection); 
    return self; 
} 

- (id) initAsServer { 

    xpc_connection_t xpcConnection = xpc_connection_create_mach_service([[[NSBundle mainBundle] bundleIdentifier] UTF8String], 
                     dispatch_get_main_queue(), 
                     XPC_CONNECTION_MACH_SERVICE_LISTENER); 
    if ((self = [super init])) { 

     self.serverConnection = YES; 
     [self setupConnection:xpcConnection]; 
    } 

    xpc_release(xpcConnection); 
    return self; 
} 

@end 

जाहिर है, मैं कुछ श्रेणी के तरीकों जो आत्म व्याख्यात्मक उपयोग कर रहा हूँ। उदाहरण के लिए:

@implementation NSError (CategoryXPCMessage) 
+ (NSError *) errorFromXObject:(xpc_object_t)xObject { 

    char *description = xpc_copy_description(xObject); 
    NSError *xpcError = [NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{ 
         NSLocalizedDescriptionKey: 
         [NSString stringWithCString:description encoding:[NSString defaultCStringEncoding]] }]; 
    free(description); 
    return xpcError; 
} 
@end 

ठीक है, यह मैं अपने आप को दोनों क्लाइंट-साइड और सर्वर-साइड के लिए एक इंटरफेस की स्थापना का उपयोग कर। हेडर कुछ इस तरह दिखता है:

- (void) startListenerConnection { 

    [self stopConnection]; 
    self.managerXPC = [[CommXPCManager alloc] initAsServer]; 

    __block AppXPCInterface *this = self; 

    self.managerXPC.connectionHandler = ^(CommXPCManager *peerConnection) { 

     [(NSMutableArray *)this.peerConnections addObject:peerConnection]; 

     peerConnection.messageHandler = ^(CommXPCManager *mgrXPC, xpc_object_t event, NSDictionary *message) { 

      [this processMessage:message forEvent:event]; 
     }; 

     peerConnection.errorHandler = ^(CommXPCManager *peer, CommXPCErrorType errorType, NSError *error) { 

      [this processError:error forErrorType:errorType]; 
      [(NSMutableArray *)this.peerConnections removeObject:peer]; 
     }; 
    }; 

    [CommReceptionist postGlobalNote:kAppXPCListenerNoteHello]; 
} 

यहाँ कार्यान्वयन ग्राहक शुरू करने के लिए है:

@class CommXPCManager; 

@protocol AppXPCErrorHandler <NSObject> 
@required 
- (void) handleXPCError:(NSError *)error forType:(CommXPCErrorType)errorType; 
@end 

static NSString* const kAppXPCKeyReturn = @"AppXPCInterfaceReturn"; // id returnObject 
static NSString* const kAppXPCKeyReply = @"AppXPCInterfaceReply";  // NSNumber: BOOL 
static NSString* const kAppXPCKeySEL = @"AppXPCInterfaceSelector"; // NSString 
static NSString* const kAppXPCKeyArgs = @"AppXPCInterfaceArguments"; // NSArray (Must be xObject compliant) 

@interface AppXPCInterface : NSObject 

@property (readonly, strong, nonatomic) CommXPCManager *managerXPC; 
@property (readonly, strong, nonatomic) NSArray *peerConnections; 

- (void) sendMessage:(SEL)aSelector withArgs:(NSArray *)args reply:(void (^)(NSDictionary *replyDict, NSError *error))reply; 
- (void) sendMessageToPeers:(SEL)aSelector withArgs:(NSArray *)args reply:(void (^)(NSDictionary *replyDict, NSError *error))reply; 

- (id) initWithBundleID:(NSString *)bundleID andDelegate:(id<AppXPCErrorHandler>)object forProtocol:(Protocol *)proto; 
- (id) initListenerWithDelegate:(id<AppXPCErrorHandler>)object forProtocol:(Protocol *)proto; 

- (void) observeListenerHello:(CommReceptionistNoteBlock)helloBlock; 
- (void) removeListenerObserver; 

- (void) startClientConnection; 
- (void) startListenerConnection; 
- (void) stopConnection; 

@end 

यहाँ कार्यान्वयन श्रोता शुरू करने के लिए है अब यहाँ

- (void) startClientConnection { 

    [self stopConnection]; 
    self.managerXPC = [[CommXPCManager alloc] initAsClientWithBundleID:self.identifierXPC]; 

    __block AppXPCInterface *this = self; 

    self.managerXPC.messageHandler = ^(CommXPCManager *mgrXPC, xpc_object_t event, NSDictionary *message) { 

     [this processMessage:message forEvent:event]; 
    }; 

    self.managerXPC.errorHandler = ^(CommXPCManager *mgrXPC, CommXPCErrorType errorType, NSError *error) { 

     [this processError:error forErrorType:errorType]; 
    }; 
} 

आदेश है की चीज़ों का।

  1. आपका मुख्य अनुप्रयोग सहायक अपने bundleID < का उपयोग कर सुन शुरू होता है इसकी सहायक शुरू होता है --- महत्वपूर्ण!
  2. मुख्य अनुप्रयोग एक वैश्विक अधिसूचना के लिए सुनता है और फिर संदेश
  3. ग्राहक संदेश कनेक्शन

स्थापित है अब सर्वर क्लाइंट के लिए संदेश भेज सकते हैं भेजता है और ग्राहक संदेश भेज सकते हैं जब भेजता है सर्वर पर (उत्तर के साथ या बिना)।

यह बहुत तेज़ है, यह अच्छी तरह से काम करता है, और ओएस एक्स 10.7.3 या इससे अधिक के लिए डिज़ाइन किया गया है।

कुछ नोट:

  • सहायक के नाम बंडल आईडी के रूप में एक ही नाम होना चाहिए
  • नाम अपनी टीम आईडी
  • सैंडबॉक्सिंग के लिए, दोनों मुख्य अनुप्रयोग के साथ शुरू होगा और सहायक ऐप एप्लिकेशन समूह सेटिंग सहायक बंडल आईडी

जैसे उपसर्ग के साथ शुरू होना चाहिए हेल्पर बंडल आईडी है: ABC123XYZ.CompanyName.GroupName.Helper अनुप्रयोग समूह आईडी होगा: ABC123XYZ.CompanyName.GroupName

इतनी के रूप में किसी को भी नहीं बोर करने के लिए

अतिरिक्त विवरण मैं बाहर छोड़ दिया वहाँ रहे हैं। लेकिन अगर यह अभी भी अस्पष्ट है तो पूछो और मैं जवाब दूंगा।

ठीक है, उम्मीद है कि इससे मदद मिलती है। अर्विन

+0

हाय आर्विन, मुझे बंडल आईडी और प्रावधान प्रोफाइल के साथ कई परेशानीएं हैं, क्या आप दो अलग-अलग ऐप आईडी और प्रावधान प्रोफाइल का उपयोग मुख्य के लिए करते हैं और एक सहायक सहायक के लिए करते हैं? – IturPablo

+2

@ अरविन क्या आप पूर्ण कार्यान्वयन प्रदान कर सकते हैं, क्योंकि यह संदर्भ वेब पर सबसे अधिक आशाजनक स्रोत जैसा दिखता है। परियोजना के लिए कोई भी जिथब लिंक बहुत उपयोगी होगा। मुझे ओएसएक्स 10.8 के साथ पता है हमारे पास एनएसएक्सपीसीसी कनेक्शन है जिसके लिए मुझे सेब से अच्छा संदर्भ मिल सकता है, लेकिन मेरी परियोजना आवश्यकता 10.7.5 और बाद में समर्थन करना है। धन्यवाद। –

5

किसी को भी है कि यह साथ संघर्ष कर रहा के लिए ठीक है, मैं अंत में 100% प्राप्त संचार दो आवेदन प्रक्रियाओं के बीच काम करने के लिए सक्षम था, NSXPCConnection

नोट करने के लिए कुंजी का उपयोग करें कि आप केवल करने के लिए एक NSXPCConnection बना सकते हैं तीन चीज़ें।

  1. एक XPCService। आप नाम
  2. एक मैक सेवा के माध्यम से एक XPCService से सख्ती से कनेक्ट कर सकते हैं। आप एक मैक सेवा से सख्ती से
  3. NSXPCEndpoint नाम से सख्ती से कनेक्ट कर सकते हैं। यह है कि हम की तलाश कर रहे हैं, दो आवेदन प्रक्रियाओं के बीच संवाद करने के लिए।

समस्या यह है कि हम सीधे एक आवेदन से NSXPCListenerEndpoint स्थानांतरित नहीं कर सकते हैं।

इसमें एक मशीन सेवा लॉन्च एजेंट (See this example for how to do that) बनाने में शामिल था जिसमें NSXPCListenerEndpoint संपत्ति थी। एक एप्लिकेशन machservice से कनेक्ट हो सकता है, और उस प्रॉपर्टी को अपने [NSXPCListener anonymousListener].endpoint

पर सेट करें, तो दूसरा एप्लिकेशन machservice से कनेक्ट हो सकता है, और उस एंडपॉइंट के लिए पूछ सकता है।

फिर उस एंडपॉइंट का उपयोग करके, NSXPCConnection बनाया जा सकता है, जिसने सफलतापूर्वक दो अनुप्रयोगों के बीच एक पुल स्थापित किया। मैंने वस्तुओं को आगे और आगे भेजने का परीक्षण किया है, और यह सभी अपेक्षित काम करता है।

ध्यान दें कि यदि आपके आवेदन सैंडबॉक्स है, तो आप एक XPCService बनाने के लिए, होगा अपने आवेदन और Machservice

के बीच एक मध्य आदमी के रूप में मैं बहुत पंप कर रहा हूँ कि मुझे मिल गया यह मैं working-- ' मीटर काफी अतः में सक्रिय है, इसलिए यदि किसी को भी स्रोत कोड में रुचि रखता है, बस कोई टिप्पणी दें और मैं प्रयास अधिक जानकारी के

कुछ बाधाओं पोस्ट करने के लिए के माध्यम से जा सकते हैं मैं भर में आया था:

आप launc करने के लिए है ज अपने machservice, इन पंक्तियों हैं:

OSStatus     err; 
    AuthorizationExternalForm extForm; 

    err = AuthorizationCreate(NULL, NULL, 0, &self->_authRef); 
    if (err == errAuthorizationSuccess) { 
     NSLog(@"SUCCESS AUTHORIZING DAEMON"); 
    } 
    assert(err == errAuthorizationSuccess); 

    Boolean    success; 
    CFErrorRef   error; 

    success = SMJobBless(
         kSMDomainSystemLaunchd, 
         CFSTR("DAEMON IDENTIFIER HERE"), 
         self->_authRef, 
         &error 
         ); 

इसके अलावा, हर बार जब आप अपने डेमॉन के पुनर्निर्माण, आप पिछले प्रक्षेपण के एजेंट अनलोड करने के लिए, है इन बैश के साथ आदेश:

sudo launchctl unload /Library/LaunchDaemons/com.example.apple-samplecode.EBAS.HelperTool.plist 
sudo rm /Library/LaunchDaemons/com.example.apple-samplecode.EBAS.HelperTool.plist 
sudo rm /Library/PrivilegedHelperTools/com.example.apple-samplecode.EBAS.HelperTool 

(अपने इसी के साथ पहचानकर्ता, बेशक)

+1

हाय ए ओ, क्या आपने गिट रिपोजिटरी बनाई है या आप अपने कार्यान्वयन के साथ नमूना कोड साझा कर सकते हैं? धन्यवाद। – vtruant

+1

यहां आप जा रहे हैं: https://github.com/MattyAyOh/XPCLab –

+1

बस इसका परीक्षण किया गया है, इसे आपके लिए बॉक्स के निर्माण और चलाने के लिए –

संबंधित मुद्दे