Parsing HTML in Swift 3 (and RTF, etc.)

A friend of mine and I were discussing how to parse HTML and turn them into NSAttributedStrings the other day. That is to say, to take a tagged string, such as

<h1><i>This</i> is <b>NPR</b></h1>

And produce an NSAttributedString that will look like:

This is NPR

xkcd comic
*This* is HTML
  • My friend, who works at a well-known dating app startup, had a rather limited problem (no font or color variations, for example), and could hard-code much of his solution, using NSScanner to do the rest.
  • I came up with an algorithm using a struct to hold Range and NSAttributeName information, and filling those structs by extracting the information while walking through the original string using a regex pattern (something like <\/?\w[\w\d]?\w{0,9}>) to catch the tags.
  • But before we could have the fun of combining/comparing the two solutions, I had a facepalm moment, discovering the built-in methods for doing so, and wrote the following extension (below).

AutoLayout Equations and The Trivial Solutions that Magic Away your UIViews

The Lost Socks of Interface Builder

There are times when AutoLayout makes me think of views as socks: sometimes you cannot locate a UIView no matter how simply you laid it out the night before. It doesn’t matter if you did it programmatically or in Interface Builder, it may as well be on the dark side of the moon, or stolen by UIView Gnomes. You suspect Autolayout is the culprit, but you get nothing in the console. Nada. Silent failure. No [UPDATE: Often no] helpful remarks like:

“I’ll assume you know what you’re doing, usually, and were merely distracted by some 18th century disease — say, dysentery — when you gave me illogical and contradictory constraints. By looking or not looking at this window, you are agreeing that it was ok for me to break some of those constraints at my whimsy. Next time, try harder, or don’t try at all, buddy. And stay healthy — cholera is not covered by Apple Care.”

I have begun reading Erica Sadun’s excellent, if only slightly dated*, iOS AutoLayout Demystified. She notes what the Apple Docs say, that autolayout basically solves a system of linear equations. What…??, you ask. This is today’s nugget: you already learned the basics of solving systems of linear equations in high school, if not grade school (for those readers in grade school, read on and learn!).

*”Completely updated for iOS 7 and Xcode 5!”

 

tl;dr — sometimes the only solution to an equation is the trivial solution (e.g., 1 – x = 1 + x is true when x = 0). This is different than no solution (e.g., x – 1 = x + 1). In autolayout, no solution leads to a warning/crash/constraint-breaking. A trivial solution can often (but not always) lead to silent failure – a view of 0 x 0 dimensions — though in Xcode 7, the compiler has often said “You probably didn’t mean it, I’ll break one of these constraints.”

 

Appendix

N Equations for N Unknowns

Let’s solve for x, shall we?

x = 3

Have you got it? I hope so. In this equation, there is one unknown, and we can fully solve for the variable, x. The same is true for this variant:

3x – 2 = 7

Although more convoluted, we essentially have a single Unkown, and one equation suffices to solve for it.

If we had two unknowns, however, we would not be able to do so:

y + x = 4

Indeed, the set of possible solutions is infinite, since you can pick any pair of numbers that ‘cancel out’ (for example: [0, 4], [1, 3], [-100, 104], and so on…). That set, by the by, can be represented visually (say, on graph paper) as a Line. But we can solve this:

Screen Shot 2016-01-20 at 11.42.25 AM

For the visual learners, this would be represented by taking that line (y = -x + 4) and picking the spot where = 3.

Screen Shot 2016-01-20 at 11.44.25 AM

System?

When we presume that the x in the first equation is the very same x in the 2nd equation, we are viewing the two as a system. Put differently, the equations comment on one another. Think of Sudoko.

Su Doku, xkcd-style
Click Me for something slightly worse!

Fancy Mathy Pants

In school we learned to “plug in” the variables from one equation into the other in order to solve these (“substitution method”), and most high school math courses teach linear arithmetic (“elimination method”). But there are many sophisticated techniques for solving these equations quickly and efficiently.

[The place to start might be Khan Academy, but I am a big fan of Gilbert Strang’s course (and textbook!), now online for free from MIT (text not free ☹ )].

Conclusion: Solving for x, Solving for UIViews

What about these equations, do they have a viable solution?

x = 3, x = 4

