Cloudy

Have you ever used a cloud service to support the function of a mobile app? Whether it’s AWS, Azure, Firebase, some other service, or even a server of your own, it’s time to learn. Cloud services allow users to work seamlessly across multiple device contexts, as well as making it possible for users to interact with each other. Getting familiar with how to set up and interact with these services will increase the scope of projects you can handle.

If you’ve used one of them and gotten comfortable with it, I strongly suggest at least trying out one or two others. Not all services are the same; they have their own strengths and weaknesses and idiosyncrasies. There’s no one perfect operating system or programming language, and there’s certainly not one perfect cloud service.

Using a cloud service is also a good way to get used to the idea of handling users with intermittent or context based connectivity. While modern mobile devices are usually within range of connectivity of some sort, you can’t take that connectivity as a given.  Ideally, as much functionality of your app as possible should be available offline. For some apps this might be a very small set of functions, but even a little bit helps, particularly if you handle the transition back to connectivity well. Build the user’s trust!

This also means that you need to handle more complicated testing scenarios around connectivity issues. Don’t just test on wifi! Test on cell data. Test on minimal and intermittent cell connectivity. Be inventive and some up with the worst case scenarios you can think of and test those. You can’t test everything, but catching issues before the code is deployed is generally cheaper than handling support calls/emails and is less destructive of user trust.

Not Just a Word; Not Just a Checkbox

Don’t wait until the end of the design (or development!) process to think about accessibility issues. Accessibility is not just a buzzword. It’s not just a checkbox on your prepare for deployment list. It’s about making sure there are as few barriers as possible for all your users. And no, I’m not talking about capturing a few extra folks who might be sight or hearing impaired. I’m talking about the larger (and largely invisible) group of people who have various kinds of color blindness. I’m talking about making your app easy to use by people who are keeping track of kids while shopping for groceries, or students in a lecture, or people working in a poorly lit office or out in the sunshine at a soccer game.

Mobile devices are mobile and people take them everywhere. This is both a strength, because they tend to always have them available; and a weakness, because they take them into less than ideal situations and still expect to be able to use them. Accessibility features are for everyone, not just people you think of as being covered by (inadequate) ADA laws. And accessibility works best for everyone if it is part of the initial design decisions rather than being an after thought. Make it part of the design. Make it part of testing. If the team pushes back, come up with use cases for otherwise able people who would benefit. Can’t come up with an appropriate use case? Try harder.

Sometimes the pushback will come from the client. Be ready with your arguments. Implementing accessibility features up front tends to be cheaper (and more thorough and less likely to break things) than bolting it on at the end. You have to test accessibility features because, whether or not you intend them to be used, someone will eventually use them. Making sure accessibility features don’t break your app (even if your app doesn’t make full use of them) can save you losing that customer plus all the friends they tell about the problem. It’s cheaper to keep an existing user than to get new ones. Plus, it’s the right thing to do.

What’s in a Name

Are we still having this issue? Will it ever go away? (Yes, and almost certainly no, but one can live in hope.)

Look, it’s very easy to think that names are simple. You have a first name, maybe a middle name or initial, and a last name. Except that it is never that simple. If the data set you’re currently working with happens to be that simple, then you have a ticking time bomb waiting to encounter a perfectly ordinary name that will blow up your code.

I just ran into this one this week. A third party vendor we’re working with (through two removes, and isn’t that a joy) cannot deal with last names that have spaces in them. If you’re the eighth president of the United States, Martin Van Buren, and you try to add your data to this database, it will reject your name. The problem is that the database is trying to separate first and last names into their own fields, but the data being imported has the entire name in one field. So the data import process is using spaces to break up the string into first name and last name. But it can’t tell whether the first name should be Martin Van or if the last name should be Van Buren, or if maybe there is a middle name stuck in there for some reason. (Because, yes, it is also possible for a first name to have a space in it. Really and truly.) And last names can even have multiple spaces.

I would not be at all surprised if this vendor’s system also had problems with names that have apostrophes in them. I feel for the O’Brian’s and the rest of the apostrophe’d of the world, I really do. Hyphens don’t usually cause as much of an issue, but they can.

If your system is foolish enough to track middle names, then you’re going to have to deal with people who have more than one middle name. Two is not at all uncommon. Three isn’t unheard of. Are you going make your users pick just one of their middle names and lose the rest? And have you accounted for people who don’t have any middle name at all? (NMI is a truly ugly middle initial.)

Speaking of not having names, what of the large (yes, very large) number of people who don’t use surnames? I’m not talking about Cher and Bono here. I’m talking about whole communities where it is normal for people to have only one name. (See Indonesia and Iceland.) DO you leave the first name blank? The last name? Can your system handle a blank first or last name?

Now think about the people who use a first initial and go by their middle name instead of using a middle initial. Or a first name that has both a period and a space in it. Really. Names aren’t all Dick and Jane and Smith and Jones, not by a long shot.

