Under The BridgeUnder The Bridge

Musings
Getting On Board

So how bad is the retention on mobile apps these days? Pretty bad, you probably guessed; but this bad?

How to Make Your Users Open Your App Again

According to studies, one in four mobile apps is abandoned after a single use. So apart from focusing on first impressions and engaging users during the first launch you should think about how to keep bringing them back over time… Ask this question before you start building anything: How can I ensure that users will keep coming back?

  1. Start a drip email campaign during onboarding.
  2. Update users with their results by email.
  3. Use personalized notifications: push, SMS, chat bots.
  4. Leverage of social mechanics.

Read the whole thing — the infographics are great. For more perspective on long term retention, check out

Your User Onboarding Flow Is Too Shortsighted

Yes, the initial goal of user onboarding is to teach someone how to use your app. But if all a user has done is learned the ropes of one feature, the job isn’t done. Good user retention means going far beyond basic user onboarding. Retention has many stages, and if you want to keep your retention numbers high, you need to think about user onboarding past the first day…

For some specific tips, check out

User Onboarding Best Practices

It’s easy to make onboarding exclusively about the product—logistics, how-tos, and the nitty-gritty details about your product. But your onboarding still needs to be all about the customer. That starts by creating a seamless user experience centered around buyer personas and jobs-to-be-done to align the promise of your product with the onboarding experience…

A common theme you’ll notice here is exposing only appropriate functionality. Why, a “design pattern”, we could call that idea:

Design Patterns: Progressive Disclosure for Mobile Apps

Progressive disclosure is a strategy for managing information complexity. When you use progressive disclosure, you show only the information necessary at that point in the interaction. And you display more advanced functionalities of the app interface as the user interacts with it…

A most important aspect of that progressive disclosure is to never ask the user for a permission when there’s any chance they might refuse it, as they probably will if the benefit is not obvious and immediate. Good advice here:

Mobile UX Design: The Right Ways to Ask Users for Permissions

When it comes to requesting permission, the worst thing an app can do is to bombard users with permission requests without any notice or explanation. Both asking your users for permission too early or for too many things at once are common mistakes. And yet, many apps still do that…

So there’s plenty of food for thought. Some more links with gritty details you may find useful:

How Zendesk Onboards New Users is a neat teardown — check the rest at UserOnboard too.

UI Interactions “The best UI Interactions for your inspiration, every day.” — onboarding specifically

iOS Onboarding without Signup Screens

Cross-Platform Onboarding Without Signup Screens

Onboard is a particularly clean and simple framework for quickly adding onboard screens.

WWDC16 TL;DR

So that was a bit of a relief of a WWDC this year, eh? Generally in line with the more sober predictions, no massive upheavals anywhere, nice steady evolution and new integration points in all sorts of interesting places! Even keep 32-bit for another year, only the clearly underpowered A5 devices got dropped this time around. Videos are pouring into WWDC.app for your viewing, and while you try to block out the time to watch them all and join the discussions at WWDC16 on Github, which looks like a neat idea:

The purpose of this project is to create a place where the exchange of opinions about WWDC16 sessions can take place. For each video there is a corresponding GitHub issue that serves as a place for a discussion regarding a specific video. Enjoy!

here’s some links to get you up to speed:

Andy Bargh’s newsletter this week, WWDC 2016 Initial Impressions quickly hit the high points for developers.

Op-Ed on WWDC 2016: What We Got, and What We’re Still Missing is a solid evaluation of the tentpole user updates this time around.

iOS 10 Tidbits: Individual Read Receipts, Wake Alarm, Music Storage Optimization, and More is a good hub for discussions of the subtler changes in iOS 10 you might have overlooked so far.

But the immediate concern for most of you — well, after Swift 3.0 Preview 1 Released!, but that we knew about already — is most likely Xcode 8, which you’ll be pleased to hear looks like a pretty sweet upgrade all around:

What’s New in Xcode

Xcode 8.0 beta Release Notes

