I don’t know a lot about Core Bluetooth [1], so I can’t help you with that side of this, but I’m happy to tackle this in a more abstract sense.
I tried around a lot already, but I cannot manage to "collect" devices
within a specified time and return those through the scan-function.
When scanning for services it’s best not to impose a timeout. The problem is that, whatever timeout you choose, you end up with suboptimal behaviour:
-
If the timeout is too long, you needlessly delay the display of services you’ve already found.
-
If the timeout is too short, you might just miss a service.
A better approach is to consider this operation as an ongoing source of add and remove events. That way you can continually monitor that source while the user is interested in your service list.
And once you think about things in those terms, it suggests a better way to handle this in Swift, namely as an AsyncSequence. See here.
I’ve had great success implementing this using AsyncStream. See here.
The main gotcha with the latter is flow control (aka back pressure). AsyncStream doesn’t have comprehensive flow control support, so you have to be careful when dealing with potentially infinite streams. For example, if services were coming and going at a furious rate, the buffer inside the AsyncStream could grow very large.
In practice, this isn’t really an issue for your situation, where you’re going to be able to consume these events faster than Core Bluetooth can generate them. That’s not true in other situations, for example, if you were using AsyncStream to model a TCP connection is an async sequence of bytes.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
[1] For the specifics, I recommend Apple Developer Forums, tagging your question with Core Bluetooth.