A Health Update

I’m writing this post from a hospital bed. And I couldn’t be happier.

You hear folks say chemotherapy sucks, but until you go through it yourself, you don’t really know how bad it can be. It remains a popular activity only because it’s better than the alternative.

My first exposure to chemotherapy was with this contraption: a fluoroscope.

A fluoroscope sitting in the middle of a room at Hoag Hospital
Lovely to look at, less lovely to lie on.

Every week, they used this machine to tap into my spine, extract 5 mg of fluid for analysis, and replace it with 5 mg of methotrexate. There was only a local anesthetic during the procedure and the hardest part was knowing that there was a needle, turned up to eleven, going into my back.

It was afterwards that things got dicey: the nerves in your spine float in a thecal sac filled with spinal fluid that acts as a kind of insulator. Since we were exchanging the fluids, it was easy for the levels to get out of balance and for the nerves to react.

The result were the worst headaches I’ve ever experienced. The good news is that the remedy was simple: to lie flat on my back to ease the pressure gravity was putting on my spine.

That was also the bad news: many days were spent lying prone and trying to avoid boredom. Watching shows and scrolling timelines just doesn’t cut it when that’s all you can do.

Thankfully, the spinal headaches subsided quickly when the six-week course of lumbar punctures finished at the end of January. But my body began to face a new challenge: chemotherapy infusions of Bendamustine and Rituximab.

Everyone experiences chemotherapy differently. Just as every body is different, so is the reaction to the chemicals that are killing the cancer.

The first effect I noticed was in my tastebuds: everything I put in my mouth had a slightly metalic taste, so my eating habits changed. My beloved morning coffee was replaced by tea, food needed a lot less salt, and I started eating a blander diet (cottage cheese with berries remains a favorite).

Some people experience nausea and other gastric issues: luckily, I avoided that. I also didn’t have any hair loss, but my normally thick and curly hair lost its body and became lifeless: an external expression of what was happening to me internally.

As someone who’s always been active and strong, the biggest overall effect of chemo was losing muscle mass and suffering from overall fatigue. It felt very strange to be weak.

I was on a 28 day cycle for my infusions: during the first week I got pumped full of chemicals and then spent three weeks letting my body process them. One of the things they gave me with the infusion on a Tuesday was a dose of steroids that gives the body a boost during the initial onslaught. But by the weekend, that wore off and I felt like shit. It usually took until the middle of the second week before I started feeling human again.

I didn’t lose my appetite, but I wasn’t eating more than normal. The problem was my metabolism was working overtime and my calorie intake didn’t adjust. I lost 50 pounds over the course of a couple of months and eventually got to the point where I was having five meals a day. Too bad it all tasted bad.

A screenshot showing my weight loss over the past year: ranging from 250 to 200 lbs
This could also be a graph of my happiness.

One thing that I did to fight my diminished capacity was a daily walk. Anyone who exercises regularly knows that there are always plenty of reasons to avoid it: you didn’t sleep well, you have an important project to finish, or you’re sore from a previous workout. When you’re doing chemo, add feeling like absolute shit to that list.

I still had nerve damage in my spine, so my “walk” was more like a shuffle. Thankfully my wife found some awesome walking sticks to aid with my balance. They are clearly labelled “Not A Medical Device” but they are my most important medical device.

Winter sunsets, exercise, and walking sticks are good medicine.

My daily exercise was just like any gym workout: dread at the start, joy at the end. Sometimes there wasn’t much behind that joy: at my lowest point, a walk around the block on flat ground got my heart rate up to 160 bpm. Breathtaking, literally.

That low point was in March. In the week following my infusion, where I was already feeling like crap, I came down with a type of pneumonia that affects people with weakened immune systems. I had no strength and my blood oxygen level plummeted below 90%. Getting from the living room to the kitchen for a drink of water felt like running a marathon, and then my Apple Watch pinged to inform me that I was having an episode of atrial fibrillation. It was a lot and I honestly had thoughts of “is this how it ends?”

Thankfully, antibiotics battled the pneumonia quickly and the chemo effects subsided. My doctor offered to skip the next cycle of chemotherapy, but I decided to push on. There is only one way to be done with a thing.

Throughout all of the infusions, the nerve damage that occurred before the lymphoma discovery didn’t improve. As I said above, my gait and balance were severely compromised: going up and down stairs was particularly challenging. The tingling sensations on my backside and numbness near my abdomen became a bigger concern with each passing month. It wasn’t getting better and I feared it was a permanent condition.

