React-native native module possibilities for background task on IOS - ios

My Problem: I have an app that communicates with a medical BLE device. I have it all working but my problem is that when an ios user puts the app in the background I stop getting/processing the messages sent via bluetooth. Android seems to keep getting these messages but from what I've found, on iOS, the JS bridge is torn down and there isn't a solution out there for this problem. The phone must continue to process the data sent from the BLE device.
My thought is this and this is my question for you all.
Would it be possible to create a native module for ios that will always be running and be doing the following: getting ble data as it is notified. Store that data to the file system and push it to a webservice all while the app is in the background? It would also be great to have the ability to read the fs created files and show some data about them when the app comes back to the foreground. Would this be possible?
Do you know of another option that could work?
Any help is greatly appreciated.

OK as I was heading down the native path and reading on the ios bluetooth schtuff I found this article Core Bluetooth Programming Guide and specifically it mentions a plist setting.
The Core Bluetooth background execution modes are declared by adding the UIBackgroundModes key to your Info.plist file and setting the key’s value to an array containing one of the following strings:
bluetooth-central —The app communicates with Bluetooth low energy peripherals using the Core Bluetooth framework.
bluetooth-peripheral —The app shares data using the Core Bluetooth framework.
So I thought to myself, would just by adding these keys to my xcode project that iOS would be smart enough and not care that I am a RN app and not native... well that was the ticket! I plugged these values in and the ble data is processed even when I open another app. "Wallah!" ;)

You have to enable iOS background mode capability in your Xcode project settings.
Also take a look at react-native-ble-plx which provides background support for both iOS and Android.

Related

Connect to a backgrounded iOS app acting as a peripheral from a macOS app

I have an iOS and macOS app that make heavy use of Core Bluetooth. The core functionality of the app involves having a central device (CBCentralManager) connect to a peripheral device (CBPeripheralManager), retrieve some data, then disconnect. Either device, whether macOS or iOS can act as either a central or peripheral depending on who needs the data.
At first I thought there was an issue with my code, but after testing the app with two iOS devices, one is able to connect and extract data from the peripheral device even when the peripheral device is locked and the app is in the background. Now according to the docs concerning background advertising on iOS under "The bluetooth-peripheral Background Execution Mode" this is kind of expected:
...they can be discovered only by an iOS device that is explicitly scanning for them.
Is there any way to have a macOS app discover peripherals even when they're backgrounded? I'm sure the code I've written is correct because it's the same across iOS and macOS.
Update 1
I believe that this might be possible just unsure how to approach the issue. Using Apple's Bluetooth Explorer on macOS, I am able to find the desired device AND I'm able to see and read data for my custom service.
This finding is validated from logs from my iOS device about the read requests which are from my peripheralManager(CBPeripheralManager, didReceiveRead: CBATTRequest).

How to share data between apps while in background?

