Building auraphone
I was at a networking event. About 40 people at a bar/restaurant in Culver City and it was great! Lots of interesting people. Great conversations but when it was all over, I had no way to contact any of these people. I guess I'm just not smooth enough to ask for their insta or digits.
And so I started writing this bluetooth app. Using CBCentralManager on ios and BluetoothManager on android. Each phone broadcasts as a peripheral but also connects as central. Rooms full of phones running the app gossip. Simple right?
Think of the term "peripheral" as server and "central" as client. Yes there are differences in bluetooth and there are reasons for those terms, but my life got much easier working on this app when I started just thinking client server. So in a room with just two phones, which one is which? It can't be a coin toss. If 50% of the time both phones act as the server and neither client, bad. Or if both phones act as clients, bad. So how do you break the tie? You start up your server AND you act as a client looking for servers to connect to. Just be careful not to connect to yourself!
With bluetooth your server advertises and when you connect it tells you what characteristics it has. Think of characteristics as "endpoints". They are not the same as an http endpoints at all but again my life got easier when I started thinking of them like this. Our app has two characteristics PROFILE_CHAR and PHOTO_CHAR and step one is a client hits PROFILE_CHAR endpoint and gets back json from the other phone with device_id, first_name, photo_hash, instagram and it doesn't have to be json. It could be Protocol Buffers and binary but again, I went with json and yes, easier life.
So with my 200 OK from PROFILE_CHAR endpoint I look at the photo_hash which is a 256 sha from the binary data of the image the user picked. If I have this file already cached, I'm good and I disconnect from this server. If not I hit the PHOTO_CHAR endpoint and get this image data and save as hash.jpg locally. And then I disconnect.
After I disconnect from a server I place that specific bluetooth server id on a cooldown list. I have other phones in the room I need to connect with! And all this time I'm also acting as a server myself. Well, sometimes. Sometimes when I'm busy being a client getting a photo I'll pause my server actions. And it depends on ios vs android. There is lots of complexity in the BLE (bluetooth low energy) stack. This loop of find a server, connect, get my info, disconnect, repeat is a great little loop. But there are limits and GATT errors and queue buffers that get full and MTU (max transmission unit) that can make it so two phones right next to each other take a while before they finally find each other.
So I made github.com/andrewarrow/auraphone-blue which is a BLE stack simulator all written in golang. If you look at the wire package you'll see a pretty complete BLE implementation using the file system and domain sockets to mock the bluetooth radio. The swift package and kotlin package should look very familiar to anyone who has worked on ios or android BLE.
My plan was to run many mock phones this way and test all the weird BLE differences between ios and android here. It did not work. The only thing this golang auraphone-blue repo did for me was really help me understand how bluetooth works. This BLE stack that I made in golang doesn't help me fix ios and android bugs, it only introduces its own subtle golang filesystem ble bugs!
In the end nothing fixed all the bugs better than just running two real ios phones and two real android phones and having them write to disk very through logs PLUS ble specific json files showing exactly what each operation was doing and what info it got back. I ended up writing logic to zip up the entire local directory of the phone with all these files and logs and doing an HTTP POST to my local mac just to get all the data off all 4 phones quickly after each run.
Now it's not like this app will keep running when you have your phone in your pocket. iOS has rules on bluetooth connections and it's basically only if your app is running and foreground. So the way I see auraphone working at an event, you walk around and mingle as normal but yeah every one has their phone out and running the app but ONLY this app. You are still present and in the conversation not just looking at other distractions from your phone.
But now effortlessly after your conversation is done and you move around the room, you have a record of who that person was! Also the list is sorted by last updated_at desc so whoever you are near will be at the top. Great for when you have met someone earlier that night but forget their name. Now you just look down at your auraphone app that's already out and running and say oh hey jessie!
The app is in the ios app store. For android we serve up the apk at auraphone.apk. We are testing it now at BLANKSPACES Culver City.