Archive for the ‘Various Frustrations’ Category

Using TextEdit as your git editor

For a little while, I’ve been using emacs as my git editor because I strongly feel that vi is something that should happen to other people. It’s been fine but not everyone loves emacs or likes the debris it leaves in its wake. So I thought I’d try out TextEdit instead.

After a little testing of approaches, I first tried out this:

git config --global core.editor /Applications/TextEdit.app/Contents/MacOS/TextEdit

I picked this rather than some of the other approaches because it’s straightforward in launching the app. There’s one problem though, which is that git doesn’t pick up on the fact that a file has been edited and closed when the application remains active:

% git commit --amend 
hint: Waiting for your editor to close the file... 
(...waits forever...)

The commit completes and works when I quit TextEdit but I don’t like  to quit the app each time I update a commit, especially if I have other files open. The amended commit does complete on quit:

% git commit --amend [master 59a0934] Testing TextEdit!
Author: erica <erica@ericasadun.com>
Date: Thu Jul 12 08:02:26 2018 -0600
1 file changed, 3 insertions(+), 1 deletion(-)

So I changed my approach. I turned to open instead:

git config --global core.editor "open -W -n"

TextEdit is open‘s natural environmental editor for text. You don’t have to specify more than open for git to work with the right editor.

This approach uses two tweaks. When you launch an app with open, the -n flag instructs open to launch a new instance of the application even if one is already running. You may see two “TextEdit” icons open in your dock, for example.

Combine -n with -W and you have a slightly better solution.  The -W “wait” flag tells open to keep waiting until the launched application has finished running. This allows git to to wait “for your editor to close the file”, which you do by quitting TextEdit. Sure, I’d much prefer that TextEdit run using a “single file” mode, but this isn’t a bad solution.

Sadly, I couldn’t find any undocumented launch flags to make TextEdit run in single file mode and while it’s easy enough to write a Mac app that edits a single file at a time and quits on closing, it’s not a practical solution for everyone.

Is there a way to automatically propagate “done” back to git without ending a TextEdit process? I couldn’t find one. If you have a better idea, please let me know.

My Mac mini, kernel_task, and dusty hardware: Bring back my mini’s zing

Over the past few weeks, my Mac mini has been getting less and less responsive. The kernel_task has been spinning up taking up ridiculous amounts of CPU time and dragging my system to its knees.

I did what anyone would: I ran hardware diagnostics (passed). I ran SMART diagnostics (passed) and then I web searched the hell out of the interwebs, and there I found an unusual suggestion. Several sites suggested that I may have built up dust accumulation in my mini and that the fan control was trying to mitigate this.

Fortunately, I’m one of the lucky ones (for very low values of “lucky”) with a self-serviceable 2012 Mac mini instead of the upgrade a few years later that removed the service hatch. (*shakes fist*. *darn you Apple.*)

I opened it up and sure enough it was pretty dirty in there. I vacuumed and then I used compressed air to finish (after finding the child who had “acquired” it for an “important project” several months ago and never returned it). I performed a thorough vac and dust of the work area where it rests along with my many backup and external data drives.

Plugged it back in and for nearly a week so far I have not had the same issues reoccur. It seems a tiny bit black magic but it also seems to be working (fingers crossed).

I thought I’d write up a quick post to share my experience and see if anyone else has been through this and has advice or suggestions. For me, it’s like having my Mac back again. I still need a refreshed mini (hint Apple hint) but I have serious concerns about buying one without a self service hatch.

Apple’s move away from self-service products has cemented its appeal as a “computing appliance” provider but it also means expensive service calls for any problem. Much as I’d like them to give us a Mac Pro Lite, at a lower price point than the Pro and a higher one than the mini, with lots of configuration options,  I just cannot see that kind of product ever existing in today’s Applesphere.

A lot of us mini owners cling tenaciously to our six-year-old hardware (or, for some, 4 year old), but I’ve seen no indication that the mini has a future at all in the lineup. If it’s not a product appealing to the BMW owner set or essential for internal Apple use, I don’t really see it having a place in Apple’s marketplace.

