Respond 2016

In its third year and bigger than ever, Respond Australia’s Responsive Web Design Conference, was held for the first time in two cities, over two days. Kicking off on the 7th April at the National Maritime Museum in Darling Harbour.

Respond2016

Attending ‘Respond’ fuelled me with an overwhelming sense that you can never stop learning or being challenged. 

Attending a conference like Respond isn’t something I’d usually consider. As an Experience Designer, it probably comes down to an assumption that I would not understand a lot of the code rich talks and that these talks would scare me. Ironically, one of Karen McGrane’s leading themes throughout her presentation was advising us not to make assumptions about a user’s context based on any single factor. Thankfully through a stroke of luck I won tickets to Respond during Web Directions 2015, and was able to attend the conference despite my assumptions.

Greeted by new, friendly faces sharing a career and a love of coffee just like my own, I began my solo adventure into what I’d assumed would be a daunting two days that looked something like this:

confused-goat

Those assumptions I made were completely wrong. The topics that were spoken about were very timely and relevant, and I even found myself eager to attend code rich talks. Not so scary after all!

Throughout the conference I picked up on some common underlying themes – opening our minds, challenging industry trends and a friendly reminder to update our passwords.

Adaptive design

What is it? How should we use it? And why is it any different from Responsive Design?

The term ‘Adaptive Design’ was mentioned quite a bit, most notably by Dina Gohil and Lucinda Burtt’s presentation from Fairfax Media on the latest SMH re-design, still under betaKaren McGrane defined Adaptive Design as serving something different. The concept is used to serve content to a user based on their specific device and context.

“Adaptive and responsive solutions work together – they’re not competitors.”

Karen summarised, “Adaptive and responsive solutions work together – they’re not competitors.” Yes it is important to deliver contextual variables to users, but the device type alone shouldn’t be what changes the experience a user might see. Many other factors come into play – analytics, location, velocity and time. Above all a seamless experience should be delivered across all devices. Don’t compromise on this experience by making assumptions.

Accessibility

Never forget accessibility, including catering for assistive technologies. At Bilue we believe accessibility is so, so important, we’ve written about it a few times before. People are using devices to access content more than ever. It is our job to make a product accessible, and we’re not just talking bigger fonts and AAA colour passes. We’re talking, making sure screen readers will be able to clearly communicate tasks and flows to their users.

Russ Weakley really brought it home that it’s our duty to ensure our sites and our digital products are truly accessible. Reminding us that small, simple steps can have huge rippling benefits for users that need them the most.

respond-audience

Security

Digital security stakes have never been higher than they are now. Rachel Simpson from the Google Chrome team reminded us all that we are only as a safe as our weakest link when it comes to tech. Ensuring our users are secure and their experience is still pleasant can be a complicated balance to reach. It goes against human capabilities to expect users to remember different login credentials for each and every online account they’ve ever created. Often users end up falling short and expose themselves to security breaches. An important point made by Simpson was to understand that as your users are stepping through a flow they are also being expected to make a number of quick decisions. It’s important to be timely and meaningful when it comes to the safety of their accounts.

Performance

Performance of your site is directly affecting your revenue. Peter Wilson considered this hard truth, stating that performance is a hot topic in the industry and so it should be. Currently it takes 15.2 seconds on average to fully load a webpage, using a fast desktop network connection. Factor in poor mobile connections, and EFS interference, you will be losing revenue fast! Get rid of the baggage and set performance as a high priority when creating your product.

Be different

A number of speakers challenged why everything is looking a bit the same online these days and motivated us all to question exactly why that is. Navigation systems, layouts and modern frameworks together are creating websites that have become clones of each other. Be inspired by things outside of the digital world, it’s up to us to change that.

Respond has left me filled with motivation to learn, be involved and stay connected. Web Directions are holding a number of great conferences over the year, check them out here: Transform, Code and Direction.

Augmented Reality in mobile today

Last Thursday, 7 April 2016, a few of us from the Sydney office attended Convergence, billed as a conference for Wearable Technology, Smart Devices and the Internet of Things (IoT). The main stand out for us at the event was the dominance of Virtual Reality (VR) and Augmented Reality (AR) devices.

In VR, devices and technology can be used to recreate the world digitally for the user to explore. AR aims to augment the reality around you and can be explored using a camera feed with digital information laid over the top to enhance the user’s view.

While we were at Convergence demonstrating our product design and development principles with a prototype smart shopping bag (more to come on that later) – it made us stop and think about how would we use VR or AR in today’s environment? Whilst we believe there are some great examples of VR out there, AR is more easily applied to today’s environment through the use of mobile phones. Therefore AR is more accessible to companies for enhancing their customer experience.

microsoft-hololens

Source: Shape the future of holographic computing. https://www.microsoft.com/microsoft-hololens/en-us

Most of the examples of AR exhibited at Convergence took the form of digital content overlaid onto the user’s view of their immediate environment. Microsoft took centre stage to discuss their recently ‘released’ Hololens. This is a headset that overlays digital images onto the screen in front of your eyes to simulate a hologram. This was an impressive presentation, only diminished by the fact that there is just one Hololens in the country (at the time of writing). By contrast there are as many mobile phones in Australia as there are people which made us realise the huge potential for using AR to enhance the mobile experience.

Mobile developers have been creating new experiences in AR since 2009 across a broad variety of disciplines that are within easy reach of most people today. Such experiences include an artist who leveraged mobile technology to bring to life in real time with voice and video, his Archibald Prize entry ‘Wilarity’. Architecture and Interior Design are fields utilising the mobile AR space with apps transforming blueprints and floor plans into 3D models. For example the Ikea app where you can view what a piece of furniture might actually look like in your home without getting up from the couch. However, marketing and brand awareness are going to be the big winners here as consumers start interacting with a company’s products in new and interesting ways, such as the humble McDonalds happy meal box coming to life and evolving into an interactive game when viewed on a phone. This cross-over of the real and virtual worlds can create powerful, memorable experiences.

