Archive for the ‘Apple’ Category

More Fun with Xcode 10 and CryptoQuip

Wednesday, October 10th, 2018

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.

Big Move: Shutting Down Google Chrome

Monday, October 8th, 2018

Code Clean Up

This morning, while looking at Google Chrome on my work laptop, and with John Gruber's words ringing in my head:

Man oh man, did Google hit the Mac version of Chrome with the ugly stick or what? Worst looking tabs I’ve ever seen — they look like a rendering bug.

and to be fair, that's what I thought of the changes they put in, yet after working with it for a few weeks I was more accepting of it's new design. But that was just me getting used to it - it wasn't that I was seeing the design factors they were going for.

So this morning, I just decided that on my laptop, I'd stop using it. There was a time that Chrome was a great alternative to IE, yes - on the Mac, and Firefox wasn't really all there, and Safari was still getting going, and if you wanted to have a fast, stable, browser, you went with Chrome. Period.

But those days are no more. Chrome is not a good citizen of the machine - it's got real tracking and security concerns, and in general, I just was getting tired of looking at the app that didn't at all look like a Mac app when I was posting and viewing my blog. So enough. It's over.

I'm using Safari Technology Preview because I like to test what's coming, and while I would not use it for my "main" browser activities, I am more than happy to use it for viewing the blog, and making my football picks with some old friends. Nothing is critical, and everything is OK.

We will see who this goes - I'm betting it'll be just fine, and I'll be happier to not be running a Google app that doesn't look like they wanted to make a native Mac app. That's up to them - and fine if that's what they want to do - I just don't have to like it. Or run it.

Getting Apache 2.4.34 + PHP 7.1.19 Going on macOS 10.14 Mojave

Friday, October 5th, 2018

Yosemite

This morning I thought I'd perform the ritual of getting the old web development tools that I've used in the past going again - this time on macOS 10.14 Mojave. Now I haven't used PHP in ages, but I've still got code and databases for Postgres to use that - so it makes sense to get this all working again, and it's always fun to see how things work out.

Getting PostgreSQL 10.3

Loads of coverage here about Postgres, and it's just so simple to get the latest version from Homebrew:

  $ brew install postgresql

I've even posted how to upgrade from major version differences, so it's easy to get the latest Postgres running on your box, and the tools are just superb.

Activating UserDir in Apache 2.4.34

As in the previous updates, the UserDir extension is not enabled by default, so we need to get that going right away. This enables the code to be run from the development directories, and that's a big time-saver. First, we need to enable the UserDir module in Apache, and then make a specific config file for the user in question. Start by editing /etc/apache2/httpd.conf and line 174 needs to be uncommented to read:

  LoadModule userdir_module libexec/apache2/mod_userdir.so

and then similarly on line 511 uncomment the line to read:

  Include /private/etc/apache2/extra/httpd-userdir.conf

