iOS app

icon still not final

Core Data is like conversation: Take things out of context, and eventually, it will all come crashing down on you.

Me, in an attempt to begin this entry with something witty

ScreenFloat lets you keep visual references to anything you see on your screen floating above other windows using screenshots. It’s also a screenshot organizer.

Disclaimer: Estimated Time of Arrival, Pricing

I don’t do ETAs for my own products.
I’m a solo developer, I have multiple apps that need maintenance and updates, there are just too many moving parts for me to be able to estimate basically anything. And while that may be a serious lack of managerial skill: I accept that flaw and ignore it šŸ¤·ā€ā™‚ļø.

Regarding pricing, I don’t know what ScreenFloat 2 will cost yet. But I am resolved on its upgrade path: existing customers of ScreenFloat 1 will receive ScreenFloat 2 for free.

About this Journal

I thought it would be fun to chronicle my progress, struggles, successes, failures, struggles, failures, break-throughs, failures, and random stuff while developing ScreenFloat 2. That’s all.

Entry 2 – Core Data

This week, I’ve been busy with getting ScreenFloat 2’s migration to Core Data going and working, the first task being to decide on how I want to handle Core Data in the first place.

No multiple contexts, no problems. Right?

It’s been more or less established that, at the very least, you should have two managed object contexts when working with Core Data: One on the main queue for UI work, and another one on a background queue, for fetching and other “work”, so it doesn’t block the UI of the app.
This can make things tricky, because an object obtained on a background context should not and can not be used on the main queue to update the UI (and vice-versa). It has to be – for the lack of a better word – “converted” to a main queue object so that it can be used there.

So when I began working on migrating to Core Data, I thought, what if I could have the best of both worlds, with only one main queue context? Wouldn’t that solve all my potential problems?

John Hammond: “I’m not making the same mistakes again!”
Ian Malcolm: “No, you’re… making all new ones.”

Jurassic Park 2: The Lost World

What if the ScreenFloat app wasn’t aware about its Core Data nature at all? I could do all the Core Data stuff in a separate XPC service, and ScreenFloat would communicate with it to retrieve and update objects. The XPC service is its own process, so doing things there on the main queue context wouldn’t block the UI of ScreenFloat at all.

Sounds too good to be true? That’s because it is.

Issue #1 – Abstraction and Maintenance

To communicate with the XPC service, I’d have to create what I call “translator” classes that I send back and forth from and to the XPC service – classes that ScreenFloat understands (because it wouldn’t know about Core Data entities/objects), and the XPC service understands (so it can “translate” changes back to the Core Data store).
That would result in more work and maintenance. Anytime I wish to update a property, I would not only have to update the Core Data model and its entities, but also these custom “translator” classes.
And what about relationships in the Core Data model? Those would be a pain to handle this way.

Issue #2 – Bloating

ScreenFloat 2 will not only consist of the main app, but also a Share extension, at least.
That would mean to have to have this XPC service available to it as well, which in turn would mean having the XPC service inside the app twice – unnecessary bloat.

Issue #3 – iOS

iOS does not offer XPC services to 3rd party developers. But I want to have the same way of handling Core Data on all platforms ScreenFloat will support (I don’t want to have to do basically the same work twice), so it’s another no-go.

It was nice dreaming and wondering about this, but in the end, the more traditional approach to Core Data is still the best in my case.
Now I have a background queue context – used only for saving to disk -, on top of that the main queue context – used for updating the UI -, on top of that another background queue context – used for actually retrieving and editing stuff -, and on top of that an optional background queue context for work I might want not to persist/save, so it’s easy to discard. It works well so far.

Migrating ScreenFloat v1’s database to v2

I figured, the best way to get Core Data set up, working, and to see if my implementation works correctly, is to code it on-the-fly, adapting and changing it as needed. The best opportunity for this was to work on the migration of ScreenFloat 1’s dual-plist-file-based library. It’s the perfect case to see if my contexts are set up correctly, if conversion from one context to another works as expected, if all data and relationships are populated correctly, if it performs well, and if it saves to disk correctly.

On my MacBook Pro M1 Max, it imports the 699 Shots that currently reside in my ScreenFloat 1 library in less than 0.5 seconds (copying the files to their new destination, reading the plist files, creating the Core Data objects, and saving to disk).

It’s so fast that I had to slow it down artificially, so that the user can at least read that it’s upgrading the Shots library. If it weren’t for that, the progress bar would just be a weird, flashing artefact in the UI, leaving the user clueless as to what just happened. So instead of starting the migration process right after the Splash Screen appears, there’s a little delay, and then the process starts. When it finishes, there’s another short delay, and the Start using ScreenFloat button appears.

Migrating the library also got me thinking about what additional (meta)data I might need further down the road. For instance, ScreenFloat 1 doesn’t do “favorites” for Shots. So an “isFavorite” property would be a good idea.

Another one’s a bit more complex:
Users can put Shots into Categories to organize them. I’d like to store a bit of contextual information for that. For instance: when was this shot added to this category?
If a Shot could only be added to one category, that would be easy – just have an optional “dateAddedToCategory” property. But categories have a multiple-to-multiple relationship with Shots: a category can contain multiple Shots, and Shots can be added to multiple categories.
To my knowledge, the only way to do that is with another Core Data entity (let’s call it “CategoryShotMetadata“) and a many-to-one relationship to both the category and the Shot. When a Shot is added to a category, it automatically creates an object of this metadata entity, populates its “dateAdded” field, and sets up the relationships to the category and the shot. This makes it easy to fetch later: the Shot-to-metadata and Category-to-metadata is a one-to-many relationship (a Metadata object has one Shot and one Category, but a Shot/Category can have multiple Metadata objects). Now, the metadata object can be identified by the combination of its single category and single shot relationships.


