Inspiration
AirDrop (and more recently, NameDrop) are incredibly cool pieces of software due to the "Wow" factor involved. Devices linking based on proximity rather than having to scan a QR or enter a code feels like magic. They are also technically complex, and when you look behind the scenes you get a sense of how much difficult engineering went into designing those systems to make the user experience as smooth as it is.
However, there are are some downsides as well. Most notably, the closed ecosystem of Apple means that people with Android phones have no way to share photos and other files with their iOS friends, and vice versa. There are plenty of similar apps that work cross platform, but they are all imitations of AirDrop under the hood, piggybacking off Apple's original solution to the problem.
This was the core inspiration: Remake something with the proximity linking magic of AirDrop, but in order to make it personally fulfilling, make it technically distinct to give us a chance to solve new problems rather than reusing existing solutions.
The second inspiration was the physical connection of a handshake. Across so many cultures, this is a gesture of welcoming and acknowledgement, and so we liked the symbolism of real human connection as a proxy for digital connection.
The third inspiration was a desire for privacy in our modern digital ecosystem. Too many apps require accounts (that usually in turn need a lot of personal information). We wanted to make something that was genuinely just a useful, functional tool - no ads, monetisation opportunities, or data harvesting. We wanted it to be a website so there was no need to download anything, and we wanted it to work without needing accounts of any sort. In the same vein, when we approached file transfers later in the server, we deliberately accepted the added complexity of setting up Peer2Peer file transfer to avoid having any information be sent via the server, ensure complete privacy for the users. It's nice to dream of an internet where this was the standard approach.
The last inspiration was more about the scope of the project. We've seen plenty of incredibly cool hackathon demos that would no doubt be amazing if they had another month of development to help them realise all the features they wanted. However, we think it's much more satisfying to build something small, complete and functional during the timeframe of the hackathon, rather than have the pitch relying on future promises of features and functionality. There were obviously a lot of ways you can use a proximity device link, of various complexity scales. We settled on filesharing in this regard because people understand the problem that it's solving, and it's less complex most other options, so we could focus on making it work well and polish the user experience, ensuring we leave the hackathon feeling like we've completed a project rather than just a demo.
What it does
The core idea is to enable file transfer by "handshaking" two phones to establish a connection. When you open the website and hit the start button (and accept the request for sensor access if prompted), each phone starts recording accelerometer data. When it detects a shake, it sends the data off to the server, and if a matching shake comes through in the next few seconds, it sets up a WebRTC connection that allows file transfer between the two devices without needing the support of the server.
How we built it
AirDap is a deliberately minimal program, built to be small, complete, and unbloated.
Frontend was done in React, with vanilla CSS (no need for Tailwind or shadcn)
Backed is a tiny node.js server that just listens for handshakes and sets up connections. This is hosted on fly.io in order to make a live demo work.
The WebRTC system uses Google's public STUN servers. We have a small TURN server on a free trial hosted by
metered.cato provide fallback when STUN fails.
Challenges we ran into
Initially we thought that ultrasonic audio would be the way to do proximity detection, but after struggling with that for a while, it became apparent that the speaker and microphone quality were frequently not good enough to enable transmission. We moved entirely to accelerometer data after a few hours.
The largest technical challenge was handshake matching. Since all sensors are going to be tuned slightly differently, we had to find a way to take two time series that are not identical and compute how similar they are. After doing some research into various methods of solving this problem, we settled on Dynamic Time Warping (DTW) matching and wrote up a small implementation for the server. Initially we were matching magnitude only, but it was pretty inconsistent, so it now attempts to match the x, y and z components as well as the overall magnitude. Dealing with correlation between handshakes was the most difficult part of the project, and in some ways it's one we haven't fully solved. There's so much variance and noise that it's honestly impressive it works at all.
WebRTC was a lot to learn. As a term that's often bandied around, it would seem like it's a simple and easy to set up technology, but it has a lot of unexpected pitfalls. Dealing with edge cases like whether people are on mobile data, home or university networks, routing failures, and capacity issues made it a lot more complicated and took a lot of development time to fix.
Debugging was a bit of a nightmare - since it's a phone-based web application, we can't get good debugging logs from emulating a phone in something like android studio, nor can we get proper dev tools on mobile browsers. Having to repeatedly deploy, identify and fix errors was a struggle.
Accomplishments that we're proud of
The most enjoyable part of this hackathon was solving novel issues that came with inventing (effectively) an entirely new technology. We had to make decisions about algorithms, matching thresholds, shake detection, and various other unexpected areas.
As hard as it was, debugging was actually very satisfying when we solved problems. As mentioned before, due to the difficult nature of debugging, we had to ensure that code that was written was correct the first time to minimise errors and redeployments. It also meant that when a bug was found, we couldn't quickly iterate on fixes, we had to spend time thinking over what could be causing the issues to make sure we could fix it right the first time. This lead to a more calculated and slower pace - "move slow and don't break things" - which meant that development was relaxed and felt more productive compared to constant small tweaks in attempts to fix things.
Finally, it was funny to match the prowess of a trillion dollar company. Not making any claims that AirDap is better than AirDrop, but it's still funny to take products that have probably had millions of dollars spent on development and make an okay replica of them in a weekend.
What we learned
As has been the theme over the last two headings, we learnt that mobile-focused web development is hard. WebRTC is also very hard.
On the positive side, we learned that designing digital experiences for interesting forms of user interaction are a really fun experience. We probably could have had similar functionality with just pressing a button or something instead of a handshake, but that would have been boring and not nearly as interesting to design or build.
What's next for AirDap
AirDap is a finished product. Until we hit the limits of the hosting free trials, it'll stay up and stay working. There's nothing else that needs to be implemented.
That being said, if we did have an extra few days of development to use, we'd probably focus on improving handshake detection consistency. There was a few instances where handshakes took a couple of times to recognize, and we also found that mimicking similar motions without making phone-to-phone contact could be spoofed after a few tries.
It'd also be nice to extend the file sharing options to work with some built in things - share business cards, contacts, social media accounts, or other useful things to transfer.
Built With
- fly.io
- github
- metered
- node.js
- react
- webrtc
- websockets
Log in or sign up for Devpost to join the conversation.