# Realm vs CoreData
Table of Contents
I want to start off by stating that I am not intending to compare performance or strongly weight end user results kind of statistics, but instead just experimenting with both to compare the experience a developer would have working with one or the other. To be completely honest, I doubt I have enough experience with either one to really make any definitive statements about which is a more pleasant experience for a develeoper, so obviously, I can only provide you with my own impressions and encourage you to experiment yourself to come to your own conclusions. I would also assume my example projects are overly simplistic, so again, I encourage you to try them for yourself.
Round 1: CoreData
CoreData is what we learned at Lambda. This is justified, if for no other reason, by the fact that this is what the industry typically uses. I mean, it’s included in the base SDK that Apple gives you, so it makes sense that it’d be what most in the industry use (amongst other reasons). I will admit, I had long harbored prejudice against CoreData as, both in my previous experimentation with it and doing reasearch online, it seemed to be difficult and confusing to implement. I had also heard it described in a way that made it sound like using it in Swift felt very clunky (as it was designed for Objective C, over a decade ago). I am happy to say that these are extemely minor concerns! I admit that the implementation is slightly round-about, but not overly so.
CoreData Pros
- WYSIWYG model editor
- The term WYSIWYG maybe isn’t the most perfect descriptor, but it’s kinda cool how it gives you an interface to create your data model.
- Super easy model migrations
- Just add a new model version and make changes – the automatic migration is pretty great at moving from one version to another
- It’s super easy to create a new entry in your data
- It can literally be as easy as initializing an object. If you want the object to stay in the database, just send the context a save command.
- The code templates I have make it super quick and easy to implement
- Lambda gave us templates for a
CoreDataStack
singleton that provides a main context and container (disk) access, an NSFetchedResults
var template to use in a UITableViewController, and finally an NSFetchedResultsDelegate
drop in boilerplate code. Granted, these aren’t just provided to everyone, but they made it fairly painless for me.
- Resulting Bundle Size
- CoreData is part of iOS (and macOS and iPadOS and tvOS) and is therefore included in the base OS install. This means that the framework can be excluded from the bundle that ships for the users to download.
- Learning how to use CoreData taught me some very good design patterns
- To be fair, this isn’t inherently a good thing about CoreData itself, but not having had a formal education on database handling prior to Lambda showed me not only how my instructors used it, but also how its pieces come together to make something functional and fluid
- Its age and therefore the available documentation
- It’s not hard to find an article, blog post, or howto pertaining to CoreData.
NSFetchedResultsController
manages sections in table views
- Not having to manage your sections independently is a brand new concept to me and NSFetchedResultsController just works*
- *when you use it right – I did experience some odd behavior when I implemented it wrong once!
CoreData Cons
- WYSIWYG model editor
- Counter to the pro, one might argue that, even if you don’t use the automatic code generation, you’re still somewhat pigeonholed. I haven’t experimented with the non automatic code generation much, but it just doesn’t feel as dynamic as other classes.
- Optionals aren’t optionals
- In the WYSIWYG editor, there’s a checkbox to indicate if a property is optional – despite being used with Swift, this is completely separate from the term optional in Swift. My understanding is that it means that the underlying database may or may not have a value, but it doesn’t translate to the class behaving in the same way we expect in Swift
- Its age and therefore the available documentation
- Contrary to the pro, tutorials might be super dated (and the majority are). It ultimately might be hard and confusing to find one relevant to the current iteration of CoreData. (and actually, this is precisely why I dabbled in Realm before I did anything with CoreData)
- Current tutorials might assume previous experience and therefore understanding
- Roundabout implementation
- There are a large amount of classes and objects that need to come together before you can actually start using your data
- Reliance on ObjC integration
- This just naturally brings some cruft alongside
- Potentially too easy to create new items
- I don’t believe this is inherent, but is effective for the variation we implemented.
- An example: We used CoreData as a cache for a FireBase database and were left with the choice to create an intermediary model to conform to
Codable
or conform the base class model to Codable
– the simpler way (and what we used) was to the use the intermediary, as least partially because simply initializing the class would create an object in our context, even if we didn’t want to. There are definitely workarounds to this, but it’s something to be aware of.
- Potentially confusing non single-source of truth
- There’s the data on disk, which can be different from the main context, which can be different from any other context you create in the interim – no upper limit on creating them either. Contexts can also inherit from other contexts, which adds to complexity
Round 2: Realm
I actually learned how to use Realm first. To be fair, when I say "learned", I mean "had horrible implementation practices and didn’t use it right". But it at least gave me a taste of how it works. Then, when I learned CoreData, it taught me better design patterns. The thing that struck me the most coming back to it, though, was that it didn’t feel as "swiftier" as I had remembered.
Realm Pros
- More concise
- There are fewer steps to getting it up and running (perhaps not if you count using Carthage or CocoaPods, but once that’s done…)
- Code based model
- Your data model is a fairly simple code file with only a few, simple parameters. The catch is more that they are not obvious without researching them, but there’s an easy cheatsheet for the basics.
- Its age and therefore the available documentation
- It’s grown fast, but most tutorials should still largely resemble the current iteration of Realm.
- Deliberate persistence methods
- Creating an object works independently of saving it to disk. Additionally, if you want to edit a live object, you need to use a special function to make changes first
- Live object edits
- If you retrieve an object from the database, its data is exactly what’s on disk. At all times. If you change an object, it reflects those changes on disk immediately. The only limitation (which, might be dated if a small snippet I saw recently is true) is that objects need to be written from the same thread they were created on.
- Single source of truth
- Directly piggybacking off the previous pro, this ultimately means you don’t have multiple versions of the database lurking around in memory. If you grab the same object in two different instances on two different threads and make changes to one, those changes are reflected immediately from the other.
- Online research indicates superior performance
- I haven’t tested this myself, but ever performance comparison I’ve seen puts realm somewhere between decently and ridiculously faster than CoreData (and alternatives).
Realm Cons
- Bundle size
- Unlike CoreData, Realm’s binaries aren’t shipped with the OS, so you need to include that in your app bundle, inflating its size. I don’t know how much this actually affects the end result, but it does.
- Its age and therefore the available documentation
- It’s grown fast – I’ve already ran into outdated documentation issue
observe
used to go by a different name
- Price of server side software
- I haven’t used it, but there’s a server portion to the software that I believe provides some sort of automatic syncing or something. I’m not sure of the specifics, but it’s quite expensive, especially if you want to self host. (this isn’t required, though, and CoreData doesn’t even have this kind of function, so it’s probably not even a super strong need.) That being said, I believe this is how Realm (the company) finances their work to even be able to provide the mobile database in the first place.
- Reliance on ObjC integration
- Not in the same way as CoreData, though. The effects are relatively minor, but they are there, and make your code look just slighly uglier.
- Somewhat weird persistence methods
- These are probably a consequence of the always live data models, but once an object is live, it needs to be modified or deleted through a special closure. This isn’t intuitive and, in my opinion, makes the code look a bit uglier.
- No equivalent to
NSFetchedResultsController
- More specifically, there’s no built in section management see. It does, however, prodive you with a super nice and concise row updater for table views.
Conclusion
This might not be the article you were looking for if you just wanted a "this one is better" answer as both have their strengths and weaknesses. After this, I believe I have a slight preference for Realm, but that could change if I find myself needing to implement sections in a table or collection view. Additionally, you may have noticed I sometimes used the same thing as a pro and a con, potentially for both Realm and CoreData. Ultimately, those are a matter of perspective and how you personally feel about those issues. In the end, there isn’t really a winner, despite what I had expected going in!
If you’re curious to see my simple demo project, I didn’t actually put it in my usual repo, but instead created its own. You can get it over here – Realm Branch – CoreData Branch.
I want to start off by stating that I am not intending to compare performance or strongly weight end user results kind of statistics, but instead just experimenting with both to compare the experience a developer would have working with one or the other. To be completely honest, I doubt I have enough experience with either one to really make any definitive statements about which is a more pleasant experience for a develeoper, so obviously, I can only provide you with my own impressions and encourage you to experiment yourself to come to your own conclusions. I would also assume my example projects are overly simplistic, so again, I encourage you to try them for yourself.
Round 1: CoreData
CoreData is what we learned at Lambda. This is justified, if for no other reason, by the fact that this is what the industry typically uses. I mean, it’s included in the base SDK that Apple gives you, so it makes sense that it’d be what most in the industry use (amongst other reasons). I will admit, I had long harbored prejudice against CoreData as, both in my previous experimentation with it and doing reasearch online, it seemed to be difficult and confusing to implement. I had also heard it described in a way that made it sound like using it in Swift felt very clunky (as it was designed for Objective C, over a decade ago). I am happy to say that these are extemely minor concerns! I admit that the implementation is slightly round-about, but not overly so.
CoreData Pros
- WYSIWYG model editor
- The term WYSIWYG maybe isn’t the most perfect descriptor, but it’s kinda cool how it gives you an interface to create your data model.
- Super easy model migrations
- Just add a new model version and make changes – the automatic migration is pretty great at moving from one version to another
- It’s super easy to create a new entry in your data
- It can literally be as easy as initializing an object. If you want the object to stay in the database, just send the context a save command.
- The code templates I have make it super quick and easy to implement
- Lambda gave us templates for a
CoreDataStack
singleton that provides a main context and container (disk) access, anNSFetchedResults
var template to use in a UITableViewController, and finally anNSFetchedResultsDelegate
drop in boilerplate code. Granted, these aren’t just provided to everyone, but they made it fairly painless for me.
- Lambda gave us templates for a
- Resulting Bundle Size
- CoreData is part of iOS (and macOS and iPadOS and tvOS) and is therefore included in the base OS install. This means that the framework can be excluded from the bundle that ships for the users to download.
- Learning how to use CoreData taught me some very good design patterns
- To be fair, this isn’t inherently a good thing about CoreData itself, but not having had a formal education on database handling prior to Lambda showed me not only how my instructors used it, but also how its pieces come together to make something functional and fluid
- Its age and therefore the available documentation
- It’s not hard to find an article, blog post, or howto pertaining to CoreData.
NSFetchedResultsController
manages sections in table views- Not having to manage your sections independently is a brand new concept to me and NSFetchedResultsController just works*
- *when you use it right – I did experience some odd behavior when I implemented it wrong once!
- Not having to manage your sections independently is a brand new concept to me and NSFetchedResultsController just works*
CoreData Cons
- WYSIWYG model editor
- Counter to the pro, one might argue that, even if you don’t use the automatic code generation, you’re still somewhat pigeonholed. I haven’t experimented with the non automatic code generation much, but it just doesn’t feel as dynamic as other classes.
- Optionals aren’t optionals
- In the WYSIWYG editor, there’s a checkbox to indicate if a property is optional – despite being used with Swift, this is completely separate from the term optional in Swift. My understanding is that it means that the underlying database may or may not have a value, but it doesn’t translate to the class behaving in the same way we expect in Swift
- Its age and therefore the available documentation
- Contrary to the pro, tutorials might be super dated (and the majority are). It ultimately might be hard and confusing to find one relevant to the current iteration of CoreData. (and actually, this is precisely why I dabbled in Realm before I did anything with CoreData)
- Current tutorials might assume previous experience and therefore understanding
- Roundabout implementation
- There are a large amount of classes and objects that need to come together before you can actually start using your data
- Reliance on ObjC integration
- This just naturally brings some cruft alongside
- Potentially too easy to create new items
- I don’t believe this is inherent, but is effective for the variation we implemented.
- An example: We used CoreData as a cache for a FireBase database and were left with the choice to create an intermediary model to conform to
Codable
or conform the base class model toCodable
– the simpler way (and what we used) was to the use the intermediary, as least partially because simply initializing the class would create an object in our context, even if we didn’t want to. There are definitely workarounds to this, but it’s something to be aware of.
- An example: We used CoreData as a cache for a FireBase database and were left with the choice to create an intermediary model to conform to
- I don’t believe this is inherent, but is effective for the variation we implemented.
- Potentially confusing non single-source of truth
- There’s the data on disk, which can be different from the main context, which can be different from any other context you create in the interim – no upper limit on creating them either. Contexts can also inherit from other contexts, which adds to complexity
Round 2: Realm
I actually learned how to use Realm first. To be fair, when I say "learned", I mean "had horrible implementation practices and didn’t use it right". But it at least gave me a taste of how it works. Then, when I learned CoreData, it taught me better design patterns. The thing that struck me the most coming back to it, though, was that it didn’t feel as "swiftier" as I had remembered.
Realm Pros
- More concise
- There are fewer steps to getting it up and running (perhaps not if you count using Carthage or CocoaPods, but once that’s done…)
- Code based model
- Your data model is a fairly simple code file with only a few, simple parameters. The catch is more that they are not obvious without researching them, but there’s an easy cheatsheet for the basics.
- Its age and therefore the available documentation
- It’s grown fast, but most tutorials should still largely resemble the current iteration of Realm.
- Deliberate persistence methods
- Creating an object works independently of saving it to disk. Additionally, if you want to edit a live object, you need to use a special function to make changes first
- Live object edits
- If you retrieve an object from the database, its data is exactly what’s on disk. At all times. If you change an object, it reflects those changes on disk immediately. The only limitation (which, might be dated if a small snippet I saw recently is true) is that objects need to be written from the same thread they were created on.
- Single source of truth
- Directly piggybacking off the previous pro, this ultimately means you don’t have multiple versions of the database lurking around in memory. If you grab the same object in two different instances on two different threads and make changes to one, those changes are reflected immediately from the other.
- Online research indicates superior performance
- I haven’t tested this myself, but ever performance comparison I’ve seen puts realm somewhere between decently and ridiculously faster than CoreData (and alternatives).
Realm Cons
- Bundle size
- Unlike CoreData, Realm’s binaries aren’t shipped with the OS, so you need to include that in your app bundle, inflating its size. I don’t know how much this actually affects the end result, but it does.
- Its age and therefore the available documentation
- It’s grown fast – I’ve already ran into outdated documentation issue
observe
used to go by a different name
- It’s grown fast – I’ve already ran into outdated documentation issue
- Price of server side software
- I haven’t used it, but there’s a server portion to the software that I believe provides some sort of automatic syncing or something. I’m not sure of the specifics, but it’s quite expensive, especially if you want to self host. (this isn’t required, though, and CoreData doesn’t even have this kind of function, so it’s probably not even a super strong need.) That being said, I believe this is how Realm (the company) finances their work to even be able to provide the mobile database in the first place.
- Reliance on ObjC integration
- Not in the same way as CoreData, though. The effects are relatively minor, but they are there, and make your code look just slighly uglier.
- Somewhat weird persistence methods
- These are probably a consequence of the always live data models, but once an object is live, it needs to be modified or deleted through a special closure. This isn’t intuitive and, in my opinion, makes the code look a bit uglier.
- No equivalent to
NSFetchedResultsController
- More specifically, there’s no built in section management see. It does, however, prodive you with a super nice and concise row updater for table views.
Conclusion
This might not be the article you were looking for if you just wanted a "this one is better" answer as both have their strengths and weaknesses. After this, I believe I have a slight preference for Realm, but that could change if I find myself needing to implement sections in a table or collection view. Additionally, you may have noticed I sometimes used the same thing as a pro and a con, potentially for both Realm and CoreData. Ultimately, those are a matter of perspective and how you personally feel about those issues. In the end, there isn’t really a winner, despite what I had expected going in!
If you’re curious to see my simple demo project, I didn’t actually put it in my usual repo, but instead created its own. You can get it over here – Realm Branch – CoreData Branch.