Nice technique to specify log messages

Just changed jobs, and having to switch back to Objective C for most of my work. I’ve used a selectable macro in the past for log messages:

#if 0 // 0 == no debug, 1 == lots of messages
#define LOG(...) NSLog(__VA_ARGS__)
#else
#define LOG(...)
#endif

You can add this to each source file, and selectively turn messages on or off with one tiny change. But the problem is, you look in console and there are slews of log messages. So how to know which is from what file?

Well, I just found out I can change the above to:

#if 0 // 0 == no debug, 1 == lots of mesages
#define LOG(...) NSLog(@"DBManager: " __VA_ARGS__)
#else
#define LOG(...)
#endif

That is, since Objective C will coalesce strings, it will merge @”DBManager: ” into whatever format string you used.

I suppose the __FILE__ or NSStringFromClass([self class]) might work too – but I didn’t try.

How to Calibrate a New Monitor

The Apple ColorSync calibration screens are useless. I entered a bug over 8 years ago on it, and nothings changed.

My over-5yr-old Hanns-G 27.5″ model died (cost $400+) and I replaced it with a 27″ LQ 27MP57HT-P monitor (cost ~$125!). However, when I plugged it in to my Mac, it looked terrible!

After trying the Apple calibration, I re-discovered a web site that I now remember using to calibrate the old monitor: LCD Calibration

Using the sharpness test, I discovered that the LG essentially turns it off at a setting of 50, not 0 and not 100.

In the end, I found settings of:

Brightness: 70
Contrast: 71
Black Level: High
Super Resolution: Off
Color Levels: All at 50

Hope this helps someone someday. I found nothing googling around.

Incredibly small+compact+clever Swift code for descriptive Auto Layout constraints.

I book marked SwiftAutoLayout when I first saw it announced. This amazingly compact and innovative bit of code was written by a young Canadian student Indragie Karunaratne.

Currently, there are several popular DSLs for doing Auto Layout related work (mostly creating constraints), but they are all (IMHO) way to large and all encompassing. Indragie’s code is lightweight, clear, and does most of what you’d want. I often evaluate code I use with the question: “Can I maintain this if the original author abandons it?” Clearly this code falls into the “yes” category (for me and for most others too!)

This code hadn’t been updated since early this year, so I
forked it and addressed one feature request and added support for new constraint options available in iOS8.

Lets look at an example of creating two constraints:


let constraints: [NSLayoutConstraint] = [
contentView.al_centerX == rLabel.al_centerX,
detailLabel.al_baseline == rLabel.al_baseline
] // wrapped for easier viewing
contentView.addConstraints(constraints)

In this simple example, there are two equalities. More complex constraints might have a multiplier, constant, and priority, in which case they’d look like:


let constraint = view1.al_left == view2.al_right * 2 + 10 ~ 100

instead of the standard method:


let constraint = NSLayoutConstraint(item: view1,
attribute: NSLayoutAttribute.Left,
relatedBy: NSLayoutRelation.Equal,
toItem: view2,
attribute: NSLayoutAttribute.Right,
multiplier: 2.0,
constant: 10.0) // wrapped for easier viewing

constraint.priority = 100

Almost better is the wow factor you get when reading the code to understand how it works! By using extensions to UIView (the al_… attributes), these expressions get turned into ALLayoutItem structures, which you the user never see. They simply act as placeholders for values, so the expression can evaluate to a single NSLayoutConstraint!

It took me a few reads of the code to “get” it, then “Wow!”. In the end, you get an incredibly useful utility barely consuming 250 lines of code, and have the opportunity to see Swift used in a way you probably never even thought of.

[Lastly, I should add that Indragie contacted me, and has asked for a pull request so he can wrap this Swift 2.0 code into his original repository – something I will do shortly when iOS 9 goes GA.]

Amazing technique to embed non-optional assignments within a comma separated “if let” statement