I'm afraid I already know the answer of my own question, but I decided to ask anyway before losing my hopes.
I have the following use case: an app writes some bytes in a "shared" resource (let's say on a file) and another app reads the data and sends them to an external device via BLE while in background. Unfortunately, I know that concepts like shared resource and background are bounded in iOS. What I tried so far is:
Using App Group to share data between two apps
This is working fine even in background, but both the apps need to be produced by the same developer team (i.e. Team ID must be the same). This is a problem because one app is not produced by my developer team.
Copying data in the pasteboard
This is not working when app is in background. Data will always be nil and will update only when the app becomes active again.
...and of course there are...
Background limitations
Even though I go for the App Group solution, the only way I can manage to read data and send to the BLE device in background is by starting a background task. This obviously is a caveat: the task has an expiration time (from tests I performed it keeps going for about 3 minutes before being suspended by the OS). I don't need to run a long-time task, but I cannot assure it can be performed completely by 3 minutes or so.
Here's the question: Is there some other solution for this use case or should I finally give up?
If you are using CoreBluetooth to send files to your Bluetooth device, you can try adding bluetooth-central as UIBackgroundMode key in Info.plist of your app.
Apple has mentioned this in its programming guide:
Communicating with a Bluetooth Accessory Apps that work with Bluetooth
peripherals can ask to be woken up if the peripheral delivers an
update when the app is suspended. This support is important for
Bluetooth-LE accessories that deliver data at regular intervals, such
as a Bluetooth heart rate belt. You enable support for using bluetooth
accessories from the Background modes section of the Capabilities tab
in your Xcode project. (You can also enable this support by including
the UIBackgroundModes key with the bluetooth-central value in your
app’s Info.plist file.) When you enable this mode, the Core Bluetooth
framework keeps open any active sessions for the corresponding
peripheral. In addition, new data arriving from the peripheral causes
the system to wake up the app so that it can process the data. The
system also wakes up the app to process accessory connection and
disconnection notifications.
In iOS 6, an app can also operate in peripheral mode with Bluetooth
accessories. To act as a Bluetooth accessory, you must enable support
for that mode from the Background modes section of the Capabilities
tab in your Xcode project. (You can also enable this support by
including the UIBackgroundModes key with the bluetooth-peripheral
value in your app’s Info.plist file.) Enabling this mode lets the Core
Bluetooth framework wake the app up briefly in the background so that
it can handle accessory-related requests. Apps woken up for these
events should process them and return as quickly as possible so that
the app can be suspended again.

iOS Core Bluetooth app used like a Central doesn't work in background

I've an app that uses Core Bluetooth in foreground, everything is working fine. Now I'm trying to enable the background usage, I checked the correct options in Capabilities like the documentation says but the sync doesn't happen, only when I call the app to foreground again. Someone had this problem also? Should I implement more things like "State Preservation and Restoration"?
Just to be more clear, I'm using a specific UUID.

How to establish a communication channel between Apple Watch Extension/App and iOS App

I'm exploring the WatchKit SDK.
When I have a WatchKit app, is it possible to set values (e.g. Text, settings) from the iPhone app on the WatchKit app? Can I call functions in the WatchKit app extension from the iPhone app?
If someone managed to do this, could he/she post an example? Thanks!
You can use App Group and sharedDefaults to share data between the WatchApp/Extension and the App on the phone.
see example:
WatchKit SDK not retrieving data from NSUserDefaults
Study up on iOS8 Extension/App Groups/sharedDefaults and watchkit extension will make more sense.
This sample takes a UIImage from Shinobi chart, save it to defaults as image.
Then extension picks up the image through defaults and shows it on watch
https://github.com/ChrisGrant/ChartWatch
This one uses multipeer connectivity to have watch talk to phone.
https://github.com/jsclayton/swatches
but this uses Bluetooth and I presume the Watch OS also communicates to the phone using bluetooth so not sure if they'll both be allowed.
We have no devices to test on yet so the /swatches app is just watch simuator talking to iphone simulator on same mac.
If youve ever done low level AV programming you know the app may run on the simulator but fail on the device because the simulator can cheat an use Mac OSX media layer. May be the same for bluetooth.
other samples
https://github.com/search?q=WKInterfaceController&type=Code
There are several solutions: CoreData, NSKeyedUnarchiver and NSUserDefaults. With a common background for sharing the common data resource (Database, file or user default settings), this is enabling App Groups capabilities on both targets project properties.
In the following post is explained how to do it with default settings and you can also download the demo project.
With watchOS2 now Apple supports Watch Connectivity Framework to pass information from watch extension to app and vice versa.
Taken from Apple's docs
Communicating with Your Companion iOS App
The Watch Connectivity framework lets you create a bidirectional communications channel between your WatchKit extension and your companion iOS app. Use this channel to coordinate activities between the two processes. For example, you might use this framework to push updated information from your iOS app to your WatchKit extension. The framework provides options for transferring data in the background or while both apps are active and replaces the existing openParentApplication:reply: method of the WKInterfaceController class.
For more information the classes of the Watch Connectivity framework, see Watch Connectivity Framework Reference.
Taken from Apple's Developers Library
You can see this library
https://github.com/mutualmobile/MMWormhole
It do Message passing between iOS apps and extensions.
looks like the links with brain.clear are not pointing to the right destination for ShinobiChart example
https://github.com/ShinobiControls/ChartWatch

Send data to BLE supported Non iOS device from iPhone using CoreBluetooth

I would like to implement one iOS app . The app functionality is When I click on the UIButton in the iOS app , one LED should be ON in the Non iOS device (It is supporting the BLE) . So I know how to read the data from the Non iOS device using the CoreBluetooth framework. But dont know how to send data to Non iOS device . So My doubt is
Is there any thing we need to implement in the Non iOS device for Understanding the commands which are sent from iOS app ?.
For example I am sending One string #"Start".
Any ideas or suggestion could be more helpful .
Well for starters there is not magic way for you to send data to your non-iOS device, and for it to magically understand what it needs to do with it.
Check the BTLETransfer Example from the sample code in the developer portal it shows how to transmit data between two iOS devices. Furthermore, the peripheral role in the example is the one you have to mimic on your non-iOS device so it understands how to receive data your sending from a CoreBluetooth Central Manager.
In the example they use a rudimentary form of communication by setting a EOM flag (END OF MESSAGE) but it is effective and it works, it is not bulletproof though, but feel free to experiment with it. It will be useful if you have some knowledge on Network Transfer protocols and packet transmission techniques, error checking, acknowledgement, synchronisation, etc. So you can build or chose one that suits your needs.

Resources