I finished the last of my infusions in May and my body slowly started to recover. Food started tasting better, and my strength and stamina started to return. My daily walks got longer: first a quarter of a mile, then half a mile, then a mile, and then something fantastic happened.

At the end of a walk around our local state park, I went to grab something in the car glovebox. As I did this, I tilted my head forward and the back of my legs lit up with a feeling I had never felt. Something was changing in my spine: and after a couple of weeks it was clear that this was a sign that the nerves were fixing themselves.

Our guess is that the chemotherapy infusions, which attack white blood cells and other parts of the blood that aid in recovery, had retarded the healing in my nervous system. Now that my body had a chance to repair itself, it was.

I can now go up and down stairs without hanging on for dear life. I’m able to walk without aid, but I still like my walking sticks for longer outings since they let me push myself harder. I’ve also started working out in a gym with a trainer: I told him about my stair issues, and now he has me doing them backwards and by hopping on all fours. I am so happy to look like a doofus, and for the continued improvement I’m seeing with exercise.

My regained ability to walk and a stronger immune system allowed me to leave the house. My first night away from home was a short trip to Topanga Canyon to celebrate an August birthday:

All hail the sunflower goddess!

After that successful trip, we took a short boat ride to have a nice lunch and look at some kelp. It felt so good to be able to do normal things again.

A trip to visit The Blue Forest

One lingering part of my life that hasn’t been reestablished is swimming. All the chemotherapy that has been put into my body has been through a port catheter: a small device under my skin that hooks directly into my carotid artery. Getting an infection there would be a very bad thing, and water increases that risk: be it from ocean water full of living organisms or a swimming pool that kids pee in.

With the current El Niño conditions, that’s been a hard thing: the water is warm and “interesting”. My new gym also has a beautiful Olympic-sized pool for lap swimming. I’m happy to be in this hospital bed doing a final stint of chemotherapy because when I’m done, the port is removed.

This last procedure is to make sure there is no lymphoma in my brain fluids: not a difficult or dangerous treatment and the side effects are minimal. But it does require close monitoring because of the high dosages involved.

In six weeks, I’ll be done and spend the winter in that heated pool so that I can finally swim in my beloved Pacific next summer. The buoys are still there, even though the high surf this summer knocked one out!

Last year was hard, and it got worse over time. This year has also been hard, but it’s gotten better with each passing month. For that I’m grateful.

I’m also grateful for my wife Lauren: it’s impossible to imagine making it through all of this without her help, support, and encouragement. The silver lining in all this strife is that it’s made our relationship much stronger. Thanks sweetie!

As with my previous account, there’s an unwanted coda. No matter how hard I try, there’s a complication at the happy ending!

I had typed up everything above as the doctors and nurses prepared me for the first dose of methotrexate. It takes a while for your blood’s pH level to reach a point where the treatment is safe, so I spent much of the day lying in bed, peeing into urine cups, reminiscing about my year, and typing.

Around 10:30 PM, the medication was in my brain and I was trying to wind down for the night (easier said than done when part of the regimen includes steroids). While scrolling through Tapestry, I noticed quite a few posts about a newly announced PHP vulnerability. This caught my attention because we use it for our blogs, an ad server, delivering Kickstarter rewards, and a bunch of other small things.

(This is the point where family that doesn’t understand what I do for a living continues to not understand what I do for a living.)

It quickly became apparent that this was a big deal and something that could allow an attacker access to our server. I had to shut things down before my brain shut down. Thank goodness the steroids held out.

After a couple of hours, I had blocked access to PHP processes in every nook & cranny of our server. After sending a quick message to our Slack explaining how everything was broken, I collapsed.

The next day started with a head and server that were barely working. Our server was out of LTS, so the first order of business was to get it back onto the latest version of Ubuntu using hospital WiFi. It was a good thing my heart rate and blood pressure were being closely monitored.

(Thank goodness for Lish, which proved to be immune to hospital IT shutting down my ssh connection to accept terms & conditions every few hours. There’s also a “I should have my head examined” joke in here somewhere.)

If you noticed that the Iconfactory sites were kinda broken last week, now you know why. It’s because I was kinda broken last week.

Now I’m finishing this post from a comfy chair on our deck. Typing into the latest version of WordPress and PHP. And I couldn’t be happier.

TipKit for the Real World

