ahmedk92 / Blog

My blog, in Github Issues.
https://ahmedk92.github.io/Blog/
18 stars 4 forks source link

When to decide to use Core Data in an Application? #22

Closed bashmoanas closed 4 years ago

bashmoanas commented 4 years ago

Did you ever chose to use Core Data without using its persistence layer?

ahmedk92 commented 4 years ago

Hi, thanks for dropping by.

When to decide to use Core Data in an Application?

If:

  1. The data is too big to fit in UserDefaults. More on this here #17.
  2. You don't want to bother with sqlite.
  3. You don't want to use a third-party persistence solution.

I have more to say on the last two points, but let's answer your other question first.

Did you ever chose to use Core Data without using its persistence layer?

I don't get what you mean by "without using its persistence layer". Can you please explain?

bashmoanas commented 4 years ago

By definition, Core data is not a database, it is a framework that you use to manage the model layer objects in your application, and it happens that it can persist your data. And as I understand it you can benefit of Core Data features without needing to persist the data in its underlying SQLite database? Or am I getting this wrong?

ahmedk92 commented 4 years ago

If you mean using Core Data with in-memory storage, then yes, you can. However, I don't see advantages for this approach over using Swift structs and collection APIs.

I hope I'm not still missing your point 😅

bashmoanas commented 4 years ago

I think we are onto something :D So, if the data is too big to UserDefaults, one might use Core Data. Understood. You don't want to bother with SQLite, I believe I don't want to :) but I will wait your elaboration on this. You don't want to use third-party persistence solution. Again, I will wait for your elaboration because the question would be when should I use a third party over Core Data?

ahmedk92 commented 4 years ago

Great!

You don't want to bother with SQLite

As you said earlier, Core Data is not a database. However, it's often mistaken as such, or even an ORM. The Apple-provided sqlite API (C-based) is too low-level for the liking for any developer. Also, many developers don't like the switch between relational (thinking in tables, relation and SQL) and OOP. So, it's easy to view Core Data as a convenient sqlite replacement. This is also reinforced by the fact that Core Data uses sqlite for its storage (but not only sqlite). Developers are then surprised by the complexities introduced by Core Data, all while what they really want is the basic CRUD tasks you commonly do with sqlite. Luckily, there are decent third-party sqlite wrappers with a wide feature spectrum; from nano-libraries like SwiftSQL, to a full-featured persistence solution like GRDB. I recommend reading the GRDB docs for learning more about databases from an application developer point of view. It's excellent.

You don't want to use third-party persistence solution

This is a controversial subject in software development. Some are liberal in using third-party dependencies, some are conservative, each with good reasons. Some (like me) see third-party dependencies (especially open-source) as a technical debt. Use it to save time, but keep in mind it's not unlikely for a day to come when you need to maintain it yourself or roll your own alternative. Don't get me wrong, I love (and contribute) to open-source, but open-source libraries can be problematic if you can't maintain it (or a fork) yourself (or pay someone to do so). Open-source libraries are not guaranteed to be kept alive and well-maintained. Basing your project on a project that you have no control (your contributions) nor influence (your money) is wishful thinking. So, it's clear why would some pick an inferior Apple-provided solution over a better third-party solution.

Left is an important detail; why think of sqlite or a third-party in the first place? What's wrong with Core Data?

Intricacies

Like we briefly explored above, Core Data gets complicated so quickly. You have to setup a "Core Data stack", deal with "managed object models", "managed object contexts", "store coordinator", "persistence coordinators", construct an "NSFetchRequest" and enumerate data with "NSFetchedResultsController", "faulting", and more importantly follow The Laws.

Realm is a perfect example (API-design-wise) on how to implement a Core Data replacement while offering a friendly API. Realm is based on very similar ideas to those of Core Data (lazy loading) and suffers from similar problems as Core Data (see the end of the next paragraph).

Un-Swifty Style

Ignoring intricacies, Core Data may made sense in the past, in the Objective-c era. It's not the case with Swift. A defining feature of Swift APIs (API designed in Swift in general; not necessarily Apple-provided) is prioritizing value types (structs & enums), and maintaining type safety. Core Data requires you to subclass NSManagedObject for data (some may say DTOs), and write your queries in a stringly-typed fashion (NSPredicate). Not only that, for efficiency, this NSManagedObject subclasses are mostly empty (look up "core data faulting"), and they're mostly a view to a database record. This makes them problematic to pass them around between threads (Realm suffers from that).

Conclusion

This is not Core Data bashing. I'm just exploring what about Core Data that makes it not appeal to many developers. Of course some may like it. And of course it has powerful features (like secure storage), and a very good integration with CloudKit.

bashmoanas commented 4 years ago

Thumbs up for the Un-Swifty Style. Well, that sums it very well.

Appreciate you taking the time to reply to my question.