We are starting a blog post series on crafting client-server integrations. Throughout the posts we discuss why it’s important to have well-defined communication between your client and the server. We touch on the importance of what to do and the thinking process applied when approaching the architecture and implementation of your iOS and backend applications. These posts are not overly technology-specific and talk about general ideas so that you can apply this new approach to the problem immediately.
These posts are designed for several different types of IT specialists: project managers; product owners; software architects; and backend, frontend, and mobile developers. Project managers and product owners will learn exactly what goes into developing a project and how to best organize and schedule the workflow. Software architects will learn an alternative approach to developing a software product. Developers will learn how to best integrate the client with the server in order to achieve an optimal user experience. Everybody will see just how vital the communication process is during software development.
In this blog post we take a look at why deliberate client-server integration is very important (and even more so for iOS apps).
How Most App Projects Fail
On The Surface
When you develop an iOS application (or any mobile or rich UI client application for that matter) the approach taken varies depending on the specific challenge you face, business considerations at hand, and the desired outcome. On average, when building a consumer-facing application developers tend to architect and implement client iOS applications independently from the server backend architecture. This potentially causes problems in the future for the application and for the product in general.
Sooner or later the day comes when you need to make a change to your code. This might be a simple change that improves user experience (to the delight of your users). But, for the love of god it takes forever to implement! Your models aren’t suitable for that. Your view controller is more than 2k+ lines of code. Your backend is not even remotely prepared to be changed (so that it can serve data according to the new requirements). At this point you have no idea what's going on! Sound familiar? After yet another sleepless night you wonder if it’s better to have your app built from scratch with all the precautions in place.
Typical ways teams and developers approach app development:
First an MVP of the iOS app is built and then server backend developers try to catch up and come up with CRUD-ish endpoints that barely comply to any RESTful guidelines. iOS developers don't know what they need on the client side (or even in what form). They usually have no idea how the APIs they want will impact backend performance and stability. This is one of the worst scenarios imaginable!
Another typical scenario is when two teams try to work together (or more often against each other). One team works on the backend and another on the iOS/client side. The most common problem for these guys is lack of coordination and organization. The server team builds generic APIs that the iOS team either doesn't need or can't consume and process due to mobile limitations or other constraints. The iOS team in turn doesn't know what they need to know about the backend side of things and demands unreasonable APIs or just blindly uses whatever the server guys give them. This is slightly better but it’s still a bad scenario.
The last common approach is creating server APIs first and then afterwards creating an iOS app that connects to it. Most of the time the problem in this case is that the server-side developers build something really generic and unsuitable for mobile usage which makes the iOS client side guys use whatever they've been given. This sometimes leads to success when the server guys listen to feedback and stated requirements given by the iOS developers, but it still lacks structure.
Client-Server Integration Approach
Details Of a Smart Solution
When building iOS client side apps pay careful attention to how they integrate with the backend. Everything you have in the app directly or indirectly impacts the server. The server and client go hand-in-hand. Optimal implementation of each (keeping a close eye on their integration) achieves the best user experience. You do not want them fighting each other. You want them working together so that they always communicate in harmony.
This is what we call the client-server integration approach.
The implementation of this approach encompasses:
- project analysis and outline
- modeling and architecture
- backend API sketching
- client-server communication sketching
- client side domain modeling
This approach works best for consumer-facing applications backed with the server API. However, the first two steps are suitable for software development in general.
1. Project Analysis and Outline
Every app needs to be thoroughly planned out from the get-go. Your clients come to you with a business problem that they need solved, but they don’t provide you with a precise and comprehensive list of requirements. They probably just tell you their wants and needs and the end result that they expect from you. So it is is your job to turn that list of wants and needs into a list of high level but comprehensive requirements that will go into the system you are going to create.
The more information you have about the business function of the app before writing a single line of code the better off you are. We use a lot of different tools like Trello, Project Tree (work in progress), and Basecamp for planning and communicating with clients at every stage of the development cycle. Early on in the project, it’s crucial to figure out as many details about what the app needs to do as you can. Always be on the same page as the client (or product owner) regarding the project. Otherwise, you might end up building what's pictured above.
2. Modeling and Architecture
Domain modeling is one of the first things you need to do when building an app. It serves and processes all of the data and it drives data flow. At this point you should already have a list of requirements based on your client’s expectations. If a client wants to automate his business processes, you should first model those business processes (an “as is” model). Then suggest how to optimize them (a “to be” model). In some cases, after this analysis, you can come to a solution based on the existing IT system(s) (or possibly a solution that doesn’t involve IT).
You must look at the “big picture” of your system. This means looking at the system, its components, and the relationships and communication contracts between them. These will be specified further in the development process.
When designing models you must understand what business needs and data structures you are going to work with and how to best organize them. Often the process of domain modeling helps optimize business requirements. Find out ahead of time if some of them are potentially redundant and get a clear overall picture.
3. Backend API sketching
Different apps require different APIs. With this in mind, there are different ways to build APIs and you must decide which way is best for your given situation. The most widely used and flexible architecture is REST. Servers that are REST compliant are easy to consume and can be easily changed and configured to serve data to iOS apps. Crafting APIs for a particular client application is sometimes called “building APIs for experience”. Sketching it ahead of time (sometimes even in great detail) is important for creating smooth client-server integrations.
4. Client-Server Communication Sketching
There are a lot of existing libraries and frameworks written for REST on both the client side (AFNetworking, RestKit, Mantle, Overcoat, etc.) and the server side (Rails, Django, numerous other frameworks, etc.). REST architecture helps when sending and receiving data to and from the backend in a unified agreement/contract. Also RESTful API driven client applications tend to share some of the domain modeling and logic with the backend. It helps when integrating them since both sides speak the same language.
5. Client Side Domain Modeling
Almost everything that the backend has is most likely represented in one form or another on the client side. You need to make sure that you accommodate iOS constraints and create domain models and logic that works best in the context of a mobile application. RESTful natured servers help a lot in streamlining and unifying the client-server communication process. Even though your iOS app is not a server it will benefit a lot from structuring models, which are more or less RESTful, but have a client side twist.
Let's look at an example of a real world application. Let's call it a News App. In fact it's not a real app but rather an excerpt of a set of features from an existing app that we built for one of our clients. It's an iOS app that displays curated articles from various RSS news sources.
As you can see on the surface it seems easy enough. We've got a user sign in, a list of articles, and searching and filtering by categories with favorites added. There's nothing to it on the iOS side, we just need good backend APIs! Right? Wrong. You need to solve the problem from top to bottom and be responsible for the solution from the top level (server) down to the lowest bits (iOS UI). That's the only way to build a robust iOS app that is easy to maintain, delights users, can be changed rapidly, and seamlessly goes through further iterations.
Here is a very high level overview of what's involved in this application:
Admins need to be able to create and manage the list of RSS resources to get the news articles. So we need to build a small admin web panel to do that.
The server app needs to update and pull data from the RSS news sources. So there must be some sort of a background process that pulls it periodically.
Since the content (news articles) is created by the machine there must be a review tool for content pre-moderation. It requires an admin web panel that facilitates that process. Reviewers can approve or reject articles, change titles and descriptions, tag them, quickly preview them, or feature them. Because of the nature of the review process we can't get away with a canned admin panel CRUD solution. We need to build a small Rich UI Web application instead that is crafted just for that.
We need a RESTful JSON API to send and receive the data to and from the iOS app.
Finally we want to build an iOS app that consumes RESTful API. We also provide and store the data locally for caching and loading speed purposes.
You can see that on the surface, a seemingly simple app has grown into a full blown service with multiple layers. In order to build it and make it work well it needs to be planned ahead of time and you must have a strategic plan during development to end up with one seamless integrated piece.
In the next blog posts we explain our approach to each piece in detail and we give you an understanding of why and how to approach the development of iOS apps and systems in general.
Next Blog Post
In the next blog post we will discuss the analysis of business problems, domain modeling, and system architecture.
If you have any questions feel free to leave a comment below or shoot us an email at firstname.lastname@example.org, we'd be happy to help you.
Authors: Alex Bush @alexvbush, Alex Petropavlovsky @petropavlovsky. Editor: Tim Baron.