iOS 12 will make the iPhone feel personal again

I quit my job in 2008 to create an app based on the touch UI of the iPhone. I couldn’t stop talking about how Steve Jobs would call the iPhone a “lifestyle device”. It’s the entire reason the app I created as focused around fashion. Fashion, in itself, is very much a personal and a lifestyle choice. Now that smartphone sales have peaked, the arms race of achieving marketshare is over. Apple seems to be switching gears to making the iPhone as enjoyable as it was over ten years ago.

Memoji’s seem to be a moat against snapchat.

If snapchat were to build a phone that allows users to completely express themselves, I’d imagine it’d have something like Memoji’s at the core. One of Snapchats best value proposition is the ability for users to craft messages to a close group of friends. It seems Apple realizes this is of great importance since they seem to be doubling down on Animojis. At first, the idea seems silly, but if you look around, this is a natural progression of the personal avatar. Nintendo has had them for years with the Mii, but they didn’t have the power of Apple’s user graph behind them, or a camera that would track facial expressions. Bitstrips, in it’s early days as a Facebook plugin, was probably the most personal, self-expressing avatar creator out there. I still laugh to this day thinking about the Bitstrips that had inside jokes with friends or family members. Snapchat is making the best of Bitmoji’s, but Memoji’s have the potential to exceed the self-expressing capabilities by users actually speaking and making the facial emotions, rather than crafting drawings of themselves. This experience then has an extra purpose when sharing – the user can actually share their feelings or burdens with someone.

Machine learning at the center of personalization

The updates to the Photo’s app show evidence to how committed Apple is to creating a deep level of personalization that will connect with it’s users. The application of ML for personalized results is at the cornerstone of Spotify’s recommendation engine, which Apple is seeming to take a similar path with Photos.

At WWDC 2017, there is a talk that shows how Apple integrates NLP into Safari and other apps to create more accurate autocomplete suggestions for the keyboard. The demo felt a little creepy, but also seemed very magical. I’m curious if machine learning is at the center of SIRI recommendations and muting notifications for apps you no longer use.

When we talk about machine learning advances in the tech industry, we often overlook Apple’s achievements in this space. Most of the credit goes to their secret culture and SIRI’s poor track record.

SIRI Integrations

The customization of SIRI is my favorite announcement of IOS 12. I still have app Workflow installed on my iPhone and my Apple watch. Since the acquisition, I have been very eager to see what Apple was planning. The UI (at no surprise) looks very much like the Workflow app but now with the power of SIRI. I’ve always wondered how far Apple would let SIRI fall behind before going back to it’s roots to become a “doing engine”. I’ve been lucky enough to see one of the co-founders of SIRI named Dag Kittlaus speak about the origins of SIRI. He showed a few slides from his original pitch deck to investors. One of the slides which he dubbed “the million dollar slide” said: “SIRI, order flowers for my wife”. He then began to say this was the ah-ha moment for investors. Ever since, I’ve had hopes that some day SIRI would finally become the doing engine it was at its origin. Like some of us, I’ve written SIRI off the last few years due to frustration, and better choices… like Alexa – but unfortunately the Echo isn’t a full lifestyle device I take with me everywhere.

I’ve been wanting to develop a SIRI app extension for awhile, but I couldn’t because of domain limitations. Also, the possibility of being a SIRI suggested app is very low, as it has even a more narrow set of requirements.

Now that the API has more domains, the new SIRI API integrations might reduce friction. We could see a whole new category of apps emerge. It’s obvious that SIRI is still behind, but having developers create more integrations is a step in the right direction.

Do not disturb and Notifications

I’ve been reading the book called “Why We Sleep”. It’s had a profound effect on my life as I’ve taken sleep for granted. Until I started reading this book I was unaware of the data that supports the importance of sleep. Sleep, in addition to eating, and exercising, are life aspects that humans plan their days around. Again, Apple seems to focus on personalization with a full DND mode so you can reduce distractions going back to sleep. The ability to shut off the fire hose of notifications at any time, even when I leave a location is empowering and personal.

Self Quantification through Screen Time

I’m a big believer in self quantification. Many of the watchOS’ value propositions with fitness are at the center of self quantification. Screen time, which allow users to self quantify their own phone usage applies this type of game. The obvious use case is to limit our children’s usage around the devices but self awareness is the first step in any lifestyle change. I’ve been off Facebook and Messenger since January as a new years resolution, and I’m contemplating re-using the apps again now that I can set limits. The fact that I now have an option makes it seem that I don’t have to completely have to have an app uninstalled, and for Apple’s ecosystem is a very good thing.

