More Fun with Xcode 10 and CryptoQuip

xcode.jpg

This morning I dove back into Xcode 10 and CryptoQuip - this time fixing up the UI elements because I had the test string in the NSTextView and that was sloppy and there were no tips on the text boxes, and the hint was a pair of NSComboBoxs, and that wasn't as nice as the NSPopUpButton I'd used in the Swift version. So it was time to clean it up.

The first thing was to pull out the test string from the NSTextView and put in the tool tips on where to put what. That was simple... converting an NSComboBox to an NSPopUpButton was not as easy. I was hoping it was a simple object change, but it really had to be a remove-and-replace which wasn't horrible because the placement tools for Xcode 10 are really nice.

CryptoQuip Xcode Project

What was a little more painful was the fact that I needed to create all 26 values for the NSPopUpButton A-Z in the UI. There didn't seem to be a simple way to do it. And now that Xcode 10 has removed the Object Library from the UI, I had to find the new Library Search feature... very "Spotlight"-like, and not horrible, but it was a bit of a surprise to see it gone.

The final part was really cleaning up the code on the -decode: method. That was a mess because I was previously looking at each UI element in isolation, and that was a mistake. Also, I wasn't putting the values back... it was just a mess. So I decided to clean it up like:

- (IBAction) decode:(id)sender
{
  // get the values from the UI elements
  NSString*   cyphertext = [[self getCyphertextLine] stringValue];
  NSString*   cypher = [[self getCypherChar] titleOfSelectedItem];
  NSString*   plain = [[self getPlainChar] titleOfSelectedItem];
 
  // if there is no cyphertext, flip to the test case for testing
  if ((cyphertext == nil) || ([cyphertext length] == 0)) {
    cyphertext = @"Fict O ncc bivteclnbklzn O lcpji ukl pt vzglcddp";
    cypher = @"b";
    plain = @"t";
    // ...and feed all these back into the UI so it looks nice
    [[self getCyphertextLine] setStringValue:cyphertext];
    [[self getCypherChar] selectItemWithTitle:[cypher uppercaseString]];
    [[self getPlainChar] selectItemWithTitle:[plain uppercaseString]];
  }
 
  // now let's call the solver
  [self solve:cyphertext
        where:tolower([cypher characterAtIndex:0])
       equals:tolower([plain characterAtIndex:0])];
}

Now, we are looking at just the cypher text, and keying off that for the test case. Makes a lot more sense. Much better.

All builds and runs fine. Check it all in, and really happy with the way it all worked out. Looks a lot better.