It has taken a lot longer than we previously thought, but we made it here, to our first big point release for nRF Connect 2.0. Throughout this “two-point-oh" journey, you’ve been an invaluable asset to us, both for your patience, your support, and your feedback. And at every single step of the way, we’ve been doing everything we can to improve your experience and suit your needs regarding the most important tool in your Bluetooth toolbox.
During development of 2.1’s massive list of features, we pulled the brakes many times on everything that we were working on and we addressed your feedback, during Beta Testing, to satisfy your concerns. We want to listen, and we want you to keep telling us what we can do better.
To that end, 2.1 is still another step along the way. It is not yet the release you might’ve been waiting for – app-wide logs -, but with each incremental improvement across all areas in nRF Connect, there are less things in our plate before we can finally get there.
But before that, let’s have a small look into today’s release. Unfortunately, we made so many changes and improvements – no wonder our build number, #270, represents roughly 16% of all the commits required to build 2.0 from scratch – that it’d take us until 2020 to talk about everything we improved. If you’re reading this, chances are you might not have received an automatic update yet, since we’re erring on the side of caution here, and following a staged rollout. But feel free to open the App Store app in your phone and manually trigger an update.
Let’s get started.
‘Light Mode’ in nRF Connect for iOS 2.1
Though it might look like a simple concept to translate an app from light to dark colors, that preconception couldn’t be further away from the truth. As many fellow iOS Developers have shown, this is not a simple ‘invert colors and call-it-a-day' thing. It requires a lot of patience and understanding to comprehend how switching from prominently light screens to dark might confuse users, given that until now, all we had to do was to focus on keeping the foreground light, and the background dark. Simple rule.
But with Dark Mode, users expect a little more. They want colors. They want the content to become front-and-center, keeping unnecessary details in a different shade. It’s much easier for our eyes to process color than it is shapes, and by placing emphasis on the critical elements of our UI through color, we reduce the mental load of processing what each element is. At the same time, those sprinkles of color in a sea of darkness cause our brain to fixate on them a lot more, bringing a lot of depth and vibrancy to our apps using the exact same layout.
Whatever your opinion about Dark Mode is, (is it a trend, or just a fad?) the numbers speak for themselves. Ryan Jones, Head of Product for a landmark iOS App such as Flighty, commented all the way back in January how he was surprised by rumors suggesting iOS 13 would bring full-OS Support for switching between the two across all apps. Fast-forward ten months later, with Flighty having Dark Mode alongside iOS 13’s debut, and even he is surprised that 1 out of every 2 users launch the app in Dark Mode.
You have all spoken. You want Dark Mode. So we made it happen.
Dark Mode in nRF Connect for iOS 2.1
Our biggest problem implementing Dark Mode was not having a good sense of what APIs we would need to use – Apple's own WWDC talks did a good job at that. And community posts such as NSHipster’s take on these new APIs meant we were armed with all the possible weapons in our developer arsenal to affect our existing codebase and custom theming capabilities as little as possible (I.e. break as little as possible)
In fact, Apple’s APIs turned out to be so good, with the best rule being to use as many as Apple’s own system colors as much as possible, that we threw out our own Theming system, which we put in place since the beginning of nRF Connect 2.0’s development, and relegated all the hard work on our existing traitCollectionDidChange() callbacks to alert our app’s state that the it is now running under a different color scheme. That’s how good Apple’s work on UIKit has been regarding Dark Mode.
Still, we were missing something. It was very easy for us to change our white backgrounds to white, and our black text to the label system color so that we’d get the desired behavior automatically (black text on Light Mode, white on Dark). But we were missing a guiding principle to lead us in our design, and in this regard, we found Instagram’s own blog post on the subject to be our beacon – pun not intended!
Part of our problem was that we needed an idea to kingpin the design of our app. And we took inspiration from Instagram’s colors to bring a sense of depth to our own Dark Mode. At the same time, our ‘Light’ design received some slight changes, courtesy of the small color shifts required to make Dark Mode stand out. If we left some part out and it sticks like a sore thumb, please let us know
The ’Share’ Button allows users to Share their Logs using the standard iOS Share Sheet
As you all know, our #1 requested feature is to return to offering full-time logs across all actions performed by nRF Connect. And at this point, what we can say is that we now have a sketch as to how such a feature could be implemented and integrated into the current nRF Connect’s design, so yes, we are working on it so-to-speak.
In the mean time, it was paramount for our users to get better access as to why some DFU operations failed or were successful when they were, so we added the much-needed feature of being able to visualize, in near real-time, all the operations going on when performing a Firmware Update. Keep in mind though, that this is not implemented as soundly as we’d like, so these results will not be present if the app crashes or if you disconnect from said device.
nRF Connect for iOS 2.1 parsing EID, UID, URL and TLM Frame Types
Another request we received came in the form of better Eddystone support. In previous versions, nRF Connect could read the Eddystone data, but it could not parse it well, and all frame types were parsed as if they were all of URL type. This is no longer the case, with four frame types supported, as well as parsing for all Eddystone Service UUIDs as specified in the official Eddystone Specification.
Advertiser Tab in nRF Connect 2.1 for iOS
Another significant change can be found in the Advertiser Tab, which although functional, we found it to be a bit cumbersome to use, asking users to constantly name their own Advertiser Configurations one-by-one. If you’re the sort of power user who needs tens of configurations at the same time, setting these up couldn’t have been fun.
This is why, with 2.1, Advertisers receive an automatic name based on their Apperance. This means every time you set an Advertiser, you’ll be able to see their name adapt to their advertised Services, greatly simplifying the task of finding them later, as well as speeding up your use of the app. Of course, if you’d like to name each Advertiser yourself, you’re free to do so, and we won’t change the name from underneath your feet.
We also received some feedback asking where were the options to set-up and further configure the advertising parameters in nRF Connect. At the time of this writing, configuring parameters such as the Advertising Interval and Transmission (Tx) Power for Advertising are not possible to set in iOS. Apple promises to “advertise[s] data on a ‘best effort’ basis, due to limited space and because there may be multiple apps advertising simultaneously”, so we are unable to comply in this regard. However, we believed a lot more people might question themselves the same thing, so we decided to add a little bit of UI to clarify said matter.
Many parts of the app received touches here and there to strengthen our design and make the app feel a lot more cohesive. For example, you’ll find that our landscape layout for smaller devices, such as the iPhone SE, iPhone 8 or iPhone 11 Pro look a bit better now, with its on-screen icons taking a more proportional amount of space regarding the screen’s limitations.
RSSI Graph(s), RSSI Graph Context Menu, and Advertiser Service Context Menu in nRF Connect for iOS 2.1
But believe it or not, one of the things that puzzled us the most when we began working with Dark Mode, was how our device colors weren’t correct. In previous releases of nRF Connect, we ensured all of our devices followed a semi-random pattern of colors to make sure they could be used to visually distinguish between them. We knew the code wasn’t working well because it was easy to catch duplicated copies of a color one after the other, but our locks around the appropriate code were sound and Xcode’s Thread Sanitizer didn’t seem to pull any warnings about it. So we began doing printf() calls instrumenting our code and discovered that, yes, the pseudo-random code was working as expected. However, for CoreBluetooth, each Device’s advertisement is seen as a new discovery of the same Device, and parsing each new CBPeripheral instance as nRF Connect kept scanning triggered a new color for each “advertisement”, thereby, producing said coloring bug in the UI. Funny how issues sometimes arise from where you least expect them to be
Speaking about colors, we need to speak a bit about the Graph Tab. To achieve our seamless design between iPhone and iPad Layouts (or regular-width iPhone(s) in landscape), we had to go all-the-way with our own custom Tab Bar View Controller. iOS's default wouldn’t allow us to switch from a bottom-tab layout to a sidebar-layout when changing modes, so we had to do that ourselves. And one of our mishaps was that we didn’t check fast enough whether we are in Single Pane or Dual Pane mode, making the app sometimes believe we were in landscape mode when we were in fact in portrait on an iPhone, triggering two, parallel, RSSI Graph View Controllers, only one of them user-visible, with each one of them calculating every single plot point twice.
Needless to say, this has been fixed. As well as a race condition between the background thread updating the Graph’s underlying data and the UI Thread displaying it, causing, what we believed to be, the #1 source of crashes in nRF Connect 2.0.x. Fingers crossed that this turns out to be true!
nRF Connect for iOS 2.1 on an iPad
There is so much more we’ve worked on and that we’d love to talk about. For example, in our never-ending quest to keep learning and making nRF Connect the best app it can be, we scrambled our Date.timeIntervalSince1970 calls in favor of a monotonic timer based on your device’s kernel boot-time; the reason being that the former’s values are vulnerable to the system’s Date & Time changes, such as a manual change triggered by the user, a time-zone change, leap years, Daylight Saving Time, and so on. By basing our Timestamp comparisons on your kernel’s wake time, we are guaranteed a stable amount of seconds between two Date(s) no matter what the clock on your iOS device says.
We also improved the speed of the app, by splitting our single serial event DispatchQueue in favor of the “one queue per subsystem” approach championed by Apple, meaning file-writes, file-reads and logs no longer block the app from listening to your touches.
However, in-depth discussions around these topics and more will have to wait for later, when all of our higher-priority tasks and features for nRF Connect are resolved
Until then, we would like to remind you that by taking a part in our Beta Program, not only will you get access to the latest and greatest version of nRF Connect sooner than anyone, but also, you’ll be able to inform us about the features and details that you need to get the work that you need done. As we’ve gone through above, several critical features of nRF Connect 2.1 were informed by you, our users. Even details such as the colors for our text and icons under Dark Mode received feedback and were, as a result, better thanks to your input. We’d like this close collaboration to continue in our path towards making the best BLE tool there is on the App Store, so please, comment below and join our Testflight Beta program.
While you do that, we’re going to maximize Xcode and begin work on the first commits for our follow-up release...