Correct, they don’t! If those equations represented constraints, they would crash the app, or eliminate your views — or Xcode could/might ignore one of them for you, and let you off with a stern warning. And if the latter happens, heed the warning, and fix the constraints – because if you are not deciding how to place your views, who is??

 

Adding a Decoration View to a UICollectionView in Interface Builder

tl;dr: You Can’t. But…

My current project employs multiple UICollectionViews with custom layouts. Those layouts have a nice decoration view that I borrowed from Joe Keely and Kyle Richter (repo here), which puts a sleek, modern IKEA style ‘shelf’ behind the collectionView’s

Saweeet UIDecorationView
Saweeet UIDecorationView

cells (i.e., the ‘books’).

However, I kept getting an error, which the debugger translated as “You need to register your decoration view as a class or a nib, or prototype it in storyboard.” This, I was happy to do, except that storyboard does not provide decorationView protoyping, just header/footer views, and of course, the collectionViewCells themselves.

…you can register them in initWithCoder.

Imagine my surprise when despite all my efforts to register the durn view, Xcode was not in the least impressed. To make a long story short, I remembered that when initializing an object in Storyboard, initWithCoder is called (rather than init). I do not recall exactly which Apple docs gave me this nugget (please let me know in the comments), but I believe it was some chain of hyperlinks bouncing off NSCopying and NSCoder protocols.

In hindsight, there it is, clear as day, on SO. But duplication of answers to debug questions is (often) Good for the Internet, providing a larger bullseye for a questioner to hit. Happy Bug Hunting y’all!

…and we’re back!

UICollectionViews and I (part I)

tl;dr – one-line designated-init-boilerplate

If you take nothing else from this post, here is a clever LOC I encountered in Ash Furrow’s book on UICollectionViews:

Ok, on to the post (or skip to the summary):

First Thing: Apologies.

My apologies to you, my adoring audience and fans, during the unexpected and unexplained interruption. I cannot change your expectations, but I can provide an explanation: I switched web hosts to save $100, and learned much about the process in doing so. My biggest lesson (read “mistake from which I am determined to squeeze out something constructive”) was in regards to the WordPress Migration plugin.

Namely, I learned that It Exists! Never migrate by hand again; next time you are lost in the woods with your celebrity crush, and desperately need to find food, shelter, and to migrate your wordpress site, use this swiss army knife to look suave in front of your million dollar companion as you save the day!

Second Thing: Some Ash Furrow tips on UICollectionView

I have been working on an app for my portfolio that uses UICollectionViews, and ideally, needs a custom layout. This is a fun challenge, since it involves a bit more of my math background, but I really appreciate the tidbits an experienced dev throws in when showing you around a favorite piece of tech. Thus, I am going through Ash Furrow’s book on UICollectionViews, and thought to share some of the tidbits I picked up so far, halfway through.

Furrowisms

  • XIBs and Storyboards are not really worth it for UICollectionViews, (with the possible exception of just having a blank one for the initialization code). Why?

“There are two problems with storyboards and collection views: the tight coupling between the collection view cell (its reuse identifier) and the code, and some tricky debugging when you modify the settings of the storyboard in code at runtime. You can’t rely on what you see visually at compile time because it’s likely going to be changed by code at runtime, anyway.” (Kindle Locations 834-836)

  • “[Use] custom UICollectionViewCell subclasses to keep your code loosely coupled; your view controller shouldn’t know about the internals of the cell’s view hierarchy.” (Kindle Locations 840-841)

Summary Conclusion

  • Clever 1-line init boilerplate.
  • WordPress Migration plugin for painless blog migration.
  • I’m knee-deep in UICollectionViews, and aim to present a recipe/tutorial on layouts soon, knock on wood.
  • Homage to Ash Furrow _|-\o_

Yet Another UI Demo App

“Libraries for Developers” UI demo app

This is an update/add-on to my earlier post about UI Controls apps. This app, like Cocoa Stars, is a ‘meta-app’, presenting and demo’ing a curated collection of third-party libraries or pods. I have found almost no overlap between the two apps, which is most impressive. You are able to ‘star’ and share links of the repos, which is very helpful, since I often find myself going through the demos like a catalogue, all at once, rather than seeking a specific solution for a given need. The PRO version costs $1, which I purchased to support the developer. Check it out!

Transcompilers and Interlinguistic Diplomacy

One of the most frequent questions asked by initiates into the profession is What language should I learn? This post…is not about that. Rather, it’s about transcompilers.