Android and iOS has flipped value props

Since the beginning, Androids value proposition was always about giving users power in customizing their experience at the expense of battery life and UX. It seems Android is now focusing on the UX side with the updated material design and iOS seems to be focusing on customization with the latest release of iOS 12. Time will tell to see which strategy will be more effective in the long run especially since Google has a large advantage with ML capabilities.

Helping humans collaborate through open source

As a technologist, I’ve had numerous ambitions to create open source projects to solve large architectural problems. I wanted to do things like bring Netflix’s Hystrix to NodeJS or contribute to the Spring Framework only to put it off and later find out that someone actually had the will to do it.  I’ve started to contribute to open source software around the concept of human collaboration – it’s as rewarding as seeing others succeed.

As I’ve matured as an engineer, I began to understand the true factors that makes someone a “Senior” Engineer are the soft skills and what matters most is believing in building a 10x team. After reading the book: Best Kept Secrets of Peer Code Review, I realized that some companies used to think code reviews were an actual competitive advantage! This hit home for me as we continue to scale our engineering team at ABODO Apartments.

Repeatable Checklists

One of the takeaways from the book is having repeatable checklists for your code review process to prevent from mistakes from happening. I’m a huge fan of repeatable checklists for software deployments, phone interviews. I started using Manifest.ly for myself after I read The Checklist Manifesto by Atul Gawande. I totally missed the boat on putting them in place for a code review system.

Codify Your Teams Norms

We use Github and CircleCI to run tests and lint files but it was very cumbersome to have to go from Github to CircleCI to see the output of the failures. Luckily, there is a tool that allows us to add a logical step in our build process – Danger. They believe in automating common code review chores to allow humans to think about harder problems.

We use Pronto to ensure we conform to coding styles for Ruby, JS and SASS. The issue is we have to install and run Pronto locally on a per developer basis and even have a git pre-commit hook that will run before you push code. Developers are unique as snowflakes I consider their development environment to be sacred,  and it can be very difficult to enforce everyone to conform to the same local environment and not to mention it’s hard to scale as you add more developers. The Danger Pronto plugin that I wrote now allows you to use any Pronto runner with Danger.

Bots

As a long time IRC user and big advocate for Slack and a contributor to conversational commerce bot apps, I love the fact that we add another virtual member to our team. The advantage here is that you can defer the repeatable communication of something to a bot, rather than a human sound like a broken record and they could also get frustrated for having to repeat themselves.

Creating A Better Code Review Experience

Overall, it’s improved our team culture and we’re seeing less defects due to smaller PR sizes and more test coverage. What I’m most excited about is the opportunity for other teams to benefit through these new set of tools.

 

The Secret to Writing Tests

Far too often teams or individuals stop writing tests for a number of reasons but here are the top three:

  1. They take too long to run.
  2. Very high learning curve – only a few teammates know how run them and even fewer know how to write them.
  3. A lot of the codebase becomes non trivial, untestable state

You’ll hear a lot of that testing should be part of your culture, but when people talk about culture, what does that really mean? With tests, I think you can ask one simple question:

Do we treat test code like production code?

There are a lot of similarities you should draw from “production code”:

  1. Does it run fast and efficient?
  2. Is it written modularly for code reuse and extensibility?
  3. Does it follow team coding style guidelines and code linters?

I’ve been on many teams that set very low standards on test quality to encourage the team to write more tests. I believe this has diminishing returns because tests can easily get copy and pasted, and can incrementally take longer and longer to run. This also has effects on the length and quality of code reviews that the test code is a part of.

Code is code, tests are code, so treat tests like production code

This will take effort and diligence. Luckily there are a lot of tools that assist in insight and analysis in your tests because after all, it’s just code but it ultimately comes down to your teams culture and values.

If your tests are not easy to run, or can run quickly, testing will soon be abandoned. If you and your team ask yourself this simple question from time to time, testing could very well be a part of your teams culture.

 

The impact React Native will have on cross functional teams

One of the most undervalued elements in high performing agile teams is cross functionality of skills. As Jeff Sutherland explains in his book Scrum: The Art of Doing Twice the Work in Half the Time, he references a U.S. Special Forces team who are cross trained in medical assistance, and weapons. This ensures the team has all the necessary skills to complete the mission, from start to finish. This concept really breaks down with mobile developers, especially with the gap in skill sets with native mobile developers.

Small engineering teams that have native developers in their composition usually allow native developers to have to a limited contributions to web front-end development, and even more limited back-end contributions. The same cannot be said for other “full-stack” developers contributing the other way.

Alternatively, they break off the native teams independently and only have them contribute by platform. Want to reach a new audience by developing an app on another platform? Create a new team. This is difficult and expensive to scale, not to mention you’re adding risk by allowing the separated teams to be bottlenecked by any particular task. This also limits knowledge exchange and collaboration between developers and does not create a culture or environment for teaching each other. This can also create a culture of individual code ownership which can lead to individuals defensive about their code and other individuals thinking areas of code is not their responsibility.

Learn Once, Write Anywhere

JavaScript is one of the most commonly used languages today and React Native can de-silo teams to be more cross-functional because it optimizes for a common syntax that can be used for multiple platforms.

Artsy has a really good write-up of their experience using React Native in a new project without having to create a new team. This is proof that React Native can have an impact on existing teams, rather than only choosing React Native upon a creation of a team.

The need for “native knowledge” is still needed to make exceptional apps but does not require an entire team of native developers. This is an advantage when building a team, where you don’t have the distraction of trying to hire “rockstar developers” for one platform when you should be looking to build a 10x team.

Last Mover Advantage

Appcelerator has had cross a platform development solution with JavaScript for native apps called Titanium. React Native has a few advantages:

  • ReactJS – Gaining popularity fast. Having a widely used web tool reduces friction in trying React Native. By being a web tool first, it can gain early adopters that are “Team Web” who are advocates of JS being the language of choice for developing native apps.
  • Developer Experience – Unlike Titanium, React Native doesn’t have the barrier of license fees and IDE’s.
  • The Facebook brand for developers – They’ve come a long way from “move fast and break things”. With each open source project or platform they’ve released, they’ve been showing more of their craft at work. (I’ve always marveled at the Facebook iOS team and some of the engineering challenges they’ve taken on and solved.)

Not For Everyone

It’s still a bit early. Breaking changes, out-dated stack overflow posts, hard to find best practices and solutions in Google searches and very few team case studies.

This shouldn’t stop teams from experimenting with React Native. If teams aren’t looking for ways to self improve, then they don’t fully understand Agile.

 

Xcode – Building multiple targets with Google Cloud Messaging

If you haven’t seen my slides on How to quickly eat your own dogfood in iOS, you should. It allows you to get the product in your hands faster and can help eliminate any assumptions you have about the UX by actually using it. The biggest caveat you run into is having configurations on a per target basis. For example, Google Cloud Messaging requires a GoogleService-Info.plist file in your bundle that contains a GCM_SENDER_ID and a BUNDLE_ID. The values will be different for both your beta builds and production builds. You can’t have two of these files because you’d have to name them differently and the Google library loads the plist directly by name.

The solution is to modify the GoogleService-Info.plist file after it’s been copied to the bundle. First add a step to your current Build Phase, specifically after “Copy Bundle Resources“. OS X has a built-in tool called PListBuddy which we’ll use to modify the GoogleService-Info.plist once it’s been copied to the bundle. It’s ok to modify it in the bundle before it’s been digitally signed.

/usr/libexec/PlistBuddy -c "Set GCM_SENDER_ID " $BUILT_PRODUCTS_DIR/.app/GoogleService-Info.plist
/usr/libexec/PlistBuddy -c "Set BUNDLE_ID " $BUILT_PRODUCTS_DIR/.app/GoogleService-Info.plist

Perform a clean, then build and you’re good to go. Alternatively, if you don’t want to hide configurations like this in an IDE, put it in a separate .sh file and execute the script. This way you can see that there is a file in source control and it’s not hidden to other developers with an IDE setting.

You could also use this technique to modify your Info.plist values between your prod and beta builds, so you don’t have to have separate .plist files for each of them.

Front-end JavaScript Logging and Crash Reporting

One of the biggest things I miss about mobile development is remote crash reporting. It was absolutely essential. It was funny at the time because it seemed like such a revolutionary concept but then I realized that I should have been doing this for both languages on the server and in the browser. Now that I’m not doing as much mobile development I started looking for a similar exception aggregation system. I was pleased to find a language agnostic system called Sentry.

