Simultaneous Event Visualization for Mobile Devices

A story about building a better way to log events in mobile applications with a focus on iOS.

Kyle Beyer
Hacker School

--

This past week, my 2nd @HackerSchool in NYC, I worked on a project to create a better way to analyze events across many devices. Below is a story about my motivations and brief summary of the outcome. Last week I reflected on my first week @HackerSchool.

When I first learned of the Multipeer Connectivity API (a.k.a — Nearby Networking) for iOS it seemed reasonably complex yet not unapproachable. I didn’t have much experience with Objective-C, the language used to program iOS apps, but the capabilities of this new API were compelling to me (explaining why will require a different story) and I wanted to gain a first-hand understanding of the features. As a way to experiment and gain understanding, I built a simple app that enabled any connected device to turn on the flash of any other connected device. I get to control your flash, you get to control mine. Simple enough.

My naivety about the robustness of the application was quickly uncovered. The happy case worked okay. Open the app on one device, open the app on another device, wait for the devices to create a peer connection, viola … a switch appears to control the flash of peer device. Well, that happened most of the time. Sometimes they didn’t connect at all. Sometimes it took a long time to connect. If the app was turned off and then back on the re-connection was inconsistent. Long story short, there was clearly more work needed to get anywhere near useful.

Becoming Data Driven

Details matter. The difference between a good experience and a remarkable one is in how much attention was given to the details. I had reached a point in my experiment with the MultiPeer API where the details started to matter, I wanted to learn how complex it would be to handle the edge cases with grace.

From past experience, I knew that a key part of making relevant progress when confronted with a complex problem is having data with which to drive decisions. Without data, one should expect frustration and confusion.

So what data is helpful in this case and how should it be captured? The initial area I wanted to deal with was the connection process between devices. While Xcode can be used to step through the process on one device, it’s not helpful for seeing what happens simultaneously on multiple devices. As an alternative, I created many log statements (NSLog in Objective-C) to capture the state at different points in time. Then, the log files for each device could be reviewed.

Ugh. Reviewing text files, pulling out the relevant data, and re-packaging to make it useful is frustrating at best. There a couple ways to make it less painful. One is to automate the parsing of the log files to capture and visualize the data. Another is to change the log mechanism to capture the data more concretely as it happens.

Inspiration and Understanding

In the context of all possibilities, reviewing log files after the fact is not a very effective way to learn. Interacting with the events as they happen is much better.

I was first struck by this concept after watching Bret Victor’s talk Inventing on Principle. If you haven’t seen it, stop reading and go watch it. Seriously, I’ll wait right here.

There is really no replacement for seeing into the system as interactions are happening. It not only provides a data driven approach, but also enables experimentation and inspiration via quick feedback loop. As a result, it was clear that the appropriate adjustment to the logging mechanism would be to capture data more concretely as it happens.

Build vs. Buy

When considering options for using an existing tool, I found many examples of DIY NSLog macros but was unable to find a way to enable real-time visualization and analysis of simultaneous events across iOS devices. While changing the information that NSLog sends to the log file or output window is helpful, it wouldn’t help with real-time analysis and further mining of the data would require a custom text parser.

There are some additional reasons I decided to build. One was the amount of time it could save. I estimated that if it could cut 100 hours of development and debugging time in half it would be worth it. So the rough budget I set was 50 hours. I’ve spent around 30 so far and you can see the progress later on.

Another consideration was the learning experience. One of the technologies I want to become more proficient at during my time at Hacker School is D3.js, a javascript visualization library. In addition, I wanted to step back and review some fundamentals of Objective-C. It turns out that building a Visual Event Logger is a great way to do both.

So worst case, it would be a great learning experience. As a bonus, I would have more control over the data both in terms of what was captured and how was visualized.

The Result

Enough background. Let’s take a look at where I landed.

As the first phase of the project, I built a simple class in Objective-C to make using the Event Logger easy from anywhere in an iOS application. There are only two classes, one represents the event data to capture and the other handles sending the event data to configurable destination(s). As a convenience, the Event Logger class supports a concept of log levels. This enables each log statement to be associated with a level that can later be filtered out as appropriate depending the current application environment.

MPIEvent captures the data
MPIEventLogger enables control of log level and output destination

It was simple enough to validate this worked well by writing a series of examples to log data to the console.

Some examples of what can be down with MPIEventLogger

Great. So now we have a fancier version of NSLog. What’s missing is a way to see the information in a visual format in addition to textual. To enable that, I built a web application to receive and render the data in a dynamic timeline. When the web application receives data, it routes it to two destinations; a database and a socket connected to the browser.

Screenshots and Source Code

If you’d like to know more about the implementation, both the web application and event logger projects are on GitHub. The images below show the current state of the integrated solution in action.

Event timelines for each device
Mouseover event blocks to see details including duration.

As Simple as NSLog

On Thursday, I gave a demo at Hacker School. Afterwards, a fellow student, Laura Skelton, showed me how to configure a precompiled header (.pch) file to enable all NSLog statements to be processed by TestFlight’s remote logging API. She suggested a similar approach would be useful with MPIEventLogger so users of the API could automatically route existing NSLog statements to the Web dashboard.

That feature is now implemented as well. It’s pretty slick and makes it super simple to get started.

A macro to use MPILog in place of NSLog

Next Steps

In it’s current state, this new event logging capability is working well for my current needs. There is plenty of additional work that could be done to optimize including alignment with Apple’s ASL Logging levels, performance tuning, and improvements to the visualizations. However, my plan is to pause implementation of new features in order to focus on learning more about and working through the details of the Multipeer Connectivity API.

It’s Only a Sketch

I’ve been nibbling at The Art Spirit during my commute on the Subway. I’ll leave you with an excerpt that was an inspiration to me this morning.

People Say, “It is only a sketch.” It takes the genius of a real artist to make a good sketch—to express the most important things in life—the fairness of a face—to represent air and light and do it all with such simple shorthand means. One must have wit to make a sketch. Pictures that have had months of labor expended on them may be more incomplete than a sketch.

--

--