Author's Posts

Yoink Mac App Icon

I’m happy to tell you that today, Yoink 3.2.5 is available for download from the Mac App Store. It’s a free upgrade for everyone who’s purchased it before.
You can download a 15-day trial for the app here, even if you’ve tried it before.

What Is Yoink?

Yoink simplifies and improves drag and drop on your Mac.

Simplify.

It simplifies drag and drop by providing a temporary place for files you drag, so you can navigate more easily to the destination of the files. It’s especially useful when trying to move or copy files between different windows, Spaces or (fullscreen) applications.

Moving a file with Yoink

When you start moving a file in Finder, or app-content like an image from a website, Yoink appears at the edge of your screen, offering a temporary place for you to drag the files to. Without having to keep the mouse button pressed, you can now get to the destination of your file quicker and easier.

Improve.

Drag and drop is improved in several ways, including:

  • Collect multiple files from different locations you’d like to move to one destination without having to go back and forth
  • Split up a multiple-files-drag so you can move files to different places without having to go back and forth
  • Copy files to multiple locations more efficiently

Customize.

You can customize Yoink’s behavior so it fits in perfectly with your workflow. Aside from having to option to show it at either edge of your screen (at the top, center or bottom), you can set it up to only appear when you drag files to the edge of your screen or to appear directly at your mouse cursor when you start dragging, making drag and drop even faster.

Yoink appearing at the mouse cursor

For applications where you don’t need Yoink, add them to a “blacklist”, so Yoink doesn’t interfere with your work. A keyboard shortcut (by default, F5) lets you manually show or hide it, should you need it anyways.

What’s New in Yoink 3.2.5?

Version 3.2.5 improves support for photos dragged from Photos.app on macOS Sierra, reduces the app’s energy footprint and CPU usage during drags and improves the user experience throughout several parts of the app.
As a result of the discussion about disabled checkboxes being poor UX design (blog post), I updated Yoink’s “Behavior” preferences pane to have a more understandable UI:

Yoink 3.2.5's new Behavior preference pane

Further Improvements

  • Improved Yoink’s behavior if auto-recognition of drags is disabled
  • Force-Touch-To-Select-All-Then-Drag-Out is now a more pleasant experience
  • At first launch, Yoink now respects and reflects macOS Sierra’s “Reduce Motion” setting
  • Several bug fixes regarding QuickLook, Force Touch and file cleanup

Pricing and Availability

Yoink 3.2.5 is available for purchase on the Mac App Store for the price of $6.99 / £4.99 / €6,99. It is a free update for existing customers of the app.
You can download a free, 15-day demo version here, even if you’ve tried Yoink before.
Yoink runs on Macs with OS X Lion 10.7.3 or newer. OS X Yosemite or newer is recommended.

If you’re interested in writing about Yoink, you can download the press kit here, which contains screenshots, links to a short video and further information. Promo codes are available to members of the press at press (at) eternalstorms (dot) at.

Yoink Usage Tips

To get the most out of Yoink, I’m collecting useful tips and tricks for you on this website.

I’m looking forward to hearing from you and to see what you think about Yoink v3.2.5. If you like the app, please consider leaving a little review on the Mac App Store, it would help me out a lot! Should you have trouble with it or have any feedback or questions, please be sure to get in touch, I’d love to hear from you! Thank you.

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

Translating your app into different languages is becoming more and more important. And articles like this one (techcrunch) seem to confirm that.

With Yoink 3.0 (mac app store, website), I localized the app into Japanese, Simplified Chinese, French, Portuguese (European and Brazilian), Korean and Italian (in addition to the languages that existed from the start: English and German).

Yoink In Brazilian Portuguese

Yoink in Portuguese

Here’s how revenue of Yoink increased a month after its 3.0 release (compared to the month before):

  • Japan: 305%
  • France: 212%
  • China: 144%
  • Portugal: 120%
  • Italy: 80%
  • Canada: 76%
  • Brazil: 45%
  • Belgium: 37%
  • South Korea: 16%
  • Switzerland: 4 %