On a Monday morning, I thought I’d take a crack at implementing tips in one of my apps. There were some gestures and other features that customers weren’t finding and explaining those things with tips would be helpful. I expected the task to take about a day.

It ended up taking a week.

Why so long?

Well, the first problem is when you watch the introduction video from WWDC ’23 you’ll see outdated code throughout the presentation. TipsCenter doesn’t exist. Configuration is completely different. And there is no mention of UIKit.

Then, when you look at the sample code, it’s all SwiftUI. At least the sample compiles and runs because it uses a completely different syntax than what was shown at WWDC.

But the fact remained: I had UIKit views where I wanted to display tips. And there wasn’t any information on how to accomplish that. Did Apple really release a framework that didn’t work on the code we’ve been crafting for the past 20 years?

Tips are something you want to add to existing code. And UIKit is the most likely case there: you’re not going to rewrite your views in SwiftUI just to explain some features. The biggest failure with the TipKit introduction is that it ignored the past and how apps have historically been built.

Eventually I stumbled upon TipUIPopoverViewController which inherits from UIViewController. That should work!

And it did.

But it didn’t: the close button on the popover didn’t work. And my first day was over.

This is the point where you start to learn that a Tip is a dynamic state machine that’s mostly out of your control. My problem was understanding how that state machine interacted with my own code (and its state).

Eventually, you also learn that the Tip’s state is persisted. Until you realize that any changes you make are stored in a SQLite database, debugging is very confusing. It’s also easy for your own state to get out-of-sync with the Tip state: there is not a single source of truth.

Your first task will be to figure out how to get the Tip close buttons to work. The sample code for TipUIPopoverViewController hints at what you need to do: implement an asynchronous task that monitors the state of the tip. When that tip gets into the right state, it’s your job to both present and dismiss the popover view controller.

Unfortunately, that sample code doesn’t scale well. If you have a view with multiple tips, you’re going to be littering your code with tip instances, observation tasks, and popover controllers. It’s a mess and a clear sign that the TipKit developers didn’t think much about UIKit.

My solution is a TipPresenter class. It’s instantiated by your view controller, starts an observation task, and then presents or dismisses a popover as the Tip’s state changes. It significantly reduces the clutter, makes refactoring views/tips easier, and it even works from Objective-C code (yes, some of us still have that).

One thing to keep in mind when you’re using TipPresenter: the observation task is a strong reference with weak references to a view and controller. Make sure you call stop() as you clean up your view: if you’ve ever used a notification observer, you’ll know the pattern and why you need it :-)

Another pattern emerged once I had a convenient way to present tips: view updates and tip updates go hand in hand.

Most of our UIKit apps rely on a Model-View-Controller architecture. The model gets updated, changes propagate to the controller, which uses a view to display the new information. Every UIViewController has something like an updateView().

You’ll quickly find that your model changes will need something that moves state to the tip presenter. Whenever updateView() gets called, you’ll also call updateTips().

I’ve been referencing a Tipster project repository throughout this post. Feel free to download and experiment. If your UIViewControllers are written in Swift, check out PresentedViewController. If you’re working with Objective-C, take a look at LegacyViewController. The ToggleTipPresenter is used in both view controllers.

The TipKitHelper file contains the Tip definitions, the TipPresenters, and the configuration helper class (which also has Objective-C members). Also of note: this code is compatible with iOS 17 and later.

I’m not thrilled with the need to have separate implementations of the TipPresenter classes, but since Tip is a struct that can’t be bridged to Objective-C, it has to be that way.

To quickly find important stuff in the project, search for NOTE:. There is also a lot of debugLog() in the code to help you see what’s going on from the Xcode console.

As you get more familiar with TipKit, I highly recommend this article on Fatbobman’s Blog – it digs into the more advanced aspects of TipKit and includes an example of how to do an inline tip with UIView or NSView.

Armed with this code and information, adding TipKit to your UIKit app should take less than a week. Maybe even just a single day like I initially thought!

Spotlight: Not Right

A few weeks ago, my iPhone started having a serious problem: it could no longer search for things. This bug affected the App Library, Mail, Notes, Messages, Settings, and more. Having a device that couldn’t find things was crippling.

All signs pointed to this being an issue with the Spotlight index on the device: the database was corrupted and unable to do queries or updates.

Of course I searched for clues on how to fix this issue and tried the following things:

  • Forced restart
  • Changing language and region settings
  • Toggling location services for Suggestions & Search
  • Reindexing All Items in CoreSpotlight using Developer Mode
  • Toggling the App Search settings
  • Updating iOS from 26.4.1 to 26.4.2
  • Toggling Siri on & off
  • Looking at Console output to check spotlightd for errors
  • Soliciting advice from 25,000 followers on Mastodon

None of these things worked.

All of the hints I saw online ended with “if this doesn’t work, just Reset All Settings”. When you go to do that, you’re presented with the following dialog:

I’ve been adjusting my settings on my phone since 2007 and honestly couldn’t imagine the fallout from resetting them to defaults. All I knew is that this would be incredibly disruptive to my life for several months as I stumbled over things that needed setup.

For example, would a nice evening in a restaurant with dim lighting be interrupted when I triple-clicked the side button to get the Magnifier to read the menu? Being taken out of the moment by tapping around in Settings was not something I wanted to risk.

That left me with one alternative: a full device backup and restore. I did this on my Mac to make it as speedy as possible, but the process still took a couple of hours. During all of which I was without my primary device.

Afterwards, there were immediately problems:

  • Apple Pay was reset on both my iPhone and Apple Watch, requiring me to update my drivers license and credit cards.
  • TestFlight builds were uninstalled: for a developer this is significant.
  • Logins to apps that don’t use the keychain didn’t work.
  • The 24 apps using FaceID needed setup again.
  • All hints in all apps were reset.
  • Some Safari content blockers weren’t working and needed updates.
  • All apps prompted for Allow Access on Local Network and other privacy features.
  • Apps on the Home Screen that required FaceID to open were reset.
  • Unlocking the iPhone with Apple Watch needed setup.
  • Developer Mode needed to be re-enabled.

In short, this took several days to sort out. And the entire time, it pissed me off because it was entirely avoidable.

On the Mac, there is a simple procedure to rebuild the Spotlight index. This same affordance is not available on iOS.

It just works, my ass.

Spotlight is a database that’s accessed by a lot of processes in a lot of different situations. It’s reasonable to expect that all this activity can uncover bugs that corrupt the index. The kinds of issues that are hard to reproduce, but easy to repair with a simple button labeled “Rebuild”.

Why doesn’t that button exist on iOS? Maybe it’s a product manager in denial. Maybe it’s because the Spotlight developers are always working on fresh database and don’t ever see the issue (my database had likely existed for months or even years).

Whatever the reason, there are plenty of YouTube videos and Apple Support discussions that show this issue is widespread. My proposal is to add a button to aid customers:

  • Put it in the Search category, since folks understand this issue as “search doesn’t work”. Do not bury it somewhere deep in the hierarchy because when you have a corrupt Spotlight index, you can’t search in Settings. It’s got to be easy to find that “Rebuild” button.
  • Add some context for anyone who uses it. The Mac support article mentions that “This can take some time, depending on the amount of information being indexed”.
  • Show some kind of progress indicator as the index rebuilds, as the Mac does.

Until this happens, Spotlight just isn’t right.

Apple folks: FB22651086

Pico Names

One of the things I love doing is naming things. Whether it’s for products, or things that I encounter daily, it’s a habit.

Fifteen years ago, I started a list for our new dog, Pico. My wife and other family members joined in on the fun. Last December, we updated the note for the last time.

I’ve shared this list over the years and everyone gets a kick out of it, but the main reason I’m putting it up here is so I have a place to remember all the good times we had together.

The names are in chronological order, the photos are not.

Our first day together.

Snooty

Pico-bahn

Snoot Butt

Bud

Always on the lookout for suspicious activity.

Officer Pico Rivera, Dog Cop

Snootsicle Von Tootsicle

Struttin’ Von Buttin

Snootsie Von Tootsie

With his 10× doppelgänger at the dog park.

Mr. Toothpick McShivers

Piconator

Snoots

Squeeko

Snootsicle Bootscicle

Packed wet sand is the perfect medium to show off your skills.

Sandy Dandy

Sandicle Dandicle

Budly Studly

Always pay attention to nearby vehicles. Or take a nap.

Captain Snoot of the S.S.Picobahn

Barkey McLoudbutt

Power Snoots

Lord Voratio

Rooter

Barky Boy

Sir Barksalot

High Falutin’ Snootin’

The Force was definitely strong with this one.

Obiwan Snootobi

Turd Burgler

Snoot Doggy Dog

