Enterprise or Business to Employee (B2E) mobile apps can be quite different from their B2C counterparts. B2C apps, tend to focus on a small number of screens or feed for their main usage, and additional screens are not as frequently used, but there to serve ancillary functionality as needed.
B2E apps, are focused on function, normally recording or accessing data for their day to day job. Many of them are replacing hand written recordings, for digital records, that are automatically synchronized to the main database. The fact that these users are employees to a larger company, and are using it as required by their job, results in a number of differences you have to handle, not just in the code, but the processes surrounding it.
I assume that most of you will have heard of MVVM and Dependency Injection. I would recommend these for any Xamarin Forms development, not just enterprise. Using MVVM with Dependency Injection, will set you up towards a quality Xamarin Forms app. How to architect your app if it’s going to have a very large code base, is another story, but it will not be covered in this post.
But, when we are dealing with the enterprise, there are additional considerations, you need to make.
If you use one API, that you control, lucky you. Unfortunately that isn’t always the case in enterprise apps. You may have a smattering of API’s that you don’t control, and they can change, during your apps lifetime, especially when you are dealing with a poorly implemented API.
To counter this, I always create an aggregate service layer, for my repositories. A repository class, is just the code that connects to the API and send / retrieves data between them.
This shields your application from API changes, and removes it as a dependency when unit testing.
Due to many more pages, multi-step forms and possibly multi-role capabilities, navigation can become increasingly difficult. Navigation flows you may encounter are:
- Don’t allow the back button to go back to the login page.
- Start a multi-page form fill in, with the ability to leave, then come back, and expect to resume in the same state.
- Warn or stop navigation, if a user has failed to complete the required steps.
- View a page, but don’t keep it in the navigation stack, once they have moved on.
- Avoid duplication of pages in the navigation stack, and load the existing one if present.
These navigational flows are quite complex, and they are not built into any MVVM framework, except for Exrin. It’s one of the main reasons, Exrin was created.
Enterprise grade security systems, aren’t really any more secure than any standard security system, they tend to be just more complex, and hence ripe for incorrect implementation. You may come up across Citrix, Microsoft Online or Azure Active Directory. If you are lucky, you will have nice OAuth API flow to work with.
Security becomes more important, when sensitive records are kept, such as patient records. Rules, I use, when dealing with sensitive information:
- Use expiring tokens for authentication. Don’t store any username or password.
- Don’t put any decryption key or sensitive information in your code. It’s all reverse engineerable, and essentially public.
- Don’t store sensitive information, if you don’t have to.
- If you must store sensitive information, ensure it is encrypted.
The encryption key must be generated by the mobile app, at runtime, then stored securely, such as in the KeyChain or KeyStore, only accessible to the app at runtime.
B2C apps mostly have the luxury of saying, you must be connected to the Internet, while using the app. B2E apps don’t always have that luxury, such as mine sites or Wi-Fi black spots in large buildings, like Hospitals. This means you will need some kind of offline storage. In this scenario, to avoid complications, it is best to always have your app run off the database, with a Synchronization Service, running to provide connection to the API’s.
DevOps is establishing the set of processes and collaboration between development, management and the businesses IT operations. It is similar to agile, and Continuous Delivery, but adds additional coverage to management and IT operations, that are normally left out of the development loop. DevOps isn’t something you will normally find at a small company, but may find at the Enterprise level.
How is DevOps related to Xamarin Forms development? Its not inherently tied to it, but they are some things that you can do to make your life easier.
- Establish JSON based configuration files, not hard coded configuration. This helps when deploying to different environments, e.g. Testing or UAT.
- Setup VSTS (or similar) and connect to AppCenter as one of the first things you do.
- Setup Analytics in your app to record relevant metrics compared to expected outcomes.
To delve deeper into analytics, I wanted to mention the absolute importance of them. While I recommend them in all apps, with Enterprise apps, the business has already approved the project based on expected outcomes. Ensure you can tie these expected outcomes to a specific metric.
For example, if the goal was a simple, save employee time. First, establish the baseline, the business is currently experiencing. If filling out a paper based form used to take approximately 2 minutes, then it took another 2 minutes for someone else to copy it into the system, and maybe another 2 minutes to correct any mistakes in recording, on average it takes 6 minutes per form. Ensure you measure the time taken to fill out the form, in the mobile app, and how often it is done. Then you have an exact metric of employee time saved. The business will then tie this to their internal estimates of what an employee’s time costs.
Mobile Device Management
When you are at a large company, it’s common for the business to have an MDM suite, to manage all their employee’s mobile devices. Unfortunately these systems, sometimes don’t have any API that can connect up to your automated build process. I still recommend using AppCenter, to provide testing and UAT capabilities, then deploying manually to the MDM, when ready to go to production.
First, lets look at the project structure. Portable Class Libraries, or .NET Standard Libraries are a must use in these scenario’s. Shared code is far too hard to maintain over long periods, with multiple developers. MVVM and Dependency Injection are essential, and while Xamarin Forms comes with these features baked in, it is recommended to use an MVVM Framework. There are plenty of good MVVM Frameworks out there. For myself, and the style of architecture I wanted to use, none of them quite fit as well as I wanted them to.
The native projects are kept rather light. I only put Custom Renderers, or platform specific code, that I will use with dependency injection. Any configuration, will be loaded or setup here as well. This may be different depending upon your MVVM framework, and dependencies.
Configuration files are normally kept in the native project, for any platform specific configuration. You may also keep configuration in your App project, for cross-platform configuration. To ensure you have configuration files that are easier to work with Continuous Deployment, have a look at Configuration Files in Xamarin Forms, to see how to set this up. Configuration is then also injected into the app via an IConfiguration object, which is fantastic when unit testing.
This is your main starting point, and where the Xamarin Forms Application (App.xaml) will be located. This project has a dependency on Xamarin Forms, and will provide any bootstrapping as required. Depending upon your MVVM Framework, this is normally where I map Views to ViewModels, and initialize the Dependency Injection Container.
The framework project is a simple library, that contains only definitions, or generic helper code for the entire app. Keeping this project with zero dependencies is key to allow it to be available across all libraries in your app. Think of the framework app, as the generic contracts that allow you to pass data between projects. This project will have NO reference to Xamarin Forms.
Your main business logic, including ViewModels and Models, will be located in here. The interesting point to note here, is there will be NO Xamarin Forms reference. This is key, if you want an easy time setting up Unit Tests. Inside the Logic app you will also want to include a Service Layer and Repository Layer. These can be branched out into separate projects if you need to, but generally it’s easy to keep them in the same app.
Service Layer & Repository
The next approach I take, when dealing with services, such as connecting to API’s, is to first create an aggregate service layer. This service layer acts as a service that connects with repositories to retrieve the information, from multiple repositories and give them back to the Model. Sometimes the Service layer may simply be a pass through layer, but often its great in combining and manipulating data from various sources to your app. This also means that any changes to the repository are shielded from your app. It becomes increasingly great when you are in control of your own API and numerous modifications are made during your development lifecycle, which were out of your control.
The repository layer is simply a connection to a database, or an API. It gets the data from the source and passes it back to the service layer, for mapping into an app friendly model, for consumption.
This project, will contain all your Xamarin Forms views, behaviors, converters, effects and any other UI related code. It is completely separated from your business logic and the two projects won’t reference each other.
While I know its perfectly acceptable to place UI related code, in the code behind of a view, I take a hard line and don’t allow anything in the code behind file. Behaviors, Effects, Converters or writing a Custom Control, is preferable. It keeps your Pages, completely XAML, encourages you to reuse controls, and other UI related code. It also alleviates having to monitor and track which views have code, and if it needs to have a corresponding unit test.
As important as always, adding a unit test project is essential to quickly spot potential breaking code, as you develop the app. While I won’t go over various approaches of how to code Unit Tests, the unit tests here will only be testing the Logic project of your app. The Framework and App projects should only have bootstrapping code, or definitions. It’s unlikely to contain any business logic. The View project will also have no unit tests, unless you want to test behaviors, or converters. Even so, these behaviors and converters can run code in the Logic app for anything substantial. If your converters, behaviors etc aren’t substantial, you can normally avoid unit testing these.
Because the Logic project is just a standard library, with no reference to Xamarin Forms or native Xamarin, it is extremely easy to unit test. I normally create the unit test as a Full .NET Framework project, and run with xUnit. Though NUnit is also another common alternative.
If you wish to unit test code in your native Xamarin project files, you will need special runners, that some unit testing frameworks provide. However these are normally a little trickier to setup. As such if all business logic can be contained in the logic project, you will have a very easy time.
UI Tests are important to test the Views in your app and complete integration tests between your views and code. I would recommend Xamarin UITest, though developing scripts in Appium is another common approach I have found. Ensure you code the AutomationId on each visual element, and any mobile testing framework will be able to pick up these ID’s to perform actions and read values.