Skip to main content

Tech

Writing is hard

45 sec read

I think that what I do here can't really be called writing; it's more like scribbling, my posts are rather small and rare. But I try to be consistent, even if what I'm going to write about seems to not be of a big deal, because I believe that any info, no matter how big or small, might turn out to be useful to someone.

On the other hand, despite all these facts, I have weeks when I have absolutely no idea what to write about; there's zero inspiration. I can't even imagine how hard it is to consistently write posts of 500, 1000 or more words. Hats off.

NSDate operators

1 min read

I personally find this a bit of a mouthful, especially if you have to type it a lot:

if someDate.compare(otherDate) == .OrderedAscending {
  // Do stuff
}

Update, Oct 10, 2017: These are now built-in for Date. Leaving these here like they are (Swift 2), since the whole post is just about them.

But we can have a few operators to make our lives a bit easier:

Continue reading →

A fi programator după 40 de ani

39 min read

Postarea originală poate fi găsită aici. Unele cuvinte/exprimări traduse ori sună ciudat, ori își pierd din înțeles, așa că pentru acestea, am adăugat între paranteze termenul în varianta netradusă "(așa)". Am încercat pe cât posibil să păstrez tonul autorului.

Aceasta este prezentarea pe care am ținut-o la App Builders din Elveția pe 25 Aprilie 2016.

Slide-urile sunt disponibile pe SpeakerDeck. Înregistrarea video a sesiunii este disponibilă pe YouTube. Articolul a apărut în format fizic în ediția din iunie 2016 a Hacker Bits.

Continue reading →

Detecting retain cycles and improved logging

4 min read

I think adding everywhere a deinit method, with a print statement inside, is a decent first barrier against retain cycles:

deinit {
  print("Object X has been deinitialized.")
}

This way, if you expect object x to deinit at some point but it doesn't, you at least know you need to start searching, and where.

Now, for the improved printing, to make this a bit cleaner and easier:

Continue reading →

Improving UIFont workflow

1 min read

Usually an app has fonts with well defined purposes. So why not let enums make our lives easier, a little bit? First, a couple of them, to define our font families and weights:

struct Font {
  private enum Family: String {
    case avenirNext
    case proximaNova 
  }
  
  private enum Weight: String {
    case regular
    case medium
    case demiBold
    case bold
  }
}

Then a method to easily create fonts:

Continue reading →

Setting variables with tuples, switches and closures

2 min read

Let's say we have a custom UILabel, which in turn has several types; maybe a StatusLabel that can be of type sold out and expired. The label would have several common properties, but each type would have something specific. How can we go about this?

class StatusLabel: UILabel {
  enum StatusType {
    case soldOut 
    case expired
  }
  
  init(type: StatusType) {
    super.init(frame: .zero)
    
    font = UIFont.common
    layer.cornerRadius = 4
    textAlignment = .center
    translatesAutoresizingMaskIntoConstraints = false
  }
}

We now covered the common parts, and we could go ahead and set the backgroundColor and textColor like this:

Continue reading →

Better interaction between viewWillTransitionToSize and CGSize

1 min read

Instead of checking if size.width > size.height, we can have three handy CGSize extensions:

extension CGSize {
  var isCompact: Bool { return height > width + delta }
  var isWide: Bool { return width > height + delta }
  var isSquare: Bool { return abs(width - height) < delta } 
}

For usage within viewWillTransition(to:with:) I don't think the delta will be really needed, but if we want to use these properties for our own custom views, it might come in handy. Modify its value to fit your own needs, of course.

The MAS, updates and the CLI

1 min read

I've had problems with stuck updates, or slow downloads with the MAS for as far as I can remember. softwareupdate never really was of much help, using MAS' Debug menu neither, nor killing softwareupdate related processes.

Yesterday I found the answer to all of this: a gem for manipulating the MAS from the CLI. It uses native APIs, from login (the MAS login pops up), to downloading files (you can even start an update with the MAS and finish it on the CLI - the download files are the same). And you also get a nice, little progress bar.

A few commands available:

Continue reading →

Easier hugging / compression handling

2 min read

I'm pretty sure this won't suit all cases, but, usually, a label / button should highly resist being vertically shrunk more than its intrinsic size. On the other hand, we won't always mind if it grows larger than its intrinsic size, but we'd like to avoid it, if possible.

I, personally, find this a bit of a mouthful:

label.setContentCompressionResistancePriority(.required, forAxis: .vertical)
label.setContentHuggingResistancePriority(.defaultHigh, forAxis: .vertical)

So, let's extract them into a method, with default values as added bonus. We'll also use an enum, so we can have "intermediate" values as cases:

Continue reading →

TableViews, collectionViews and Swift enums

2 min read

I talked about how we can have a safer and cleaner tableView/collectionView section handling, but we can improve it even further, with protocol extensions:

protocol Countable {
 
  var rawValue: Int { get } // 1
  init?(rawValue: Int) // 2
 
  static var count: Int { get } // 3
 
}

This is a protocol that mimics an enum that conforms to Int: it has a rawValue of type Int (1), it has an initializer based on said rawValue (2), and it has a static var (3) that will be used to hold the total number of cases. And here's where extensions come into play:

Continue reading →