title: Swift I
tags: ios, Swift, uikit, class, foundation, programming, string, productivity, tips, snippets, xcode
comments: true
date: 2014-11-03 13:23:06+00:00

As I am rebuilding my app in swift, might as well share things as I come across them. To my surprise, some really basic stuff have changed and don't behave as they did in Objective-C.

## Class Name

To load `UICollectionViewCell`s from NIB, I use a universal category/extension that loads the nib from class name. Of course, the easiest way to this was:

```objc
+ (UINib *)nib {
    NSString *nibName = NSStringFromClass(self);
    return [UINib nibName:nibName bundle:nil];
}
```

The reason we can use `self` directly is because self represents the caller class in Objective-C. So, even though this is a category on `UICollectionViewCell`, the result string from class will be resolved appropriately when we say `[MyCollectionViewCell nib]`.

So, simple enough, let's try converting the code to swift:

```swift
class func nib() -> UINib {
    let nibName = NSStringFromClass(self)
    return UINib(nibName: nibName, bundle: nil)
}
```

Yay, that was easy... Not. That doesn't work, and it fails. Let's print the value of `nibName` and see why: `MyProject.MyClass`. In swift, due to the existence of namespaces, the class is prefixed with it's target namespace. Unless you want to rename all your XIBs, and use the new convention, I suggest you add a global function that extracts the class name from the verbose form. Something like:

```swift
var classString = NSStringFromClass(self)
let range = classString.rangeOfString(".", options: .CaseInsensitiveSearch, range: Range<String.Index>(start:classString.startIndex, end: classString.endIndex), locale: nil)

var identifier = ""
if let dotRange = range {
    identifier = classString.substringFromIndex(dotRange.endIndex)
}
else {
    assertionFailure("Couldn't resolve class: \(classString)")
}

return identifier
```
