0

I'm working on a device that keeps count when a door is closed. What I'd like to do is when I walk through the door, my iPhone automatically syncs the data on the device and sends that count to the server (via iPhone) without me opening the app or having it in the background. Is this possible, if so how?

Here's a diagram of what I'm thinking:

Door closes -> BLE notifies iPhone -> BLE sends count to iPhone -> iPhone sends that value to server

All without the user (me) touching my device or opening the installed iOS application.

John Riselvato
  • 12,854
  • 5
  • 62
  • 89

2 Answers2

5

Your app has to be running in the background to do something, but that is OK, because Core Bluetooth background mode will take care of that for you.

First, you need to select "Uses Bluetooth accessories" background mode in your project.

Now, your program flow will be something like this:

  1. Your user runs your app which scans for available doors and displays them to the user
  2. Your user selects a door that they want to connect to
  3. You save the identifier of the selected peripheral somewhere like NSUserDefaults
  4. You connect to the peripheral
  5. Once you get a call to the didConnectPeripheral delegate method you can read the count and update your server once you get the value
  6. The user can now suspend your app and do something else
  7. Eventually the peripheral will go out of range and you will get a call to didDisconnectPeripheral. In this method you immediately re-issue the connect to the peripheral.
  8. Since you have Core Bluetooth background mode, when the peripheral is eventually seen again you will get another call to didConnectPeripheral in the background, and you can proceed as per step 5 (In this case your app is already in the background so it will just go back to suspended state after you have read the data without the user doing anything).

You update the server in step 5. This step executes regardless of whether the app is in the foreground or background. The user doesn't need to open your app.

Now eventually iOS may remove your app from the suspended state, say due to memory pressure. In order to still be able to connect to the peripheral when it is seen you need to opt in to state restoration as described in the Core Bluetooth Programming Guide

Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • this answers half my question which is good but I'm still unsure if I can get a packet of data from the BLE device and send it to my server without the user having the app open. Is that possible? – John Riselvato Aug 21 '16 at 14:23
  • I have clarified my answer; you update the server in step 5 and the user doesn't need to,open your app to do this; it is running in the background. – Paulw11 Aug 21 '16 at 20:44
  • Alright, I think I understand everything now. Thanks! – John Riselvato Aug 22 '16 at 19:05
  • Awesome mate, I got this all working in about a day. Everything you've said helped me a lot. The only thing I don't have implemented is the suspended state code which I'm working on now. Just wanted to let you know it worked. – John Riselvato Aug 28 '16 at 01:35
2

If you are up for building your own circuit board and Bluetooth LE firmware, this is pretty straightforward:

  1. Add a contact switch that sends a voltage level change to the circuit board whenever the door opens.
  2. Increment a counter on the microcontroller when the level changes.
  3. Write firmware that advertises an iBeacon packet with the counter as the least significant part of the iBeacon identifier (32 bit major and minor).

A phone can then pick up this counter by using CoreLocation APIs to both monitor for the beacon (for fast background wakeups) and range for it (to read the specific identifier), then sending the counter value to the server based on the identifier read.

The advantage of using CoreLocation instead of CoreBluetooth as @paulw11 suggests in his very good answer is faster background wakeups of the app, allowing an app to reliably read the counter in the background. With CoreBluetooth, this background wakeup can be much slower, and door open events are more likely to be missed.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • I do have my own hardware device I'm working on so that's good to know. A quick question about UUID, is the major identifier what the app subscribes to and the minor doesn't matter and can be dynamic? – John Riselvato Aug 21 '16 at 14:15
  • The ProximityUUID is what the app "subscribes to" (the term usually used is "monitors for") and both the major and minor can be dynamic. If you make these dynamic, you have four bytes to work with, so the counter can range from 0 - 4294967295 – davidgyoung Aug 21 '16 at 18:58