tl;dr – Why does this matter?

What is a transcompiler?

First, what is a regular compiler? A traditional compiler translates from a higher level of abstraction (e.g., Objective-C) to a lower level of abstraction (e.g., assembly or machine language). If a regular compiler can be thought of as ‘vertical’ translation, a transcompiler would be horizontal translation: it translates code from one language to another language of the same level of abstraction.

Screen Shot 2015-07-06 at 9.16.44 AM

It is very hard to write machine code directly. Humans overwhelmingly have some medium between us and the machine.
It is very hard to write machine code directly. Humans overwhelmingly have some medium between us and the machine.

One example is Coffeescript, a programming language that transcompiles into JavaScript, but has syntactic sugar inspired by Ruby among other languages. Wikipedia has a short and sweet example of how you can write something in one way, and have it compile natively as if it were written in a different way.

Where does Objective-C fit in?

Mostly, it doesn’t. This is because Objective-C has been developed more or less to support Apple devices, and the devices + language are more or less a one-to-one fit. However, often the tricky part of coding is not the UI, but the computations under the hood, aka business logic (I don’t only link to wikipedia, but I have found that, when it comes to All Things Code, it often is short, sweet, and to the point in an accessible way). Enter j2objc.

J2objC: Google’s Solution to a Shared Problem

J2objc is a script-based translator that converts Java source code into Objective-C source for iPhone/iPad applications. It is not an emulator, but outputs source code that can be built by XCode or Make, so the resulting apps run natively. My next post will be a non-methodical summary and highlight of descriptions I have found in the docs, and from a presentation (here) by the head of the project, Google’s Tom Ball. I have also been playing around with the tool, and will report any successes I have had. And if the gods smile on my efforts, I just may include a tutorial.

J2objC is not a cross-platform application tool. The source-code is compiled into object files, then linked up into an app. Your iOS device is running pure Objective-C. I will

tl;dr – Why does this matter?

This tool allows you to plug Java files into your Objective-C project. Java is still the #1 most popular programming language (by some metrics, at least), so collaboration can be made more easily. Java is also used for Android app development, and though it cannot be said that you could “write once, run anywhere”, it can automate much of the hassle of cross-development (e.g., the team at CodeName One, or these guys).

Helpful Unicode Characters

While the standard keyboard usually grants access to all the keys in regular use, and creates hotkeys for power use, in the middle lie the forlorn, neglected symbols. Symbols tap into an ancient and effective register for quick and immediate recognition, so they are especially appropriate to squeezing more functionality from said keyboard. Moreover, as a relative beginner in a class with other relative beginners, I find that communicating hotkeys and shortcuts is not as effective without the appropriate icons. So here they are, along with the unicode number needed to type them.

[How do you type unicode characters? Switch to the unicode hex input keyboard, then hold ⌥ + ???? and the icon magically appears!]

Source: obvious, no?

[How do you add the unicode hex input keyboard? See below.] By the by, you’ll often see these characters’ numbers preceded by & or # or x’s. They refer to the number’s base, and the character system used. So these characters are actually preceded by a Ux????. ‘U’ for unicode, and ‘x’ for hexadecimal.

Mac Special Key Icons and Unicode Number
 – F8FF
⌘ – 2318 – the Command Key symbol
⌥ – 2325 – the Option Key symbol
⇧ – 21E7 – the Shift Key (really just an outline up-arrow, not Mac-specific)
⎋ – 238B – the Escape Key (also not Mac-specific; described as “BROKEN CIRCLE WITH NORTHWEST ARROW”, or an escape character from ISO 9995-7).
And while we’re at it, some related (not mac-specific):
⇥ – 21E5 – the Tab Key symbol
⏎ – 23CE – the Return Key symbol
⌫ – 232B – the Delete Key symbol
⌽ – 233D – a possible substitute for the Power symbol
And even less used, but still common enough to merit Apple’s attention:
Mnemonic note: ALL the common arrow symbols are from 2190 to 21FF (list here), so play around, have fun!
← – 2190
↑ – 2191
→ – 2192
↓ – 2193…
⇞ – 21DE – Page Up symbol
⇟ – 21DF – Page Down symbol
etc.
Adding the Unicode-Hex Input keyboard

Go to Preferences  → KeyboardInput Sources and search for “Unicode”, and check the box.