If you’ve made an assumption about how long a name should be, there’s a good chance that you’re underestimated. Do your research. If you’re trying to create a good experience for your users and maintain valid data in your database, you don’t want people’s names getting truncated just because they’re longer than you had expected.

We haven’t even gotten to honorifics and suffixes yet, and we’re not going there today. Just be aware that storing and displaying names, especially when moving them from one system to another, is not as easy as you might think.

Ye Olde Code

With limited exceptions, most mobile applications have a very short life, assuming they ever get used at all. [Insert links here] And a mobile app that isn’t updated every 6 to 12 months is essentially abandoned. If you’re a coder for hire, working on multiple projects for multiple clients, over a three year period you could easily touch 20 to 40 apps or more. (For reference, in the last five years I’ve easily worked on over a hundred apps, only one of which is still being actively maintained and updated.)

This is a good thing, yes? Now what happens when a client comes to you and says, remember that app you developed for us two years ago? We’d really like to get it installed on a device so that we can use it as part of a demo.

Did you archive the executable you delivered? Is it an enterprise app you can just resign so that it will install? Will it run on a current version of the operating system? If it runs on the current operating system, will the graphical assets look decent on current displays?

Or maybe you need to rebuild it. You do have the source code controlled in a repository, right? Do you still have an IDE that you can use to compile it? Will the IDE run on the operating system your development machine is currently running?

Even if the contract explicitly stated that you would not provide this service, you can potentially generate good will with clients when you are able to help them out. Just don’t let yourself get sucked into providing too much support for free. It’s best to determine ahead of time (before the request comes in) just what level of effort will necessitate creating a new work order and subsequent charges.

But also remember that, even with the best of intentions and the most reasonable systems in place, you won’t always be able to meet the client’s needs. (The client needs a 32-bit iOS app designed for a non-retina screen to run on the latest iPad Pro for a major event that’s happening in 24 hours. Ahem.)

The Vicissitudes of Time

Managing time and date values is always a fun trick, for some value of fun. First, UTC is your friend. Embrace it and hold it close. Use it whenever manipulating or comparing time date values. With few exceptions, translation to local time should be reserved for user display. Luckily, most modern operating systems have well developed standard ways of managing date times. Use them. Don’t roll your own without a very good reason. No, one better than that. Anyway, that’s the easy part

Now imagine an app with time and/or date based business rules. Your user should do something every 4 hours, or shouldn’t do something more often than once a day. You store the starting date time and then you compare it to the current date time. But what if your user hopped in a plane and flew across the country, or across the international date line. Were your business rules designed to take travel into account? If a user takes a daily action at 11:59pm, should they be allowed to repeat it at 12:01am? Sometimes the answer is yes, and sometimes the answer is no, but it needs to be solved at the requirements level, not the implementation level. Always look for the edge cases when dealing with date time related business rules and try to decide how (or if) to deal with them before you start implementation.

Now remember that when you’re relying on the system time on the device, that’s a value the user can change at will, even while in the middle of using your app. Is this something that needs to be taken into account in the design? Maybe it’s just let the user deal with any fallout. But if there’s anything security or access related triggered by time, then you need to be ready for users who get their devices to lie to you. (Hey, at least it means they’re using the app, right?) Often the solution to this is that the master time is calculated by your server which the device has to check into. Some users will play thee games maliciously. Some will do it out of curiosity. Just be aware that it can and will happen.

Then there’s the problem of testing apps implementing business rules that span days (or weeks or months). It’s seldom feasible (or reasonable) to read testing out over that span of time, so why not just roll the time forward or backward on the device? Time travel! Except that, unless it’s a dedicated test device, you might run into unwanted side effects. One possible way to get around some (but not all) of those potential side effects is to roll the time back into the past before you start your test, working your way toward the present.

But as soon as your app has to publish to a server, your test results are likely to be problematic. Again, depending on the design. It’s easy to change the time on a device. It’s not to simple to arrange getting the time changed on a server unless it’s an isolated and dedicated server. Even when it isn’t a problem to time shift on the device and publish to a server, we ran into a real life case where our testing time shift crossed the boundary of an SSL certificate renewal. Odd things can trip you up. Be on the look out.

One of my favorite techniques for dealing with business rules that cover large periods of time is to do test builds that substitute a shorter unit of time; seven days becomes seven minutes, or ten hours become ten minutes. A simple substitution of time units makes it easier to set up the test situation with a simple toggle in the code.  Please don’t depend on going in and manually updating every substitution every time you change in and out of test mode as you will eventually miss one.

Happy coding!

Infernal Noisy Machines

Recently I found myself in the office on a Saturday afternoon. It happens. (Deadlines don’t care, but you want your software to be good, yes. Just don’t do it too often. Especially don’t do it too often if you work for yourself.) We’re working in Xamarin, which I am still getting comfortable with, and to make it even more interesting, the bulk of the content of the app is being provided as React code that has to interact with the backend.