There are great services available to help you: iCanLocalize, Gengo, wordcrafts, brlingo, just to name a few.
Yoink in Japanese

Yoink in Japanese

So, if I have one tip for you today, try to localize your apps at least into Japanese and Chinese – it will be worth it.

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

… Did

Released ScreenFloat 1.5.13 (mac app store, website, blog post)
Just in time for macOS Sierra I was able to release a compatibility update for my picture-in-picture productivity-app ScreenFloat.
As I previously mentioned, macOS Sierra introduces a new sandbox entitlement which prevented ScreenFloat from working correctly, because it prohibited launching an interactive screencapture section using NSTask.
Version 1.5.13 adds that entitlement and fixes a couple of minor bugs along the way, as a good bugfix- and compatibility update should 🙂

Blogged about Re-Implementing macOS’ screencapture CLI (blog post)
When I first learned macOS Sierra broke ScreenFloat, I immediately switched into my worst-case-scenario-mode and started working on my own implementation of macOS’ screencapture utility – at that point, there was no way to be sure Apple would make that sandbox entitlement public and let developers use it.
The in-depth blog post details what I found poking around in macOS’ screencapture command line utility and how I went about implementing my own solution making it look and work almost exactly like Apple’s solution.

Worked on Transloader 3.0 (mac app store, app store, website)
One of my goals for Transloader 3.0 is to support a multi-Mac environment.
In order to do that, I had to transfer the app’s inner workings from iCloud Key-Value Storage to CloudKit.
The reason is pretty straight forward: Up until now, Transloader sent a URL the user entered for download on a Mac to iCloud, associated with a unique key, something like ‘14225b23-fafb-41cd-be35-461acc583084’.
I would prefix that key with the current state of the download, as to be able to show it in the iOS Transloader UI:

  • no prefix – the download has not yet been received on the Mac
  • dwnld – the URL has been received on the Mac and is downloading
  • dlfin – the download has finished on the Mac
  • faild – the download failed on the Mac
  • –del– – the download was deleted on the iOS device and is to be cancelled and deleted on the Mac

Mind you, this was before I had CloudKit and I had to get the most out of what I was handed. And it worked pretty well, if I may say so. But it was already pretty complex. And when it comes to a multi-Mac environment, it’s not very extensible.
Sure, I could add yet another prefix to specify the Mac, but that’s got head-ache written all over it. Plus, if I’d like to extend the system even further, I’d be in trouble.
Having two prefixes, one to specify the Mac, one for the download state, isn’t something you can easily wrap your mind around, and it’s a nightmare to debug (believe me, I had an internal build of this working). Along with other pitfalls, it just wasn’t worth proceeding with this method.
The beauty of iCloud’s Key-Value Storage is that it syncs “transparently”. You use it like NSUserDefaults (where you might store users’ preference settings) and the OS would sync it in the background, whenever it would see fit. If sync failed, the system would try again at a later point. Beautiful.
With CloudKit, you have to take care of all the syncing (and errors) yourself. But you have so much more possibilities when it comes to your data model.
I now have two record types: ‘Mac’ and ‘Download’. A download record references a Mac record, which lets Transloader know which Mac(s) a download belongs to, and the Mac would take according actions (i.e., start the download).
Furthermore, the download record contains the current download state and additional metadata used internally in Transloader. It’s clean and understandable.
However, what had to happen, happened. In a frenzy of keeping everything in sync, I forgot to put the user first.
The beauty of Transloader is that you could add a URL if you had an internet connection or not and it would sync as soon as an internet connection would be available.
In my first version of CloudKit-based Transloader, I made the user wait for a successful sync: You’d add a URL and instead of adding it to your downloads-list right away, the app would wait to hear back from iCloud’s servers to see if it worked.
That might be (it’s not) OK if you always had a good, working internet connection. But what if you didn’t? Then you couldn’t add the URL, because CloudKit would return an error and tell the user to try again later.
That’s unacceptable. So I refactored the system in an important way:
I separated the sync from the data model. That was my error in thinking.
I thought – sync right away and you won’t run into any trouble, you’ll always be in sync.
But the proper way to handle it is this: Know that the data the user enters is always “right” and worry about the sync in the background. That definitely takes the pressure off.
Syncing should happen instantly, of course, but if it doesn’t because of an error, I don’t make the user wait and the user doesn’t lose the URL. Sync is just retried at a later time.
I also had trouble debugging push notifications. Not because of my code, but because Xcode 7 and/or macOS El Capitan couldn’t cope with maintaining code signing in regards to the Apple Push Service over restarts / logouts of the Mac, so push notifications would arrive at the Mac, but they wouldn’t be forwarded to my app. I even had a system of getting it to work again, after hours of experimentation – Reset to “Don’t Code Sign”, clean and build, Set to “Code Sign Automatically”, clean and build. Tada, it worked again (until the next restart or logout).
In macOS Sierra and Xcode 8, this is a thing of the past and everything is working perfectly. I can finally restart whenever I feel like it.