Next, make sure that the file we just included is set up right for including the user
directories. Edit /etc/apache2/extra/httpd-userdir.conf and line 16 needs to be uncommented to read:

  Include /private/etc/apache2/users/*.conf

At this point, you need to make sure you have at least one file in the /etc/apache2/users/ directory for each user, like: drbob.conf:

  <Directory "/Users/drbob/Sites/">
      Options FollowSymLinks Indexes MultiViews ExecCGI
      Require all granted
  </Directory>

where the last line - Require all granted is new as of Apache 2.4, and without it you will get errors like:

  [Thu Dec 18 10:41:32.385093 2014] [authz_core:error] [pid 55994]
    [client fe80::7a31:c1ff:fed2:ca2c:58108] AH01630: client denied by server
    configuration: /Users/drbob/Sites/info.php

Activating PHP in Apache

The mext thing to do is to activate PHP in the supplied Apache 2 with macOS 10.14. This is line 177 in the file - /etc/apache2/httpd.conf and you need to uncomment it to read:

  LoadModule php7_module libexec/apache2/libphp7.so

and then verify a file called /etc/apache2/other/php7.conf exists and contains:

  <IfModule php7_module>
    AddType application/x-httpd-php .php
    AddType application/x-httpd-php-source .phps
 
    <IfModule dir_module>
        DirectoryIndex index.html index.php
    </IfModule>
  </IfModule>

which does all the other PHP configuration in a separate file to make upgrades easy.

Finishing Up

At this point, a simple restart of apache:

  $ sudo apachectl restart

and everything should be in order. Hit a URL that's a static file with the contents:

  <?php
    phpinfo();
  ?>

and you should see all the details about the PHP install - including the PostgreSQL section with the version of Postgres indicated:

Apache PHP on Mojave

What's really great is that Apple has included lots of support in the default PHP install:

  • PHP 7.1.19
  • Postgres 9.3.7
  • MySQL 5.0.12
  • SQLite3 7.1.19

so there's no reason to do anything more to get the kind of support that I used to get. And I get the other databases for free. This is great news! I then run my little test page to make sure the database ocnnection is working:

PHP + Postgres Test

and everything is working exactly as expected!

Updated Homebrew for macOS 10.14 Mojave

Wednesday, October 3rd, 2018

Homebrew

This morning I wanted to make sure that Homebrew was up-to-date on my laptop - now that I'd upgraded it to macOS 10.14 Mojave. In the past, changes to the OS and Xcode almost always meant that I had to update with a simple:

  $ brew update

and off it would go - updating the code for brew as well as the list of new, updated, and deprecated packages. This time, it also pointed out that in the upgrade to Mojave, I think Apple cleared out some empty directories. The update instructed me to:

  $ sudo mkdir -p /usr/local/sbin
  $ sudo chown -R $(whoami) /usr/local/sbin

so that the /usr/local/sbin directory was created, and owned by me. Sounds fair - I don't think I had anything there - and we're good to go, but it's really impressive how they have handled all the package management and versioning. I really like the tools these guys make.

iTerm2 and Mojave Conflicts

Monday, October 1st, 2018

iTerm2

This morning I was updating iTerm2 and realized that ~/Library/Images/People was there but it wasn't something I could ls... and I thought Great! Corrupted disk... but then I started digging into the problem and found some interesting things with macOS 10.14 Mojave.

To start, this is what I was seeing:

  peabody{drbob}378: ls
  ls: .: Operation not permitted

and I thought permissions - but it wasn't. I checked the permissions on the directory, and then the ownership, and root wasn't doing any better. This was a bad situation. I had a back-up at home, and I was able to see that it was just this one directory, so maybe it was Mail.app - nope... that wasn't it.

Then I decided to see what the Finder said - and there were all the files! I could make a new directory - People2 and use the Finder to copy all the files to the new directory - and then remove the old People and rename the new one. But the files were invisible on the rename!

OK... this was getting closer - it's the directory name. So let's try Terminal.app - and when I tried to change to ~/Library/Images/People it asked if I wanted to allow Terminal.app to access my Contacts.

Ahh...

This was a simple issue of sandboxing for security. iTerm2 wasn't triggering the request for permissions to that directory, and so the app wasn't allowed to "see" it. Very clever. Sadly, you can't manually add an application to the 'Contacts' in the Security part of System Preferences. Too bad.

For now, I know the problem, and how to work around it - and when iTerm2 gets this fixed, it'll ask, and as I did with Terminal.app, I'll say "OK", and we'll be good to go. Wild.

UPDATE: There's a pretty easy fix for this in Mojave and it's in the Security System Preferences - you simply need to drag the iTerm app into the list, and then select the checkbox. Simple. It now has access to all the directories.

Permissions on iTerm2

Reading Up on CloudKit

Wednesday, September 26th, 2018

CloudKit

After I went through Swift and Xcode, I was looking for something to read, and CloudKit seemed like a really good thing to read - as I know a friend is using it for his app, and it's one of the really nice features that Apple is making available for server-side uses in the iOS and macOS apps. I'm not at all sure when I'll use it, but I really wanted to get to know it so that I can know what it's capable of, and the basic limitations it's got.

To start, it's important to see this as what might be called a very simple database, and it's probably a good idea to take Apple's cue and call them RecordSets. It really is best to think of them as Collections, as it's not really a traditional database at all, but you can mimic a lot of database activity with it. Still - Collections is the best way to think about it.

Next, they have certainly put in a lot of work to make sure app developers have the tools they need to specify these records on the Apple developer web site. It's really impressive, but then again, Apple uses CloudKit a lot - so it makes sense that you make the tools that help you make apps.

What's interesting is that they have a very logical, clear, data access pattern that covers getting just the updated records... or sending a predicate and getting all the records that match that, or paging them as needed to make the app more responsive to the user. What I find very nice about CloudKit is that for thumbnails of the images - they don't do a thing - it's up to you, the app developer, to make those, and put those in the record. That way, you control the style, image quality, etc. of the thumbnail. Very nice.

I Like that they have the batch and single operation interface, and they have really gone all-in on the NSOperation as the tool for doing all this work. If you get used to that, and good at using it you're going to be set with CloudKit. They have subclassed that to have a lot of different operations, and true to NeXT and Apple form, the names are a little strange to me now - having done a lot of functional coding over the last few years - where names are typically a lot shorter, but that's just the way NeXT has always been.

As I was watching the WWDC sessions, and reading the docs, I realized that this could not really be made a lot simpler for the general case of interacting with iCloud, but it sure was a lot more complicated than any one app would really need. I kept thinking about how to simplify this and make it into a library with simpler access patterns. Then I'd realize that it would be restrictive, and so it would only be good for a subset of all use-cases, and again Apple did the right thing, and it's complex because it's a complex system.

Still... I can bet that if I had to use it in an app, I'd have to make a Framework or something to encapsulate the use cases that I was going to be using - just because I'd need to abstract this away to make it simpler to see how the part interacted with one another. But I suppose that another point to consider is that an app isn't about a lot of complexity, and so interacting with CloudKit is probably the most complex thing an app is doing, and so it's not really surprising that this is as complex as it is.

Low down: it's impressive, and full-featured, and I think it's great that Apple made it.

MacOS 10.14 – Mojave Arrives!

Tuesday, September 25th, 2018

Apple Computers

Yesterday, around noon, I guess, macOS Mojave was released, and signified the end of a very exciting week for Apple. First it was iOS 12, and Xcode 10, then the new iPhones, then macOS Mojave. What a week!

I'm not going to use Dark Mode - it's just too hard for me to read the small text, but that's OK. I like that Apple is trying new things, and it's getting people excited about the UI again, which is always good. I do like a few of the UI changes that they added - there is now a clear distinction between the apps in the Dock, and those that are permanent members of the Dock. Nice. I also like that Safari 12 is getting more strict with the security and ad blocking. It's an entirely different world out there now - as opposed to 10 yrs ago, and I like that Safari, and Apple, feel that security and privacy is a fundamental human right.

There are tons of things under the covers, I'm sure. I've read about several, and as Xcode 10 was likely the build system, I'm guessing that there are nice performance boosts in several spots as well. All very cool stuff.

More Xcode 10 Performance Tests

Monday, September 24th, 2018

xcode.jpg

This morning I decided to take another look at the Xcode 10 performance tests on my CryptoQuip puzzle solver, but this time, looking at the Objective-C version and see if the Xcode 10 changes would make it any faster. Turns out, I'm very glad that I did.

I was getting a very odd error on the line:

int main(int argc, const char *argv[])
{
    return NSApplicationMain(argc, argv);
}

the value of argv was causing a SIGABRT - and I just had a feeling it was some setting in the old project file and I needed to clean those up - so after a little bit of updating, it compiled and ran just fine.

I then put in the timing of the call with a few lines:

- (BOOL) attemptWordBlockAttack
{
    // sort the puzzle pieces by the number of possible words they match
    [[self getPuzzlePieces] sortUsingSelector:@selector(comparePossibles:)];
    // ...now run through the standard block attack
    NSTimeInterval begin = [NSDate timeIntervalSinceReferenceDate];
    BOOL ans = [self doWordBlockAttackOnIndex:0 withLegend:[self getStartingLegend]];
    NSLog(@"%lu Solution(s) took %f msec",
        (unsigned long)[[self getSolutions] count],
        ([NSDate timeIntervalSinceReferenceDate] - begin) * 1000);
    return ans;
}

so that I'd get a similar result as the Swift version - basically, taking everything out of the time in the solution except the attack. That's as close as an apples-to-apples as I could get with the other versions.

What I found out blew me away:

CryptoQuip[87317:16056980] Loaded 25384 words from /Users/drbob/.../words
CryptoQuip[87317:16056980] Ready
CryptoQuip[87317:16056980] Solving puzzle: 'Fict O ncc bivteclnbklzn O lcpji ukl pt
                               vzglcddp' where b=t
CryptoQuip[87317:16056980] 1 Solution(s) took 0.464082 msec
CryptoQuip[87317:16056980] Solution found: 'When I see thunderstorms I reach for an
                               umbrella'

Now the times for Clojure were in the 6 msec... and Swift was about 7 msec... but I had to do a double-take on this... I had no idea Objective-C was going to be this fast! I had to compute, by hand, the number of milliseconds since the reference date - January 1, 2001 - just to make sure I was doing the math right. I was right... it was right... I checked the code several times, made sure I wasn't skipping the actual solution... and I wasn't.

Wow... Apple has really outdone themselves on this... sub-msec on the solution. Wow! I have to say this is excellent news in my book. I can live with Swift, and I know it's the future, and it's fast... but it's not this fast, and that's just amazingly cool!

Xcode 10 Performance Tests

Tuesday, September 18th, 2018

xcode.jpg

This morning, with Xcode 10 updated yesterday with iOS 12, I thought I'd take a run at the Quipper code that is based on Swift 4.2. In the past tests on Xcode 9, I was seeing times in the 40 msec (Release build) and that was nice as it was fully 20 msec faster than ObjC on the same machine, but it's still a far cry from the 6 msec of Clojure on the same machine.

But I've heard a lot about the speed improvements in iOS 12, and it seemed like a smart thing to test the performance on the same code, on the same box - but with Xcode 10. So I did. Wow.

2018-09-18 06:59:04.76 Clearing out all old data for the attack...
2018-09-18 06:59:04.79 List of Possibles:
2018-09-18 06:59:04.79   ... bivteclnbklzn :: 1
2018-09-18 06:59:04.79   ... O :: 2
2018-09-18 06:59:04.79   ... ncc :: 29
2018-09-18 06:59:04.79   ... pt :: 40
2018-09-18 06:59:04.79   ... vzglcddp :: 46
2018-09-18 06:59:04.79   ... ukl :: 589
2018-09-18 06:59:04.79   ... Fict :: 1727
2018-09-18 06:59:04.79   ... lcpji :: 2168
2018-09-18 06:59:04.79 Starting the word block attack...
2018-09-18 06:59:04.79 working on word: 0 [bivteclnbklzn] - 1 possible matches
2018-09-18 06:59:04.80 working on word: 1 [O] - 2 possible matches
2018-09-18 06:59:04.80 working on word: 2 [ncc] - 29 possible matches
2018-09-18 06:59:04.80 working on word: 3 [pt] - 40 possible matches
2018-09-18 06:59:04.80 working on word: 4 [vzglcddp] - 46 possible matches
2018-09-18 06:59:04.80 working on word: 2 [ncc] - 29 possible matches
2018-09-18 06:59:04.80 working on word: 3 [pt] - 40 possible matches
2018-09-18 06:59:04.80 working on word: 4 [vzglcddp] - 46 possible matches
2018-09-18 06:59:04.80 working on word: 5 [ukl] - 589 possible matches
2018-09-18 06:59:04.80 working on word: 6 [Fict] - 1727 possible matches
2018-09-18 06:59:04.80 working on word: 7 [lcpji] - 2168 possible matches
2018-09-18 06:59:04.80 1 Solution(s) took 7.602294921875 msec

I was just shocked - 7.6 msec - that's within reasonable tolerance with the Clojure code - and all that improvement is in the compiler! I have to tip my hat to the Xcode engineers - that's an amazing improvement. I'm guessing that macOS Mojave is going to be quite a treat in a week, as it's been built with these tools. That's something very nice to look forward to.

For now, I'm super happy with the performance of Swift 4.2 - and while I'm not a huge fan of the syntax, it's got the performance that means it's something to take seriously, and use as opposed to Clojure which was problematic on the iOS and macOS apps anyway.

Great News!

iOS 12 Drops Today!

Monday, September 17th, 2018

IPhoneX

We are entering a very exciting week for Apple folks, such as myself. Today it's iOS 12 with the Memoji, automation with Siri, more efficient code to make a lot of things faster on older hardware, and soon - multi-person FaceTime. That last one is interesting to me as it really challenges Google Hangouts and GoToMeeting. They are good products, but this will be in all iPhones, and that's got a really big advantage in market-share.

I also read the comparison of the iPhone Xs Max with the 13" MacBook Pro - and the iPhone was certainly on par with the laptop... it's just crazy how much capability Apple is packing into these phones... I think I need to do a little looking into ARKit and see what it's got. I'm not really sure that I have an augmented reality idea in me, but it might be really nice to see how to do these things. You just never know.

Exciting week!