UITextView, autocorrect, and custom attributes

For this week’s “Nerd Snipe”, I spent way too much time at work trying to track down a pesky bug related to our editor. Long story short, we send some custom NSAttributedString.Keys to signify differences in rich text. For instance, a heading attribute with an integer value may tell a parser to wrap text in an <h2> when converting the string to HTML.

Oddly, sometimes that special attribute wouldn’t be included when text was autocorrected, so the generated HTML wasn’t always what we expected. After a lot of digging I believe this could be a bug in UITextView (or maybe NSTextStorage).

Inspecting the value of attrString in the NSTextStorage function func replaceCharacters(in range: NSRange, with attrString: NSAttributedString) after autocorrecting some text shows that it only seems to include attributes that were defined in Foundation (e.g. NSFont, etc.), but not our custom ones.

Regular typing works fine – you see all the expected attributes set in textView.typingAttributes.

In scenarios like these I like to make the simplest example to help confirm I understand it, so I’ve made a repo demonstrating the issue in case it’s helpful for anyone.

Wyze Cam in iOS

Flip Dots!

I saw flip dots (also called flip discs) last year for the first time and instantly knew I needed some in my life. If you’re not familiar with them, check out how they work!

The particular model I have is the ALFAZETA XY5, which may be the easiest way to get up and running, but certainly not the least expensive.

After getting the board, all you need is:

  1. 24V power supply
  2. Something that talks over RS485 (in my case I used an ESP8266 connected to a MAX3485 board)
  3. Their documentation that defines the controller data protocol

I plan to write in more detail how it all works, but for this demo the stack is:

  1. SwiftUI app that runs SwiftGFXWrapper (which is mainly Adafruit’s GFX Library under the hood)
  2. The app sends the entire pixel buffer over UDP to the ESP8266
  3. The ESP8266 sends data to the XY5 over RS485 using their controller’s protocol