Archive for the ‘Various Frustrations’ Category

Well that was a surprisingly bad Apple Store experience…

Remember the battery amnesty? Despite the stores doing everything they could to try to convince me not to replace the batteries, I insisted and persisted. I figured $29 would buy me the start of a new battery life-cycle.

Less than 2 years later, my daughter’s iPhone SE battery is dead.

Let me try to explain how important her iPhone is to her. She goes everywhere with it: to stores, in the car, at appointments. There is no time when she’s not tapping on it, from morning until she sleeps. It’s one of those neurodiversity things and it is her great comfort.

It took us a couple of weeks until we could finally snag an appointment last week and the appointment was for today. I have just returned.

It seems that instead of replacing her battery, they gave her back her original one–and her original iPhone, apparently. They had planned on replacing the phone as well, which I remember we were told was an option, but didn’t. The genius figured this out because her serial number was supposed to retired at the time they traded it out but instead they never did.

But because of that her device as a serial number that the Apple corporate system considers invalid. We could not get a loaner. We could not get a repair. And we won’t be able to even start our process for a few weeks more because the serial number issue must be addressed before they can even talk to us about the bad battery.

So after driving almost an hour each way, we got, well, nowhere.

No phone, and no timeline in which we can estimate how to move forward. Our only option, according to the genius, was to buy a new phone and wait it out. I declined the purchase.

So, they’ll look into it and we should get a phone call before August to figure out the next steps and set up another appointment. And start the process all over again.

Update 1:  Call in to Apple. Senior advisor (“I’m as high as you can escalate”) says: “This is the store’s problem. We can’t handle it here.” She offered to let us pay (again) for the battery replacement that was never done. After almost 3 hours on the phone, she got the Park Meadows coordinator into the call and I’ll pick up with them tomorrow.

Update 2: Final outcome: Apple will do the work we paid for almost two years ago within the next week or so! No apologies. No refunds for the work they didn’t do. No kind words about being sent home from the genius bar without any action. They offered to give me a $30 trade-in for the SE on a new phone — exactly what the online store would normally offer for a used SE.

Update 3: Just a few minutes after hanging up with Park Meadows, this arrived in my mailbox. I don’t intend to pay $269 for a repair we already paid for. Seriously, WTF?

Building a silly WatchKit App

WatchKit apps are easy to build and draining to debug. I don’t know what it is about extensions but they’re never fun to work with. The other day, daughter asked for an app to play some favorite sounds. I promised I’d write up a post about this, so here it is.

The entirety of the code took maybe a couple of minutes. This is one of the many places where using SwiftUI is a sheer delight. I did have to play with renderingMode to override the default B&W scheme for three of my buttons:

I decided to go with bundle-stored audio rather than deal with the complexities of adding audio assets to an xcassets item. Quick and easy. I limited the daughter to just 4 out of her long list of requested sounds to simplify my life. She returned with her list grudgingly prioritized.

Trimming and converting the audio to wav took seconds, thanks to command-line ffmpeg. Creating the art, too, was simple. I just used Preview to create all the required App Icons. Call it another 5 minutes to get that done. It was a great time to use Preview’s magic selection wand and its support for layers and transparency.

Where all the trouble lay was getting the watch app to consistent deploy to hardware for testing. Although this was a watch-only app, the phone still plays a big role. And I finally discovered that keeping my phone tethered to the computer when deploying to the watch made for a much smoother and more consistent experience. But the frustrations of failed deploys led to over an hour invested.

Here’s a quick summary of where my development time was spent.  Area corresponds to the level of effort:

The actual coding was nothing. Asset prep is always tedious but it’s O(n). It’s pretty clear from the start how much effort is needed, which varies by the number of assets used. You don’t add more complexity when you’re working with the right formats and tools.

The vast majority of headache is getting the Xcode tooling and the hardware to sync, install, and test. This really should be the easiest part, but it was endlessly frustrating. I don’t know if my tether-breakthrough is a universal solution or if my next project will be just as frustrating.

In the end, what should have been a half hour project stretched to several hours. I hope the next one will be way shorter.

Catalina GIFfing: Quick workflow from screen to animated GIFs

All the leaves are green.

And the sky is blue.

I’ve been at my desk.