The problem is, you have this complex set of assignments to complete before you can take an action, and most of them are optionals – but not all:


for cell in tableView.visibleCells {
  if let indexPath = tableView.indexPathForCell(cell) {
    let user = users[indexPath.row]
    if let ratingLabel = cell.contentView.viewWithTag(100) as? UILabel { 
      setRatingLabel(ratingLabel, user: user)
    }
  }
}

Now imagine more assignments, a few optionals then a non-optional – it regresses to the old “cascading if let” situation in pre-Swift 1.2 code.

This type of situation appears in my code all the time, so I

posted a question on the Apple internal Swift forum asking for suggestions.

Fortunately, it was answered by OOper! It seems that you can embed a non-optional assignment by prefix it with “case”:


for cell in tableView.visibleCells {
if let indexPath = tableView.indexPathForCell(cell),
   case let user = users[indexPath.row],
   let ratingLabel = cell.contentView.viewWithTag(100) as? UILabel
   {
     setRatingLabel(ratingLabel, user: user)
   }
}

I’d love to say I completely understand why it works – I think it’s because ‘case’ statements can fail or succeed. In any case all my code using this works just fine.

While looking a bit odd, the final code is more compact and easier to follow.

Swift 2.0: Catching enums having associated values

Many blogs touch on the ability of Swift to throw an enumeration that contains a payload value, but no one has really shown how to get the associated values – particularly if the different enumeration payloads differ in type.

Here is an example, which shows how to catch those errors and extract the associated value:

enum Foo : ErrorType {
case First(String)
case Second(Int)
}

func flup(i: Int) throws -> Bool {
  if i == 0 {
    throw Foo.First("Howdie")
  }
  if i == 1 {
    throw Foo.Second(2)
  }
  if i == 2 {
    throw Foo.Second(4)
  }
  return true
}

print("Howdie")

do {
  try flup(0)
} catch Foo.First(let error) {
  print("ERROR: \(error)")
} catch {
  print("WTF: \(error)")
}

do {
  try flup(1)
} catch Foo.First(let error) {
  print("ERROR 1: \(error)")
} catch Foo.Second(let error) {
  print("ERROR 2: \(error)")
} catch {
  print("WTF: \(error)")
}

do {
try flup(2)
} catch Foo.First(let error) {
  print("ERROR 1: \(error)")
} catch Foo.Second(let error) {
  print("ERROR 2: \(error)")
} catch {
  print("WTF: \(error)")
}

This is what appears on the console:

Howdie
ERROR: Howdie
ERROR 2: 2
ERROR 2: 4

How to develop a common subclass for UIViewController, UITableViewController, and UICollectionView controller?

This task is seemingly impossible. You’d like to have some common methods to use for all three controllers. Because of the apparent lack of the ability to “interject” a UIViewController subclass into a UITableViewController, I just never used it. When UICollectionViewController came out, though, I was determined to find a way to do this.

At first I tried using a UIViewController – .m and .h – with macros, but I never got it to work properly. Finally, I created two files, ¬†BaseClass.h and BaseClass.m. In the former, I just declared the methods themselves along with any public properties. Then in the implementation file, I coded the methods. Note there is no “@interface…” or “@implementation”.

Finally, I created three subclasses, STViewController, STTableViewController, and STCollectionViewController, and between the interface declaration and “@end”, included the base class file. Voila – works like a champ.

What’s even more amazing is that Xcode’s editor works just find with these naked methods when editing BaseClass.m – it parses them and highlights errors just as it would for a normal class!

A property/ivar/outlet was just changed, how do I find out who did it?

I see this post all the time on StackOverflow. The answer is surprisingly simple:

– if you have an ivar, convert it to a property with a synthesize ivar=ivar if needbe to avoid having to prepend a “_” to usages

– write your own setter, and add logic tests and NSLog messages

Рput a breakpoint on the NSLog message, and run your app

Voila! You app stops when the value changes, and you can see who the offender is!