Keycode constants for the Logitech R800 Professional Presentation

If you’re using an R800 on the mac for a custom application along with my CSTEventManager library, the following keycodes can be used. Don’t forget that you should configure the R800 as an ISO keyboard.

Code Number Description
116 The Previous Slide button
121 The Next Slide button
96 Start/Stop Presentation toggle button
47 Blank screen toggle button

Adding NOT-MODIFIED (304) behavior to AFNetworking 2

After reading this stackoverflow post, I thought that I would simplify it by subclassing AFHTTPRequestOperationManager and wrap all of this stuff in a new method that I called GET:parameters:success:failure:unmodified:

According to this other stackoverflow post, NSURLCache needs a little bit of time to warm up, so I added a class initializer. From your AppDelegate’s application:didFinishLaunchingWithOptions: method you can call this early:

Using this new method is simple:

Hopefully this will be useful for you. If you’re worried about a nil unmodified or success block, you can prefix those calls with if (unmodified) unmodified(operation,responseObject) and if (success) success(operation,responseObject).

A little macro magic for handling NSError** within a method

I don’t like checking if the caller passed me a nil NSError** in my own methods, especially if the implementation is somewhat lengthy, so I’ve put together a very basic C macro that declares an autoreleasing NSError* to use as temporary storage in case of a null NSError** parameter from the caller:

Imagine that I have a method named foo that takes a single NSString* and an optional NSError**:

Now I don’t need to check if I’ve been passed a valid NSError** pointer, because it will be assigned to the local tempError variable if it was nil.

iOS 6, Base Localization, and UISwitch

I just thought I’d share something I ran across today with iOS 6 and UISwitch controls.

If you put a UISwitch in a XIB and expect the text inside of the UISwitch to appear in the right language, iOS 6 will look in your app’s (current region name).lproj for a file named (same as xib).strings.

For example, if I have a UI defined in SettingsViewController.xib, and that UI has a UISwitch, and I want a Japanese user to see that switch’s on/off in Japanese, I need to make a file named ja.lproj/SettingsViewController.strings. The strings file doesn’t need to have anything in it, but it can’t be zero length. The easiest thing to do is just throw in something like:

And then convert that file to a binary plist using the plutil command-line tool:

Note: don’t forget the ‘1’ in binary1. More information on man plutil.

If you’re developing exclusively within XCode 5, then I’d suggest just localizing any XIBs and let XCode do the magic for you.

Handling Cocoa keyboard events using Blocks

I’ve added a project to GitHub on handling keyboard events in Cocoa apps with blocks.

The handling code is all in the CSTEventManager class: you can register for events like this:

Here’s the contents of my README file from the GitHub project:

NSEvent uses NSTimeInterval (the time since your computer last booted) as the time when an event occurs. For logging and other purposes, I’d rather have an absolute time, and coming from Java, I’m used to Unix time (milliseconds since January 1st, 1970).

I found some great code on Stackoverflow for efficiently converting an NSTimeInterval to a Unix time. Using an Objective-C NSEvent category, I added a new property to NSEvent called “unixtimestamp” that gives you the value in a long long:

The relevant code is in NSEvent+CSTUnixTimestamp.h/m

At the same time, I wanted something similar to the Java AWT’s addEventListener API for handling keyboard events using blocks.

I’m not an AppKit expert, but from what I gathered the simplest technique is subclassing NSWindow and track the keyboard events there. Instead of plopping all of the handling code in that subclass, I made a separate protocol and class so you can quickly reuse the code in other NSResponder implementations.

The protocol is CSTEventSource.h, and the handling class is CSTEventManager.

Another thing that I found annoying is that NSEvent keycode constants don’t exist for most of the standard keys, so I created one for just a couple of keys as an example of how it could be done. Check out CSTKeyConstants.h/m to see how I did it (nothing special).

This project has a complete UI example. When using these classes in your own project that builds everything from a nib, remember to input the NSWindow subclass in the object inspector’s Custom Class field. One trick that I do is override –initWithContentRect:styleMask:backing:defer: and add an NSLog message: if the logging message doesn’t appear when the nib is loaded, that means I forgot to set the custom class.

Run the program and press the spacebar. You should see the down and up events in the attached NSTextField, and the up event is also logged using NSLog, showing how you can register more than one handler per event type.

Repeat keydown events are blocked by default in the CSTEventManager, but you can enable them using the property keyDownRepeat:

Cocoa wrapper for iOS cryptography

Java has many APIs that I miss when programming in Objective-C, but by far the most painful loss has been the Java Cryptography Extension. I’m not an expert in cryptography, but there’s an elegance in that API that is missing from Apple’s CDSA and CommonCrypto mashup available natively on iOS.

So, I thought it would be nice to abstract some of the features behind Objective-C protocols:

  • KeyGenerator: creates new SecretKey objects
  • SecretKey: represents a symmetric key
  • KeySpec: represents pre-existing key material for generating SecretKey objects using a SecretKeyFactory
  • SecretKeyFactory: generates a SecretKey from pre-existing key material
  • Cipher: represents an engine for either encrypting plaintext or decrypting ciphertext with a symmetric algorithm and an existing SecretKey
  • RSAKey: I didn’t do much to abstract this. This should really be called “AsymmetricKey”.

All of the code is up on GitHub. Here’s a quick example of how you can generate a new 128-bit AESKey:

And how you can generate an AESKey from a password using the PBKDF2 specification:

Note: I’m using ARC, so if you’re importing the code into an older iOS application, please keep that in mind.

Creating temporary files from Cocoa

I wish NSFileManager had something like Java’s java.io.File.createTemporaryFile, but it doesn’t.

So I added it with a Category. Wonderful thing, Objective-C categories.

The project is up on GitHub, but I thought I’d include just the code here as well: