A recent episode from the featured an interesting interview with , who has been developing in iOS since the first iPhone, was creating Mac apps before then. SwiftCraft podcast Matteo Manferdini It offers what is currently a contrarian take on iOS architecture, but one that resonates with me — being in favour of MVC. In the rapidly changing software industry it’s essential to keep an extremely open mind, because the lines are really thin between fad and revolutionary. Although I’ve been exploring MVP, MVVM, and VIPER in recent years, none of them have been compelling enough to convince me that they’re less complicated and cleaner than MVC be. can I’ve been meaning to write a blog post expanding on Matteo’s , why a ruthlessly lean MVC is perhaps the cleanest solution, and how it’s all tied into a programming culture where . Lotus MVC pattern we’re making slightly complicated concepts into incredibly complicated solutions The Lotus MVC pattern is still a little bit too close to VIPER for me, but it’s the closest literature I’ve come across to argue for a lean MVC that is capable of organically growing, rather than setting up unnecessary boilerplate code from start. I’ll expand on my thoughts on Lotus MVC, and how it ties into a pattern that I’m calling (part joke, part serious) to combat against the trend to double down on complexity, at another time. FUMVC When classic software engineering concepts of high cohesion & low coupling are applied along with SOLID principles, MVC in iOS tends to strike a balance between a particularly well abstracted yet easy to follow architecture. This is beneficial to both rapid prototyping or MVP’s, or longer term legacy code ( MVC growth). organic The abstraction between the models and the view controller Matteo referred to was a , and I couldn’t help but think that it’s the small and manageable pattern that I usually adopt for any Core Data work. Except I usually call it something like a or . Model Controller ModelManager ModelCoordinator Trying Different Abstractions Over the years I’ve swung between a few different patterns working with Core Data, that could probably be summed up by the following phases: When I started iOS dev I was using more of a model controller pattern, with a central model object doing a combination of performing the CRUD operations (or more pedantically in iOS — add, fetch, save, and delete), and setting up the , , Core Data stack, and any that was needed. This was unfortunately, also usually a singleton. NSManagedObjectContext NSPersistentStoreCoordinator NSManagedObjectModel heavyweight migration On one particular project, a frontend developer provided some feedback on the API interface calls that he thought made more sense for the iOS frontend. Based on this, I experimented with adopting a pattern where each model’s class or extension contained their own CRUD operations. They could therefore be used like the following , or . There was a lot of boilerplate here, and all for not much gain. The initial intention with things like the fetch call, was to be an alternative to specifying predicate strings, and using customized sort descriptors from enumerations and the like. But on reflection, I believe that every developer should be familiar with predicate strings, as the syntax is universally appicable to SQL queries, and every developer should familiarize themselves with SQL queries, even when using an ORM. modelType.create(withProperty: String) modelType.fetch(byProperty: String, containingValue: String) Since iOS 10 when the simplified the setup involved with the Core Data stack, and prior to that when generics became a thing with the rise of Swift, I’ve been favouring an approach where 1 or 2 smaller abstractions coordinate between the data models and the view controllers. Generics makes the prospect of reducing boilerplate code particularly attractive, and with the gently guiding you to create a new background MOC every time you need a background MOC, this also helps in mentally discouraging you from implementing it as a singleton. NSPersistentContainer NSPersistentContainer A slide , the introduction of NSPersistentContainer. from WWDC 2016 On that note, I thought I could share the above latest implementation of a Core Data that I’m favouring — the purpose being that can drop this into their codebase no matter how your data models are set up! ModelController anyone The Model Controller I’ve uploaded this to a , which will be used for the greater purpose of reusable abstractions. This is the 1st , so the library is currently really small. new repository FUMVC contribution to FUMVC The shouldn’t try to everything, if it’s primary purpose is to be highly reusable. I’ve kept the code to a minimum for this reason. ModelController I usually use conventionally verbose Apple influenced function names, such as something like . Yet lately I’ve been influenced by my work in React apps and its naming that seems to be influenced by intermediate operations — which seems to be the naming conventions that as well. So the functions are defined as: addDataStorageEntry Apple are moving to add(type:) total(type:) fetch(type: predicate: sort:) save() delete(by objectID:) delete(type: predicate:) What the sample code in this blog post doesn’t do — it only uses one managed object context (the view context used for the main thread), and it doesn’t implement thread handling, as it would detract away from the main topic. Although I have updated the Github repository with some thread handling, and cover it a little bit below. But for now, let’s dive into each of the above functions… The properties just consists of an , and 2 s for the main thread and a background thread. ModelController NSPersistentContainer NSManagedObjectContext There is a convenience initializer with a single purpose to set the model name via dependency injection instead of being coupled to the Core Data abstraction. The is lazy because of this. The private ’s default value should set the model name to the bundle, a likely safe scenario should you opt for the designated initializer. The is set via the convenience initializer rather than a setter, because its single purpose it to be needed on instantiation and nowhere else. NSPersistentContainer modelName modelName The takes care of the creation of a new subclass. If Recipe is one of your model entities, you can use it by . ModelController+Add NSManagedObject modelController.add(Recipe.self) I’ve included a total function as well as a fetch function in , as they’re both fetch related. This is where your s are done, and the predicate strings and sort descriptors are optional, as you might want to use fetch to simply retrieve all records. ModelController+Fetch NSFetchRequest How to use total and fetch: let total = modelController.total(Recipe.self) let predicate = NSPredicate(format: "name LIKE %@", "Fetcheroni Pizza")let fetched = modelController.fetch(Recipe.self, predicate: predicate) The is pretty standard. Even if you don’t use a Core Data abstraction, it’s very likely that you’ve written a method to check for and wrap a try/catch. ModelController+Save save() hasChanges Finally, the . There are 2 delete methods here — one with the standard interface pattern used in the fetch method, with the type and predicate passed in to find the object you want to delete. ModelController+Delete The other checks for the , which is an issue that is consistently overlooked in deleting Core Data objects. Accessing the object via a fetch is no guarantee that the same object will be deleted on the same thread that it was accessed on, so deleting by ID is the recommended approach by Apple. The predicate method also wraps the method for this reason. NSManagedObjectID delete(by objectID:) How to use: modelController.delete(by: recipe.objectID) let predicate = NSPredicate(format: "name LIKE %@", "Deep Pan Pizza")modelController.delete(Recipe.self, predicate: predicate) Thread handling There are advantages to using either and . Both are functions that accept a closure to enable you to use a managed object context on the correct thread it’s associated with. perform(_:) performAndWait(_:) Note, that this is slightly different to using or , where sure, while it may be true that they would be executed on a different thread, you are not necessarily enabling the context to to the thread it’s with. DispatchQueue.global() async(_:) sync(_:) match associated Getting back to and , the only difference between the 2 is that continues the flow of execution. So in a function where you want to return a value for some reason that doesn’t depend on any asynchronous operations, you would use to continue execution and return something not based on that block. perform(_:) performAndWait(_:) perform(_:) perform(_:) If on the other hand, what your function is returning depends on the block, you could use to allow the block to finish executing before the function returns. More is . performAndWait(_:) explained here We could go with either approach in the , or we could even go with a combination. For now, I’ve updated the repo with the approach (the above sample code has no thread handling), and have added a completion block as a function parameter to allow the continuation of execution via the completion (as opposed to the return approach with ). ModelController perform(_:) performAndWait(_:) I just think by limiting the usage of until it’s really needed, reduces the chances of blocking the main UI thread. As after all, the , as with most good abstractions, shouldn’t restrict the flexibility in how a calling component should use it — it’s up to the parent object to decide whether to block the main thread or not, not some mystery box behaviour in an encapsulated interface. performAndWait(_:) ModelController However, maintaining flexibility in providing returns and completion blocks comes at a little bit of a cost of clean code. For this reason, if the will eventually add behaviour into its implementation, I’d want to do this via Max Howell’s . This uses the JavaScript concept of promises, to reduce the messiness of nested completion blocks, as well as propagating error handling. performAndWait(_:) perform(_:) ModelController performAndWait(_:) PromiseKit The repo also currently doesn’t utilize the background context, and providing this functionality would be the next obvious implementation. It doesn’t need to blow out any more than that though, this should be a really simple and lean reusable library as the for any Core Data codebase. I feel as if reusable libraries are best that way, and any extra functionality should be an extension on that library or just customized for the particular codebase being worked on. Otherwise it doesn’t get , and that’s the whole point of libraries. ModelController first port of call reused Where To Next? I found accessing the type as a value along the lines of a bit redundant, and one step working against this from an elegant API. I’m not sure if this is possible, but it would be great if you could add an enumeration for the Core Data model types, along the lines of Benedikt Terhechte’s blog post on the section of , by implementing the protocol. On another note, this is a great reference for everything to do with in Swift, and I highly recommend bookmarking it. EntityName.self using custom data types StringLiteralConvertible enumerations The most pressing issue would be providing an elegant and minimal interface to the background managed object context. This could be done via an extension or option protocol on the though, as I think that having a background MOC is something that most developers rush into without a need for it. ModelController I will also be blogging an update on the greater concepts of FUMVC, and how the repository is likely to take shape.