I’ve been enjoying my time with Core Data so far (and I’m fully aware that this might change at any given moment šŸ˜‰ ) . It’s definitely more complex than my previous two-plist-file-approach, but – let’s be frank – Core Data is just better.

That’s it for this time.
Thank you for joining me. Feedback, input and questions are welcome: mail me, tweet me.
Take care! šŸ¤—

Read more

Yoink for iPad and iPhone's App Icon

Today, Yoink for iPad and iPhone is 3 years old 🄳. Time surely flies when you have… bugs to fix.

It certainly doesn’t feel like three years. It feels like only yesterday, to be honest.
On the other hand, the release process, yes, that felt like it took three years, because I was eager to release alongside iOS 11 (which, due to its drag and drop capabilities, made Yoink for iOS possible in the first place), but there were some serious delays with App Review, who rejected the app multiple times because of its keyboard extension, and later, its File Provider (while other, similar keyboard/FP extensions were apparently perfectly fine and allowed on the App Store. This is my single biggest gripe with App Review – the inconsistencies in rejections. It’s obvious why these things happen, and it’s understandable, but it’s frustrating nonetheless).

But all that’s in the past. Yoink for iOS has been out there for three years now, and it has been doing great – thanks to all of you who use it, leave ratings, reviews or send feedback.
It’s been featured on the App Store on numerous occasions – here are a few examples:

Yoink featured on ios app store

Yoink iOS App Store Feature  17 09 2020 14 39 25

Yoink iOS iPhone App Store US Feature  07 12 2017 13 06 01

So thank you all for three amazing years. Let’s hope for many, many more šŸ¤—

P.S.: Keep an eye out on my social channels (twitter | facebook | linkedin), as I’ll be posting a few promo codes there!

Ā 

– Matthias
mail | website | twitter | instagram | facebook

Read more

Yoink for iOS Icon

I’m happy to announce the immediate availability of Yoink v1.1 for iPad and iPhone.
It’s currently being featured on the App Store under ā€œNew Apps We Loveā€.

What’s Yoink for iOS 11?

Yoink strives to improve and simplify drag and drop and speed up your workflow.
It accepts almost anything you can drag, copy or share on your iPad and stores it for later use. This way, your fingers are free for more important things.

It’s a storage place for anything you might need later – an image from a website, a text snippet from a document, a URL, etc.

Here’s a quick YouTube video of how it works (check your sound, there’s some music) :

And a second one (with music, again) :

What’s New in Yoink v1.1?

Aside from numerous improvements and bug fixes, like an improved keyboard extension, the ability to create stacks by dragging items onto one another, smarter Spotlight indexing and a new take on the Share extension (it doesn’t need confirmation anymore for adding items), there are a lot of new features:

Clipboard Integration
When you open Yoink and have something new on your clipboard, Yoink will automatically offer to store it for you.
(You can configure this so Yoink doesn’t ask at all, and anything new gets automatically stored when you launch the app).

Download URLs
When you use Yoink’s Action extension to send something from another app to Yoink, the extension automatically detects if it’s a URL you are saving.
If that’s the case, you have the option of downloading the file the URL points to instead of saving the link to the URL in Yoink.
An optional notification can inform you about finished or failed downloads.

Today Widget
From the Today Widget, you can quickly copy the most recent items stored in Yoink to your clipboard, and save content from your clipboard in Yoink.

Quicker Sharing, Copying
Instead of having to tap Edit any time you’d like to share an item from Yoink with another app, each item and stack in Yoink now has a button that lets you quickly access those options.

Better iPhone Awareness
Quick Actions (via 3D Touch on the Home screen) for quickly adding your clipboard contents from your home screen, or to start a download.
Peek and Pop for items and stacks in Yoink
Full iPhone X Ā support

URL Scheme
You can now communicate with Yoink from other apps using Yoink’s URL scheme.
For more information, please visit the Yoink for iOS Usage Tips website and read Tip #6 šŸ™‚

File Provider
Finally. After being rejected by Apple for the initial version of Yoink (over and over again), the file provider extension has now been approved and is part of the Yoink experience on your iOS device.
Any app that uses the documents browser can now access items stored in Yoink.

Pricing and Availability

Yoink for iOS is available on the App Store right now, a little longer for the introductory price of $2.99 (€3,49). An iPad or iPhone with iOS 11 is required.

Yoink is also available on the Mac.

Links

Yoink for iPad and iPhone Website: https://eternalstorms.at/yoink/ios
Yoink for iOS Usage Tips: https://eternalstorms.at/yoink/ios/tips
Yoink for iPad and iPhone on the App Store:Ā https://itunes.apple.com/app/id1260915283?mt=8
Yoink for iOS Press Kit: https://eternalstorms.at/press/Yoink-iPad-1-Press-Kit.zip

Yoink for Mac Website: https://eternalstorms.at/yoink/mac
Yoink for Mac Usage Tips: https://eternalstorms.at/yoink/mac/tips
Yoink on the Mac App Store:Ā https://itunes.apple.com/app/id457622435?mt=12
Yoink for Mac Press Kit:Ā https://eternalstorms.at/press/Yoink-3-Press-Kit.zip

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