One indication against this gloom is Apple’s magnificent iPod line, which has at least gotten semi regular updates. The iPod touch is about the best value you can buy with an Apple logo on it outside of the core iPad released this past March. Both fit into if not BMW owner appeal, then at least BMW owner’s kids appeal. I just don’t see the Mac mini doing that.

Is the mini dead forever? I’m not sure. I like bringing my own displays, my own mechanical keyboard, and thousands and thousands of dangled USB add-ons. That’s what a desktop does for me and why the (self service) mini is the perfect fit.

If you want to point at one change Apple made that said to me: “No mini for you, move to the left!” a la that Seinfeld episode, it was the death of the escape key. The escape key philosophically services a self-reliant power user. And I’m just not sure that Apple is in that market anymore.

Will I get my mini pro? Probably not. Will there be a paradigm shift so profound that customized dev systems can co-exist with mechanical keyboards using a new desktop system? Maybe. What do you think? Are you a mini devotee? Share your thoughts.

Simulators gone bad

Recently, some of my simulators launched and loaded just fine. Others simply went black. It didn’t seem to matter which firmware I was simulating. Some devices were just happier than others.

Naturally, I turned to the system console, which provides device-by-device logs, but I couldn’t really find anything.

I tried restarting and rebooting the sims. I tried resetting the core simulator service. I tried a lot of things. (No actual chickens were harmed.) Finally, I stumbled across a Apple Dev Forum thread about issues with the beta system. The advice offered in-thread was this:

  • Quit the simulator. (I also killed com.apple.CoreSimulator.CoreSimulatorService because reasons.)
  • Run xcrun simctl erase all
  • Set a framebuffer renderer hint: defaults write com.apple.CoreSimulator.IndigoFramebufferServices FramebufferRendererHint 3

It worked.

Yay! \o/

From the thread, apparently hints 1 and 2 do not work but 3 does. An Apple Engineer noted that, “hint 0 is auto (currently prefering Metal and then falling back to OpenGL if unavailable). Hint 1 prefers Metal and hint 3 prefers OpenGL. Hint 2 used to mean OpenCL, but we dropped OpenCL support.”

Upshot is that I lost many hours but I seem to have a working solution for dealing with a common problem. I hope this write-up helps you if you encounter the same issues.

Update: Guru Russ Bishop recommends against using this long term. He writes

If you (as I) have deadlines, and cannot wait for this problem to be fixed, this fix will get you back to work. Russ reminds me, though, “Use it temporarily only if you have this problem, and don’t forget to delete the pref in the future”

Happy WWDC: Time to unenroll your devices

It’s that special time of year: new announcements, new APIs, and new betas. If you’ve got a device you depend on, don’t forget: it’s a great time right now to unenroll your beta profile so you don’t accidentally upgrade to beta 1. A big thank you goes out this morning to Jeff Forbes, who reminded me about the timing!

Unfortunately, all the developer support docs are currently offline before the event. I’ve reconstructed the following from memory and web searches as I deleted my iOS beta profiles about a month or so ago. If I’ve gotten anything wrong, please let me know and I’ll correct.

If you’re on macOS, open System Preferences > App Store, and click the “Change” button next to Your computer is set to receive beta software updates. Confirm “Do Not Show Beta Software Updates”. I chickened out from actually clicking the button this morning on my dedicated primary beta system so I don’t know the steps from there.

On iOS, hop into Settings > General > Profile to delete the iOS Beta Software Profile. I believe you tap “Delete Profile”, enter your passcode, and then tap Delete. Once deleted, the device should longer subscribe to the iOS public betas.

Apple vs my daughter’s iPad: Part II

I just got off the phone with Apple, after speaking to a point person on the executive relations team. Isabella G offered to set me up with an escalated support member. I thanked her (and accepted) but said that my concern in this matter went wider than my specific case.