Anyway, one of the things I was getting grumpy about was a feature where you can preview a sound by selecting it from a picker. It had to work on both iOS and Android and the implementation used dependency injection. (Playing a sound is highly platform dependent so the code had to be implemented separately for both iOS and Android. The C# code in Xamarin then calls the appropriate method depending on the device. Very nifty.) It was working on Android devices and I wasn’t seeing any defect tickets on the issue, but it wasn’t working at all on my personal device. I had to track down the problem.

First I verified that the call from the javascript front end was making it into the back end.  Then I verified that the code was retrieving the proper full path to the sound file in the app sandbox.  All looked good. Run it in the simulator, there are no errors, and the sound plays. Run it in debug mode on the device, there are no errors, but no sound plays. Grr. I get a fresh cup of coffee and then do a quick search, suspicious that there might be something odd about the Xamarin code we’re using. And I find a post form someone back in 2015 who had the same issue. He had the mute button on his iPhone turned on.

The first time I got bit by this particular problem (because of course this wasn’t the first time, much to my chagrin), was back in 2011 when I was working on an educational app with video content. I don’t know if I felt more silly then or now. The truth is I’ve had this exact same issue about once every three years or so, just infrequently enough that I forget every time. Maybe next time I’ll remember how much I dislike noisy devices.

Whenever you’re working with audio content, don’t forget to check the mute button as well as the volume. In fact, if you’re working with audio content, I strongly suggest reading up on how your OS handles sound channels.

Which reminds me that I should take the time to read up on the specifics of how Android does it.

Pet Peeve

This is the time of year when I reliably gnash my teeth. I hate it when development tools autoupdate instead of asking for permission first. I’m looking at you, Xcode. Xamarin is even worse. Oh, Xamarin. At least I’ve had enough experience now to have some idea of what’s going wrong when you start throwing cryptic error messages out of the blue. New OS release? Oh yeah.

Yes, I know it’s good to get people to update to the new stuff. Yes, I know that if you give them a solid nudge, that many of them will never update, ever, and will expect you to support your older versions forever. But I hate how easy Apple makes it to accidentally turn on autoupdate for something, and there seems to be no way to turn it off.

Speaking of versions, if you want to do mobile development, get used to the idea that you are likely to need two to three versions of the IDE available at any given time. (Except Xamarin, dang it.) (Yes, you can run multiple versions of Xcode on one machine. Yes, it can get a little wonky sometimes.) This can end up taking up quite a bit of disk space.

For example, I currently have the following applications that I use for daily work: Xcode 9.2, Xcode 8.3.3, Xcode 7.3.1 (about to retire this one!), Android Studio 1.5 (about to retire this one!), Android Studio 2.3.1 (also about to retire), Android Studio 3.0.1 (need to get the latest), the full Microsoft Office Suite for Mac, Photoshop, SourceTree, Sketch, Sublime Text, Slack, Safari, Firefox, Chrome, Fabric, Navicat, Postman, Transmit, and Visual Studio. That’s not counting the extra text editors or a small collection of image optimization apps and random tools.

The moral of the story is that, when you get the chance to spec out a development machine, get all the disk space you can get your hands on.

Where to Start

So, you want to be a mobile developer. Where do you start? What language do you learn? What platform do you use? Should you develop for iOS or Android?

Well, it depends on where you’re starting from. If you are comfortable in java, then I’d start with Android. If you don’t have access to a Mac, then definitely start with Android. Just know that, unless you are willing to restrict yourself to one platform, you’re eventually going to have to work in both iOS and Android. There are still places where you can specialize in just one platform, but an ability to work in both platforms will give you more flexibility. You’re also going to want to become familiar with at least the basics of front end type development (HTML, css, and javascript to start with as a bare minimum.)

You just need to pick one to start with. Ideally you want to have an actual device you can test your code on as well. And if you aren’t planning on specializing in one platform, then I strongly suggest making sure you have experience using both iOS and Android physical devices. And by using, I mean carrying them around and using them for your regular daily tasks.

If you’re starting as a front end developer, you’re probably going to be tempted to use one of the hybrid type tools available such as Ionic, or whatever is popular at the moment. Pick one you like and learn it. And then, I strongly recommend learning at least the basics of how to develop native code on at least one platform. The hybrid tools can be very useful, but chances are good that you will eventually run into something that will require dropping down to the native code. And if you learn how the native code works, you’ll be in a better position to understand what’s going on with the hybrid code when things get weird.

Get your development environment set up and find yourself a tutorial that you like and can understand. If you’re not sure where to start, Ray Wenderlich’s site (https://raywenderlich.com) is not a bad place to begin, but there are lots of options out there. Once you’ve got a tutorial or two under your belt, come up with your own idea for an app. It can be simple and silly, just so long as it gives you incentive to learn more things. The most important thing is to start.