We particularly like that it’ll support both Swift 2.3 and 3 to ease the transition there.

and get this, Travis-CI already supports the Xcode 8 Beta initial release! Nice job, guys.

And boo! They killed Alcatraz, but yay! for Xcode Extensions — A brave new world

So that’s Xcode. For API changes, start out with

What’s new in iOS 10 for Developers

and move on to the various backgrounders from the mothership:

Foundation Release Notes for OS X v10.12 and iOS 10

What’s New in Core Data in OS X v10.12, iOS 10.0, tvOS 10.0, and watchOS 3.0

If you mobile:

If you desktop:

If you Safari, watch, tv, or whatever, run down the rest of the release notes list:

In other news, the App Store Review Guidelines were completely rewritten; check out App Review Guidelines: The Comic Book. Yes, the comic book. And keep an eye on AppStoreReviewGuidelinesHistory.com for updates as the new format gets digested.

The Human Interface Guidelines are completely rewritten as well — bigger fonts! obvious buttons! cards! — and the API Reference has a sharp new look and organization too. The Apple documentation beavers have certainly been busy!

And if you have a bit more time, go poke around Guides and Sample Code some more and check out all the new code goodies added this week.

What, yet more time? Write an article about some particularly nifty piece of new kit. Here’s some suggestions for starters:

And for anything we missed here, check out Michael Tsai’s WWDC 2016 Links and BNR’s WWDC 2016: Developer Reading List!

UPDATES:

A quick list of overlooked announcements at WWDC’16

Big, bold, and beautiful: Apple’s design language is changing in iOS 10

iOS 10 UI kit from puzzles.design

WWDC 2016 Viewing Guide

wwdc-downloader: “WWDC 2016 video downloader script written in Swift.”

Ole Begemann’s WWDC 2016 Retrospective

The Future Is Subscribed

In case you’ve been under a rock the last couple days, we just had the biggest upending of the App Store since In-App Purchases:

Wow! So that’s the big news for this WWDC, eh? Er, actually…

“…but frankly, we’ve got a busy enough keynote that we decided we’re not going to cover those in the keynote.”

O_o Seriously? What on earth are they going to announce next week, the Second Coming and the Millennial Kingdom? Well, while we wait, the discussion rages about just how much difference this will make to indie development. To get you up to speed:

2013’s Adobe’s Subscription Model & Why Platform Owners Should Care is a great exposition of the mutual value proposition of subscriptions.

App Store 2.0 — will it change things?

We, as a company, have been on the App Store since the very first day (YES) of its existence and have over 50 million downloads worldwide. Readdle managed to build a sustainable business creating great productivity apps that people were happy to pay for.

But 2.5 years ago we saw a big shift and decline on the App Store, that hit all premium priced apps with one time purchase model.

So here are some new things that we know and our reaction to them…

Developers can gate apps behind subscriptions, within limits, Apple says: Let the redesigning of your app as a service begin!

How we made an App Store subscription success

As the co-creator of Zombies, Run!, a fitness app that transitioned to a subscription model just over one year ago, I couldn’t be more delighted. 🍾 + 🎉 all round, folks.

Before all that 🍾 + 🎉 though, I want to share the lessons we learned in the past year — a terrifying, exciting, and ultimately very successful year…

And as usual, Michael Tsai has a great roundup on Pre-WWDC App Store Changes if you feel like getting deeper into the discussions. If not, pleasant dreams waiting for that “busy enough” keynote Monday. Speculation is rampant as usual, but nobody seems to have any real clue, so let’s go with the prediction we like best:

One more nail in the coffin of the Wintel ecosystem coming from Apple

So if they do announce the next-gen PowerBook ships with ARM macOS 12 this fall … you heard it here first!

Standing on Guard

Here’s a question for discussion that will bring shivers of shared pain to the Swift programmer, no doubt:

Sneaky Swift Tricks: The fake Boolean

