Software Development

Today, I released two quick updates to my apps Yoink for Mac and ScreenFloat. Here’s what’s changed.

Yoink for Mac v3.4.3

Yoink for Mac app icon

– Fixed a rare crash when trying to share files
– Fixes a bug where the keyboard shortcut would act up after deleting a file held by Yoink in Finder or using the app’s Share extension
– Fixed a bug where, after changing the screen’s resolution, Yoink would be misplaced

Links:

Yoink for Mac Website (with free, 15-day demo)
Yoink on the Mac App Store

ScreenFloat v1.5.15

ScreenFloat App Icon

– Fixes a rare crash when dragging the mini-icon of a floating shot


Links:

ScreenFloat Website (with free, 15-day demo)
ScreenFloat on the Mac App Store

Read more

When copying files in Finder, you might have noticed that the newly created, still-being-written-to files are ‘grayed out’, conveniently informing the user that the file is not ready yet.

Greyed out files in Finder

I wanted to replicate that for an upcoming upgrade of Transloader (along with a progress indicator, as you can see in the screenshot above, but that’s another topic), and after trying a couple of things, I found out how to do it.

I tested this on macOS High Sierra only, since it’s the OS version I’m targeting right now, but I don’t see a reason why it wouldn’t work on earlier versions of macOS.

It’s All in the Date

After digging around on the internet, I found that all that needs to be done is to change the file’s creation- and modification dates to one specific date, namely:
January 24th, 1984, 09:00:00 AM

Setting the creation and modification dates of the file to be greyed out

And it works great – the created file appears ‘grayed out’ in Finder.

There’s a downside, however:
When copying a file in Finder, and trying to move that still-being-written-to file, Finder will display a convenient message that tells the user the file is in use and moving it might cause problems.
This doesn’t happen when using this date-setting approach.

So I kept digging.

The Solution

What I did, then, was use Terminal and the ‘mdls’ command to list the meta data of the still-being-written-to file:

mdls in Terminal on a copying file

At first, coming from the date-approach, I noticed the kMDItemFSCreationDate item, stating
1904-01-01 00:00:00 +0000

However, setting that as the creation date does nothing at all.

Then, I noticed the kMDItemFSCreatorCode and kMDItemFSTypeCode fields (red arrows in the screenshot of Terminal above).

Setting those like this…

Setting creator and type codes in Objective-C

…does exactly what I wanted – it ‘grays out’ the file in Finder, and displays the convenient Finder error message when trying to move it:

Finder error message when trying to move a still being written to file

Mission accomplished – we’re done!

Please keep in mind, though, that the user may still choose “Continue” to move the file, so you should definitely use an NSFileCoordinator to take care of that.

Read more

As some of you may know, getting Yoink for iOS through Apple’s App Review was, to say it lightly, a bit of a pain.
In the end, I was able to release it, but a month late. Had this been my first app as an indie developer, there’s a good chance I would have had to declare bankruptcy now.
I am fortunate enough to have a couple of apps out already that create a steady income, but still, I spent about two months exclusively on this app, so it’s still scary thinking about how I got rejected over and over.

Long story short, here’s a couple of thoughts I’ve had during all of this.

TestFlight App Review

From the very beginning, I’ve had Yoink available to a couple of (awesome) testers via TestFlight.
Now, when you add a new app or a new version of the app to TestFlight, it has to go through a review before testers can download and test it.

My question, then, is: Why not reject the app right there if it doesn’t comply with the rules in the App Reviewer’s eyes?
If this is not checked, why have a review for TestFlight apps in the first place?

Or if that’s unrealistic for some reason, perhaps TestFlight App Review could give sort of a “likelihood of getting through the ‘real’ App Review”. Maybe on the levels of “yea, good luck with that” to “possibly, tentatively not going to be rejected”.

It would have saved me (and the App Review person) a *lot* of time and nerves had, for example, the File Provider extension been rejected right then and there for not being cloud-storage based. Or the keyboard, for not having a traditional method of input. Those are all things that could have been avoided, had TestFlight App Review caught these things.

Reasons for Rejection

Yoink was rejected for different reasons and in different areas of the app.
But those reasons were given to me one by one, one submission and “Waiting for Review” -> “In Review” cycle after another.
That’s *such* a waste of time (not only for the developer, but also for the reviewer. But *especially* for the developer).
Why not keep going after finding a reason for rejection and see if there are other issues after that? If so, the reviewer could note them all down and give them to the developer all at once, not one by one.

Notice of Escalation

When an App Reviewer isn’t sure about an app, the review is “escalated”, meaning it goes up one instance in the App Reviewer hierarchy to be reviewed by a “superior”.
That would be the perfect time to let the developer know in advance that, “look, review is going to take a little longer because we’ve run into an issue with your app. Please stay tuned, we’re working on it.”.
Not only would the developer know that it’s going to take longer for the app to be reviewed, they’d also have reassurance that the App Reviewer hasn’t forgotten about the app – anybody who had an app “In Review” for more than twelve hours knows that feeling 😉

