XPC...Can't call a reply block multiple times?

I'm trying to have an XPC service call a reply block multiple times. It has some work to do that can take some time. In this situation, it makes sense for me to pass back results to the caller in batches.


The block has two parameters a BOOL and a dictionary. The BOOL is YES if XPC is finished with all its work, and the dictionary contains all arrays (each array has NSStrings).

That's about it.


So the method looks something like this:


-(void)inspectArticle:(NSString*)articleString reply:(void (^)(BOOL finished,NSDictionary*dict))reply
{
   //partial work up here.

    if (objectCount >= MAX_BATCH_SIZE)
   {
          reply(NO,dictionary);

        //unload reported objects..and do more work...
    }

     //finished
     reply(YES,dictionary);
}


After the first call to the reply block, it just poops out. XPC continues, but firing the block does nothing (the calling app doesn't get the message).

Accepted Reply

I'm trying to have an XPC service call a reply block multiple times.

I’m not surprised you’re having problems with this; it’s not how XPC is intended to be used.

There are two standard ways for doing this sort of thing:

  • Have the first reply pass the relevant state (like the current result offset) back to the client and then have the client make another XPC request with that state.

  • Have the client send the server an endpoint, at which point the server can deliver results to that endpoint asynchronously.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Add a Comment

Replies

I'm trying to have an XPC service call a reply block multiple times.

I’m not surprised you’re having problems with this; it’s not how XPC is intended to be used.

There are two standard ways for doing this sort of thing:

  • Have the first reply pass the relevant state (like the current result offset) back to the client and then have the client make another XPC request with that state.

  • Have the client send the server an endpoint, at which point the server can deliver results to that endpoint asynchronously.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Add a Comment

I'm also going the XPC route and, in a similar case, tried to also use the connection in the reverse direction — setting up a proxy in the service.


This works fine but apparently it's tricky to have the service use the reverse connection to report progress, or request more data from the application, while responding to an application request; I'm running into deadlocks in that case. Is that a limitation of XPCConnection or am I just not understanding the service's runloop?

Yeah I kind of got that feeling...that my idea wasn't the way to go. I ended up reworking my code to get things going.


Thanks for responding. I wish I would have saw your post earlier but it seems that email notifications aren't working anymore on the forums.