Moshe Berman writes, “If I’ve got a bunch of chained guard let statements, how can I diagnose which condition failed, short of breaking apart my guard let into multiple statements? Given this example:

How can I tell which of the 4 let statements was the one that failed and invoked the else block?”

How, indeed? TL;DR There isn’t a really good way. Bah.

However, besides the linked article there’s an active discussion at the Stack Overflow question, and we’d suggest checking on them to see if anything that suits you has shown up, and if not pick up some more Swifty tricks along the way. The one we like the best so far is this gist from AfricanSwift defing the =∅ (null check) debug operator:

If you have a better suggestion, that Stack Overflow question is waiting!

State of JSON Address

So this weekend we’re taking a look at a weather API service that provides data in JSON. So we’re looking around for new and/or notable and/or actively maintained developments in the JSON + Swift world. Always enjoy a good treasure hunt, don’t you?

Particularly nifty thing we stumbled across is JSONExport, which isn’t that new but was to us. If it’s new to you too, check it out:

JSONExport is a desktop application for Mac OS X written in Swift. Using JSONExport you will be able to:

  • Convert any valid JSON object to a class of one of the currently supported languages.
  • Preview the generated content before saving it.
  • Include constructors only, utility methods only, both or none.
  • Change the root class name.
  • Set a class name prefix for the generated classes.
  • Set package name for Java files.

And you have a baker’s dozen options of output for that:

  1. Java for Android.
  2. Java for Android – to use with Realm.
  3. Swift Classes.
  4. Swift Classes – To use with SwiftyJSON library.
  5. Swift Classes – To use with Realm.
  6. Swift – Core Data.
  7. Swift Structures.
  8. Swift – Struct – Gloss
  9. Objective-C – iOS.
  10. Objective-C – Mac.
  11. Objective-C – Core Data.
  12. Objective-C – To use with Realm.
  13. Swift – Mappable [not included in README — ed.]

Convenient! Or perhaps you’d like to handle Core Data serialization more directly? Here’s an option:

Groot: “From JSON to Core Data and back.”

Groot provides a simple way of serializing Core Data object graphs from or into JSON.

Groot uses annotations in the Core Data model to perform the serialization and provides the following features:

  1. Attribute and relationship mapping to JSON key paths.
  2. Value transformation using named NSValueTransformer objects.
  3. Object graph preservation.
  4. Support for entity inheritance

Or here’s another option:

Sync: “ Modern Swift JSON synchronization to Core Data.”

Sync eases your everyday job of parsing a JSON response and getting it into Core Data. It uses a convention-over-configuration paradigm to facilitate your workflow.

  • Automatic mapping of CamelCase or snake_case JSON into Core Data
  • Handles operations in safe background threads
  • Thread-safe saving, we handle retrieving and storing objects in the right threads
  • Diffing of changes, updated, inserted and deleted objects (which are automatically purged for you)
  • Auto-mapping of relationships (one-to-one, one-to-many and many-to-many)
  • Smart-updates, only updates your NSManagedObjects if the server values are different (useful when using NSFetchedResultsController delegates)
  • Uniquing, Core Data does this based on objectIDs, we use your primary key (such as id) for this
  • NSOperation subclass, any Sync process can be queued and cancelled at any time!

If you’re just looking for JSON parsing into objects without the Core Data integration, there’s … a surprising number of helper options these days:

… and a veritable plethora of others. If we and all those collections missed your favorite, let us know!

Some discussions to help you decide which of these if any suits your particular use case best:

How I deal with JSON in Swift

Everything You Need to Know About JSONJoy, SwiftyJSON & OCMapper

Swift JSON Shoot-Out

The state of JSON parsing in Swift – Part 1

Enjoy your paradox of choice!

UPDATES:

Here’s another that generates SwiftyJSON/ObjectMapper friendly classes: SwiftyJSONAccelerator

Tip: Swift Common Initializer Pattern

Here’s a handy tip for reducing duplication and/or frustration with your initializers:

Common Initializer Patterns in Swift

