All blogs tagged: Swift

September 6, 2020 17:41
November 25, 2023 15:03

My struggles with NSPersistentCloudKitContainer

Read about my struggles with the new NSPersistentCloudKitContainer and how I got it to work in my app Hippo.

This is going to be a bit of a technical post.

During WWDC 2019 Apple announced a super simple way of adding iCloud synchronization to your app with NSPersistentCloudKitContainer. The promise is great: simply switch your CoreData stack from a regular NSPersistentContainer to NSPersistentCloudKitContainer and voila, your app will sync 🥳.

For the basic setup, follow this tutorial or check Apples documentation.

While this basic premise does hold up, I encountered quite some practical issues while adding iCloud sync to my app Hippo. To be honest, it drove me kind of crazy, so much that I almost ditched iCloud sync to move on to something easier 😬

I thought to share some of my biggest struggles here, maybe it will help you with getting iCloud sync into your app!

Issue 1: where is the existing data?

Probably your users will have some data in the app after you add iCloud sync. But NSPersistentCloudKitContainer did not sync existing to iCloud from my app initially.

The issue was that the original NSPersistentContainer did not have history tracking enabled. Thus only newly created objects or updated objects would be pushed to iCloud.

To solve this I implemented an ugly work-around: I've added a isSyncedToiCloud flag to all CoreData entities which defaults to false. Then on launch, the app checks if there are entities that havent been updated and will flip this flag.

This will trigger NSPersistentCloudKitContainer to push the entities to iCloud.

Issue 2: crash when adding an entity to the model

This issue took me forever to debug.  When you add a new entity to your model, you could get these kind of errors: Constraint unique violation, reason=constraint violation during attempted migration It turns out that this is a bug in NSPersistentCloudKitContainer on iOS 13.

New models should be ordered alphabetically and be added at the bottom of the list 🤦‍♂️. My solution was to prepend a "Z" to the new entity name, but this is quite an ugly solution.

This should be fixed in the latest iOS 14 beta's, but while you support iOS 13 you'll need to be careful with naming new entities.

Issue 3: how to let users enable/disable iCloud sync

Most apps allow users to enable and disable sync in the apps settings screen. Or sync is a premium feature only enabled if you have a subscription.

I tried to implement a setting switch to disable iCloud in Hippo from the app, but it's rather impossible to implement with NSPersistentCloudKitContainer.

First of all, there is a recommended way to turn off syncing, by setting cloudKitContainerOptions to nil. Be sure to do this before you call loadPersistentStores.

But, you will run into issues with this code. Since the container will only be loaded once when the app starts, and its contexts will be used in various views and background processes in your app, it's not simple to change this while your app is running.

I tried for quite some time to get this implemented but gave up after I got a reply from Apple. I now point my users to their iCloud settings in the Settings app to enable or disable sync. Not ideal, but I have no clue how to do this otherwise.

iCloud in production

I've submitted Hippo 1.4 with NSPersistentCloudKitContainer to Apple today, hopefully my users can enjoy the benefits of syncing, and I can move on to another feature 😁

November 25, 2023 15:03

Pientere Tuinen app

My newest product: an app for the Pientere Tuinen sensor.

I have a Pientere Tuinen ('Clever Gardens') sensor in my garden. It is a soil humidity and soil temperature sensor. Humidity is an important factor for plants, so the Pientere Tuinen project is gathering data from gardens all over the Netherlands. The data can be viewed through an online dashboard, but I don't check it much. Then, a couple of weeks ago, I noticed Pientere Tuinen released an API. So I created a simple app that reads the humidity and temperature data from the API and shows it. This makes the data much more accessible, it's right on my phone and even has widgets!

I used the Health app as inspiration, so the main screen shows an overview of the latest measurements. By tapping on a measurement, the user can dive into more detail and see the trends of their garden's soil humidity or temperature over time. I hope this is helpful for people who own a Pientere Tuinen sensor!

Download the app

November 25, 2023 15:03

Privacy friendly iOS app analytics

Add privacy friendly analytics to your iOS app with the Simple Analytics swift package

I'm a huge fan of Simple Analytics, the privacy friendly alternative to Google Analytics. I use it on all my websites and it is great. No cookie banners are needed and the dashboard gives me all the data I need without invading my users privacy.

But for the iOS apps I made I was still using a self hosted instance of Matomo. To change this, I created a swift package for Simple Analtyics! It allows you to add Simple Analytics to your app with just a few lines of code.

You can create a shared instance with the hostname of your app:

And then add pageview or event tracking in your app:

This is the dashboard of one of my (still in stealth) apps. Notice it tracks pageviews as well as visitors. The device type is available, as is the country. It is all I need for my apps!

Check the Simple Analytics swift package on GithubCheck the Simple Analytics swift package on Github