Sheik Yer Snooty

Sir Prancelot

Pink Butt

No shortage of freckles or desire to show them off.

Freckle Pecker – Deck Commander

Snooticus Tooticus

Bupster Pupster

Snootrition 

Nudie Snoodie

Food Genius

Quicker Licker

Low tide is the best tide.

Moto Pico

Pink Gooba

A dog can only take so much hot and dusty trail, so hitch a ride.

Bud Bud

Bumpy Gut

Platemaster Supreme 

Mister Bits

There was no limit to his licking abilities.

Dr. Bits, Molecular Foodologist

The Leaf Thief

Hellen Killer

Mister Biscuits 

Snootrous Boutros-Ghali

All kinds of sizzle.

Little Sizzle (Rapper Name)

Lumpystiltskin 

A grunt is the best way to express your unhappiness with a situation.

Grunty McRunty

Yawny (pronounced Yanni)

Mister Slurps

Hacky Jack

Frosty the Dogman

The pleasures of old age and good friends.

Frosty Face (from Lori)

Bubbie

Frankenbutt (after mast tumor removal)

Zipper/Zippy Butt

Like shadows, we’re not really here, but the memories always will be.

Your Mac and a Canon Printer

Our trusty Brother MFC laser printer and scanner was getting long in the tooth and my wife wanted color printing. After a lot of research, she landed on the Canon MF644Cdw and placed an order.

Initially, we were both happy with the new printer. The print quality is great, the hardware is solid, and the touchpad for configuration and management is better than most.

But after a few months it became apparent that the printer’s networking is completely screwed up. The root of the problem is with Canon’s firmware: it’s not compatible with Apple’s Bonjour.

So how widespread is this issue?

Here is a six year old support thread about “offline” printer on the Mac. And if you search Google for “Canon offline Mac”, there are a ton of web pages and videos explaining how to “fix” the problem.

The problem with the fix is that it’s only temporary. Based on my personal experience, you need to re-fix things when you’re in a hurry to print a shipping label or report. Adding insult to injury, everyone that’s sharing the printer, whether it’s a family member or a work colleague, will need to reset their printer configuration, too.

Initially, this is a mild inconvenience. But after doing it hundreds of times, I renamed our printer “Canon MF” – the initials do not mean Multi-Function.

If you are reading this and still within the return window for the printer, head to your car or web browser right now. As you’ll see below, this is not a printer that will be easy to deal with on a Mac. It will be a purchase you regret.

If you can’t return the printer, keep reading and I’ll explain how things are broken and present a workaround that will prevent the constant “Offline” situation.

If you just want a permanent fix and don’t care about the details, scroll down to You Can Fix This.

Digging In

Since I could find no reports of the weird “Offline” behavior on Windows, I began by investigating the technologies that are specific to the Mac and other Unix-based systems:

  • CUPS, originally known as the “Common Unix Printing System”, manages the printers, their capabilities, and the queue of print jobs.
  • Bonjour lets other devices on your local network find the printer. It’s also known as Zero Configuration Networking or Multicast DNS.

CUPS felt like an unlikely culprit: everything prints great when it’s working. After checking the printer drivers against the CUPS documentation, this intuition proved correct.

But when I started looking at Bonjour, it was another story.

The following Terminal command can be used to see what printers are on your local network:

$ dns-sd -B _ipps._tcp

The command is cryptic, like all things in the Terminal, but it means “do DNS Service Discovery, browse for Internet Printing Protocol over HTTPS”.

NOTE: If using a Terminal is new to you, don’t be afraid to try the commands I’m showing: none of them will harm your Mac. You will find the app in the Applications > Utilities folder. You can copy all the text after the “$” and paste it directly into the app. Closing the window will terminate the command.

The command output will contain multiple columns, but it’s the first two columns with a timestamp and add/remove status, that show what’s wrong:

$ dns-sd -B _ipps._tcp
Browsing for _ipps._tcp
DATE: ---Sun 01 Mar 2026---
14:31:17.408  ...STARTING...
Timestamp     A/R    Instance Name
14:31:18.740  Add    Canon...(28)
14:33:21.446  Rmv    Canon...(28)
14:33:25.577  Add    Canon...(28)
14:35:34.505  Rmv    Canon...(28)
14:35:34.952  Add    Canon...(28)
14:37:33.932  Rmv    Canon...(28)
14:37:35.251  Add    Canon...(28)
14:39:37.001  Rmv    Canon...(28)
14:39:43.664  Add    Canon...(28)
14:41:58.121  Rmv    Canon...(28)
14:42:09.361  Add    Canon...(28)
14:50:13.326  Rmv    Canon...(28)
14:51:41.923  Add    Canon...(28)
14:53:39.560  Rmv    Canon...(28)
14:53:45.726  Add    Canon...(28)

Typically a printer will added when you start the command, and removed when your Mac goes to sleep.

The Canon printer removes itself every few minutes. To the rest of the network that’s using Bonjour (including everyone’s printer settings), it looks like the printer was powered off and on again. Hence the “Offline” state and the red dot in Printers & Scanners settings.

The “Offline” state is also likely to happen when you wake your Mac. The add/remove nonsense is caused by the printer and when your Mac is asleep it may miss the state change. When this happens, it can take 10-15 minutes for the red dot to turn green. When you are in this situation, you can’t add a new printer because it doesn’t exist in Bonjour. You just have to wait.

This is the root of the problem. The constant change of state eventually corrupts the cache used by Bonjour. This, in turn, breaks the CUPS configuration and your printer is either temporarily or permanently “Offline”.

A fancier version of this command speaks when the printer adds or removes itself: this lets you do things like look at the status of the printer in System Settings. After you hear “remove” you’ll see a red dot and “Offline”. An “add” turns the indicator green and shows “Idle”. This will be annoying after awhile, but it does give you great feedback about how Bonjour is messed up:

$ dns-sd -B _ipps._tcp | while IFS= read -r line; do echo "$line"; echo "$line" > /tmp/line.out; if grep -q "Rmv" /tmp/line.out; then say "Remove"; elif grep -q "Add" /tmp/line.out; then say "Add"; fi ; done

What’s in a Name?

When I started writing this report, the Bonjour name for our printer was “Canon MF642C/643C/644C (a5:d7:ad) (16) (a5:d7:a (a5:d7:ad) (28)”. A few days later it changed to “Canon MF642C/643C/644C (a5:d7:ad) (16) (a5:d7:a (a5:d7:ad) (10)”. I have no idea what caused this change, and both the names are ridiculous.

The only thing that’s important in this change are the number in parentheses at the end. Going from “Canon…(28)” to “Canon…(10)” breaks the printer configuration of every Mac on your network.

You can see this by checking the CUPS configuration:

$ lpstat -v

device for Canon_MF642C_643C_644C: dnssd://Canon…(28)._ipps._tcp.local./?uuid=GUID

There is no longer a device for dnssd://Canon…(28)._ipps._tcp. So when CUPS periodically checks the print queues and it can’t find the name, the printer is permanently offline.

When a permanent “Offline” happens, you will need to update your Mac and iOS devices:

  • Mac: Remove the printer. Add a new printer. Do this on every device in your home or office.
  • iOS: Turn on Airplane Mode, wait a couple of seconds, turn Airplane Mode off, and pick the new name.

So What’s Really in a Name?

So what’s the deal with the “Canon…(28)” that eventually turned to “(10)” and broke everything? These numbers are appended automatically when another device is already using the same name. If “Craig’s Mac” already exists on the local network, if you try to add it again, Bonjour will use “Craig’s Mac (1)”. Look familiar?

It turns out this Bonjour cache corruption happened on macOS about 11 years ago and it was a clusterfuck. Some devices on your local network, such as Apple TVs or HomePods, act as a backup system that can provide DNS information when other devices are asleep. When this cache gets corrupted, all hell breaks loose.

A printer that constantly adding and removing itself will eventually poison the cache and the next number in sequence will be used. And every time the corruption occurs, new stuff gets added to the end and you eventually end up with “Canon MF642C/643C/644C (a5:d7:ad) (16) (a5:d7:a (a5:d7:ad) (10)”. Lovely.

Can Canon Fix This?

I have no idea what’s going on inside the printer, and from all the support requests on their site, neither does Canon. All I can see is that printer needs to quit and restart Bonjour every few minutes.

Typically removing a DNS service instance happens when the app or process that’s handling the requests needs to quit. It should happen very infrequently. Most likely because you’ve turned the printer off.

Instead of acknowledging issues with Bonjour, the support folks talk about changing your printer configuration. And conveniently ignore the folks who note that they’ve done this “hundreds of times”.

This is not a problem that can be fixed by a new downloadable driver or by power-cycling the printer. It is a problem that will require new printer firmware from Canon. The last firmware update was 2 years ago.

It’s a huge pain in the ass and based on my personal experience it happens when you need the printer right now. Adding insult to injury, everyone that’s sharing the printer, whether it’s a family member or a work colleague, will need to reset their printer configuration.

So I set out to find a way to avoid Canon’s shitty Bonjour implementation in our printer set up.

You Can Fix This

For the most part, it’s possible to use the Canon printer without its “cycling” behavior in Bonjour. The printer will still be generating and changing gobbledygook names, but we will ignore them.

The trick is to use a static IP address. Since Bonjour’s main task is to find your printer’s IP address using a device name, we can skip that step if we already know where the printer is on the local network.

VideoGuy discovered this workaround and shared it on the Canon forums. I’ve made some simple tweaks that let your Mac know about the full capabilities of the printer (duplex pages, color support, supply levels, even a non-generic icon).

1. Find a Static IP Address

To implement this workaround, you first need to know how IP addresses are assigned on your network. Most of the IP addresses are assigned automatically using DHCP. So look around in your router settings for something like “DHCP Range”, “DHCP Start/Finish”. Once you know the range, you can pick an IP address outside of that range.

Say that you see “Start: 192.168.0.20 Stop: 192.168.0.150”. Picking a static IP of “192.168.0.180” is a safe choice because its past “192.168.0.150”.

You can double-check that this address isn’t in use with this Terminal command:

$ ping -c 5 192.168.0.180
PING 192.168.0.180 (192.168.0.180): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
--- 192.168.0.180 ping statistics ---
5 packets transmitted, 0 packets received, 100.0% packet loss

The “Request timeouts” and “100% packet loss” indicate that there isn’t a device at this IP address and will be safe to use on the Canon printer.

2. Change Your Printer

Now that you have a static IP address, you’ll need to update your printer’s configuration. Use the Home button below the touchscreen to get to the top-level of printer menus.

Next, drill down using the following path:

Menu > Preferences > Network > TCP/IP Settings > IPv4 Settings > IP Address Settings

By default, the printer acquires its IP addresses automatically and “Auto Acquire” is turned on. The “Manually Acquire” setting is disabled.

Turn “Auto Acquire” off, and “Manually Acquire” will get enabled. Select it and you’ll be presented with a screen where you input:

IP address: 192.168.0.180 
Subnet mask: 255.255.255.0      
Gateway address: 192.168.0.1

The first field is the one you want to focus on: it should be set to the static IP address that you picked above.

The last two fields are probably already set correctly because the values were retrieved during the “auto acquire” – if you have problems with them, refer to your router’s settings.

After applying the settings, restart the printer, and run a quick test of the IP address with:

$ ping -c 5 192.168.0.180

Instead of timeout errors, you should see “0.0% packet loss” and know that you have a good connection to the printer. If you see errors, go back to printer’s network preferences and double-check your work.

3. Setup Printer on the Mac

We’re entering the homestretch now!

On your Mac, go into Printers & Scanners settings, and select “Add Printer, Scanner, or Fax…”.

Instead of using first panel which shows all the Bonjour devices, pick the middle icon of the Add Printer dialog: this panel will let you add your printer using the static IP address you created.

Enter your static IP address into the first field, then select the “AirPrint” protocol. Make sure that the driver is “CNMF642C/643C/644C” (or whatever is appropriate for your hardware).

Name the printer whatever you want: I chose “Canon MF” (again, not because it’s “Multi-Function”).

Click Add and you will now have a new printer that never goes “Offline”. Woo-hoo!

Note that this workaround only affects printing — when you need to use the scanning features, you will still need to setup a device that uses Bonjour. This configuration will break just as often as the one for printing, but in my experience it’s not so disruptive. I typically use the scanner when doing taxes or other financial things, and having to make a new configuration isn’t a big deal because I’m not in a hurry.

Conclusion

This issue has taken countless hours to resolve. It’s a bug that appears and disappears randomly and is completely confusing from an end user’s point-of-view.

As Mac users, we’re used to things “just working” and in this case that’s just not the case. Bonjour makes finding devices and services on your network “just work”. That is, until a Canon printer gets involved.

If anyone at Canon is reading this, please get in contact: I would love to test any firmware fixes for these Bonjour problems. I’ve been building Mac apps for over 40 years and have gotten pretty good at testing stuff.