Big edit: I think the question can be simplified to--how can I run corebluetooth and initialize CBCentralManager in background thread? Thank you!
I am making an an objective c++ application with CoreBluetooth that runs through the commandline, so the object C portion needs the runloop to be explicitly called [see this]. CoreBluetooth requires there to be an active runloop so callbacks are performed. The code below makes a call to the runloop in the beginning of the program to make everything work:
implementation.mm
// inside init method
// initialize bluetooth manager, must initialize before the runloop
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
// start run loop
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
while(([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]))
{}
and I can make async calls from my c++ main method:
main.cpp
int main() {
std::thread worker(do_cpp_things); // c++ things in background thread
run_objective_c_code(); // call objective c code using main thread
}
However with this approach, my c++ portion must be run in the background thread. and the objective C application is in the main thread which is opposite to what I want. So I tried to make a new thread in the objective C file then call the current run loop of the thread:
implementation.mm
// start a new thread
-(void)startThread {
NSThread *A = [[NSThread alloc] initWithTarget:self selector:@selector(runTheLoop) object:nil]; //create thread A
[A start];
}
// call runloop while in new thread
-(void) runTheLoop {
// Commenting out initialization for the sake of simplicity before it terminates when trying to initialize the manager in this example
// self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
// TERMINATES HERE
while(([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]))
{}
}
But this just terminates early. Not sure if there is something fundamentally wrong with my approach. Again--I want to run my objective-C code in the background thread with an active runloop and my c++ code in the main thread.
Thanks!
Actually wait, this solution doesn't properly make a runloop in background thread:
One of my problems is getting a runloop to run in a background thread. main.cpp
int main() {
std::thread worker(run_cpp_in_thread);
}
implementation.mm // somewhere in init method
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop run];
Now the problem is that CoreBluetooth is exiting immediately after powered on the central manager. Seems like something to do with the framework and threading.
I believe you are asking c++ to run in thread which is working in background. Instead, just push C function to run in background
You still need to handle join properly otherwise can make your application unresponsive/crash