I explained that a no-reason account lockdown was a much broader and much more important issue to me. Our device was not stolen. My daughter did not enter bad passcodes or wrong passwords. There was no reason that the lockdown should have happened and no way for Apple Support to explain why it did  happen. If it could happen to us, it can happen to anyone and potentially at any time.

That my daughter had forgotten her security recovery information, too, led to a much broader issue. She was young, foolish, and feels sorry for her choices. At the very least, she should have changed her email when the provider shut down its services. But having an outdated email and no memory of security questions isn’t limited to her specific situation.

Consider the elderly or those who otherwise struggle with recall. They may be able to, as she was, know their passcode, account, and password but not be able to recall the specifics of the security questions or know where they had placed the documentation for the exact phrasing used when answering those questions the first time. They too may have clung to existing account names even if their email has changed over time.

The core problem isn’t that my child made regrettable decisions. She did. It’s that a lockout happened without explanation and without recourse. Something triggered the lockout. And, it clearly was something that fell outside the scope of where we, as customers, would want or accept that the lockout should occur.

I’d like to find out what that was, how Apple can prevent it from happening in the future and how they can offer remedies given the consequences of both losing information and device utility.

Update: Support call went nowhere but our support person was as usually thoroughly professional and nice. Other theories about what might have happened are “haven’t logged in for a long time, which could have activated the lockdown” (his) and “possibly the privacy act stuff this week bouncing back from a dead email” (mine).

In which Apple destroys my daughter’s iPad forever

My daughter has an iPad mini. It is a second-hand one given very graciously by a friend when his daughter outgrew it.

My daughter has taken good care of this iPad, an astonishing thing given her age and the number of second and third hand iOS devices she had accidentally destroyed when younger.

She loves it and she had a lot of precious things in her iCloud account.

The other day, Apple locked her out of her iCloud account and her iPad. We don’t know why. The Apple support people don’t know why. I think it may have to do with when I modernized my AppleID to use an email address, which is what the iTunes account on the iPad is registered to.

My daughter knows her account name. She knows her password.  She did not forget either one. She did not lose her device. She did not do anything to trigger the Apple ID issue. The only thing we know is that it happened at roughly the same time the ApplePay person told me to update my AppleID. It may be related. It may not be.

She set up this Apple ID on her own around 2010 or so, when she was quite small and listening to her Mom, who said don’t give out personal information, she made up a birthday and answers to the security questions. 8 years later, she does not know that information and there’s no way for us to guess it.

Despite the fact that she owns the iPad, has the physical iPad, knows her id, and knows her password, there is no way for her to ever use the iPad again because we do not have a receipt for the iPad, nor does the kind gentleman who gave her the iPad. The Apple Store does not provide access to records from that far back, roughly 7 years ago. Also, her email provider deleted the account about 3-4 years ago and is no longer allowing email signups.

What’s more, Apple will not unlock her iCloud account to get all those drawings and letters she put there for “safety” even though she has never forgotten her password.

We dug up a previous iPad with a cracked screen that used the same iCloud account, and for which I did have the receipt. That was insufficient for Apple to unlock her device or to let her back into iCloud, even though both devices use the same account and both are physically in our possession.

My daughter is the owner of a brick, which is not getting replaced.

Update: Just for the lawls. I don’t know why it says Weds, Dec 31. This is the older mini with the cracked screen that I had the receipt for.

The festering realities of Bluehost: In which I learn about “unifiedlayer.com”

Sometimes my outgoing email bounces for reasons I don’t understand from a variety of recipients. I usually try to contact the postmaster to find out why. This weekend, I actually got a response from one:

My apologies for the delay in replying.  Your email went into the gmail spam folder and so was not forwarded out to where I could respond immediately.

Going directly to “spam”? That’s not good.

The postmaster continued:

The reason that your email is blocked is because it originated at unifiedlayer.com. Unifiedlayer is one of the worst spam originators. They host spammers and they really don’t care, so I don’t have much choice but to block many of their mail servers.

