How to create an Objective-C Bridging header

Super important to know during this time of Objective-C to Swift transition. I’ve had to use this technique and it will be good for all Swift developers to have in their kit-bag until we can finally be 100% Swift.

How to create an Objective-C Bridging header – iOS-Blog
So you want to use an Objective-C Library or SDK in your Swift application eh? Well do not fret. This quick tutorial will show You how you can create an Objective-C Bridging Header in your Swift application so you can use them both together and seamlessly.

UIView Animation with Swift

Here is a very simple way to do UIView Animations in Swift.

First, you create an IBOutlet for a constraint created in Interface Builder in Xcode – in my case, I had a constraint that anchored to the bottom of the containing view. In the code example, the constraint is named “constraintToAnimate”. You just control drag from the Storyboard to your code as you would when connecting a control, but in this case you connect a constraint. It will look something like this (the name of your constraint will hopefully be different):

    @IBOutlet weak var constraintToAnimate: NSLayoutConstraint!

The following snippet is basically a straight-up conversion of Apple’s own Objective-C example given in the documentation article Auto Layout by Example in the Animating Changes Made by Auto Layout section (you may need to scroll down to find that section).

    self.view.layoutIfNeeded()
    UIView.animateWithDuration(0.3, animations: {
        // make constraint changes here...
        self.constraintToAnimate.constant = 250 // your value here.
        self.view.layoutIfNeeded()
        }, completion: {
            (value: Bool) in
            // completion code here...
    })

Basically, in pre-Auto Layout days you would just animate the frame. Today you just animate the constraint. It works great and once you get your head wrapped around it, it’s pretty straightforward.

UIDatePicker Height Inconsistency at Runtime [#iOSDev, #SwiftLang]

Apple needs to fix this one.

There is an inconsistency in the way that the UIDatePicker is rendered in Storyboards in Xcode vs. their rendering at runtime. This problem set me back longer than it should have this morning, since its effect was tricky to diagnose. The basic consequence of this was that the custom UIButton I had attached to the top of the date picker (inside a UIView) was not receiving taps and for the life of me I couldn’t figure out why…

First, to diagnose the problem, I used this tip to get the UIView recursiveDescription method working in my Swift project, and I was able to get a dump of the view hierarchy. From that, I could tell that the UIView I had created as a container was at a Y value of -54, and was therefore outside the bounds that I had set for the custom view, and was not receiving tap events.

Then I stumbled on this Stack Overflow post by Florian Mielke, which suggested that there is a typo-bug somewhere in Xcode or iOS in the rendering of UIDatePicker in a Storyboard vs. Runtime:

iphone – iOS 7 UIDatePicker height inconsistency? – Stack Overflow

“I can confirm that using UI(Date)Picker in storyboards has a different height (162.0) than in “reality” (216.0). Therefore you have to adjust the space to container view to fit that ‘real’ date picker height or try to solve it using auto-layout.”

Reconciling that with the output from recursiveDescription totally agreed with this, and once I increased the size of my custom view, taps were once again being received by the Done button!

How to read a JSON file from your bundle and output the contents as a String in Swift

When you’re first getting started with Swift, even the easiest things may seem a challenge. For example, reading in a JSON file, converting its contents to a String and then sending the result to the console may take a while to figure out (at least, it did for me…).

I needed to do this in my current project for diagnostic purposes, and thought it might be helpful to others, so here’s the little code snippet I used:

    // 1
    let filePath = NSBundle.mainBundle().pathForResource("MyJSONFileName",ofType:"json")
    // 2
    var readError:NSError?
    // 3
    if let data = NSData(contentsOfFile:filePath!, options:NSDataReadingOptions.DataReadingUncached, error:&readError) {
        // 4
        let stringData = NSString(data: data, encoding: NSUTF8StringEncoding)
        // 5
        println("data read: \(stringData)")
    }

As you can see, it’s pretty straightforward.

  1. Create a file path to the file.
  2. Declare an NSError object for use in the reading (this example just eats the error, however).
  3. Read in the data from the JSON file.
  4. Create an NString object, initializing it with the NSString(data:encoding:) method.
  5. Output the result.