Dynamic Type

I have a minor love/annoyed by relationship with dynamic type. Dynamic type is a system that lets users control the base size of the type used, and then the app configures its type sizes relative to that. Given that I have now reached the age where using a computer/tablet/phone almost always means needing my reading glasses, from a personal standpoint, I love it. Of course, back when I set my personal computer to use the smallest available type so that I could maximize screen space for coding (dual monitors weren’t an options for me then), it also would have come in handy. So what’s not to like?

When iOS first introduced dynamic type, most of my clients were web and print oriented and were working with designers who wanted complete and utter control of the fonts used, which meant custom fonts. Which weren’t well supported by dynamic type, quite aside from the issues of needing to imbed custom fonts in an application. (Webfonts are a wonderful thing, but they spoiled the developers I was working with and made transitioning their ideas to native apps more time consuming and painful on all sides.) Still, it was a great idea and I used it when I could get away with it.

But there was another issue. Even the Apple apps didn’t always play well when the larger accessibility sizes were used. And by not playing well, I mean the apps delivered by Apple would almost always truncate text at the largest sizes which could render an app all but unusable. (Mind you, this was also back in the era of the iPhone 5, so screens were smaller with less resolution.)

UX Peeve

Just as you can roughly categorize people as dog people or cat people, there is also a division between Android people and Apple people. Just as with pets, it’s not a sharp line, but the trends are there. Me, I’m in the apple camp. Apple products generally tend to behave, and expect me to behave, in ways that I can understand. It makes the tech experience less stressful and more enjoyable. So when an Apple UX experience fails, it can be especially grating. Today’s peeve is with the iPhone implementation of Messages.

Just as there are dog people and cat people, and Apple people and Android people, there are also those who carefully clear those little unread badges and those who revel in seeing how large an unread count they can accumulate. I’m not entirely consistent about it, but I tend to be in the clear the badges camp, especially when it comes to messing apps.

Let us consider a normal interaction. I notice that I have received a new message. It’s probably spam, but you never know. I open the Messages app and I can tell by the sender and the first line of the message that it’s not urgent and I’m not interested in responding or even taking the time to open it up. I don’t want to mute or block the sender because every now and then they send something I really am interested in, but I just want to mark this message as read so that it clears that stupid flag and I can stop thinking about it. My immediate reaction is to assume that the Messages app will work like the Apple Mail app; swipe right and you can quickly mark the item as read. It’s quick and easy and I use it all the time. But when I do that in the Messages app, instead of marking the item as read, it pins it to the top. Seriously? This is nearly the opposite of what I was expecting! And the action is so ingrained that I find myself accidentally pinning messages all the time, with a guarantee that they are the messages I am most unlikely to want pinned.

Yes, it’s a minor frustration. Yes, I did figure out how to mark as message as read without opening it. It still bothers me.

Dusting

[It’s been awhile since I’ve written here. No apologies, but we’ll see if I’m back.]

I’ve been in a bit of a rut of late. I used to love creating apps and would tinker with things on the side. But it’s been difficult to muster any enthusiasm for that in far too long. I still haven’t entirely figured out why. Is it burnout? It’s not because I’m writing too much code these days; most of my time is spent in project wrangling and communication. Part of it is that the native app side of our business has fallen off. It means I get to learn a broader range of tools by needing to handle Android and also writing in Xamarin. But it also means I don’t get to do a lot of work in any one tool set. And if you’re going for efficiency, using a tool set only once every year or so is definitely not the way to go.

Recently I found myself wanting to create another useful to me toy app and I decided to use that as an excuse to dip my toes into SwiftUI finally. And it hasn’t been bad. I like that it isn’t an entirely new ecosystem and is instead an adjunct to Swift. It also feels like an excellent way to develop interfaces that work well across a wide variety of screen sizes and aspect ratios. And yes, it’s nice to be able to enjoy learning something new in my trade. It also makes me think that if I had my choice, I’d prefer to be working entirely in Apple ecosphere, iOS, iPadOS, macOS, and even watchOS. (I still haven’t worked with watchOS yet) I need to think about that.