Finally, some concrete information. I searched for “unifiedlayer”, finding common searches like “is unifiedlayer unsafe” and “unifiedlayer spam”. Go ahead and do those searches yourself. You’ll find that overall trust in unifiedlayer-originated mail is somewhere up there with body cavity searches, STDs, and politicians.

So I did what pretty much anyone would, I called my service provider. Bluehost told me that unifiedlayer was an in-house product, that they were well aware of the spam problem, that they worked on it really really hard (that’s a paraphrase, not a quote), and like every other thing that Bluehost gets wrong (and gets wrong repeatedly), that if I were just willing to pay a tiny bit more per month (five bucks in this case), they’d allow my “ericasadun” domain email to go through a different originator.

I am so sick of Bluehost.

If you have any advice on how I can transfer my web site and my email away from this festering heap, please drop me an email (I’ll probably get yours even if you don’t get my reply) and help me find an alternate home. I’ve heard good things about Digital Ocean, for example, but I don’t even know where to start in terms of moving over ten years worth of email.

At least I’ve been through the process of reinstalling WordPress and have my backups.

Thanks in advance.

Auto Layout, Playgrounds, and Xcode

Today, someone asked what the easiest way was to center a view (specifically a UIImageView) inside a parent view with minimum offsets from the top and sides.

Because you’re working with image views, it’s important that you first set the content mode. For insets, it’s almost always best to go with a “fitting” aspect-scale, which preserves the entire picture even if it has to pillarbox or letterbox. (Pillarboxing adds extra spacing to each side for tall images; letterboxing adds the top and bottom for wide ones.)

// set content mode
imageView.contentMode = .scaleAspectFit

Make sure your view can squish its content by lowering its compression resistance:

[UILayoutConstraintAxis.horizontal, .vertical].forEach {
    imageView
        .setContentCompressionResistancePriority(
            UILayoutPriority(rawValue: 100), for: $0)
}

You must preserve your image’s aspect ratio. Calculate your target ratio by dividing its width by its height:

let size = imageView.image?.size ?? CGSize()
let aspectRatio = size.width / size.height

Add strong constraints that preserve the aspect, and make the view smaller than its parent using inset values you supply:

let insets = CGSize(width: 20.0, height: 32.0)

let constraints = ([
    // Preserve image aspect
    imageView.widthAnchor
        .constraint(equalTo: imageView.heightAnchor, multiplier: aspectRatio),
 
    // Make view smaller than parent
    imageView.widthAnchor
        .constraint(lessThanOrEqualTo: parentView.widthAnchor,
                    constant: -insets.width * 2),
    imageView.heightAnchor
        .constraint(lessThanOrEqualTo: parentView.heightAnchor,
                    constant: -insets.height * 2),

    // Center in parent
    imageView.centerXAnchor
        .constraint(equalTo: parentView.centerXAnchor),
    imageView.centerYAnchor
        .constraint(equalTo: parentView.centerYAnchor),
])

If you want to be super cautious, keep the aspect and two center constraints at 1000 and bring the width and height ones down to 999. You can install the constraints as you create them but I prefer to break that part out so I can tweak the priorities for each constraint group:

constraints.forEach {
    $0.priority = UILayoutPriority(rawValue: 1000)
    $0.isActive = true
}

I always mess up with the signs (positive or negative) of the constants. It helps to test these out in a playground rather than going by memory because the signs aren’t always intuitive. Even better, write routines that automates your Auto Layout tasks because if you debug once (and add proper tests), you never have to think about it again.

Mac playgrounds are inherently superior to iOS ones as they don’t run a simulator and are faster and more responsive. That is to say, you don’t have to quit and relaunch Xcode quite so often. If you are debugging iOS layouts though, and your playground hangs when starting the simulator or running your code, learn to quit, kill the core simulator service, and relaunch Xcode. It will save you a lot of time.

I have a one liner in my utilities to deal with the service:

% cat ~/bin/simfix
killall -9 -v com.apple.CoreSimulator.CoreSimulatorService