… Downloaded

Instead of doing my usual round-up of multiple apps I’ve downloaded over the month, I decided to do away with that for good and talk about just one app I’ve tried during the month.
I’m starting with the excellent time-tracking Mac app Timing, by Daniel Alm (@daniel_a_a on twitter).

Timing Mac App IconTiming (mac app store, website)
I’m not doing much time tracking. Maybe because I haven’t done much work for other people I could bill my hours to. Maybe because I like working for a flat-rate.
Or maybe it’s because I haven’t found the right tool for the job. To be frank, I haven’t looked around much, but having found Timing, I doubt there’s any need to look much further.
Timing automatically tracks almost anything you do on your Mac.

Timing in Action

Timing in Action, with color-coded activities and hopefully many billable hours. (Screenshot taken from the app’s website)

When you have the app running, it will unobtrusively track the apps (and its windows and documents) you use as well as the time you spend there – something that can come in handy even if you don’t have the need to bill hours to someone, as it gives you insights into what documents and projects you work on the longest (and where you might be able to optimize your time).
Apps (and their windows or documents) can be assigned to projects or activities so you have a nice group of apps that belong together.
If you’re a software developer, I suggest you check out this page, which will list some of the advantages you get out of tracking your time with Timing – something I plan on doing in the future for sure, even if only to see where I can improve my productivity or fix some (extremely rare) procrastination.
A free trial of Timing is available here, and it’s available for purchase on the Mac App Store.

… Read

Austria: The up-and-coming early-stage investment capital of Europe (techcrunch)
“With Germany to the north and the high-tech Netherlands beyond that, few have paid attention to the rapid changes taking place on the other side of the Alps.”

Providing the Best Possible App Store Experience (omni)
“All of these limitations stem from a single underlying problem: they’re all due to the fixed cost of the original download of the app.”

… Listened To

Steve Jobs at NeXT Introduction Press Conference (youtube)

… Watched

The Adventures of Indiana Jones by Patrick Schoenmaker (youtube)
A beautifully animated short film of my favorite archaeologist.

Mohenjo Daro Movie Mp3 Songs Pk Free DownloadMohenjo Daro (imdb)
An entertaining and thrilling story about Mohenjo Daro’s rise and fall.

Beatles eight days a weekThe Beatles: Eight Days A Week – The Touring Years (itunes)
The movie of the year for me. Granted, I’m a huge The Beatles fan, but even if you aren’t, I think this is a more than worthwhile picture.

Lights out movie poster 2016 by johnyisthedevil da5g865Lights Out (itunes)
A good horror flick with a new concept (“lights out”).

… Ate

Köttbullar

Köttbullar. No, not at IKEA. In Stockholm, at “Restaurang Tradition“. Very good food. Very pricey, too.

… Went to See

Me at Drottningholm, Sweden

Drottningholm Palace, Sweden

Stockholm from Stadshuset Tower

Stockholm, as seen from Stadshuset Tower

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

[Note: This is a guest blog post written by Thomas Zoechling (@weichsel on twitter), a macOS developer based in Austria, about his Mac app Claquette]

Claquette Mac App Icon