We see the potential for retailers to use AR and IoT in their physical space through product information and wayfinding. For example, searching for a product in a large department store can be confusing and difficult. What if your mobile phone could overlay directions to a targeted in-store offer that interests you on the floor, and then highlight and display extra information about the product you are looking at without the need to ask a sales assistant. Further expansion on this shopping experience would be to pay from your mobile and to leave with your product in hand, similar to the self-service experience at Apple Stores.

In another example, imagine looking at the wine menu in a restaurant with endless wines to choose from. Wouldn’t it be great if you could use your phone’s camera to scan the wine list enabling it to highlight the type/region of wine that matches your taste preference or suggests a match to your meal. Fast, convenient and highly engaging for your customers.

The possibilities of AR are endless when you take the approach of enhancing the physical world with the information that the digital world can provide. And since most people have an AR capable device in their pocket, we shouldn’t wait until headsets are the social norm before exploring the opportunities.

At Bilue we believe that our lives can be enriched by the digital world, and through Design Thinking, Prototyping and Technology we can create innovative products for your customers. If you have an idea or product that you want to validate or explore, reach out to us and let’s talk about how mobility in computing, and AR, could help you achieve your goals.

Try! Swift 2016

On Wednesday 2nd March – Friday 4th March, I attended the first Try! Swift developers conference in Tokyo, Japan. As Apple’s new programming language begins to grow and mature it is now receiving a large amount of attention throughout the developer community. This conference was a great opportunity for developers of the iOS, tvOS, watchOS and Mac OS X platforms to present on the ways they are pushing the limits of the language. It has opened up many unique discussions on the ways the language itself can be improved, some of the drawbacks that exist and most importantly the best practices that have revealed themselves already within the community.

Leaving from Terminal 2 at Sydney Airport with a conference ticket I had only received days earlier off the waiting list, I had no idea of the experience I was in for and the great people I was about to meet. I sat contently in my seat somewhat rushed, fearful, nervous yet excited for my first trip to Tokyo.

Sydney Airport

We have already begun using Swift at Bilue with many of our clients and of course on our own internal projects. As a team we have been pushing ourselves forward, learning new things and working extremely hard to bring each other up to scratch on everything that Swift introduces. I’d decided that attending the conference was a great way to extend my learning and to exchange ideas with some of the leading developers from across the world.

It turned out that Tokyo was an amazingly beautiful place that seemed to deeply align with my passions on so many different levels. On the days leading up to the conference I found time to explore a few different areas, most notably my favourite place – Omotesando. I loved the quiet atmosphere and the subtle nature that seemed to somehow augment the buildings and the cityscape. I quickly learned this to be home to some of the finest coffee that Tokyo has to offer, including Blue Bottle Aoyama which was as amazing as its San Fransisco counterpart except without the long lines and hot sun.

Cherry Blossoms
 
 
 
Omotesando

For us Swift augments our design-led approach to building inspired products. It allows us to apply the core idioms of the Swift language into writing safer, more reliable and less error-prone code. Essentially, by writing Swift we can be more certain that our software behaves exactly the way we expect it to. By taking advantage of Swift’s protocol oriented approach to application architecture we end up building products that are far more maintainable for our clients long after we’ve touched them.

At the conference located in Shibuya Mark City, I attended countless talks that were each in their own way both insightful and intriguing. On the first day Syo Ikeda presented a great talk which dived deep into the broad Swift Ecosystem. Syo outlined the most popular frameworks, libraries, resources and tools that any decent Swift developer would need to know about. We also heard Laura Savino explore the intricacies and cross-overs of learning a new language, whether it be a new programming language or a spoken language. Gwendolyn Weston quickly wowed the audience with her well received and incredibly detailed use of Pokemon as an example of Swift Type Erasure.

Blue Bottle Coffee
Tokyo Dome Baseball
Tokyo Sunset

One of the biggest highlights of my trip to Tokyo was being able to find and attend a Yomiuri Giants exhibition game played at Tokyo Dome. Despite all of the hilariously cruel difficulty I went through to get my ticket printed at the convenience store, I managed to get in. I played baseball when I was younger, and I’ve seen a game in San Fransisco, but now I know that baseball in Tokyo is like none other. Another memorable moment took place on the Tuesday evening before the conference, many of the speakers and attendees organised a visit to Roppongi Hills. At the top of the Tokyo City View we watched as the sun set over the skyline and this view was nothing short of breathtaking.

On the second day Adam Bell from Facebook asked a really great question, “When was the last time you used an app that felt surreal, or broke the laws of physics?” He presented his doubts about the plain, flat and lifeless modern iOS application and then discussed the ways prototyping can be used to implement rich, interactive and immersive animations using Swift.

Daniel Eggert explored how Swift allows developers to breathe an entirely new life into old and rigid but still tried and tested Cocoa APIs such as Core Data. Later that day Chris Eidhof similarly presented a more Swift-y approach to UITableViewControllers and demoed a really fun and unique keyboard shortcut animation technique.

Fish Market
Shrine

Ridiculously early (at about 5:00am) on Thursday morning a friend and I woke up and made the trek down to the Tsukiji fish market. I’d been told that this well known fish market will be relocated really soon, so I was really glad that I took the chance to go while I could. It was a fast and intense experience with motor scooters carrying fish barrels zooming past us, it was really obvious that we had no idea where we were or what to do. Nonetheless I managed to take some really nice photos that made the early morning well worth it.

A standout talk on the final day of the conference was the excellent talk presented by Jesse Squires from Instagram on contributing to Open Source Swift. Jesse gave a really in-depth and well thought out, yet clear and simple understanding of the Swift project structure. He told us exactly how the Swift code we write in Xcode is compiled into a binary for release to the App Store. He provided a perfect guide and recommendation on contributing to the underlying Swift library at any experience level and with any skill set. Most importantly he outlined the importance of making Swift into a language that the community as a whole can enjoy and use productively.

Swift is more than a programming language. Swift is a community!

Another great talk was Ash Furrow’s overview of the Artsy approach to testing. Ash breaks down the different approaches to each of their apps based on which approach (or lack of!) they took and how it affected the team and the product itself. I really appreciated seeing Ash give this talk and outlining the balance that is required when implementing BDD (Behaviour Driven Development) or TDD (Test Driven Development) with tight deadlines and uncontrollable circumstances. He mentioned the Snapshot approach to testing, which is definitely something that I will be taking a look into and experimenting with.