With screenshot play…

(To be fully truthful, it’s currently raining cats, dogs, kittens, and puppies. But it’s lovely here in the high desert.)

With my newly updated workflow creating the following GIF took about a minute maybe from start to post. The secret? QuickTime Screen Recording (bless you ⌘-Shift-5) and “gifify” courtesy of Homebrew. Set record, demo, stop, convert, drop into WordPress:

I love how easy it is to invoke screen recording these days with macOS’s updated capture interface. It’s especially nice how the optional delay time allows me to get into the zone before recording actually starts.

Back to installation, the blocker was getting homebrew to get itself into position to fully support Catalina. I had to apply homebrew update and homebrew upgrade and homebrew doctor a number of times. Not only did I get gifify installed, but ffmpeg is finally back to working and I once again have emacs for all my git needs.

I’ll spare you how bad the emacs transition was other than to say if you have to disable system integrity and mount read-write by hand, you’re probably doing it the wrong way.

With ffmpeg, it was the dependent libraries including the ones already installed into macOS (like openssl ). Homebrew refused to link:

Warning: Refusing to link macOS provided/shadowed software: openssl@1.1

I wish I had known early about the update/upgrade/doctor approach applied multiple times by the way, not just once, until everything stops complaining and the doctor says “Your system is ready to brew”. Because at that point, installs are a breeze. Installing before then, when the configuration seemed irreparably broken was probably a bad choice.

I spent a bit of time after removing my current bandaid symbolic links. It seems to have helped that I ended up granting separate privileges to ruby in Security & Privacy a while ago. I don’t remember why I did but it’s in there and I vaguely remember going through the process while cursing Cat.

June’s almost here and I wonder if Catalina.successor() will be better or more of the same. It hasn’t been a good Cat year for me.

Broken App Store downloads on Mojave: We could not complete your purchase

This has been happening to a lot of people recently. You open App Store and try to update apps or download new ones. Instead:

And if you have 48 apps to update, you have to click OK 48 times. Argh.

I spent nearly two hours with Apple yesterday trying to resolve.

Instead, I should have just tweeted because when I did Bas Broek had the answer almost immediately:

I had already rebooted, reset NVRAM/PRAM, cleaned out my Application Support for the App Store, and, get this, at the advice of Apple itself, reinstalled freaking Mojave to try to resolve it.

What a waste of time.

I hope this may come up in someone’s Google search to save them time.

  1. Quit App Store
  2. At the terminal: open $TMPDIR/../C/com.apple.appstore/
  3. In Finder: trash everything in that folder including any pending updates / stuck items.
  4. Relaunch App Store
  5. Done

Update: Gwynne Raskind adds: “$TMPDIR/../C is confstr(_CS_DARWIN_USER_CACHE_DIR)”.

Catalina permissions: Chrome, Zoom, etc

Ran into trouble this weekend where I was unable to add permissions for a number of apps to allow access to my microphone and camera.  (And yes, I’m aware of the security horrors of Zoom but I had work to do.)

They wouldn’t give the normal permissions request:

Instead, I got a message directing me to System Preferences:

Once there, the prefs did not list the app for normal check-to-enable:

I couldn’t unlock and drag on an app.

With some help from Bas Broek and this article, which specifically addressed the inability to grant access in Catalina, I discovered that rebooting with a NVRAM/PRAM reset might help. It sounded like sacrificing chicken entrails but it worked. While a regular reboot didn’t help, the Cmd+Option+PR reboot did.

Apple Support Article: How to reset NVRAM or PRAM on your Mac.

I hope this helps someone else to avoid the time I wasted.

How to fix: Ooops, I lost track of those beta upgrades

What happens when you put off beta upgrades and put them off and off and off and suddenly the release version has outpaced the beta? This happens:

And this happens:

So there you are, stuck in beta and complaining to your friends about what is, ultimate, my your fault. If you don’t update on a timely basis, you can waste a few hours (as I just did) getting your system back on track so you can mess with (for example, just to pull something out of thin air) Swift Playgrounds for iOS for Mac (which requires the 10.15.4 beta10.15.3).