Speaking of Apple and covid, they announced that their stores were open again, and they are. I’ve been dealing with an irritation with my iPhone and have been waffling between putting up with it until new devices are announced this year, seeing if I can get my current phone fixed, or just going ahead and buying a new one. I walked into my local Apple store yesterday and found out that the soonest Genius Bar appointment I could get was Saturday. Ugh. So could I just buy a phone today? Well, yes and no. If I went online to make my purchase I could pick it up there, but if I needed to actually talk to someone, then I’d need to make an appointment, and the soonest available appointment was this weekend. It didn’t appear to be an issue with the number of employees as there seemed to be as many of them on the floor as I was used to seeing pre-covid, but I could be mistaken.

I did not pass Go. I did not spend over a thousand dollars. I left. And then I went online to make a Genius Bar appointment for this weekend so I can find out if it’s an easy fix. Then I should have enough information to decide whether to go ahead and get an iPhone 12 or wait for the new models. I’ve already had this one for a year longer than I had planned, so I will be buying a phone one way or another, it’s just a matter of which one. And now I’m thinking about whether this is all a good sign for Apple, because there are a lot of people willing to schedule appointments to spend money with them, or a bad sign because they might not have the staff to service the demand. And then I think about how I’m planning on replacing my laptop next year and how much money I spend on Apple products in any given year.

TAAW

Thank you, perl* for that most useful phrase, There’s Always Another Way. It was another rough week. The solution I had intended was just not working. We did some tweaks and it was still crashing. Still more tweaks still more crashes. Late last night, before it got too early in the morning, I gave up and went to sleep. Sure enough, I woke up early with an idea.

Just because you have picked out a solution doesn’t mean you have to stick with it. Yes, your great ego=-inflated developer brain doesn’t want to give up, but when you’re facing a real deadline, something has to give. You can either pitch out the original idea and try something different, or you run away screaming. Happily I chose door one.

Yes. sometimes that means scrapping a bunch of code and rewriting vast swathes of architecture. Honestly, by the time you get to that point, chances are good that a rewrite is going to be immensely faster than trying to force the original direction. When you’re stressed out and so neck deep in the problem that you start dreaming about it, you can consider letting your back brain chew on the idea for a little bit to see what wild ideas it comes up with.

No, you should change course every time you hit something that’s a little harder than you expect. If you’re afraid to learn a few things on the fly, and admit that you need to learn them, them you should probably consider a different career. In this case, I found a much simpler solution that will meet our needs in the scope of this project. But I also have another topic (complexities around Grand Dispatch) to dig into later.

*Perl, the language. It’s a clever and fiendish little language best used for projects that can be thrown away rather than maintained. Have you heard Scalzi’s bit about the failure mode of clever is asshole? Yeah, it applies in coding too. But it’s a fun little language and worth at least taking a look at if you’ve never played with it.

Ground Control to Major Tom

Here’s one that sounds like it ought to be simple, but when it isn’t it can bite you: Plan for how you’re going to test your app.

Does your app depend on sending data to or receiving data from other systems? Does your app validate the data it receives and handle failures gracefully? User entered data should always but always be treated with the utmost suspicion. But even generated data can bite you if the other end makes an apparently minor change to a database schema.

Or what if your app is displaying (for example) catalog data provided by a third party that has to be filtered based on user roles. And, for example, let’s say that this data is being updated on a very regular basis. How do you very that users are seeing all of the items they are supposed to see but none of the items that they aren’t supposed to see?

The standard method is to set up a set environment and populate it with real data so that you can test there. Which works until you have enough moving pieces and enough players and third parties who don’t want to play. You have to get creative and you have to code with more even paranoia than usual. The trick is to not leave it to the end. Prioritize it, think about it, document it, and get everyone involved to sign off on it. And have a fall back plan, because no matter how much testing you do, you can still get surprised.