Group Photo
Wine Salesmen
Chris and Phill
Lee and Phill

There is no other way to say it than this – I met so many amazing developers and people at Try! Swift that I just know I’m going to be really great friends with for the rest of my life. It underlines exactly why I chose to become a software developer, and exactly why I believe software creates opportunities that make the world a much better place to be.

A takeaway for me from the conference was that for the foreseeable future Swift is at the bleeding edge of the Apple Developer Community. And as has come to be expected, Swift is taking shape in the form of a strong, powerful and great community. There are so many developers learning Swift together right now, each and every one pushing the boundaries of the language making it a greater language to build amazing things with over time. Swift has the potential to greatly improve our development experiences at Bilue as well as to ensure that the inspired products that we create truly fulfil their purpose for the people that use them.

Daigoji Temple
Meditation

We intend to continue working hard on writing Swift and will post some of our thoughts, experiences and code here as we go. Thank you to everyone who organised Try! Swift, which turned out to be an amazing conference in a beautiful city bringing together some of the smartest minds from around the world.

 

ありがとうございました

New Call-to-action

 

Accurate Apple Device Reporting in Google Analytics

For some reason Google Analytics doesn’t expose a dimension that represents which specific model of iPhone/iPad that the user is using (iPhone 4, iPhone 5, iPad Mini 2, et al). This makes it very difficult to track your mobile users’ usage by specific device type.

This article describes the technique that Bilue uses to provide a comprehensive, accurate, future-proof solution.

Possible Solutions

Firstly, let’s look at a couple of other techniques that are often considered and discuss the shortcomings of each.

Option 1. Raw values from utsname

Apple offers APIs to retrieve the raw identifier (eg. iPhone7,2). For example:

#import <sys/utsname.h>

struct utsname un;
uname(&un);
NSString *identifier = [NSString stringWithCString:un.machine encoding:NSUTF8StringEncoding];

This identifier can then be sent to Google Analytics as a custom dimension.

However, the values returned from this API (eg. iPhone7,1) are not fit for human consumption. Business stakeholders don’t want to see reports containing these values. Not only that, it is virtually impossible to look at the values and know which specific identifiers are related to which physical devices.

This is a technically correct solution, but offers little business value.

Option 2. In-app mapping

This seems to be the most commonly chosen solution, and basically involves the app having a big lookup table that maps the raw device identifier mentioned above into something more readable (eg. iPhone 6 Plus), and then sending this translated value to Google Analytics as a custom dimension.

The big problem with this is that the lookup table is hard-coded into the app at the time the app is shipped. The lookup logic will not know what type of device it is running on for any phone that was launched after the app was released. At that point, it has two choices:

  • Send a generic value like Unknown. In this case, Google Analytics will have a whole collection of events that are all lumped in together as coming from unknown devices. Consider the case when Apple launches 3 new phones… all three phones will be reporting as the same type: Unknown.
  • Send the raw identifier iPhoneX,Y. This is a more technically correct solution in that it doesn’t lose the raw information, however, the output in the reports will continually have to be massaged because it will contain a mixture of human readable device names and raw device identifiers.

Every time new devices are launched by Apple, the only hope for correct reporting is to release a new version of the app and hope that users choose to upgrade.

This is a brittle solution.

Option 3. Screen resolution

Out of the box, Google Analytics does provide a Screen Resolution dimension that contains values like 375x667. At a high level, these values can be reverse engineered to determine roughly what type of device it was based on the following table:

  • 320×480 => iPhone 4 (and smaller)
  • 320×568 => iPhone 5
  • 375×667 => iPhone 6
  • 414×736 => iPhone 6+
  • … plus some other values for iPad

Again, this has problems in the reporting space because the translation of the resolutions to specific models is non-obvious to the casual observer. It also is very general in that you cannot differentiate between, say, the iPhone 5, 5c and 5s.

Data Mapping in Google Analytics

An oft-overlooked feature in Google Analytics is the ability to upload a mapping file that can be used to translate custom dimensions from one value to another. We can use this to our advantage to get Google Analytics to perform the mapping.

Solution Overview

Broadly speaking, the solution involves the following steps:

  • When setting up Google Analytics, a mapping file is created to map the raw identifiers (iPhone7,1) into human readable variants (iPhone 6 Plus)
  • At run-time, the phone sends up the raw device identifier (iPhone7,1)
  • Google Analytics maps that raw identifier into the human readable value
  • Run reports using the mapped human readable version value
  • Profit?

When new devices are released by Apple, the mapping info can be updated in Google Analytics without having to ship a new app.

Another awesome benefit is that Google Analytics will also apply that new mapping info to historical events, so even if you take a few days/weeks to update the mapping info after a new device is released, it will be retroactively applied.

Implementation Details

Creating Custom Dimensions in Google Analytics

We are going to create three new Custom Dimensions in Google Analytics:

  • appleDeviceModel – Contains the raw device identifier sent from the device. eg. iPhone5,3
  • formFactor – Contains a reasonably general description. eg. iPhone 5
  • formFactorDetailed – Contains a pretty exact description. eg. iPhone 5c (GSM)

To do this, click on the Admin tab at the top of Google Analytics, and navigate your way to the Custom Definitions/Custom Dimensions menu for your property. Add 3 new Session dimensions with the names outlined above.

Google Dimensions

Your dimension numbers may be different depending on how many custom dimensions you are already using. Take note of the dimension numbers; you will need them in the next step.

Creating input data

Now you need to create a file that contains the mapping info.

Important: The first row of the mapping file must contain the dimension numbers of the dimensions you just created. The first one is the key (appleDeviceModel), and the next two are the values that will be mapped (formFactor and formFactorDetailed).

For reference, our latest file looks like:

ga:dimension7,ga:dimension8,ga:dimension9
"iPhone1,1","iPhone 2","iPhone 2G"
"iPhone1,2","iPhone 3","iPhone 3G"
"iPhone2,1","iPhone 3","iPhone 3GS"
"iPhone3,1","iPhone 4","iPhone 4"
"iPhone3,2","iPhone 4","iPhone 4"
"iPhone3,3","iPhone 4","iPhone 4"
"iPhone4,1","iPhone 4","iPhone 4S"
"iPhone5,1","iPhone 5","iPhone 5"
"iPhone5,2","iPhone 5","iPhone 5 (GSM+CDMA)"
"iPhone5,3","iPhone 5","iPhone 5c (GSM)"
"iPhone5,4","iPhone 5","iPhone 5c (GSM+CDMA)"
"iPhone6,1","iPhone 5","iPhone 5s (GSM)"
"iPhone6,2","iPhone 5","iPhone 5s (GSM+CDMA)"
"iPhone7,1","iPhone 6","iPhone 6 Plus"
"iPhone7,2","iPhone 6","iPhone 6"
"iPhone8,1","iPhone 6+","iPhone 6s"
"iPhone8,2","iPhone 6+","iPhone 6s Plus"
"iPod1,1","iPod 1","iPod Touch (1 Gen)"
"iPod2,1","iPod 2","iPod Touch (2 Gen)"
"iPod3,1","iPod 3","iPod Touch (3 Gen)"
"iPod4,1","iPod 4","iPod Touch (4 Gen)"
"iPod5,1","iPod 5","iPod Touch (5 Gen)"
"iPad1,1","iPad 1","iPad"
"iPad1,2","iPad 1","iPad 3G"
"iPad2,1","iPad 2","iPad 2 (WiFi)"
"iPad2,2","iPad 2","iPad 2"
"iPad2,3","iPad 2","iPad 2 (CDMA)"
"iPad2,4","iPad 2","iPad 2"
"iPad2,5","iPad Mini","iPad Mini (WiFi)"
"iPad2,6","iPad Mini","iPad Mini"
"iPad2,7","iPad Mini","iPad Mini (GSM+CDMA)"
"iPad3,1","iPad 3","iPad 3 (WiFi)"
"iPad3,2","iPad 3","iPad 3 (GSM+CDMA)"
"iPad3,3","iPad 3","iPad 3"
"iPad3,4","iPad 4","iPad 4 (WiFi)"
"iPad3,5","iPad 4","iPad 4"
"iPad3,6","iPad 4","iPad 4 (GSM+CDMA)"
"iPad4,1","iPad Air","iPad Air (WiFi)"
"iPad4,2","iPad Air","iPad Air (Cellular)"
"iPad4,4","iPad Mini 2","iPad Mini 2 (WiFi)"
"iPad4,5","iPad Mini 2","iPad Mini 2 (Cellular)"
"iPad4,6","iPad Mini 2","iPad Mini 2"
"iPad4,7","iPad Mini 3","iPad Mini 3"
"iPad4,8","iPad Mini 3","iPad Mini 3"
"iPad4,9","iPad Mini 3","iPad Mini 3"
"iPad5,1","iPad Mini 4","iPad Mini 4 (WiFi)"
"iPad5,2","iPad Mini 4","iPad Mini 4 (LTE)"
"iPad5,3","iPad Air 2","iPad Air 2"
"iPad5,4","iPad Air 2","iPad Air 2"
"iPad6,8","iPad Pro","iPad Pro"
"AppleTV2,1","Apple TV","Apple TV 2G"
"AppleTV3,1","Apple TV","Apple TV 3"
"AppleTV3,2","Apple TV","Apple TV 3 (2013)"
"AppleTV5,3","Apple TV","Apple TV 3 (2013)"
"i386","Simulator","Simulator"
"x86_64","Simulator","Simulator"

Importing Custom File

Using the Admin/Data Import menu item for your Google Analytics property, perform the following actions:

  • Create a new Data Set
  • Choose Custom Data
  • Give it a name like Apple Device Identifier to Form Factor Mapping
  • Choose which view you want it applied to (you probably want all views)
  • Click on Next Step
  • Select appleDeviceModel as the key
  • Select formFactor and formFactorDetailed as the imported data.

Your settings should look like the following screenshot.

Google Data Import

  • Click on Save
  • Click on Finished

At this point, you’ve defined how the mapping will be performed but you haven’t loaded any data.

Choose the Managed Uploads option for your newly created data set, and upload the file containing the mapping data. Google Analytics will verify that your data matches what it expects (for example, the header rows match the custom dimension numbers, and the coloumn count is correct). You will notice that the Status field will be temporarily be set to Processing – sometimes this takes a few minutes to change to Completed.

At this stage, the import is successful and the data will start to be mapped.

Posting from App

The behaviour within the app is pretty straightforward. You just need to send the raw device identifier to Google Analytics as a custom dimension (making sure that you reference the correct number). In the example above, the appleDeviceModel dimension is 7.

#import <sys/utsname.h>

struct utsname un;
uname(&un);
NSString *identifier = [NSString stringWithCString:un.machine encoding:NSUTF8StringEncoding];
[tracker set:[GAIFields customDimensionForIndex:7] value:identifier];

Downsides

So far, the only downside with this approach is that the mapped custom dimension data is not available in the Real-Time view of Google Analytics. For us, this hasn’t been a real problem but it is worth mentioning.

And, of course, it is worth mentioning that there has to be a very real discipline of updating the mapping data in Google Analytics when Apple releases new devices. As I mentioned before, though, at least these updates can be made outside of the app release cycle.

Awareness

Independent of where you work or live, every individual can benefit from self-awareness and understanding how they interact with others. Here at Bilue we’ve been discussing the topic of strengths and how people’s strengths relate to each other within a team environment.

Being aware of others means more than simply being polite and respectful around an office. Awareness is about spending the time to understand the individuals around you, their motivations, their desires and their strengths. Knowing this will inform the way you communicate and express ideas, opinions and thoughts amongst your team. In this way being aware can mean the difference between an open-minded, successful team with the freedom to explore ideas and a scared, narrow-minded team unable to break down the communication barrier.

It’s important that awareness focuses on strengths and abilities of peers, instead of on weaknesses. Finding ways that your strengths can integrate with the strengths of others will form stronger team relationships and team members will feel more valued within a team culture. Learning new skills from those around you will start to come naturally, and others will start to learn new skills from you.

