Fixing things Apple broke

November 14th, 2017

Every time Apple updates the OS they break things that I rely on. Sometimes it’s simple things like pinning the dock to the bottom of the screen. Other times it is things like making the menubar translucent. People usually figure out fixes and they are usually command-line switches. My Mac Mini is getting older, and recent updates to Xcode seem to have made the process of compiling apps much slower, so I’m probably going to upgrade my computer in the near future. This post will be a collection of things that I can apply to my next Mac.

Apps no longer appear in the tab switcher.
I noticed a while ago that if I close all of the windows in Safari after a while it does not appear in the app switcher list. According to Michael Tsai Safari and other apps are going into a new state called App Nap. You can prevent this with this line:


defaults write -g NSDisableAutomaticTermination -bool TRUE

Display File Extensions


defaults write NSGlobalDomain AppleShowAllExtensions -bool true

Show the Library Folder


chflags nohidden ~/Library/

Show Hidden Files
This is useful for finding things like git repositories.


defaults write com.apple.finder AppleShowAllFiles -bool true

Restart Finder
For some of these you need to restart the Finder. You can do it with the Force Quit menubar item or the command line.


killall Finder

Adding a subdomain with Certbot

October 16th, 2017

It’s relatively straightforward to have multiple domains and sub-domains use the same Certbot certificate when they all point to the same document root. Adding a sub-domain that points somewhere else is not as easy.

I wanted to add a beta sub-domain for testing a site rewrite. I could get the certificate to generate, but I couldn’t figure out how to modify the Apache config files for the beta. This is how I did it.

To figure out what should be done, I ran this code to expand the existing certificate.


sudo /opt/certbot/certbot-auto --installer apache --webroot -w /www/example -d example.com,www.example.com  --webroot -w /www/example_beta -d beta.example.com

To verify that it did what I wanted, I ran:


/opt/certbot/certbot-auto certificates

and got this:


Certificate Name: example.com
    Domains: example.com beta.example.com www.example.com
    Expiry Date: 2018-01-14 19:35:43+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/www.example.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/www.example.com/privkey.pem

I was originally looking at the example.com file in the sites-available directory, but what I should have been looking at was in the Certbot generated files that end in -le-ssl.conf.


<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    ServerAdmin root@example.com

    DocumentRoot /www/example

    CustomLog /var/log/apache2/example.com.access_log combined
    ErrorLog /var/log/apache2/example.com.error_log

    ErrorDocument 404 /missing.php
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/www.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.example.com/chain.pem
</VirtualHost>

</IfModule>
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAlias beta.example.com
    ServerAdmin root@touringmachine.com

    DocumentRoot /www/example_beta

    CustomLog /var/log/apache2/example.com.access_log combined
    ErrorLog /var/log/apache2/example.com.error_log

    ErrorDocument 404 /missing.php
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/www.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.example.com/chain.pem
</VirtualHost>
</IfModule>

You need to run this code after changing the config files.


sudo service apache2 restart

Don’t forget to change your DNS record to add the sub-domain.

Apple Mail Preferences Pane

October 9th, 2017

When updating to the Mac OS High Sierra Beta my computer hung. I let it run for a long time, but was unable to get it to continue. I restored from a backup, but it did not have all of the files for my email. I had to re-enter my email accounts and restore messages manually. Somewhere in the process, Mail app stopped being able to display the Preferences Pane. I added a new user to my Mac and the Preferences Pane showed up fine, so it looked like something in my user preferences was either missing or corrupted. I removed various things from ~/Library/Preferences/com.apple.mail but nothing fixed the problem. Then I stumbled on a StackExchange mentioning that some things are stored in ~/Containers.

Sure enough, removing Container.plist from com.apple.mail caused Mail to regenerate whatever is in that file. I now get all of my preferences back and they appear to be the same as before the crash.

willAnimateRotationToInterfaceOrientation: duration: deprecated

September 27th, 2017

After iOS 8 willAnimateRotationToInterfaceOrientation is no longer supported. After some experimenting I found that a drop-in replacement for:


- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration {

     ... code

} 

is


- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {

     ... code

     } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {

     }];
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

In case it isn’t clear, replace the method and then after your existing code, paste in the completion code and call super.

statusBarOrientation deprecated

September 27th, 2017

My apps use code to put objects on the screen and the layout of my apps changes depending on the orientation of the device. I had been using statusBarOrientation to determine the orientation, but it as been deprecated as of iOS 9. It still works in iOS 11 but since I have to update my apps anyway for iPhone X, I decided that now would be as good a time as any to update the code.

I believe the reason for the deprecation is that now apps can appear in a sidebar, so they don’t have a status bar. I have not enabled that behaviour in my apps, so it doesn’t affect me. The recommended way to get the orientation is to look at the screen size.

I had been using this line at the top of each file where I needed to do something depending on orientation.


 UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

I use a utilities class for things that I use across classes, so I decided to put it there so I could change it easily if I needed to at some point in the future.


+ (NSString *) orientation  {

    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    NSString *deviceOrientation = @"Portrait";
    if (screenSize.height < screenSize.width) {
        deviceOrientation = @"Landscape";
    }
    return deviceOrientation;
}

The replacement code in each class is:


NSString *orientation = [Utilities orientation];

The enum UIInterfaceOrientation has not been deprecated, so I could have returned one of the values and not had to change any other code, but the conditionals are messy and hard to read,


if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)

so I decided to return a string instead to make the code easier to read, e.g.


if ( [orientation isEqualToString:@"Portrait"] ) {

Well Golly


Atheism Plus

Buy from Amazon