Great, so I found my crash reporting system but the next step was how I was going to implement it on a large scale.  I quickly turned to the patterns that the most logging frameworks use in Java and Python. Native JavaScript’s console.log() was great, but didn’t offer the flexibility I’d want for a large scale app. I wanted the ability to have different log levels and display logs in the browser console when I was debugging things, but at the same time I wanted to report a crash if I ever invoked logger.fatal().

I did some searching for JavaScript logging frameworks and I found a port of Java’s log4j, log4javascript. I found this to be pretty awesome but I was skeptical of using it right away as I didn’t want something bloated that had a full kitchen sink. It does offer a lot, but there were a lot of features I was looking for, specifically the ability to create different logging adapters that would allow me to log to Sentry. One thing you have to be careful is that if you log too many fatal errors you could overload your Sentry server so you’ll have to load test and scale accordingly. Sentry does have configuration options for Redis queues etc. to handle large volumes of logs.

In order for JavaScript to log to Sentry, I’d have to use one of their clients, Raven-JS. Once I got that working standalone, I wrote an adapter for log4javascript that would allow me to log all fatal() and error() logs to Sentry.

If you’d like to take it a step further, you can create a wrapper that instantiates the logger and configures it for you.

com.restlessThinker.Logger = {
    getLogger: function (name) {
        var loggerName = name || null;
        var logger = log4javascript.getLogger(loggerName);
        var consoleAppender = new log4javascript.BrowserConsoleAppender();
        var globalLoggingLayout = new log4javascript.PatternLayout('[%-5p] [%d{HH:mm:ss}] [%c] ::: %m%n');
 
        var subHostName = com.restlessThinker.Util.subHostName();
        consoleAppender.setThreshold((subHostName === 'prod') ? log4javascript.Level.ERROR : log4javascript.Level.DEBUG);
        consoleAppender.setLayout(globalLoggingLayout);
        logger.addAppender(consoleAppender);
        // this can be modified to fit dev/staging/prod
        if (subHostName !== 'prod') {
            var ravenAppender = new log4javascript.RavenAppender('somedevkey', 'mysentryurl.com/2');
            ravenAppender.setThreshold(log4javascript.Level.ERROR);
            logger.addAppender(ravenAppender);
        }
        return logger;
    }
};

You can generate multiple loggers in different classes/files.

var logger = com.restlessThinker.Logger.getLogger('newLogger');
logger.fatal('log this to sentry');

I hope this helps!

JavaScript Interfaces

In my personal quest for the “History of Javascript“, one of the first things I wanted to analyze was code maintainability. I tend to favor code maintainability and testability when making architectural decisions in any language. Naturally this lead me to wanting to see if there were any design patterns or anti-patterns in JavaScript. My first choice was  Pro JavaScript Design Patterns: The Essentials of Object-Oriented JavaScript Programming. I must admit when I was browsing through the book I was very skeptical of it when I saw a section on Interfaces in JavaScript. I know that it can be very risky trying to implement non-native functionality into one language from another. It’s even worse when you try to shoe-horn a pattern into a different language where it’s clearly not needed. I also strongly believe that languages evolve to help eliminate the need for developers to implement design patterns and that the languages themselves can have the patterns built in.

My favorite languages are both strongly typed and dynamic so it was a little hard for me to fully let go of types when jumping into JavaScript. When picking out this book, my main mission was “How can you create a large scale JavaScript application while still having it be very maintainable”? Any language can get unwieldly and design patterns aren’t a silver bullet, but I was curious to see enterprise methodologies applied on a free-spirited, hipster language. 😉

After reading it, it’s easy to see their perspective on when it’s necessary and that their implementation was very simple. We simply need to check if an object contains the specific methods defined in an interface. It uses duck typing to determine if the method exists, it doesn’t care about the parameters but just so you don’t get undefined is not a function. We obviously don’t want this everywhere but I find it works in a few scenarios. First, if we need to group classes. Second, if we must implement some design pattern that requires an interface. Third, if we have to invoke methods on a dependency injected object that we want to throw errors if a method does not exist and give other developers working on the same code feedback.

If you’re curious, buy the book or check out my example on GitHub.

 

JavaScript the Good Parts

Every front-end, full-stack, UI developer/engineer should have a copy of this book. Every dev team should have a copy of this book. Ironically the book is very thin, but it’s also great for a refresher every few months. It’s helped me enjoy JavaScript by simply avoiding the bad parts and pitfalls while telling me “why”.