Imagine a chef that knows how to cook divine gourmet meals and yet struggles to make enjoyable desserts. The chef decides to ask his assistant, who is known for cooking amazing desserts but makes awful meals. Both the chef and his assistant stand to learn something valuable from each other.

This concept can be applied throughout your daily approach to interacting with others. Consider treating interactions as an exchange of information, a seemingly unspoken two-way transmission as opposed to a one-way delegation. Instead of projecting your own perspective on others, take the opportunity to understand the perspective of your peers and let that inform and shape your own personal knowledge.

I believe every individual should be mindful of the people they’re collaborating with on a daily basis, and the ways they can build stronger relationships, challenging others to be better and being challenged to improve themselves. No matter how you do it, you’ll grow as a person and form more effective bonds with people around you.

The Cole Classic 2016 Swim

Yesterday a small group of us took to the water at the North Sydney Olympic Pool to begin our preparation for The Sydney Morning Herald’s Cole Classic 2016 swim. The Cole Classic swim incorporates a 1km, 2km, and 5km ocean swim from Shelly Beach to Manly Beach and will take place on Sunday, 7th February 2016.

Participating in the swim is an opportunity to help raise money for a variety of 800 different charities. In 2015 the Cole Classic raised more than $140, 000 for charity. Each member of Bilue’s team will be swimming in support of The Kids Cancer Project, an extremely special cause that truly holds a certain significance for us all.

As founder Graham Cole wrote in 1982, “the event is not a race but a challenge to all persons to stretch themselves in body and mind to swim a reasonable distance through surf. It will, I hope, be an incentive to persons to involve themselves in the self-discipline required to get fit; obtain confidence in their ability through swimming to achieve pride in having performed something that is, perhaps slightly above average, and finally to recieve some recognition of their accomplishment.”

In order to rigorously prepare our team for the challenge we’ve scheduled in two distance swimming sessions each week. Beginning with 500m, we’ll increase our distance by 200-250m each session, in the hopes that by the time we race we’ll be capable of swimming at least 1.3-1.5km. In late January we’ve planned a dry-run session where we’ll attempt to swim the entire 1km in the lead up to the main event.

We’re immensely proud that we have the opportunity, people and motivation to be apart of this challenge. If you want to, you too can support a charitable cause by participating in the Cole Classic swim, or simply by donating to our cause – The Kids Cancer Project.

Yow! 2015 Conference

On Thursday 10 December, once nothing more than a $10,000 credit card debt and now a Sydney-based technology startup, Atlassian raised $US462 million in a much anticipated Initial Public Offering (IPO). It goes to show that now is as good a time as ever to push forward, break down barriers and achieve something bold.

Australia is an amazing country with a thriving technology industry that is only destined to grow.

At the forefront of this technological growth are Software Developers, Engineers and Technology Architects. The impact of technology on us all is entirely at the hands of these men and women, the systems they build and the problems they solve.

Also on Thursday 10 December, Yow Australia held the Yow! 2015 Conference in Sydney. As a proud sponsor of the largest independent event for software development across Australia, Bilue attended both the Yow! 2015 Conference and Yow! CTO Summit in Melbourne and Sydney.

Attracting the sharpest developers from across the country, the conference is an opportunity to sit infront of a diverse range of experienced, innovative and influential speakers from around the world.

Unlike your off-the-shelf technical conference, Yow! is an event focused on fostering open-mindedness, practical learning and richly engaging discussions. This year’s schedule is split into three well crafted tracks on topics ranging from Cloud Infrastructure to People & Processes, Security, Mobile, Architecture & Design, Languages, Big Data and ofcourse Software Engineering. It includes an amazing line up of well known speakers who have in many ways defined their respective industries, including – Dave Thomas, Kathleen Fisher, Sam Newman and so many more.

While there’s still another entire day’s worth of sessions about to begin, I’ve already seen talks that are going to change my perspective and approach on my work as a developer for years to come.

On Thursday morning I attended Ben Tesse & Sam Ritchie’s ‘Rethinking MVC with React Native & ReactiveCocoa’ which cast quite a unique light on Functional Reactive paradigms through the lense of Javascript’s React Native framework.

I also sat front row during an eye opening, insightful talk by Mike Magruder – ‘Mobile Performance at Facebook’ that revealed the extremly extensive efforts from Facebook sacrificed in the name of Performance testing. Aaron Bedra’s ‘Adaptive Security’ introduced me to the core concepts behind system security and how adapting to change will improve our chances against malicious attackers.

One talk that stood out as a brilliant testament to the core beliefs, intentions and driving forces for us at Bilue was Dave Thomas’ talk ‘Rigor Mortis (Avoiding)’. Put simply, Dave told his audience to ‘Think Differently’ and ‘Program Differently’. He put forward the idea that language is a limiting factor to the world around us.

What we can’t express with words, we can’t comprehend and by knowing this we can reason that by keeping an open mind, learning new languages and experimenting with different ways of solving problems we can achieve a deeper level of understanding in our work.

This concept applies extremely well to software and it holds up just as strongly when applied to everything that we do. Through an open mind, through seeking new ideas and through exploring new ways of thinking we expose ourselves to experiences and solutions we would otherwise have not even thought possible.

Yow! 2015 Conference has so far been amazing and informative for all of us at Bilue who’ve attended. New, unique and exciting ways of thinking are the creative forces driving the great work we strive to do each day. As we start to process these new ideas and perspectives from the sessions we’ve attended we’ll spend some time writing them down and sharing them with you. If you too attended Yow! 2015 Conference, enjoy today’s sessions and remember to program differently.

The State of iOS Dependency Management

Dependency management is a tricky problem to solve, even more so on iOS projects where we have to concern ourselves with things like code signing, embedded binaries, and so on. In recent years, a couple of solutions to this problem have presented themselves, each with different approaches and guiding philosophies, and each with their own tradeoffs to consider.

Manual Integration

There’s a lot of ways to integrate third party dependencies without using third-party tools. Most OSS projects use Git for source code management these days, so we can include those dependencies using Git submodules. Failing that, we can simply download the latest snapshot of a project and copy it into our project’s source tree.