Most of the time a single quit, simfix, and launch will get things moving again with recalcitrant iOS playgrounds. Be aware that malformed format strings and other auto layout issues won’t produce especially helpful feedback, especially compared to the runtime output of compiled projects. If you know what you’re doing, you can set up a simple layout testbed in playgrounds with less overhead and time than, for example, a one view project but at a cost.

Stick to projects, and avoid playgrounds, when testing even mildly complex code-based layouts. You cannot, at this time (at least as far as I know), control which simulator will be used in the playground so it’s not great for checks on a multitude of simulator geometries. The tl;dr is that playgrounds work for general layout routines. Prefer compiled projects for specific tasks.

In which I get hacked, Part 6

Last weekend, Bluehost closed down my site. After spending significant time on the phone with support, I came to the conclusion that I needed to nuke the entire site down to the ground. The WordPress install was simply too corrupt to continue or repair.

Since my secure shell access was revoked at the time, I used their control panel to entirely remove my public_html folder. They ran a scan on my account, found no further malware, and allowed me back in.

To recover, I re-installed a fresh copy of WordPress using Bluehost’s control panel tools. I then used CyberDuck (for sftp) and secure shell to upload my wordpress database and image uploads. That’s the site you’re reading today.

I reverted my theme back a few years to a version I knew was safe. I use  a customized version of the open source Frank theme. Rather than pull down a new copy, I wanted to keep my tweaks that supported the ads on the right side of the screen. They don’t produce much money but they help offset the hosting costs involved in running this blog..

I also  installed the following plug-ins, some old, some new:

  • ActivityLog: “Get aware of any activities that are taking place on your dashboard! Imagine it like a black-box for your WordPress site. e.g. post was deleted, plugin was activated, user logged in or logged out – it’s all these for you to see.
  • Really Simple SSL: “Lightweight plugin without any setup to make your site SSL proof
  • WP fail2ban: “Write all login attempts to syslog

And on a less security note:

  • oEmbed Gist: “Embed source from gist.github.
  • WP to Twitter: “Posts a Tweet when you update your WordPress blog or post a link, using your URL shortener.

Most importantly, I use Updraft Plus: “Backup and restore: take backups locally, or backup to Amazon S3, Dropbox, Google Drive, Rackspace, (S)FTP, WebDAV & email, on automatic schedules.” 

My daily database backups and my weekly upload backups (only for the current year, I already have backups for previous years) ensured I could get my site back up and running within hours of the most recent hack.

I still hate WordPress. I still wish I could run a static site and get comments and other great stuff in one convenient package. However, WordPress does the job I need it to do. It’s simple to write posts and interact with you.

My website is all about this connection. I don’t do any e-commerce. It’s basically a passion project rather than anything I do for business related reasons. I like having somewhere I can get thoughts out of my head and share them with other people. Beyond that, I don’t really have any important agendas and I don’t have the time in my life to perfect my security or delivery tools.

I want to thank everyone who sent me feedback of encouragement and support during my latest hack. I appreciate the comments and the suggestions. I now have a great list of static solutions (including github.io and DNS redirect) to fall back to if I must. Yes, I’m sticking with the crappiest solution right now. I’m doing so because it’s the path of least resistance and not because I don’t prefer your suggestions.

For those with more time and more investment, the popular consensus seems to be using Jekyll/github.io with disqus comments. Other suggestions included Hugo (gohugo.io), GetGrav (getgrav.org, “No Ruby, supports comments, fun to play with”), Ghost (ghost.org), and AWS Lightsail.

I don’t know why anyone would want to hack my nothingburger of a site but I’m glad I have friends out there who helped when they did.

Tap tap, hey is this thing on?

tl;dr: Erica’s site gets hacked repeatedly. Erica’s account is closed by Bluehost. Erica wails into the void. Played with DNS, with github.io, nuked wordpress install, re-installed wordpress, re-installed data, reinstalled plugins, scanned for malware, attempted to restore DNS, wailed into void, some semblance of site possibly restored. Maybe.

postscript: I’m posting this as a test to see if my site is back and alive. If so, please make sure to use https and not http to connect. Fingers crossed.