As developers we read all the time about the benefits of organising our projects into classes that have a single well-defined purpose however we tend not to think this way about our apps. This results in our apps directly doing more than they often have to. A Core or Common project is where some code is moved out of your app into other projects that can then be shared between different apps. Think of it as a Framework or library. Depending on how many apps you have this may seem like an overhead - having to create a new repo, create a new project, set it up as a static library or pod and finally integrate it back into your app however I find those costs worth paying because of what we gain from these Core projects.
#1. Share knowledge
If you work for a company that has more than app and those apps are maintained by more than one team, sharing knowledge becomes a very important activity as it allows a smaller team to behave like a larger team i.e. if you have two 4 person teams then by sharing knowledge via Core projects in certain situations you actually have a team of 8. The field that we work in is constantly evolving and everyday new ideas change the way that we work, with the this rapid rate of change it becomes increasingly difficult to keep up-to-date with all those changes. By working in a team you are able to spread that knowledge retrieval out to different team members and you can then gain some of that knowledge from looking at their code and discussing their changes - core projects allow this on a larger scale.
#2. Save development effort
As app developers we need to get our app into the App Store so the general public can benefit from our delightful ideas 😜.
Anything that can save on development time is to be investigated and this desire for speedy development is why we use frameworks and open source projects rather than writing everything from scratch. Core projects are a great of way of doing by taking code that your team as created and abstracting it out into a shared Core project. Core projects have the advantage here over open sources because they conform to your coding style guide, documentation approach, PR approach and if you have any questions you can always go to someone's desk and ask them directly.
Depending on the approach that your company takes it may be possible to open source those projects and so gain vital feedback from the wider development community on the quality of the those Core projects and address any bugs that are found.
#3. Reduce the scope
As our apps grow in scope it becomes increasingly difficult for any one person to keep a detailed understanding of the exactly how the app works in their mind. By splitting some of that code out into a Core project we reduce the scope of our apps and so make it easier to better understand exactly what your app is doing at any one time. Take for example networking, many open source projects have been created around that area in an attempt to reduce the overhead in making network calls which allows us to focus on what is truly important - using the data that those network calls provide to fulfil a need of our users.
#4. Different quality standards
Core projects do not need to conform to the same quality standards that our apps do - we can demand higher quality. For example code in Core projects:
- Must be used in a production app
- Must be documented
- Must be unit tested
- Must have been through at least one manual test cycle
- Must work across all supported versions of iOS with a consistent interface
This ensures that only the very code gets into our Core projects so when someone on your team uses a class from a Core project they can have a high degree of confidence that that class will do what it says it does.
I've also found that Core projects are a great way of introducing unit testing to a team and changing the way that a development team thinks about testing i.e. as an add on and not a vital part of the development process.
How do you decide what goes into a Core project?
When comes to classes getting into your Core projects you want to be that jerk security guard at a nightclub - turn anything that are not 100% sure about, not matter how 'classic' those Nike running shoes are. It's better to leave classes that could be Core classes in your app because you are unsure how useful they are than to spend the time moving them to your Core project. Your Core projects need to be as lean as they can be so that any new developer who wants to use them, is not over powered by the number of classes and methods available.
A Core project should be populated with classes that are abstract enough to be used across multiple projects. Networking is a great example here as it's a very common requirement for an app to be able to connect to server to retrieve data. By abstracting out the network calls you reduce the mental strain on the app developers - they no longer have to care about if that request is a
POST, if it's connecting to
v2 of the API instead the app developer just cares about retrieving the
Feed content and parsing it into their NSManagedObject subclasses.
The mindset of a Core developer
When developing for a Core project it is important to change your mindset. As an app developer you should be focused on creating code that solves one particular task and doesn't include any code that isn't needed for your app. However as a framework developer your mindset has to change, you should be focused on creating code that solves ones particular task in a non-domain specific manner because of this you often see protocols used more heavily in Core projects. Protocols allow us as Core developers to make demands of object that wants to use our Core class without actually caring what that object is, think UITableViewDataSource. Now what I'm not saying here is that as a Core developer you need to cover all possible cases or create classes that are so flexible as to be everything to everyone - in fact that is actually the opposite of a Core class where Single Responsibility Principle (SRP) is king. What I mean is that you need to write your classes so that they have very sharp and well defined interface between what is the Core project's responsibility and the callers responsibility.
Everything that exists in a Core class should be being used. If you ever find yourself tempted to add a method or property, 'just in case' - fight it. 'Just in case' features add to the overall complexity of a class without a immediate gain to justify their development costs. As Core developers you really are writing code for the next developer so you owe it to them to keep that class as lean as it can be.
Core projects I have found are essential to producing apps with high stability in a speedy manner. However setting up a Core project can be expensive in terms of time which is why we never directly develop in a Core project but rather classes/categories graduate into a Core project.
What do you think? Let me know by getting in touch on Twitter - @wibosco