Animated GIF is not a good video format.
Actually it even isn’t a proper video format because it lacks random access and audio support. Nonetheless animated GIFs experienced a rennaisance in recent years.
My theory is, that the format’s success doesn’t stem from the features it has, but from the ones it lacks:

  • No random access: Defaults to autoplay – No playback interaction needed
  • No sound: Guarantees silence – Always “Safe for Work”
  • No support for 32bit colors: Moderate file sizes and a characteristic look

Given those constraints, GIFs are a great way to communicate simple concepts or interactions.
Want to showcase an animation or an application feature? Instead of a static screenshot with paragraphs of text, a 3 second GIF works equally well and also draws more attention.

In my daily life as software developer, I often need a quick way to capture graphical bugs. Those clips can be easily shared with colleagues or included with bug reports.
Sometimes it’s also simpler to attach a GIF to customer support requests instead of explaining how a certain feature works.
To cover my own needs, I wrote a small macOS application that allows me to record the screen and export the result as animated GIF. The app uses a custom recording codec and also covers the rest of the GIF creation workflow like crop, trim and file size optimization.

You can download Claquette from the Mac App Store. For detailed product information, please visit our website.

Development

When I started to implement the Animated GIF feature for Claquette, I began with a naïve approach.
Armed with several years of experience in writing Objective-C and some knowledge about video APIs on the Mac, I wrote a small prototype.
That first version just read a video file frame by frame and sent the resulting frames to ImageIO. ImageIO is a system framework that supports reading and writing several file formats.
It also comes with a basic Animated GIF encoder and so I decided to skip any third party libraries and just use the built-in mechanisms of macOS.
I was able to come up with a working prototype in a single afternoon. The program was just a simple command line utility, but it was able to turn an arbitrary video file into an animated GIF.

There was just one problem… Or actually there were several of them: Due to the inner workings of ImageIO, the program used vast amounts of memory. Also, the encoding took very long and the files it created were huge. On top of all that, the resulting GIFs looked horrible.
So while it only took me one Sunday afternoon to create a working prototype, it took me several months to fix the above issues. Especially the large file size and the bad visual appearance of the resulting GIFs required a lot of research.

Getting the most out of a 30 year old file format

The original GIF specification (GIF87a) was written in 1987 – almost 30 years ago. Animation features were added in GIF89a, which is still the most recent version of the format.
So how is it possible that a file format designed for low resolution screens and 256 colors is still in use today?
It turns out that the GIF specification contains some sections that open room for exploitation. Additionally, the visual nature of GIFs allows for optimizations to trick human color perception.

