Rules to Better Apps (mobile) - 8 Rules
Want to build a mobile application? Check SSW's Mobile Apps consulting page.
If you need to build a binary app (rather than a web app) that will run on multiple platforms (e.g. iOS, Android, macOS, Windows), you can either build and maintain multiple versions of the app - one for each platform - or you can use a cross-platform (cross compiler) framework to build one app that runs on all of them.Video: Mobile frameworks - Comparing the big guns: Ionic, Electron, React Native, Flutter and .NET MAUI (6 min)
With many cross-platform frameworks available to suit every team and product, there is very little (or no) reason to build single-platform apps anymore. Even if you only initially intend to target a single platform, by using a cross-platform framework, you give yourself the opportunity of targeting additional platforms in the future.
Cross-platform app frameworks generally come in 3 flavors: PWAs, web wrappers and native executables.
PWAs are the fastest way to transform your website into a cross-platform app. However, you miss out on the native feel of having it in the app store.
Web wrappers are good for standing up quick prototypes or PoCs, but are not recommended for long term supported solutions.
Native executables (aka cross compiler) use a cross-platform API to build the app, but compile native binary executables for each target platform. Examples using this approach are .NET MAUI, Flutter or React Native.
Developers building apps that target multiple platforms are in the ideal position. Several frameworks exist to fill this niche, meaning developers have the luxury of choosing the best fit for their needs. When choosing a cross-platform framework for your team, ask the following questions:
What skills do we already have?
- For .NET teams, .NET MAUI is the best choice. It targets all the major platforms, it's performant, highly customisable, and leverages your existing skills. It also integrates well with your existing solution
- For a React team, React Native may be a smoother transition. There's still a learning curve from React to React Native, but that curve may not be as steep for teams with existing React skills as for other teams.
- For teams with good Angular knowledge, Ionic is worth considering (but as per above, not recommended for more than a quick prototype).
What platforms do we need to target?
- Not all cross-platform framework targets every platform. Most will work on the 'core 4' (macOS, iOS, Android and Windows). .NET MAUI will also work on watchOS, wearOS and Tizen. If you need to target Linux and/or the web, you should consider Uno platform.
What level of 1st party support do we need?
- Some of these frameworks are maintained by big tech companies. .NET MAUI for example is maintained by Microsoft, Flutter is maintained by Google, and React Native is maintained by Meta. However, they are not equal in terms of first party support. .NET MAUI, for example, has an Essentials API that provides access to many cross-platform hardware features, whereas many of these need to be loaded via 3rd party plugins in other frameworks.
Developers are spoiled for choice; we have the luxury of choosing from many cross-platform frameworks. Most of them are very mature and stable, allowing us to build first-class apps.
Here is a nice graphic that gives a quick run-down of the pros and cons of different frameworks:
❌ Don't use a web wrapper. They might seem tempting as a quick option to start with, but you will cause yourself pain 👎🏻 down the line.
✅ Choose a native executable framework. They let you build the best apps in the long run.
✅ Do choose .NET MAUI if your team and/or solution already use .NET.
If you're building installable binary apps (as opposed to web apps), it makes sense to use a cross-platform framework so that you don’t need to maintain multiple code bases.
Writing apps in a single-platform language or framework can lead to fragmentation and technical debt, while writing your app once using a cross-platform technology is the best way to apply DRY to your app as a whole.
There are two approaches to building cross-platform apps. One is to write a single page application (SPA) and use a wrapper technology like Cordova or Electron to turn your SPA into an installable app. This is a good approach if you already have a fully functioning web app and want it to be available for users to install via an app store.
The other approach is to use an API that is a single, cross-platform abstraction that compiles to native code executable on your target platforms. This is the approach taken by .NET MAUI (previously Xamarin), Flutter, and React Native.
Use a web wrapper, like Cordova or Electron, if your SPA is already built and offers all (or almost all) of the functionality that you want your app to provide.
Web wrapper technologies are good for apps that also work as web apps (and potentially already exist as web apps), but they also suffer from some of the limitations of web apps.
If you need multi-threading, or access to hardware features, platform or operating system APIs or system processes, then using an abstracted cross-platform API is a better option.
If you need access to specific platform APIs, you may not find them available in the web wrapper options (and almost certainly not via 1st party support). In this case, you could rule out using a web wrapper.
If you already have a .NET development team and your solution is built on .NET, it makes sense to use .NET MAUI. .NET MAUI lets you write your UI in XAML or Blazor, so if you already have a Blazor web solution, you can share your UI controls in a Razor Class Library. You could also share other things like DTOs and authentication logic between Blazor, ASP.NET Core, and .NET MAUI apps.
If you already have a strong React team, it may make sense to use React Native. There is a bit of a learning curve to go from React to React Native, but it still builds upon your team’s existing skills.
Choose Flutter if you like Dart.
Progressive Web Apps have transformed the mobile web practices to provide a native app like experiences for the users. They work just like native apps and include features such as smoother navigations, offline modes and push notifications, but are much more economical and do not use the device storage.
Progressive Web Apps are reliable which means they load instantly and the performance isn't compromised even if the network is shaky.
On the mobile the 'Add to homescreen' option can be used to create an icon on you phone.
PWAs also account for higher user engagements and conversions which is probably why many organizations are now adapting this technology to grow their businesses.
In order to be a PWA, your app should:
- Use a responsive design - So it works on desktop or mobile
- Be installable - Use a web app manifest and the beforeinstallprompt event to notify the user that it is installable
Examples of Progressive Web Apps can be seen at 10 Best Progressive Web Apps.
You can check the Progressive Web App score of your application using Chrome's Developer tools.
Note: See how to generate a PWA report on Run Lighthouse in Chrome DevTools.
Getting configuration into the hands of mobile app users can be challenging, and you need to make it as seamless as possible. For web apps, this usually isn't a problem; for any given instance, you go to that instance's URL. But for mobile apps, they often don't even know which instance to connect to.
When all the users of your app will need a single shared configuration, that config can ship with your app. But when your app needs per-user, per-tenant, or per instance config, that can be tricky.
Check out the video above for the best way to magically provide your users with configuration. And for a write-up, check out Automagic Tenant Config for Mobile Apps.
You don't have to charge users for your software. In fact, even free apps and games are designed to make money. Do you know the best way to monetize your apps?
Apps make money in all sorts of ways, even the 'free' ones. You need to choose the right monetization model for your apps depending on its functionality and audience.
Some apps require a form of payment, meaning you must pay for the app before you can use it. Others are 'free', meaning you can use the software, and all its features, without paying for it. These apps make money in other ways. The middle ground is called 'freemium', which is where you get the basic app or game for free, but need to pay to access advanced features.
Whether your app is paid up front or 'freemium', if you need to collect money at some point from your users, there are a few ways to do it:
This is the traditional approach, where you set a price for your app or game, and users must buy it before they can use it. This might be the right approach for you if:
- Your product is a AAA gaming title
- Your product is a useful, but not essential, productivity tool
- Your product is not a SaaS product (one-off payments are difficult to reconcile against ongoing cloud and hosting costs)
More information: The Legend of Engadine official website.
One-time fees work with either paid apps or 'freemium' apps; users can either buy the app up-front or use the app for free, and pay to unlock premium features.
Subscriptions have become much more popular, even for traditional desktop software. Rather than pay a one-time fee, users pay a recurring monthly or annual fee to use the software. This might be the right approach for you if:
- Your product is a SaaS product
- Your product is likely to get recurring regular use without you needing to continually drive engagement (e.g. An essential, or at least high value, productivity tool)
- Your product has other ongoing maintenance costs (e.g. Content development)
Microsoft 365 (formerly Office 365) is a suite of productivity tools that run on mobile, desktop and web. With a subscription, users get access to these apps and the connected services that tie them together in the cloud, and the cost over a 3 year period (the average time between desktop releases before Office 365) is lower than the cost of a desktop license amortized over the same period.
Micro-transactions is the practice of continually charging comparatively small amounts of money over a long period of time. Micro-transactions can be a great fit if used responsibly, but are considered unethical when combined with nefarious practices like dark patterns, 'pay-to-win' or exploiting gambling addition.
- You are certain you have an ethical model for micro-transactions
- You are not exploiting minors or people with a gambling addiction
- You have a genuine use case for providing small purchases in your app that can bring joy to your users
Video: Bad example - Pokemon Go, one of the most successful mobile apps of all time, combines the freemium model with micro-transactions to exploit a vulnerable subset of users. It's incredibly effective, but unethical
Most free apps are designed to make money too. There are of course exceptions (for example apps created by government departments or agencies, such as the Service NSW app), but generally most apps need to generate revenue; even the free ones. Free apps and games can still make money, and these are some of the ways that they do so.
The most common way for free apps and games to make money is through advertising. Ads are shown to users in the app or game, either as banners that are constantly there, or as interstitial ads (ads that appear between levels or interactions and block the rest of the app or game until they are finished). In-app advertising is still a significant revenue stream, but is considered less-professional or less-polished for certain categories of games or apps. This might be the right approach for you if:
- Your app is a mobile or web app (desktop users are less tolerant of in-app ads)
- Your app has a strong re-use strategy (e.g., 'addictive' games, or diary-like apps that require or support daily use)
- Your target demographic is less likely to pay to use an app (and less bothered by ads)
Note: If you include ads in your app, you should consider a freemium model, so that users can pay to remove them.
Some apps provide the app for free, but content within the app is paid for. This is a good model for content creators, or an excellent model for content platforms with user generated content. This might be the right approach for you if:
- Your content is your product, and your app is just a delivery vessel
- You have a lot of user generated content (and your users want to monetize that content too)
- You are regularly adding new content to your app
This approach is uncommon, but occasionally an app developer might want to give an app away for free to entice users to try another, revenue generating app. Examples include showcase apps for UI control library vendors, like Syncfusion, Telerik or Grial Kit. This might be the right approach for you if:
- Your app is used to demonstrate expertise
- Your app is a portal for a different subscription product
- Your app has low or no ongoing maintenance or support/infrastructure costs
Some apps offer functionality to users for free, and in exchange gather information about users for sale to advertisers or other interested parties. Tiktok, one of the most successful apps in the world, is a surveillance app that mines data about users, their connections, and environment. Some apps are more extreme than others, and the breadth and depth of data acquisition can vary.
NOTE: This is not an ethical approach to monetizing apps and is not an approach you should use.
Sometimes an app will use users' resources in the background. This is cool for things like SETI@Home, a screensaver that uses an idle computer's CPU to crunch numbers in the search for alien life, but less cool for apps that install an agent into a user's browser and use it to mine cryptocurrency.
NOTE: This is not an ethical approach to monetizing apps and is not an approach you should use.
A common approach is to submit your app to Testflight, wait for user feedback, then submit for App Store release. The problem with this approach is that your release cycle can be significantly impacted by Apple's review schedule. App Store and Testflight reviews can be very quick, but can also take up to 3 weeks!
A better process is to submit your build for Testflight and Release simultaneously.
- Upload your build to App Store Connect.
- When automated processing is completed (scanning of the assemblies usually takes less than an hour), you will receive an email confirmation, open Testflight and submit for approval.
- Immediately, prepare your app for submission to the App Store (by completing the appropriate metadata, e.g. new features or fixes in this version). Important : Set to Manual Release so that your app does not get automatically released untested.
- If you are using external or public users, your build must be approved by Apple for testing. Note: If you are using internal testers only (App Store Connect users), they can begin testing immediately.
- Once both your App Store and Testflight builds have been approved, get a Test Pass via the Test Please process - see Rules to Successful Projects: Do you conduct a "test please" internally and then with the client?
Tip for Mid-Sprint Releases : If its an internal app, you can accelarate the Test Please process by asking someone with an iPhone to test straight away via Testflight. Tip for End of Sprint Releases: Get the Testflight and Release submissions approved in preparation for your Sprint Review. You can then demo your release to the Product Owner and be ready to release your Product Increment after the Sprint Review.
- You can now release your app as soon as you are ready. In App Store Connect click Release to make your latest build publicly available in the App Store.
Figure: Bad Example - v1.7 is "Waiting for Review" in Testflight but only v1.6 is submitted to the App Store. This can introduce delays of 3 weeks.
Figure: Good Example - v1.7 has been submitted to Testflight and App Store at the same time - also "Waiting for Review", but your build will be ready to release as soon as testing has passed
Lack of access to physical devices for testing can significantly impact mobile development. Issues can arise that you don't know about until UAT. Do you know the best way to mitigate this and avoid spiraling development costs?
Mobile development is acutely prone to the "works on my machine" problem. Features that work on an emulator or simulator may not work as expected when running on a physical device, or features that work on iOS may not work on Android, or vice versa.
It's important to ensure that features and UI work as expected on the devices that your end users will be running the app on.
Tip Ensure that testing on at least one physical device on each OS you are targeting is part of your definition of done.
You need to choose the right option to ensure that all team members have access to the required devices without incurring unnecessary expenses.
The easiest approach is just to let your developers use their own devices for testing. This can work well at the start but leads to problems if you divide your work between devs with access to different devices.
- Developer A works on Feature 1. They test it on their Android phone, it works, so they open a PR and merge it.
- Developer B works on Feature 2. They test it on their iOS phone, it works, so they open a PR and merge it.
- At the end of the Sprint, a build is sent to testers for UAT.
- Feature 1 doesn't work on iOS, and Feature 2 doesn't work on Android.
Cloud based options like BrowserStack are awesome, as they give access to a range of devices that can be used for testing.
Using something like BrowserStack is not a good option for development, as it introduces substantial latency to your inner development loop.
However, it is an awesome tool for testing and can be incorporated into your release cycle, as an automated test tool.
Having test devices available to your developers is the best option to ensure they can test their work on the hardware and OSes that your clients will need.
Note: If your client requires a specific device or a specific hardware version for you to test on, they should supply these to your development team.
You will need to create your policy according to your organization's needs, but the following high-level steps are usually applicable to everyone:
- For each project, identify the minimum number of physical devices required to support all the necessary features and functionality.
- Create a device sharing policy that outlines the process for reserving and using devices, ensuring that all team members have access to the devices they need.
- Encourage team members to purchase their own devices that are compatible with the projects they work on. The company can provide a partial reimbursement or a stipend for the purchase of the device.
- Utilize device emulators and simulators to test apps on devices that are not physically available to the team.
- Regularly review and update the list of supported devices to reflect changes in the market.
.NET MAUI (Multi-platform App UI) is a framework that enables developers to create cross-platform applications for different devices efficiently. However, the efficiency of this framework could mean nothing if the developed apps are not tested on various devices, especially the older once.
Testing mobile apps on different devices helps in ensuring compatibility across multiple platforms and versions. Different devices have unique hardware, operating systems, and screen resolutions. Therefore, testing an app on different devices ensures that the app can work efficiently on all platforms. For example, an app that runs smoothly on an Android device might be incompatible with an iPhone's operating system, resulting in a suboptimal user experience and potential bugs.
There are several ways that developers can test mobile apps on different devices to ensure that they are running smoothly and providing the best user experience possible. One approach is to use emulators, which are programs that simulate the behaviour of specific devices and operating systems. These emulators can be very helpful for testing basic functionality, but they may not accurately represent all aspects of the user experience, such as touch sensitivity and screen size.
Some of the popular .NET MAUI emulator apps are:
- iOS Simulator: it allows developers to preview their apps on iOS and macOS devices.
- Android Emulator: it allows developers to test their apps on various Android devices.
- Tizen Simulator: it allows developers to test their apps on Tizen devices.
Testing mobile apps with cloud-based services like BrowserStack offers several advantages to developers. Firstly, it allows them to easily access a wide range of real devices and browsers for testing, enabling comprehensive and efficient app evaluation. The developers can run tests on multiple operating systems, screen sizes, and resolutions, ensuring that their MAUI app performs seamlessly across various platforms. Additionally, these cloud-based services provide instant access to devices, eliminating the need for physical hardware and saving both time and resources. However, reliance on such cloud-based services introduces substantial latency to your inner development loop, and might not be the best option for development.
Apart from BrowserStack, there are several services that offer similar functionality:
- Sauce Labs
Another effective way to test mobile apps on different devices is to use real hardware. This allows developers to see how the app performs on a variety of devices with different screen sizes, processing power, and other specifications. One approach is to borrow or purchase multiple devices to test on, but this can be time-consuming and expensive. The better way is to have a device policy for your mobile dev teams.
Regardless of the approach used, it is important to test on a variety of devices to ensure that the app works well for all users. This can include testing on both iOS and Android devices, as well as different versions of each device and operating system. Additionally, testing on different screen resolutions and aspect ratios can help identify any design issues that may arise. By thoroughly testing on a range of devices, developers can ensure that their MAUI app is high-quality, user-friendly, and reliable across all platforms.