With some basic knowledge of setting up Xcode projects, this solution actually gets us pretty far. It’s not the simplest or easiest approach, but it has its advantages. For one, not relying on third-party tools mean other team members can easily build your project without installing additional tools. This method is also the most resistant to breaking changes introduced in newer versions of Xcode, as there’s no waiting on a third-party to update their tools.

However we quickly run into issues as we add more dependencies to our project, especially when those themselves also have dependencies. Eventually we’re going to run into a case where two dependencies require two different versions of a library, and at that point we have to do a lot of messy manual resolution. Take the following example:

dependency_graph_conflict-1

Here we have a project that uses ReactiveCocoa and the (somewhat less well-known) ReactiveCocoaLayout library. In this situation, both our project and ReactiveCocoaLayout depend on different versions of ReactiveCocoa, so in a manually integrated project we have to do the hard work of resolving this conflict ourselves.

Beause of this, and various other problems, a new solution soon arrived.

CocoaPods

CocoaPods is a Ruby gem that handles the task of resolving dependencies for us, generating an Xcode project that builds those dependencies, and generating an Xcode workspace that lets us integrate them into our project. To include a dependency through CocoaPods, someone has to write a Podspec that describes how to build the framework, and what other dependencies it has. CocoaPods keeps a public repository of these Podspecs for open-source frameworks, and you can specify your own sources for private Pods.

If we wanted to recreate our example from the previous section, we’d create a Podfile in the root of our project with the following contents and then run pod install:

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '8.0'

pod 'ReactiveCocoa'
pod 'ReactiveCocoaLayout'

This approach is very much inspired by tools like RubyGems, and it has a lot of advantages. For one, it makes integrating dependencies extremely easy by taking over the duty of configuring your Xcode project for you. It also aids in discoverability, with CocoaPods.org providing a searchable repository of open-source pods, and CocoaDocs.org publishing easily searchable documentation.

It’s also widely adopted, with most frameworks offering official Podspecs, and those that don’t often having community-maintained specs that are kept relatively up to date. This popularity also means that when you do run into issues with CocoaPods, you’re rarely the first to and there’s likely StackOverflow answers already out there to solve your problem.

For authors of libraries, it can also reduce the maintainence burden of updating projects to build on new versions of Xcode, as CocoaPods handles the entire build process and updates whenever new Xcode versions are released. This does however mean that projects which also want to build without CocoaPods need to specify build steps in multiple places.

However, CocoaPods’ ease of use comes at the cost of quite a bit of complexity and a certain loss of flexibility in how you set up your project. For more experienced developers that feel they know how best to set up an Xcode project, the way CocoaPods wrests that control away from you can be frustrating. For library authors, it can also seem redundant to have to create a Podspec that mostly just reiterates information that’s already contained in Git and Xcode.

Finally, CocoaPods was initially designed to build static libraries and for a long time lacked any sort of support for frameworks. Initially, this was something only OS X developers really cared about as iOS didn’t have framework support prior to iOS 8. However, with iOS 8, not only were frameworks supported, but they became a requirement for using Apple’s new Swift programming language. Despite framework support eventually coming to CocoaPods, it has always felt like something of a second-class citizen.

So along came another solution.

Carthage

Carthage is described by its creators as “ruthlessly simple dependency management.” Its aim is to act as a simple coordinator between Git and Xcode, that picks compatible versions of dependencies, checks those dependencies out with Git, and then builds frameworks with Xcode.

To recreate our example project with the ‘standard’ Carthage setup, we would create a Cartfile at the root of our project with the following contents and then run carthage bootstrap:

github "ReactiveCocoa/ReactiveCocoaLayout"
github "ReactiveCocoa/ReactiveCocoa"

This would pull down our dependencies and build them as frameworks, but we would still need to manually integrate them. To do this we’d simply add references to them in our Xcode project and add them to the linked frameworks section of our target’s build settings.

Compared to CocoaPods, it’s a much simpler tool, though perhaps not as easy to use. Carthage does not integrate dependencies into your project in the same way CocoaPods does, instead leaving that task up to the developer. The upside of this is increased flexibility in how you integrate dependencies: whether by embedding the built frameworks, or by creating a workspace that includes all the cloned Xcode projects of your dependencies. In fact, Carthage can add all your dependencies as Git submodules, removing the need for other devs to install Carthage at all.

For library authors, supporting Carthage couldn’t be easier. You simply need to make an Xcode project that can build your framework, and then share the build schemes contained in that project. Compared to CocoaPods’ spec-based approach, this is refreshingly simple. There’s no need to submit a spec to any sort of central repository, instead users simply refer to a GitHub repo or Git URL in their Cartfile. This decentralised approach also simplifies the use of private frameworks and forks.

Carthage also tends to speed up builds in a few key ways. Firstly, frameworks are built once when you bootstrap or update your project, and then simply embedded on subsequent builds. Secondly, Carthage integrates with GitHub’s Realeases feature to download precompiled frameworks wherever possible.

Compared to CocoaPods, Carthage doesn’t have quite as much traction. There’s still the occasional project out there that doesn’t expose any shared build schemes, but this is usually simple to resolve with a quick pull request. Carthage also doesn’t help with discovering new libraries to use, your best bet there is to search GitHub.

Swift Package Manager

Announced as part of Swift going open-source, the Swift Package Manager, or swiftpm, marks the first time we’ve had something akin to an official dependency manager. It’s perhaps a little soon to say too much about swiftpm, it’s still very early and not officially released, but the current implementation and the package manager community proposal provide a lot of food for thought.

With swiftpm, developers create a Package.swift file in the root of their project that describes their project and its dependencies. swiftpm then resolves those dependencies based on git tags, pulls them down, and builds them as static libraries.

The Swift Package Manager is similar in certain aspects to both Carthage and CocoaPods. Like Carthage, it uses a decentralised approach to dependency resolution, and builds those dependencies as standalone binaries. Like CocoaPods, it uses specification files to define libraries and their dependencies — though this perhaps makes more sense for swiftpm, as it has to run on platforms where Xcode and by extension xcodebuild don’t exist.

As swiftpm builds static libraries as opposed to frameworks, there’s currently no way to include resources like XIBs or image files in a library. However, this is highlighted by the fairly in-depth package manager community proposal as something to add in future releases, alongside numerous other features that would make it more feasible for iOS projects.