The format is simple and has the following basic structure:

  1. Header
  2. Logical Screen Descriptor
  3. Global Color Table
  4. Graphic Control Extension (Frame #1)
    – Delay
    – Disposal Method
    – Local Color Table
    – Image Descriptor
    – Image Data
  5. Graphic Control Extensions (Frame #2)
  6. Graphic Control Extension (Frame #3)
  7. … (1 GCE for each animation frame)
  8. Trailer

Header and Trailer are basically just magic numbers that mark the start and the end of the file. The Logical Screen Descriptor contains some general image information like width, height and background color. The Global Color Table is a simple list of colors that may contain a maximum of 256 entries.
Main image information is stored in one or more Graphic Control Extension blocks.

Color Table Generation

The color table sections of the format specification are a good starting point to optimize the visual quality of an animated GIF.
Both palettes are restricted by the format’s infamous 256 color limit. When reducing an image that uses 32bit (16.777.216 colors, 256 alpha values) to 8bit (255 colors, 1 alpha bit) it becomes really important which colors you leave out. The process of reducing large palettes to small ones is called Color Quantization. Choosing a good quantization algorithm is crucial when aiming for visually similar images with a reduced palette.
Naïve quantization implementations are based on occurrence, where seldom used colors are left out in the final image. More elaborate algorithms use techniques like dimensional clustering or tree partitioning.

When developing for Apple devices there are several libraries that provide color quantization functionality. macOS and iOS even have basic color quantization algorithms built-in. Apple’s implementation is part of the ImageIO framework’s CGImageDestination API.

The following sample images were created using different quantization techniques. They illustrate the quality impact of the used algorithm on the final image.

CGImageDestination Quantization

The first image shows the output of CGImageDestination. The resulting colors are noticeably off. Apple’s encoder also messes up the transparency color in the GIF palette, which leads to holes in some areas of the image (e.g. the titlebar).

FFmpeg Quantization

The open source library FFmpeg also includes a color quantizer. FFmpeg produces way better results than CGImageDestination. The colors are more vibrant and the transparency color is set correctly.

Claquette Quantization

The color quantization library used by Claquette also outputs a good choice of colors. Additionally the app performs color matching to avoid color shifts and to guarantee correct gamma values.

Frame Difference Calculation

Another important factor during GIF generation is efficient frame difference calculation.
The disposal mode in the Graphic Control Extension allows an encoder to specify how the context is set up before the next frame gets rendered.
GIF89a defines 4 disposal modes:

  • Unspecified: Replaces the existing canvas with the full contents of the current frame.
  • Do not Dispose: Leaves the existing canvas as-is and composites the current (sub)frame over it.
  • Restore to Background: Sets a defined background color and draws the current frame. Areas outside of the subsection in the Image Descriptor shine through.
  • Restore to Previous: Fully restores the canvas to the last frame that did not specify a disposal method.

The Image Descriptor section can be used to define a sub-image which does not provide pixel data for a full frame. Instead it contains coordinates and pixel data for a subsection of the full image.
By using frame differences and sub-images with a proper disposal mode, redundant image data can be avoided. Depending on the nature of the input video, this can greatly reduce the file size of the final GIF.
Modern video codecs like H.264 use techniques like macro blocks and motion compensation. Those methods introduce small errors that propagate from frame to frame. Propagated errors show up as noise when calculating frame diffs and eventually lead to unnecessary large files.
Claquette uses a custom lossless codec, that only stores regions that actually changed. This guarantees exact frame diffs.

The following images show the difference between frame #1 and frame #2 of a screen recording. The only effective change between those frames is a change in the mouse cursor location. An exact diff should therefore only contain an offsetted cursor image.

FFmpeg Diff

The above diff image was created between 2 frames of an H.264 encoded movie. The visible noise is a result of intra-frame encoding errors.

Claquette Diff

The second image was created by Claquette’s image diff algorithm. It only contains the mouse cursor – The only image element that actually changed between frame #1 and #2.

Finishing Touches

After implementing technical details like encoding and optimization, there were still some features missing. Claquette needed an editing UI to handle the whole GIF creation workflow.
As I wanted to keep the app lightweight and simple to use, I decided to add only a small set of editing capabilities: Trim and Crop.
Claquette uses AVFoundation, and therefore I was able to use the AVPlayer class, which comes with a built-in trim tool.
Crop functionality was a bit harder to implement. AVFoundation doesn’t provide any UI component to display crop handles so I had to implement my own.
Besides the standard drag & move interface, my implementation also provides some unique features. It offers alignment guides with haptic feedback and the possibility to enter crop coordinates.

You can see the final implementation of the crop utility in the animated GIF below:

ClaquetteCrop

Launch

To launch the animated GIF feature, I prepared a press kit and wrote mails to review sites that mostly cover Mac software.
Additionally I submitted the app to Product Hunt and informed Apple’s App Store Marketing team.
I can really recommend to launch on Product Hunt: Claquette received over 400 upvotes and finished in the top 3 on launch day. The site also hosts a friendly community, that makes extensive use of the Q&A section below each hunted product.
I was also lucky to get some mentions from high profile Twitter users and good App Store reviews.
Two weeks after launch, Apple suddenly moved Claquette into the “New and Noteworthy” feature section on the Mac App Store front page. Of course this also lead to a noticeable spike in the sales charts.
Overall I was very pleased with the release and the reception of Claquette 1.5.


Thomas Zoechling is an independent software developer living in Vienna, Austria.
Besides working on his own products, he is also doing contract work. Currently he is helping IdeasOnCanvas to develop the excellent mind mapping software MindNode (macOS, iOS).

Read more