Swift has a very well thought-out initializer system in place. With options such as designated and convenience initializers, one must ensure all properties have values since the compiler will make sure of it. Take a look at my other post for more details.

… Your first thought may be: why not wrap it in a function and call the function from both initializers. Nope. Can’t do that because you cannot reference “self” for the method call before calling “super.init“, and you can’t call the method after initialization either until you’ve initialized all properties – catch 22:

So you end up either tedious and violating DRY, or using var/lazy and violating immutability, yes, we find that niggling on a fairly regular basis. Skipping past the narrative (follow the link if you wish) Here Is The Solution:

https://gist.github.com/alexcurylo/db743df00a6d27758b45c6537b26a800

Wow, nice! Solves the redundant code problem while still abiding by the initialization rules. It’s using a static function to initialize the properties, which indeed can be called before the class is initialized (since it’s static and not using self).

Secondly, it’s returning a tuple to initialize multiple properties at once. That’s cool too! And for the sugar on top, it’s using a “typealias” like “My” or “I” to keep the static calls short.

We like it! Very Swifty feeling, isn’t it?

h/t: This Week In Swift!

For another interesting initialization pattern, check out

Swift: Configuring a Constant Using Shorthand Argument Names

It’s a common pattern in Swift (and a really nice one!) to configure constants right when they are initialized in a closure vs later on in a viewDidLoad or another such method … ’ve always found it kind of awkward to name another UIView in the closure. Now there is a “purpleView” and a “view”. Should “view” actually be named “purpleView” also? I haven’t figured out a good solution for the naming problem here. So I was super excited to see the tweet that uses $0 instead of bothering to name the variable!

Not quite sure whether we actually prefer this, but it is more concise. Also check out the Configurable extension from the comments!

Follow The Script

Between writing our client apps in Swift and looking forward to writing our server apps in Swift, we tend to overlook that Swift can be used as a scripting language as well — seriously, is there anything it can’t do? — so here’s how you do that using Xcode:

A Beginner’s Guide to Scripting in Swift

First, you’ll need to start with a new Xcode OS X Command Line Tool Application … The cool part here is that you can even import frameworks like Foundation. Anything you can do with Foundation, you can put into a script — this includes File I/O, string manipulation, and more … Your script can even accept arguments. Just append whatever you want after your execution command to add your arguments like a regular script…

Scripting is a powerful asset and a useful tool in any programmer’s tool belt. For many iOS Devs, Swift or Objective-C are the only languages they know. If they know Swift, then there is no need to learn Python or another scripting language when writing simple scripts for any automation process.

End-to-end development and deployment with nothing but Swift? Shiny!

Another introduction here:

Scripting in Swift

A shell script is perhaps the most popular command-line scripting language, particularly in the mobile development world. To test the viability of scripting in Swift, we’ll write our markdown converter first as a shell script and then compose a Swift version. We’ll then do a quick comparison of the pros and cons of each script…

And one more example from @ayanonagon (and Swift Scripting talk here):

Swift Scripting By Example: Generating Acknowledgements For CocoaPods & Carthage Dependencies

We started using both CocoaPods and Carthage to manage our dependencies, and we wanted to add a nice little view in our app that shows a list of open-source acknowledgements and licenses. We have around 20 dependencies, and the thought of adding the acknowledgements manually sounded tedious…

Indeed it is. Well, that’s definitely our first experiment in integrating Swift scripts into our production process, then!

UPDATES:

Swift Scripting Redux: Localization

Running The Swift 3.0 Migrator On A Standalone Swift File

Third Time Swifty

So you’ve no doubt heard there’s a new Swift coming, and asked yourself

What’s new in Swift 3.0?

Swift 3.0 is changing pretty much everything, and your code will almost certainly refuse to build until you make the necessary changes. Seriously, if you thought the jump from Swift 1.2 to 2.0 was big, you ain’t seen nothing yet.

Didn’t we go through this already … why yes. Yes, we did.