In fact, looking at the proposals set forth in that document, it seems clear that the Swift Package Manager will eventually become the de-facto solution for dependency management on iOS projects. Just not today.

Which One Should You Use?

As with most things, the answer is ‘it depends’. If you want to easily bootstrap a new project, CocoaPods will take care of most of the work for you. If you want more flexibility in how you set up your project, or you want to more easily use private libraries that aren’t in a central repo, Carthage is probably the better option.

SVG Animations – Seriously Very Good

Imagine the entire web was just static. Filled in by nothing but words, information and meaningless black and white text. We would all spend a lot less time using the internet.

Thankfully we don’t. Instead the internet is a vibrant and expressive place where we immerse ourselves each day in an endless variety of unique experiences. Animation and movement are the visual language through which we catch our audience’s attention. We apply the finesse to our words and breathe life and meaning into our work.

Scalable Vector Graphics (SVGs) are a fantastic tool for every seasoned animator. Unlike traditional image formats they are built using vector paths that save into workable, writeable code. Their output is a complex XML-based structure consisting of tags like <path>, <circle>, <rect> and so forth. To these you can assign properties and masterfully take control of your SVG graphics.

SVGs are vector paths so they scale consistently without any nasty pixelation. They can be assigned fill colours, stroke colours and even border styles. Animating them is easy using CSS3 or SMIL (Synchronised Multimedia Integration Language) and brings movement and life to an otherwise static and lifeless shape.

Here’s one I prepared earlier to highlight the possibilities that can be achieved simply through the use of SVGs and animation. It is built entirely in HTML5/CSS3 using vector shapes from Vecteezy, which I then edited and exported using Sketch.

Note: Can’t be viewed in Firefox because the browser doesn’t provide support for some of this cool stuff and the playground just ends up looking weird 🙁

  1. Outlines
    An SVG’s stroke is the border of its shape. The stroke can have multiple properties such as weight and colour. Create a tracing effect using the dashed feature of a stroke and the dash-array, dash-offset properties. These indicate length of dash and dash starting point along the edge.The trick is instead of having many short dashes, we make the stroke-dasharray value longer than the border of the shape. Then we animate the stroke-dashoffset from the stroke-dasharray value down to 0. The longer the border of the path, the higher the initial values of stroke-dasharray and stroke-dashoffset needed.ferriswheel

    <span class="s4"><span class="s4">path {
     <span class="Apple-converted-space">    </span>stroke-dasharray: 3000;
     <span class="Apple-converted-space">    </span>stroke-dashoffset: 3000;
     <span class="Apple-converted-space">    </span>animation-name: draw;
     }
    
    </span></span>@keyframes draw {
     <span class="Apple-converted-space">    </span>to {
     <span class="Apple-converted-space">        </span>stroke-dashoffset: 0;
     <span class="Apple-converted-space">    </span>}
     }
  2. Fill
    Each path can be filled with colour – this feature being a major attractor to using the SVG format. Fill can be given an opacity between 0 (transparent) and 1 (opaque). This allows us to animate from no-fill to fill.swingsNote: Elements which overlap one another (eg. the axis on the carousel above) don’t want the lines of any paths behind. To avoid this all elements first get filled in with the document’s background colour and only after with a solid colour. This is achieved by chaining three animations together.

    <span class="s4">animation-name: draw, fillBackground, fill;
    </span>

    As for the colour randomness on the page: this is a little Sass mixing I built myself. It takes an input colour and returns a set of random colours within a certain range. You can check out Sass Colour Range on Github.

  3. Timing
    Originally when I built the playground, each section was dealt with individually – building it and then filling it in. Different sections were shown using Javascript’s timeout, changing the display property of each element from none, triggering the animation to start. The end result was messy so I instead used CSS’s animation-delay property to trigger specific start times for each animation. I then created an ‘end’ variable used to trigger the fill for every part of the playground simultaneously.

    <span class="s4"><span class="s4">$end-fill: 10s;
    
    </span></span>.carousel
     {
     <span class="Apple-converted-space">    </span>animation-name: draw, fill;
     <span class="Apple-converted-space">    </span>animation-delay: 0s, $end-fill;
     }
    
    .swings
     {
     <span class="Apple-converted-space">    </span>animation-name: draw, fill;
     <span class="Apple-converted-space">    </span>animation-delay: 4s, $end-fill;
     }

    Each animation can also have a timing function applied to it, changing the rate of change throughout its duration. Most elements are animating with a linear timing in order to create a more uniform and monotonous look. However certain elements have subtle changes.

    One such is the swing, which uses an ease-in-out function to make the swing seem like it’s hovering at the peak of each swing before gradually speeding towards the trough.

    <span class="s4">animation-timing-function: ease-in-out;</span>
    
  4. Rotation
    There is lots of rotation going on in the playground, each to varying degrees. The carousel and each carriage rotates a full 360°. The seesaw and swings move slightly less. Rotation of the swings is limited to the X-Axis so that it appears to swing back and forth rather than in a circle. Because the swings are drawn hanging down whereas their rotation moves from -33° to 33°, an animation has been included to first pull the swing back. This animation is called only once using animation-iteration-count, while the swinging motion is on an infinite loop.

    <span class="s4">animation-name: swingback, swing;</span>
    <span class="s4">animation-iteration-count: 1, infinite;
    animation-delay: 0s, 1.1s; </span>
    
  5. Bouncing
    There are two parts to the bouncing ducks – the spring and the duck itself. While it looks like a simple up and down motion, these two parts are distinctly different. The spring has to collapse into itself while the duck stays the same shape and doesn’t scale. Therefore the spring has its own animation using scale-Y, but the duck itself uses translate-Y to move up and down. A minor annoyance – scale and translate use different methods of determining distance (translate calculates by pixels, scale by a part of 1).ducks

    <span class="s4"><span class="s4">@keyframes spring {
     <span class="Apple-converted-space">    </span>from
     <span class="Apple-converted-space">    </span>{
     <span class="Apple-converted-space">        </span>transform: scaleY(1);
     <span class="Apple-converted-space">    </span>}
     <span class="Apple-converted-space">    </span>to
     <span class="Apple-converted-space">    </span>{
     <span class="Apple-converted-space">        </span>transform: scaleY(0.8);
     <span class="Apple-converted-space">    </span>}
     }
    
    </span></span>@keyframes duck {
     <span class="Apple-converted-space">    </span>from
     <span class="Apple-converted-space">    </span>{
     <span class="Apple-converted-space">        </span>transform: translateY(0);
     <span class="Apple-converted-space">    </span>}
     <span class="Apple-converted-space">    </span>to
     <span class="Apple-converted-space">    </span>{
     <span class="Apple-converted-space">        </span>transform: translateY(10px);
     <span class="Apple-converted-space">    </span>}
     }
  6. Sliding
    CSS doesn’t have a great deal of support for motion paths – this is still an experimental property in Chrome only. Instead of using CSS to achieve the motion of the ball sliding down the slide, I’ve used SMIL’s animationMotion property as a child node of the circle path. Path of motion is determined using the path attribute on animateMotion.

    <span class="s4">&lt;animateMotion
        path="M197.125,297.636719 C197.125,297.636719 319.5625,276.726563 385.351562,333.406251 C451.140625,390.08594 452.066406,558.484368 502.964844,571.152331 C553.863281,583.820293 634.578125,567.597656 677.324219,479.175775"
        dur="2s" begin="16s" repeatCount="indefinite"
        calcMode="spline" keyTimes="0;1"
        keySplines="0.755, 0.05, 0.855, 0.8"/&gt;
    </span>

    Much like CSS animations, SMIL’s animateMotion takes specifications for animation-duration(dur), animation-delay (begin), and animation-iteration-count (repeatCount).

    In order to create an animation-timing-function three properties are needed – calcMode, keyTimes and keySplines. ‘Spline’ is the SMIL keyword to indicate a custom bezier which is then defined in keySplines. The keyTimes attribute is also required to determine the duration of the function. This timing function creates the slow-to-fast sliding motion as the ball slips down the slide.

    slide

    Both CSS and SMIL animations don’t allow for a delay between repeats of an animation. Therefore preventing the ball sliding continuously down the slide without a break requires an additional CSS animation. This animation runs for 5x the length of the ball rolling animation, and then shows the ball for 20% of that time. With a 2-second animation on the ball there is then an 8 second gap before the ball is shown rolling again. The ball is actually continually rolling the entire time, just not visibly to the viewer.

    <span class="s2">.ball {
     <span class="Apple-converted-space">    </span>animation: slideHide 10s linear infinite;
     }
    
     @keyframes slideHide {
     <span class="Apple-converted-space">    </span>1%, 20% {
     <span class="Apple-converted-space">        </span>opacity: 1;
     <span class="Apple-converted-space">    </span>}
     <span class="Apple-converted-space">    </span>21%, 100% {
     <span class="Apple-converted-space">        </span>opacity: 0;
     <span class="Apple-converted-space">    </span>}
     }</span>