Just so you don’t waste time, don’t try installing the 10.15.3 combo updater. (Image above) You need to:

  • Unenroll from the beta program,
  • Install the latest macos from the App Store,
  • Re-enroll into the beta program, and
  • Upgrade to the latest beta.

Prepare to waste your entire morning on this, hopefully less the time I spent figuring it out courtesy of friends. Once you get the App Store blessed macos install going, remember that once it reboots, there’s another hour of wait time just on the standard install:

Those 13 minutes are a lie.

Expect at least another hour once you get to the beta access installer:

Hopefully this post will help anyone doing a websearch to get out of exactly this issue at some point in the future.

A final note: Once you’re up to date, swear to yourself that your rule of “never be the first to install a new beta” doesn’t mean “never be the last to install the new beta“. Hopefully I’ve learned my lesson.

Taking charge of those xips

Apple adopted the digitally-signed xip format for Xcode downloads a few years ago. It’s basically a signed version of zip archives. Most commonly, you download a xip and double-click. Archive Utility will open the file, verify its signature, and expand its contents.

In its default settings, Archive Utility always expands files to the same folder you download to. With Xcode, this is a big pain as moving the app with its thousands and thousands of tiny subfiles and embedded executables takes forever. Alternatively, moving the xip file from one location on your system to another can be painfully slow.

Fortunately, Archive Utility does allow you to specify where to unpack. Launch the Application using spotlight (or /System/Library/CoreServices/Applications/Archive Utility.app) and open preferences.

Although there’s no “Ask” option for “Save expanded files”, you can select where you want items to be stored using “into” from the pop-up:

Once set, you have to unset it for general use, because the location persists between launches. This is, needless to say, a big pain when you use archives for non-Xcode purposes on a regular basis:

Fortunately, you can unxip more effectively by using the command-line xip utility located in /usr/bin/xip without having to mess with Archive Utility or its preferences:

% xip
Usage: xip [options] --sign <identity> <input-file> [ <input-file> ... ] <output-xip-file>

Usage: xip --expand <input-file>

99.9% of everything you do with xip is that last “Usage” example. Still, as xip doesn’t offer a --help option, if you want to know what those interesting [options] are, you’ll need to read the man page (man xip). I prefer to open man pages in Preview instead of the command line, using this little trick:

man -t xip | open -f -a /System/Applications/Preview.app

Notice two things here:

  • First, the -t flag tells man to use the Groff typesetter (no relation) to format the page to postscript. This presents as a PDF in Preview. (Specifically, it uses /usr/bin/groff -Tps -mandoc -c if that kind of detail intrigues you.)
  • Second, the path for Preview has changed in Catalina to /System/Applications. If you want to do this on Mojave or earlier, adjust the path accordingly.

(Isn’t that a neat way to view man pages?)

While the man page suggests you can sign your own xip archives and provide your own identities, don’t bother. This format is exclusive to Apple, starting  from macOS Sierra. Only xip archives signed by Apple can be expanded in modern macOS releases. (See Tech note TN 2206 for details.)

Since --expand cannot be used with any other arguments, hop over to /Applications, and expand from there:

% cd /Applications/
% time xip --expand /Volumes/Kiku/xips/Xcode_11.2.1.xip 

Adding the time command at the start of the line lets you know how long it took to unxip, which is deeply satisfying to those of pedantic bent like myself. For those playing along, it was

xip: expanded items from "/Volumes/Kiku/xips/Xcode_11.2.1.xip"
1109.625u 275.408s 10:58.85 210.2%	0+0k 0+0io 167pf+0w

Update:

Whisky tango foxtrot: Xcode allows ObjC switch unindenting

This happened.

You might think I’m about to go off on some Swift rant (and trust me there is a Swift rant inside me waiting to emerge) but it’s the second checkbox that made my mind explode.

From:

To:

Who thought this was a good idea? I’ve never been a fan of left-aligned case in Swift although I embrace it as the standard. But in Objective-Freaking-C? As a standard Apple-blessed toggle in Xcode? No! Thrice no! The option enabling the choice is bad for Swift and worse for Objective-C.

Why is this option in there and why is it available for both languages? It would be best to, as Joe Groff put it, “let sloth naturally lead everyone to pick the default” given that the feature has been expressed in Xcode. Or better yet, file some bug reports for the broken feature.