In this article I’m going to explain some of the most important changes with as many code examples as I can, and hopefully this will give you some chance to be prepared to update your code when Swift 3.0 goes final. There are many more changes than the ones listed below, but the changes below are the ones that are most likely to hit you…

It’s like the Guaranteed Swift Programmer Employment Act! But don’t get too worked up, we completely agree with the conclusion of that article:

It’s easy to read these changes, some of which are tiny but introduce massive breakage, and imagine that Apple’s Swift engineers are just out to make our lives harder. However, the truth is that they are working hard to make sure Swift is as easy to learn, easy to use, and fast as possible, which are three very different priorities.

In particular, I have been struck by how committed the Apple team are to ensuring their changes are discussed and agreed in the open, as part of the Swift Evolution community effort. Every change above went through extensive community discussion before being agreed for Swift 3.0, which is an incredible thing to behold.

You can get involved and help shape these changes going forward: they are keen to hear ideas from a wide range of users, and it means the future of Swift really is in your hands.

So yes. If you’re writing or maintaining Swift code — and who isn’t? — we MOST strongly recommend you read this article thoroughly, and soon. Even better, get an early jump with How to install Swift 3 today and this sample project for instance. Although we’d figure that a Swift 3 running Xcode is pretty likely to show up first day of WWDC 2016, so no need to get too worked up there.

Speaking of the evolution of Swift, there’s also been a great deal of heartfelt concern voiced recently about a) ABI compatibility being missed in 3.0, and b) Swift never getting @objc on its cross-platform incarnations as the current plans lack, and what that lack of runtime dynamism means. (Spoiler: Horrible things.) Around here, we’re just fine with a) taking as long as it takes to get right, and with b) we’re pretty sanguine that something functional (geddit?) which fits the Tao of Swift will show up to address common use cases; but others find it a far more pressing concern. Great round up by Michael Tsai:

Dynamic Swift

Read that if you need to get involved in a good internet fight! Or even if you’re not, there’s still a lot of good conceptual discussion there, if you’ve got some time being familiar with the debate is worthwhile we’d say.

And speaking of being familiar with the debate, prepare yourself for Swift advocacy by checking out

Why big apps aren’t moving to Swift (Yet)

I strongly believe Swift is the future of iOS development. It’s only a matter of when, and the blocker is the breakneck speed it evolves. For smaller apps, Swift is good enough. For big apps, it’s at least a year away…

Let’s all see what we can do to push that forward!

UPDATES:

Wil Shipley smacks down the griefers in Pimp My Code, Book 2: Swift and Dynamism

How To Install New Swift Versions in Xcode

@ayanonagon’s Favorite Swift 3.0 Features

Ole Begemann’s Swift 3

littlebitesofcocoa.com #243: The Great Swift 3 Rename 🐤

Tip: Adding Fields To Interface Builder

Here’s a neat trick that might have never occurred to you — it didn’t to us, anyways:

How to use Xcode to set a text field’s maximum length, Visual Studio-style

There’s the [Visual Studio] GUI builder way…

  1. Select the text box.
  2. Set its MaxLength property in the Properties pane.

… when developing Objective-C and Swift applications in Xcode:

There isn’t a GUI builder way — just a code way, and it’s a little more work than it needs to be…

… That’s a lot of work. Isn’t there a way we can get a “max length” property for text fields, like the .NET people?

And why, yes. Yes, there is! The trick is simply to create an @IBInspectable extension on UITextField:

Swift extensions let you add new functionality to existing classes, structs, enumerations, and protocols. We’re using an extension to UITextField to add two things:

maxLength, a property that lets the programmer set and get the maximum length of a text field, and

limitLength, a method called whenever the contents of a text field are changed, and limits the number of characters in that text field.

Look over the rest of the article and download the sample project for an explanation of the techniques used here. Mighty handy for extending built-in types if you like doing your interface work graphically in Interface Builder … and who doesn’t?

Fire Up The Base