CSS and SVGs are amazingly cool and incredibly powerful. With an underwhelmingly few lines of code you can break away from the cold, lifeless and even Orwellian nightmare of a motionless information super highway.

Despite these techniques being capable of producing drastically complex animations they’re also a fantastic way to apply polish to the tiniest of details throughout your work. You can sweat the details, without sweating the details and build an experience that your users will absolutely love to use. Look out for more of these neat little animations throughout our blog posts and across our website!

Bilue’s Swift Style Guide

 

 

Today we’re open-sourcing our internal Swift style guide. This is something we’ve been working on in an attempt to codify best practices and improve codebase consistency within the company, and it’s something we’d love to have the Swift community’s feedback on.

The guide is a work in progress that’s intended to evolve as we undertake more and more Swift projects. We’re still in the early days of Swift development, and what constitutes ‘idiomatic Swift’ is still in a state of flux. As both we at Bilue and the community at large decide on new best practices in Swift development, we want to keep our guide up to date with those decisions.

Why have a swift style guide?

As the number of people working on a codebase increases, you’re more and more likely to encounter developers with differing opinions on how to write code. This can be about anything from tabs vs. spaces to things like when it’s appropriate to use computed properties.

These differences in opinion can lead to long, drawn out debates over aesthetics during code reviews. Even once a consensus is reached, it’s rarely enforced across the codebase. This approach also means the same decisions have to be made for every new project, and there’s very little consistency between the projects themselves.

With a style guide, these decisions can be made once, recorded in a central repository, and then referred to by all of the projects within our company. When a debate over style comes up during a code review, developers can simply refer back to the style guide. If a developer needs to move from one project to another, they can be assured that they won’t have to learn a whole host of new conventions and habits.

By codifying best practices in this way we improve consistency, reduce debate, and raise the general quality of all of our codebases.

How we built our style guide

Rather than start our guide from scratch, we’ve decided to fork GitHub’s style guide and modify it for our own use. This has saved us a great deal of groundwork and GitHub’s guide makes for a great starting point. We’ve made some minor changes to the original content of that guide, but so far most of our changes have been additive.

Our guide is broken up into a series of guidelines, each with a brief summary, a more detailed example to show how that pattern would be implemented, and a rationale that explains the reasoning behind that guideline. These guidelines are intended to encompass patterns that can be applied across any codebase to improve the clarity and decrease the likelihood of programmer errors.

New guidelines are added by opening a pull request on our core repo, and we generally spend some time refining new guidelines either in PR comments, or through discussion in our #swift Slack channel.

Our Swift style guide is still in its early days, but already it has sparked a lot of valuable discussion within our company. It has started pushing us towards a more consistent, company-wide coding style that makes it easier to move between projects, and is raising the baseline level of quality across each of our codebases.

If you’re looking to implement a style guide at your own company, or within an open-source organisation, our guide is under a liberal Creative Commons license and we’re accepting contributions.

logo-outline

Contact Info

Sydney
Level 1 6 Bridge Street, Sydney, NSW, 2000

Melbourne
Level 1 520 Bourke Street, Melbourne, VIC, 3000

Copyright 2018 Bilue Pty Ltd ©  All Rights Reserved