- Under Project Settings -> Capabilitier check the Uses Bluetooth LE accessories option in the Background Modes settings
What is background capabilities and why do I need it?
Quick answer: If you are developing a foreground-only application, like a game, where Flic will only be used when the app is open, then you do not need to implement this part. If you, however, want your iOS application to contunue to use the Flic while the application is no longer in the foreground then you need to implement background capabilities. What this means is that the iOS device will maintain the connection with the Flic and wake up your app to the background whenever an event occurred. This works both when your application is suspended and when it is terminated.
In short this means for the fliclib framework that the app will be woken up to the background during the following scenarios:
The iOS platform has some very strict restrictions on what an application is allowed to do when it is not in the foreground. When the application is not in the foreground you are by default not allowed to do any kind of work in the background. Apple provides a few different background execution modes that an application can choose to use provided that the app lives up to the requirements specified for the different background modes. Take a look at Apple’s own documentation of App States and Multitasking if you want to learn more about this.
One such background mode affects Bluetooth Low Energy communication which is the protocol used by Flic. This background mode, called bluetooth-central, is the mode that the Fliclib framework needs to use if you are planning to communicate with a Flic while the app is not in the foreground. This will allow your application to be woken up by the system from the suspended state to the background whenever an event has happened on the Flic. At this time the app will be allowed to perform some tasks that are related to the bluetooth event for a short period of time before being suspended again. The following three guidelines below are specified by Apple and has to be followed when using this background execution mode:
Also take a look at the Being a Responsible Background App in Apple's iOS App Programming Guide.
The requirement that apps needs to be session based simply means that the end user of the App must be prompted with a quick and easy way of entirely turning off all bluetooth communication with that specific App. This is something that you as a developer are responsible to live up to; failing to do so may lead to your app being rejected by Apple. We have made it simple for you by providing two methods on the manager (enable: and disable:) that you can use for this purpose. You can at any time check the status by reading from the readonly property enabled on the manager.
If you are reading this then you are probably aware of the fact that iOS has the right to terminate your app at any time without notice; no matter if your app is in the foreground, background or suspended state. By default this means that all tasks that your application is doing will be stopped. This could for example be due to memory limitations on the system or any other reason.
Luckily fliclib will take care of this for you! This means that you will be able to continue communicating with the Flics even after your app gets terminated by the system. Whenever a bluetooth event happens when the app is terminated the app gets launched back into the background again, at which point you are able to go ahead and restore the manager. The manager will be restored back to the last previously known state and all the Flic objects that were associated to that particular manager will be recreated. After that you can simply collect all the Flic objects again and continue to use them normally, but remember that all the rules associated with background execution still applies here. Keep in mind that fliclib does not support the built in State Preservation and Restoration for viewControllers, instead you must use the preservation methods specified by fliclib.
Unfortunately there are a few cases where background execution from state preservation in the terminated state works differently from the regular background execution from suspended state. The app will not be brought back to the background during the following two scenarios:
These two cases are particularly important to understand when using the fliclib since they can cause a problem if the user expects it to work when it in fact does not. When it comes to rebooting the iOS device Apple does not provide a way to restart the Bluetooth Low Energy related tasks. This ultimately means that in order for your app to continue the communicating with a Flic after a system reboot it need to be launched into the background again through other means, for example by subscribing to significant-change location service, or alternatively by being launched to the foreground again by the user. As mentioned above, a bluetooth state change will also destruct any bluetooth communication. This means that if the user turns off the bluetooth module on the device while the app is terminated, then it will not start working properly again even if the bluetooth module is powered on again. The same thing applies here as with the reboot, meaning that the app has to be launched by other means. These restrictions are very unfortunate, but for now they are existing and we have to learn to live with them. The best thing that we can recommend (if these issues affect your app) is that you inform your users about this so that they are aware of it.
Please note that these issues are considered as being bugs in the iOS system, and will hopefully be fixed by Apple in the future.
By setting this flag to YES you will activate the fliclib background capabilities. From this point on you will continue to get Flic events even when your app is not in the foreground.
If you have your own classes that depend on the button instances then this would also be the safe place to collect the buttons using the knownButtons method. If you have manny buttons and need to distinguish between them then the buttonIdentifier can be used for this purpose.