In case you’ve been floundering about what to do service side since Parse dropped the BaaS, here’s something you’ll want to take a look at — Google has seriously levelled up Firebase with unification and new services:

FireBaseServices.png

Firebase is expanding to become a unified app platform for Android, iOS and mobile web development. We’re adding new tools to help you develop faster, improve app quality, acquire and engage users, and monetize apps. On top of this, we’re launching a brand new analytics product that ties everything together, all while staying true to the guiding principles we’ve had from the beginning:

  • Developer experience matters. Ease-of-use, good documentation, and intuitive APIs make developers happy.
  • Work across platforms. We’ll support you whether you’re building for iOS, Web, or Android.
  • Integrate where possible. Firebase has one SDK, one console, and one place to go for documentation and support…

That’s a lot of features there, with free to minimal pricing until you’re scaled up looks like.

Particularly interesting is that they’ve put at the centre there this new analytics service,

At the heart of Firebase is Firebase Analytics, a free and unlimited analytics solution. Analytics integrates across Firebase features and provides you with unlimited reporting for up to 500 distinct events that you can define using the Firebase SDK. Firebase Analytics reports help you understand clearly how your users behave, which enables you to make informed decisions regarding app marketing and performance optimizations…

Custom audiences can be defined in the Firebase console based on device data, custom events, or user properties. These audiences can be used with other Firebase features when targeting new features or notifications.…

As it happens, we’d just been planning to get around to picking an analytics platform for the next project, as it’s been a hella long time since we last surveyed that space, or even updated with notes on the general consensus:

If marketers are going to be using analytics tools, Mixpanel or Localytics. If developers want data to play with, Flurry.

Since then, Flurry was absorbed into Yahoo Mobile Developer Suite, Localytics and Mixpanel appear to be doing fine although now we have actually accurate marketing analytics from Apple,

App Analytics is Apple’s very own analytics platform. It lives right inside of iTunes Connect. Announced at the WWDC in summer 2014, it launched finally in spring 2015 and just recently added support for tvOS apps. One might say just “another” analytics platform like free solutions from Flurry/Yahoo Mobile, Google or Facebook, but App Analytics finally provides reliable data nobody else can (Spoiler: App Store impressions, referring websites, attribution)

You should read all the rest if you aren’t familiar with it, but since it requires no technical implementation there’s no support decision to be made there so we can move on. Let’s check a couple curated collections:

Apptamin’s App Analytics Tools Round-up

iOS Dev Tools’ Analytics section

awesome-ios’ Analytics section

Well, clearly if you have trouble reaching a decision, ARAnalytics is for you:

ARAnalytics is an analytics abstraction library offering a sane API for tracking events and user data. It currently supports on iOS: Mixpanel, Localytics, Flurry, GoogleAnalytics, KISSmetrics, Crittercism, Crashlytics, Fabric, Bugsnag, Countly, Helpshift, Tapstream, NewRelic, Amplitude, HockeyApp, HockeyAppLib, ParseAnalytics, HeapAnalytics, Chartbeat, UMengAnalytics, Librato, Segmentio, Swrve, YandexMobileMetrica, Adjust, AppsFlyer, Branch, Snowplow, Sentry, Intercom, Keen, Adobe and MobileAppTracker/Tune…

And if you’d prefer to just follow the herd, looks like they’re heading for Twitter these days:

Answers Named #1 in Mobile Analytics for iOS

Back in May, Answers was ranked as #2 on iOS and #3 on Android in the mobile analytics space by SourceDNA, the world’s largest database of mobile app intelligence. Since then, we’ve been building out new features like Answers Events, which helps you track specific actions and events in real time, to better understand how users are behaving within your app.

Today, we’re thrilled to tell you that Answers has now been named the #1 most implemented mobile analytics SDK on iOS — just five months after it was named #2!

So no lack of innovation in that space, definitely. If you decide to jump on the new Firebase bandwagon, be sure to let us know how it goes for you!