Adding string attributes slightly easier

:  ~ 2 min read

Say we have a composed string that looks like this:

let date = "22 July, 2017"
let value = "€ 148"
let quantity = 5
let string = "\(quantity) of your items, in value of \(value), have been delivered on \(date)."
// 5 of your items, in value of € 148, have been delivered on 22 July, 2017.

It would be nice to emphasise the important bits, and the usual approach would be to create an NSMutableAttributedString, and to add the required attributes:

let attributedString = NSMutableAttributedString(
  string: string,
  attributes: [
      NSFontAttributeName: UIFont.systemFont(ofSize: 14)
      NSForegroundColorAttributeName: UIColor.gray
  ]
)

attributedString.addAttributes(
  [
    NSForegroundColorAttributeName: UIColor.darkGray,
    NSFontAttributeName: UIFont.boldSystemFont(ofSize: 15)
  ],
  range: (string as NSString).range(of: date)
)
attributedString.addAttributes(
  [
    NSForegroundColorAttributeName: UIColor.darkGray,
    NSFontAttributeName: UIFont.boldSystemFont(ofSize: 15)
  ],
  range: (string as NSString).range(of: value)
)
attributedString.addAttributes(
  [
    NSForegroundColorAttributeName: UIColor.darkGray,
    NSFontAttributeName: UIFont.boldSystemFont(ofSize: 15)
  ],
  range: (string as NSString).range(of: quantity)
)

That's a bit of a mouthful, if you ask me. forEach to the rescue!

let attributedString = NSMutableAttributedString(
  string: string,
  attributes: [
      NSFontAttributeName: UIFont.systemFont(ofSize: 14)
      NSForegroundColorAttributeName: UIColor.gray
  ]
)

[date, value, quantity].forEach {
  attributedString.addAttributes(
    [
      NSForegroundColorAttributeName: UIColor.darkGray,
      NSFontAttributeName: UIFont.boldSystemFont(ofSize: 15)
    ],
    range: (string as NSString).range(of: $0)
  )
}

Slightly more compact, and a bit easier to scan.

On a side note, I find it funny how NS(Mutable)AttributedString requires a String, and won't accept an NSString to init, but addAttribute(s) requires an NSRange. ¯\_(ツ)_/¯