Words and Meanings

More lessons from the trenches, and of the worst sort. There are some mistakes that seem to get made over and over again. You stub your metaphorical toe, recognize the rock, swear you’ll take care of it, and then wham! There’s that stupid rock again.

Define your terms. Explicitly. In writing.

In this case we had data being passed through three layers of services with three different companies after importing data from yet another service at yet another company. Everyone involved uses a different subset of the data and has their own data models. And their own field names. What we failed to do was document a data dictionary showing how those fields mapped between models. Normally this sort of problem would have surfaced early in testing, but there was other factors that hid the damnable rock and we’re lucky we didn’t break a toe this time.

Document your terms. Document your assumptions. Find a way to get everyone to actually read the documentation and update it when things change. And make sure you are testing those definitions and assumptions, somehow. And the more parties you have involved in a project, the more critical this becomes.

Now, how the heck do I avoid being involved in this sort of toe-stubbing exercise again? I don’t have the answer to that one.

 

When Things Go Wrong

Things you don’t want to have happen the week you intend to deploy:

  1. You finally get access to the production data. Extra points for this being on the production system itself because, for some reason, the production data couldn’t be copied onto the development system.
  2. Double extra points for not getting connected to the production system until the day before scheduled deployment.
  3. You finally get more than one test user.
  4. You’re asked to make a major change to the way you sync the primary data set. After an extensive effort to make this happen quickly, you are asked to discard that work and try a different approach.
  5. While discussing the details of a final round of acceptance testing following all the above, you’re informed of yet another change, this time to the primary transaction data.

Supposedly all these details had been settled on months ago and fully documented. But when you are dealing with a third party vendor who is also dealing with another third party vendor, things can go cock-eyed pretty quickly. When you sense this sort of situation developing (or step into one up to your elbows), stay calm and document everything. It’s especially important after phone conferences to write up and distribute a recap of the discussion. And then be very careful not to get sucked into a blame game. For now, fix the problem. Once the problem is fixed, review all the documentation to see if there’s a way to avoid having to deal with the same problem in the future.

Fun with Fonts

If you’ve ever worked on an application based on a design from a creative team, there’s a good chance that you’ve found a request to use fonts that aren’t system fonts. And if the application was designed to run on multiple platforms but the client wanted a consistent look, then you’ve almost certainly had to use something other than system fonts. In my experience, even when explicitly told to only use system fonts, the creative teams I work with manage to sneak in extra fonts without saying anything. Normally it’s because they’re used to designing for the web, not because they’re just trying to be contrary.

Now, technically it isn’t hard to use these fonts. Yes, you have to embed them in the application which increases the size of the executable and slows down load time. If it’s just a few fonts, that’s usually not a big deal.* Except that there are other possible consequences to be taken into consideration.

Do you have licensing for these fonts? And no, downloading them off them web from a free fonts website isn’t sufficient. And no, having a license to use the fonts on a web site doesn’t automatically allow you to use them in a mobile application. And based on a recent experience (although not with a project I worked on personally)**, I can no longer accept a font from a creative team based on their assertion that it has been properly licensed. Instead, I will need to get documentation of the licensing that can be checked in with the source code. Ideally, it would also be included in the application, but I’ll settle for having it with the source code.

Fonts can be an integral part of an interface design, but don’t cheap out. Spend the money and get licensed fonts. Think of it as an investment in getting great new fonts and having fewer possible legal questions in the future.

 

*My rule of thumb is that if they were told to only use system fonts and I find something else in the design, I bring it up explicitly in the review to push back. If the design has more than four fonts that need to be embedded, I get a little less polite. Also, don’t forget that every font variant (bold, italic, condensed, etc.) is a separate font.