Each language default reflects years (and decades) of language style consensus:

  • Swift: keyword-aligned.
  • Objective-C: “scope”-aligned.

This new choice in preferences is madness.

Talk me down from here, friends.

Flipping the switch and the 32-bitpocalypse

I think I’m ready to upgrade my Mac mini to Catalina. I know, I know: “But the 32-bitpocalypse! Are you ready to lose all that investment?” I think I’ve worked through that. Haven’t I?

The last few weeks I’ve been busy. I bought a smallish (0.5 TB) external SSD drive and backed up a good chunk of my Mac mini to it. Today I’ve been running tests on how it works booting on my MBP, not my mini. That’s because my underpowered mini just isn’t strong enough either in boot speed or  running off the external drive to make this a reasonable approach.

On the MacBook, however, the SSD responsiveness is pretty fine. Once booted, I’ve tested Office, Photoshop, and a bunch of other 32-bit apps and while they’re not going to win awards for speed, they run and appear to be stable.

That leaves me with the dilemma. Do I flip the switch? Do I go full Cat on my main work machine? It’s been a reasonably time since release, so what mine fields should I expect to encounter? I honestly don’t want to upgrade and then have to start restoring from Carbon Copy Cloner backups from regret. (My backups are run nightly so they’re there if I need them.)

What do you think? Pull the switch or walk away? I hate being out of step with the latest OS, even if I do have Cat installed on my MBP and am happily using it there. Give me your advice. I’m not ready to walk away from so many apps that I still use many times a week but I don’t want to freeze my mini in the past. Thanks in advance for your advice and suggestions.

How I got Rust working in Xcode

A while ago, I posted about how I set up Xcode to work with Python. Yesterday, I was taking a class on Rust and decided to use my friendly neighborhood (sp)IDE(rman) coding environment, namely Xcode.

I’m not going to say it was a stunning success but there was enough interest that I thought I’d share the steps so you too could embrace Rust through Xcode.

Install Rust. You start, as one does, by installing Rust. Hop over to https://www.rust-lang.org/tools/install to grab a copy of the tools. They install to ~/.cargo, for whatever reason. I put a link in to / usr/local/bin.

Create a Project. Create an external build system Xcode project by choosing File > New > Project > Cross-platform > External Build System > Next. Enter a product name (I called mine “Rust” because that’s exactly how creative I am.) and set your build tool (in my case, /usr/local/bin/rustc because of the link). Save it somewhere convenient.

Create a source file. Apparently “rs” (rust source?) is the proper extension. I went with “test” as my name. File > New > Empty > test.rs

fn main() {
    println!("hello world");
}

Don’t forget to add some code.

Compile. Edit your scheme.  Choose Run > Info > Build Executable > Other and select your compiler. Adding it to /usr/local/bin made it easier to select rustc for me. Then uncheck Debug executable because you’re not debugging the Rust compiler.

At this point you can click Run and you’ll see the standard option message because you haven’t specified what it should run.

Back in the scheme editor select Run > Arguments and add the source file and output file. Unfortunately, I could not get this to work with SRCROOT at all, so here it is in all its glory with complete paths.

The Pre-action removes any build product from a previous run:

So here we are. With luck, it compiles. If not, the errors appear in pretty horrible form in the Xcode console, where curses is what we do, not how the console interprets pretty text output.

You can get slightly less horrible feedback by adding the launch argument: –error-format=json

Yeah, it’s wordy but it’s slightly less awful.

Pick a path. Unlike python, rust is just a compiler. If you build, and then add a step execute, the execution output (unlike compiler errors) will not normally print at the Xcode console. The challenge is to get that information in some form where you can access it.

At first I went with a little post-action osascript and threw up the output in a separate window:

But I really wanted to make it work with the console So back I went to Applescripting. Instead of rustc, I changed my build tool to osascript:

I added this instead to my run scheme arguments.

Yep, I’m using osascript to run a shell script that just compiles with rust and then runs it, passing the output through back to Xcode.

I know this is bad. I know I should be ashamed. I hang my head.

But you know what? It works. Stray osascript-crud and all:

I’m not sure how much this makes me a programming outcast but it was kind of fun to figure out how far I could push my beloved enemy Xcode.