In closing, I’d like to say that I have nothing but respect for App Reviewers. Their job is difficult and, mostly, unthankful.
But I believe a lot of grievances on both sides could be avoided if some of these suggestions were put in place.

Eternal Storms Software Logo

– – – Do you enjoy my blog and/or my software? – – –
Stay up-to-date on all things Eternal Storms Software and join my low-frequency newsletter (one mail a month at most).
Thank you 🙂

Read more

One of Yoink v3.3‘s new features is the detection of favicons for webloc files dragged into the app, making it easier to quickly identify individual weblocs at a glance. (A webloc file is something Finder creates when you drag a URL/link to it).
Think of it as QuickLook icon previews, just for websites:

Yoink with webloc files without favicons

weblocs without favicons

Yoink with webloc files with favicons

weblocs with favicons

The advantage is obvious right away, that’s why I jumped on it the second the feature was suggested to me.

Optional Setting

Even though I really like favicon detection and have it enabled on my Mac, I decided right at the start that favicon detection would be opt-in (disabled by default), for a couple of reasons:

  1. It requires an internet connection
  2. It uses data (very little, but still)
  3. I thought I’d use a Google Service for this (which I discarded after the prototype) and wasn’t comfortable having users use it without their “consent”

1) Internet Connection

Yoink is not an app that should require an internet connection at all.
It’s a “local” Mac app, it helps you with drag and drop, why need an internet connection?

As a side note, the connection itself actually doesn’t happen in the main Yoink app, it’s an XPC service that has the sandbox privilege, so the main app isn’t affected.

2) Data Volume

A Mac usually connects to the internet over WiFi or an Ethernet connection, and the data transferred for favicons *is* very small.
But there’s still a chance you’re using weblocs like crazy on a Mac connected to the internet via your iPhone’s Personal Hotspot on a data plan, which also makes it obvious why the user needs to be able to turn this option on and off.

It just made me more comfortable to have users opt-in to this option, instead of opt-out.

3a) Google?

Google has a nice favicon detection service, which is just a URL you pass another URL into to receive the image data:

http://www.google.com/s2/favicons?domain_url=PERCENT-ESCAPED-URL

There’ no need to parse the HTML yourself for the URL to the favicon, Google does it all for you.

3b) So Why Not Google?

What if the service goes away?
With Google having a bad rep for some users, would they use this feature?
What about privacy? (I don’t know, but they might collect your IP and then know what URL a favicon was loaded for, etc.)

So even though it worked very nicely, I decided to implement it myself.

Getting the Favicon

With Google out of the picture, I had to roll my own detection and parsing.
What I do is actually very, very simple.

I load the webloc’s URL’s HTML content, and then look through the header part.
In particular, I look for one of the following lines:

rel=“apple-touch-icon”
rel=“shortcut icon”
rel=“icon”
rel=“apple-touch-icon-precomposed”

in that order. (I’m sure there are more I could go through, but those were the ones that I came across while testing.)
Should none of those exist, I just try something like:

•) http:// … /favicon.ico
•)  …/favicon.png
•) rinse and repeat for every image format you can think of

If I have no luck there, either, I bail and return macOS’ default webloc icon.

If I am lucky and I find a “rel” I’m interested in, I figure out what the href contains (an absolute link to the image, a relative path to the image, or just the name of the image file itself). Once I know that, I can load the image file and composite it into the final icon.

The final icon is cached so Yoink won’t have to connect to the internet and re-download favicons for weblocs that point to the same base URL.

Drawing the “personalized” webloc icon

I went through three iterations, each at its own, unique laziness level.

Iteration 1, laziness level 3 (extremely lazy)

Just show the favicon:

Iteration 1 of Favicons in Yoink

No wonder I didn’t use it. It’s so lazy.
Second, it doesn’t even remotely resemble a webloc file anymore. It actually looks more like an image file’s QuickLook preview icon, and that’s a bad thing, as it could very possibly confuse users.

So I went on to

Iteration 2, laziness level 2 (pretty lazy)

Show the favicon super-imposed on the webloc icon:

Yoink Favicon Icon Iteration 2

That’s better. But not good, either. Favicons can be transparent, like the one here, but they can also be opaque, blocking the WEBLOC text in the icon and making the overall icon look more blocky and less nice.

Onwards and upwards!

Iteration 3, laziness level 1 (not that lazy)

Crop out the “Safari” part of the webloc icon and paint the favicon below it:

Yoink Favicon Icon Iteration 3

If the favicon is transparent, I draw it on top of a white background (so it would fit with the rest of the original webloc icon), if it’s not transparent, the favicon’s background is used, solving everybody’s problems. And you can still see that it’s a webloc file, at first glance!

Eternal Storms Software Logo

– – – Do you enjoy my blog and/or my software? – – –
Stay up-to-date on all things Eternal Storms Software and join my low-frequency newsletter (one mail a month at most).
Thank you 🙂

Read more