**When you create applications on a work-for-hire basis, the client owns the code, and when the project ends, for whatever reason, the client can request a copy of the source code. Once the source code leaves your control, it can get used in ways you never expected.

How We Work When No One Is Looking

No, I don’t mean whether you spend too much time on social media during times you’re supposedly coding. What I want to talk about is how we code when we’re working on a solo project and/or not within a formal project context. When you’re working on a small toy project or just working solo, it’s easy to skip over all the folderol of a formal project. In fact, that can be one of the advantages of those types of projects, right? Less overhead and bureaucracy! More nimble! I think that it’s in just this situation that you should be most focussed on using – and evaluating – your workflow.

If all you’re doing is messing about with code for the sake of trying stuff out, you’re probably fine. (But if messing about with code is how you do your design, maybe give some thought to that process as well!) Disposable code is fine, so long as you are truly committed to throwing it away. As soon as you have code you want to save, it’s time to think about process and workflow.

Source code control is the easy part. You are using source code control of some sort, yes? But even here, it’s good to practice using the tool as if you were in a larger team, even if it’s just you. Don’t commit everything to the master branch. Do include meaningful commit messages. Use pull requests. And don’t forget to add project level documentation to the repository, at the very least a basic readme.

Set up testing code and strongly consider setting up a continuous integration process. This is the step I most often fail at. In fact, my unpaid side gig this week is to figure out how to use travis-ci to see if I like or not. I’ll also be adding test code to my current toy project. If you play with new tools on a smaller scale project and when you’re not under an external deadline, you have the luxury of poking around in the corners of your tools and trying different options. That means I have time to try more than one CI tool on the same project to see if I have a strong preference in any direction.

Even if you never intend to let anyone else run the code, it’s still a good idea to think about issue/enhancement tracking. Here I’m talking about internal, developer facing tracking, not the public facing type. (Although it’s possible to solve both at once depending on the project.) Think about your issue tracking interfaces with your source code control. Think about how change control interfaces with documentation. (You do have at least basic documentation, right?)

Another piece you might overlook is distribution and archive. If an executable (or source code) is sent to someone else, you really should be keeping track of who it was sent to. Does this need to integrate with your CRM solution or your billing/invoice solution? Maybe yes and maybe no, but it should be a conscious decision. When things get hairy, traceability can be a hugely effective tool, but only if it’s in place before you need it. And even if you’re not delivering projects to someone else, it can be useful to have an archive of finished projects.

What are the benefits of doing this work, even if no one else ever sees it? First, it gets you in the habit of defining and following a work flow. Developing good habits now will make it automatic to apply them to larger more complex projects. It also gives you a chance to learn and evaluate the tools in your workflow in a more contained situation. Second, if you ever do need to bring in additional developers, the project will be in a good state to hand off with a minimum off fuss and flailing. Third, maintenance will be much easier and less stressful. And because of the second point, you might even be able to farm out the maintenance tasks, freeing your time to do other more interesting projects. Third, a clean project with good workflow makes it possible to re-use code, either in another project, or in another context entirely.

Details

Ah, the joys of being a developer. You get to keep your development tools up to date. You get to make sure your IDE and source code version control, and testing environments all talk to one another and play nicely. You need to keep all your tools up to date with whatever level of support you need to provide. And you need to keep up to date with the evolving language specs while learning the interesting little bits that can make  difference when you’re trying to write clean, readable, maintainable code.

Today I got bored waiting for some other things, so I read up a continuous integration tool. Tried to set it up. Failed. Failed miserably and in such a way as to feel as though I had made negative progress. So set that distraction aside and read up on some nuances of how Swift import statements work. Dang, I learned something useful; you can import just parts of a module if that’s all you need. If you’re curious, you can read up on it yourself: https://nshipster.com/import/.

NSHipster.com and UseYourLoaf.com are two of my current favorite sources for writing about (mostly) Swift development. If you know of any others, or if you know of an equally good source focussing on Xamarin development, drop me a line.