Under The BridgeUnder The Bridge

Musings
Audit Those Version Checks!

Here’s an extra-special class of problem to watch out for in your iOS 10 testing: Brain-dead version checking. Remember the gales of laughter we all had at those silly, silly Windows programmers when they had to skip Windows 9 because of Windows 95 version checks? Well, this is pretty embarrassing, but apparently there’s a good number of us that aren’t any smarter than Windows programmers:

That’s just painful. But there can’t be that many instances of that out there, right? Right? Let’s check this fine article:

Efficient iOS Version Checking

A GitHub search shows that there are over 8000 results calling substringToIndex:1. All of that code will break with iOS 10. It will instead assume iOS 1, where the only apps that existed were jailbreak apps.

Oh, dear. Well, we know that of course you personally, Dear Reader, would never do anything like that … but we very strongly indeed suggest that you do as full an audit as possible of any codebase you expect to be running on iOS 10 to make sure the Evil Code Elves didn’t sneak anything like that in behind your back.

Read the article for more discussion than you probably need of various ways to address this problem. We say “probably” because you’re all programming in Swift now, aren’t you? so you can just use Swift’s #available operator if you really need to check a specific System version. If you’re not, hey the article dives into its implementation, so copy what you need!

PSA: File Those Radars

Yep, you’ve heard this before if you’ve been around a while, but it can’t be repeated too often:

File radars early and often: The importance of bug reporting

There’s a longstanding debate in the Apple developer community over the value of filing bugs through the Apple Bug Reporter system, commonly known as Radar. Some believe it’s invaluable, the only way to give Apple the feedback they need to ensure bugs get fixed. Others believe it’s valueless, a black hole from which little action or satisfaction ever escapes…

Right now, though, right when the first betas hit, there’s some breathing room. And that’s where radar comes in. If someone at Apple wants to get a bug fixed, they need a radar to point to. If they want to get a bug fixed as a matter of priority, they need a lot of radars to point to. Otherwise they simply won’t be given the time to do it.

That’s also why it’s meaningless whether or not someone else has already found and filed the same bug. First, if everyone assumed that, no bugs would be filed. Second, duplicate filings can be considered like “up votes” that, in volume, shift priority more than they do individually…

So, if you are a developer working on iOS 10, macOS Sierra, watchOS 3, or tvOS 10 apps and you’re encountering bugs, please consider filing radars early and filing often.

Even if you never hear back about them, there are people working on those operating systems right now, people who want to make great software and provide for great experiences — people who will deeply appreciate the radars you file, and your having their backs.

Worth reading it all, but that’s the main points — even though Radar is pretty much useless as a communication tool, it’s the only way to contribute to internal priorities there is. For instance, consider the suggestions in this excellent article on that new Apple File System:

Although APFS does checksum metadata blocks it does not do anything to provide resilience for data blocks. That is a huge omission in a modern filesystem, a point I tried to politely but forcefully make in the File System Lab directly to a responsible engineer. I got the feeling that the APFS team is divided on the necessity of this feature and some people on the team would appreciate some ammo to help win the argument internally. I would encourage anyone who agrees to file radars ASAP requesting this feature…

More importantly filing radars is effectively a vote for a feature and the APFS team is listening. You will never have a greater impact on APFS than going to bugreporter.apple.com and filing radars requesting missing features like parity on data blocks or copying snapshots.

Update: Here is my radar on Data Block Integrity if you want to duplicate it. Even if you copy-paste it your separate report counts as another “vote”.

And if you’re not convinced yet that it’s worthwhile to put in this effort … at least dupe @steipete’s Expose verify state

Steps to Reproduce:

Write a radar

Get it back for review

Observe that it’s simply “Open” no matter the internal state

Expected Results:

An additional exposed field that shows if there have been significant changes.

Actual Results:

We need to rely on guesswork or subtle language changes (which are inconsistent though) to try to guess if there has been progress.

to help out the people who do all the work here!

APPENDUM:

Hmmm — looks like the wide consensus that filing duplicate Radars is a valid way to indicate support may be incorrect:

https://twitter.com/ashtondev/status/750263229926940673

If you happen to have any informed perspective on this issue, please share!

UPDATES:

Writing good bug reports

Have a Simulator problem? File That Radar, then send it to Russ Bishop!

Brisk: “A macOS app for submitting radars”

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.

UPDATES:

OnboardingKit: “A simple and interactive framework for making iOS onboarding experience easy and fun!”

How to perfect your mobile app’s login screen

Onboard: “An iOS framework to easily create a beautiful and engaging onboarding experience with only a few lines of code.”

How Great User Onboarding Helps These Messaging Apps Grow to 1 Billion Users

SwiftyOnboard: “A swifty iOS framework that allows developers to create beautiful onboarding experiences.”

Tutti: “is a Swift library for creating iOS app tutorials and onboarding experiences.”

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

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!

UPDATES:

In-App Purchases: Auto-Renewable Subscriptions Tutorial

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

Alembic: “Functional JSON parsing, mapping to objects, and serialize to JSON.”

Atlas: “An extremely easy-to-use and lightweight JSON mapping library for iOS and tvOS written in Swift.”

Working with JSON in Swift

JSONShootout: “Compare several Swift JSON mappers.”

Rethinking Routers in Swift using Protocol Oriented Programming — Part 1

API Endpoint Testing with Postman

Simulate APIs and Backend Server with New Postman Mock Server Feature

Paw 2 – The Missing HTTP & REST API Tester For Mac

Insomnia Is Now Open Source

Dynamic UI Testing HTTP Mocking

When JSONDecoder meets the real world, things get ugly…

Swift Tip: Networking with Codable

Typesafe API calls in Swift: Generating Alamofire Handlers with quicktype

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

Command Line Swift

Scriptarian: “allows you to easily automate macOS using the Swift programming language, providing a modern alternative to AppleScript.”

Marathon “makes it easy to write, run and manage your Swift scripts.”

Scripting and Compiling Swift on the Command Line

How to Make a Web Crawler in Swift

Beak: “A command line interface for your Swift scripts”

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 🐤

What’s new in Swift 3.0

What’s New in Swift 3 – Part 1 and Part 2 and Part 3

Swift 3 and Declarative Programming

Official Swift Blog: Swift 3.0 Released!

Swift 3 Notes

Optional Non-Escaping Closures

Objective-C id as Swift Any

Updating Strings for Swift 3; Mastering Swift: essential details about strings  

Swift 3 Conversion Steps. Or “The 9 steps to Swift bliss”

Swift 3.0 Unsafe World

Writing Libraries for Swift 2.x and 3.0 Compatibility

Grand Central Dispatch (GCD) and Dispatch Queues in Swift 3

Yammer iOS App ported to Swift 3

Swift 3 and Comparing Optionals

A (mostly) comprehensive list of Swift 3.0 and 2.3 changes