Upgrades!

Apple has released OS X 10.10.3, iOS 8.3, and Xcode 6.3 on April 8th!

The good news for everyone is bug fixes. The good news for me is no more dancing between Swift 1.1 and Swift 1.2. I’ve already updated relevant code from my recent posts on GitHub. For the first time in a while, I have just the one Xcode icon in my dock. I think I’ll keep it that way for a while.

I’ve also noticed that my twenty fifteen-child theme is unreadable on mobile devices. I’m going to switch back to the main theme while I get that fixed even though it uses up too much white space. It’s better that this blog be readable on mobile since that turns out to be the primary platform used to read it!

QR Code
QR Code

Xcode 6.2: Using Swift to Extend UIImage

In my last post, I created a simple utility for creating QR Codes. Although it doesn’t have the best UX, I thought I would ignore that and separate the QR Code logic from the program to make it more generalized. This was a perfect opportunity to use Swift’s extension feature which is the analog to categories in Objective-C.

The obvious class to extend is UIImage. The extension is simple. One might argue that the resizing function could be written with a completion handler as it is inĀ rajiev‘s blog entry here. The reason I didn’t is that the resizing operation happens quickly enough that there is no need to worry about threading issues. Interestingly enough, it has the information I was looking for on the Apple Developer Forums when I was trying to figure out how to resize a QR Code without interpolation so that I would always have a pixel sharp image.

I’ve already committed my code to the QRTest project on GitHub. For those that don’t want to pull the project or look on GitHub, here is the entire extension as it exists now.

 

import UIKit
import CoreImage

extension UIImage {

    class func qrCodeWithMessage(message: String) -> UIImage? {
        let data: NSData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
        let qrEncoder = CIFilter(name: "CIQRCodeGenerator", withInputParameters: ["inputMessage":data, "inputCorrectionLevel":"H"])
        let ciImage = qrEncoder.outputImage
        return UIImage(CIImage: ciImage)
    }

    func scaleQRCodeWithNoInterpolation(size: CGFloat) -> UIImage? {
        UIGraphicsBeginImageContext(CGSizeMake(size, size));
        let context = UIGraphicsGetCurrentContext();
        CGContextSetInterpolationQuality(context, kCGInterpolationNone)
        self.drawInRect(CGRectMake(0, 0, size, size))
        let image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image
    }

}

The only downside to this approach is that it is now a two step process to create and scale the QR Code. The upside is increased flexibility and cleaner (I hope) code.

Enjoy!

 

Xcode 6.2: A QR Code Creator

It’s all well and good to be able to scan QR codes as the HelloUPC test app does. But what about creating QR codes? It turns out to be fairly easy if you know how to do it. It took me a while to figure that out. So I thought I would help save time for anyone reading this interested in the topic. I created a simple iOS app in Xcode 6.2 using Swift to create QR codes.

QRTest

First I will confess that there are a couple minor bugs in the app. The layout is not quite what I would like. It is also necessary to double tap the text input field to get the keyboard so you can actually enter your own text to encode.

The layout issue was introduced when I switched from a simple UIView to a UITableView so that I didn’t have to manually deal with the keyboard possibly covering up the text input field. The double tap issue appeared when I finally found out how to dismiss the keyboard when the return or clear button is tapped.

I’m sure both bugs are trivial to fix. I am not bothering because the purpose of the app was to test drawing pixel sharp QR codes from a String object. The app does this, so I am happy. I actually went further than I intended by providing a means to allow a user to enter text and change the QR code without having to constantly edit the original code that is in the program source code.

The code has been tested on my iPhone 5s running iOS 8.2 and on the simulator in Xcode 6.2. If someone knows how to fix the double tap bug, I would love to hear what I did wrong there. Perhaps it’s just a matter of having another connection in the storyboard file.

One thing I am disappointed about is there is no DataMatrix encoder. It is easy to do Aztec, another 2D bar code. Aztec seems to be a bit slower to scan than QR (perhaps hence the name, Quick Response?). It also has a lower data capacity. QR codes are clearly far more useful than Aztec codes. I haven’t looked up the capacity of DataMatrix, but it would be nice to have it for completeness. The HelloUPC app will scan those just fine.

For those that don’t want to download an entire project from GitHub to see how the QR encoding is done, I’ll just copy the key function here.

 

    func QRCodeImage(message: String) -> UIImage? {
        let data: NSData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
        let qrEncoder = CIFilter(name: "CIQRCodeGenerator", withInputParameters: ["inputMessage":data, "inputCorrectionLevel":"H"])
        let ciImage: CIImage = qrEncoder.outputImage
        var image = UIImage(CIImage: ciImage)

        // Scale image without aliasing. Thanks, OOPer!

        UIGraphicsBeginImageContext(CGSizeMake(200, 200));
        let context = UIGraphicsGetCurrentContext();
        CGContextSetInterpolationQuality(context, kCGInterpolationNone)
        image!.drawInRect(CGRectMake(0, 0, 200, 200))
        image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image
    }

 

As you can see, this code returns a UIImage based on the encoded String. It is a simple matter to display, print, or whatever a UIImage. I recommend saving it as a PNG file as that is lossless and the file size will be fairly small. I leave that as an exercise to the reader.

Happy coding!