With the first versions of the SDK, older Android developers remembered that they had to use the Eclipse IDE and the Ant build system to develop their app. The latter being based on XML files, you had to use external scripts as soon as you had to add a bit of logic to the construction of the app. In 2014, the development experience took a major step forward with the arrival of Android Studio and the Gradle build system. Based on the Groovy language, Gradle makes it possible to code build logic that is as complex as necessary and has generated an entire ecosystem of plugins.
However, since Groovy is a dynamic typing language, it is complicated to implement relevant auto-completion. In addition, some problems are only visible when the program is running. Since the release of Android Gradle Plugin 4.1 in 2020, it has been possible to write Gradle scripts directly in Kotlin.
You can therefore write your build scripts with the same syntax as the rest of the application and you have access to all the power of Kotlin to do so. Strong typing makes it possible to discover the possible syntax depending on the context in which you find yourself, even if Gradle concepts are difficult without having to consult the documentation.
On the technical level, interoperability is ensured. However, the integration of an undocumented plugin for this new syntax, exploiting the dynamics of Groovy, can pose some difficulties. In addition, it is unfortunate that applications generated with Android Studio continue to use Groovy scripts, which will have to be converted to KTS by hand.
OUR POINT OF VIEW
Despite these slight constraints, it is important to note that more and more projects are adopting KTS every day, which is becoming the new standard to migrate to, without real urgency, but if the opportunity arises.
HISTORY 2022
It's a new blip this year.
UI frameworks often arouse debates: external templates or programmatic implementation, a graphical tool for design or manual writing? Android's historic visual layout technology is no exception. It has a delicate life cycle to master and can be cumbersome when creating new graphical components. In addition, designed in the mid-2000s, graphics APIs took into account obsolete constraints for current smartphones, which limited the evolution of Android.
Google teams started with a blank sheet of paper to create Jetpack Compose, adopting a declarative and responsive API, inspired by the React framework. The code is more readable, with a structure similar to what is displayed, and more concise: the complexity of updating the UI state is hidden. Jetpack Compose is a complex technology: the integration is based on a Kotlin compiler plugin, a difference calculation engine, and numerous component libraries. Indeed, all the components of the Material Design System have been re-implemented for Compose.
The maturity of the framework is impressive. Common use cases are documented, easily implementable, as are solutions for edge cases. However, some functionalities may be missing compared to old components (e.g. on list animations or navigation typing safety). It is unfortunate to have to depend on non-final versions of support libraries, whose APIs can change rapidly, to use the latest versions of components and benefit from the latest features. However, the developer community remains enthusiastic and regularly produces additional articles and libraries.
OUR POINT OF VIEW
Jetpack Compose is now a safe choice for developing a new application on Android. However, beware of migrating an existing app: if Jetpack Compose integrates very well with reactive data sources (e.g. a ViewModel with LiveData, RxJava or Flow), integration on a monolithic and imperative code base could require significant changes.
HISTORY 2022
Adopt - See the Tech Radar 2022
Object serialization is crucial in software development for managing distributed systems, web services, and information exchange between different platforms.
Popular solutions like Gson, Moshi, or Jackson work well on the JVM and allow you to take advantage of thinking. Developed by JetBrains, KotlinX Serialization is distinguished by its simplicity, cross-platform compatibility, and support for Kotlin types, including nullability and sealed classes.
KotLinX Serialization supports formats other than JSON, such as Protobuf, CBOR, Hocon, and Properties. The library is powerful, lightweight, without dependence on reflection and uses a compilation plugin to generate serializers/deserializers. However, we regret that the KotlinxSerialization adapter for Retrofit2, developed by Jake Wharton, is still external to the Retrofit repository, but it has just stabilized, so it will join the other official adapters.
Although Gson, Moshi, or Jackson are popular and powerful, KotlinX Serialization is powerful, lightweight, offers better integration with Kotlin, and is cross-platform compatible.
OUR POINT OF VIEW
If you're happy with your current solution, there's no need to change immediately. However, if you are starting a new Kotlin project or if your project needs to take advantage of these benefits, KotlinX Serialization is now the library that BAM uses on all of its new projects.
HISTORY 2022
It's a new blip this year.
Before the arrival of SwiftUI, there were two alternatives to create UI in iOS:
In 2019, Apple released SwiftUI, a new declarative framework in the same trend as Jetpack Compose. This framework is also required for certain new features or improvements, such as widgets or iOS animations..
It has numerous advantages: on the one hand, the syntax is clear and simple, which facilitates skills development; on the other hand, the ecosystem benefits from special care from Apple, with dedicated tools directly integrated into xCode. It also allows you to take advantage of the pre-existing ecosystem. Indeed, SwiftUI is easily interoperable with UIKit and Combine, facilitating the transition to this new framework.
On the other hand, SwiftUI still has some shortcomings. Some APIs are not yet accessible under SwiftUI and require a bridge to UIKit. In addition, as the framework is recent, bugs appear regularly and should be worked around while waiting for a fix. These don't usually affect production, but can provide a frustrating experience for developers.
However, the major defect of SwiftUI is the supposed absence of backwards compatibility with older OS versions. This strategy encourages the abandonment of support for older versions but above all will limit the adoption of the framework as long as using new features is synonymous with leaving users in the lurch. Some APIs such as lazy grids or stable previews that we consider essential are only available from iOS 14, which leads us to consider this version of iOS as the minimum required for a SwiftUI project.
OUR POINT OF VIEW
SwiftUI is a framework that we recommend if the minimum version supported by your application is iOS 14, which makes it possible to cover 93% of the French population.
HISTORY 2022
Adopt - See the Tech Radar 2022
iOS development tools are outdated: the “xcodeproj” format, for a simple new project, induces 344 incomprehensible lines (this can go up to 3000 lines or more). Impossible to edit it by hand and therefore to review it. And for many developers, git conflicts are unavoidable. It is therefore impossible to edit it by hand and to review it. Also, for many developers, git conflicts are inevitable.
Tuist proposes to no longer version this “xcodeproj” project, but to version a configuration in Swift that generates it on the fly. For example, on one of our projects, we go from 1788 lines of code to 19 lines. The file is much more readable, and conflicts disappear.
Tuist helps modularization. For a project in microframework architecture, it automates the creation of links between projects in the same workspace, generates a dependency graph to document the project, and proposes a cache to optimize compilation.
Tuist accelerates development. In a command that scaffolds the file architecture, you generate the skeleton of a page, an API call, etc. Tuist also allows you to generate typed access to assets (images, videos, sounds, etc.) in order to avoid a crash due to a file name error.
The Tuist community is very active and the developers are responsive, making it easy to resolve issues quickly and contribute.
OUR POINT OF VIEW
Migrating an existing project to Tuist is quite simple: we migrated one of our biggest projects (including 1600 files and 50 frameworks) in a few days. We recommend adopting Tuist for all new projects and migrating existing projects.
HISTORY 2022
Trial - See the Tech Radar 2022
SwiftUI introduces new features for the UI compared to UIKit, as well as for managing the state and lifecycle of components through its reactive approach.
It offers ObservableObjects and EnvironmentObjects to externalize the state. These code primitives are very powerful, but require a well-thought-out architecture to take full advantage of their potential.
That's why we turned to The Composable Architecture (TCA): an architecture very inspired by Redux's “one-way data flow”, which aims to structure the state, make it testable and easily reusable. Its objective is also to improve the development experience by linking all state changes to user actions.
Unlike competing libraries like ReSwift, TCA is designed for SwiftUI. It also offers built-in dependency injection mechanisms that facilitate development. The creators of TCA have built an active community and have produced numerous tutorials and a comprehensive documentation, which helps smooth the learning curve. However, it is still large, which requires prior exploration, and access to it is chargeable. In addition, TCA is very opinionated in its management of the state, which sometimes complicates its integration with the rest of the iOS ecosystem.
Although these problems can be easily circumvented, the library is still new and has some shortcomings:
For now, we're using TCA with caution in our projects, waiting to see if this framework suffers from the same scalability issues as Redux. However, we can't wait for the release of the first stable version, which will include better navigation management as well.
OUR POINT OF VIEW
At BAM, we use The Composable Architecture on projects in production and we recommend that you look at this library for state management on your next SwiftUI apps.
HISTORY 2022
Assess - See the Tech Radar 2022
Dependency injection (DI) is a design pattern widely used in development, which makes it possible to facilitate testing, make code more modular, and improve maintainability. Hilt is a dependency injection framework for Android that was released by Google in 2020. It is based on Dagger 2, the famous dependency injection library, and provides a simplified implementation of dependency injection in Android apps.
One of the key issues that Hilt solved was the boilerplate code needed to set up Dagger, for injecting dependencies into Android apps. Dagger, while powerful, can be complex to set up. Hilt simplifies this process by providing a set of annotations, which can be used to mark classes to be injected and automatically generate the underlying Dagger code. This allows developers to focus on writing business logic rather than worrying about the intricacies of Dagger.
Hilt and Dagger resolve dependencies during compilation, while Koin is a service locator, which does that at runtime. This difference has a certain impact on the performance of the app at runtime. However, compile-time dependency injection libraries can complicate the creation of a micro-frontend architecture for your app, while service locators can make this task easier.
We already mentioned Koin in our previous Radar. We do not recommend attempting to replace Koin with Hilt in an existing, large codebase.
OUR POINT OF VIEW
When starting a new project, try Hilt if you want to avoid run-time errors and follow Google's advice. Otherwise, opt for Koin if you want a library that is lightweight, easy to use, and compatible with Kotlin Multiplatform projects. We recommend that you adjust your choice according to your team, environment, and platforms.
HISTORY 2022
It's a new blip this year.
The dependency injection pattern is widely used to apply the inversion of control principle when developing Android applications. Indeed, this makes it possible to make the code more modular, maintainable and easy to test. However, setting up dependency injection can be tedious.
Koin meets all these challenges with a configuration of dependencies directly in the code via a DSL that is very intuitive and easy to use. However, it meets the same need as the framework recommended by Google for Android: Dagger-Hilt.
The two work very differently. Koin handles dependency injection at runtime, while Hilt configures itself via standard Java annotations for injection, generates code, and injects dependencies directly during compilation.
Hilt will therefore be more efficient at runtime and will be able to detect errors during compilation, while Koin will not impact compilation but may issue exceptions at runtime if it is incorrectly configured. In practice, Koin's impact at runtime is minimal if not negligible.
OUR POINT OF VIEW
Now that Hilt has matured, the choice between the two is not easy. Depending on the needs, it is recommended to choose Koin for its ease of use, its perfect integration within the Kotlin ecosystem and its compatibility with Kotlin Multiplatform, or Hilt for its high runtime performance, its compliance with standards and the detection of errors during compilation. However, the final choice should be adapted to the preferences of the team and to the specific needs of the project.
HISTORY 2022
Adopt - See the Tech Radar 2022
Data storage in the application is of great importance. In order to improve the user experience and avoid waiting times for query results, it is recommended to set up a cache system. Relational databases offer real advantages for this use:
On mobile, SQLite has established itself as the solution for creating relational databases. However, it is strongly not recommended to use this technology directly, either for reasons of complexity or typing. It is then common to use an ORM (Object-Relational Mapping): a library that interfaces a database with the rest of the code.
In the context of Android, Google created and integrated Room into Android Jetpack, a set of libraries aimed at simplifying the task for developers. With Room, it is possible to easily declare the entire database structure and the various queries in a few lines of CodeKotlin, with annotations.
Room is a mature library, existing since 2018, which benefits from comprehensive documentation and is easy to use. It is easily integrated into Kotlin and offers the possibility of doing reactive operations. For example, when a table is changed (adding, editing, or deleting rows), Room automatically emits a new value, allowing components to update.
This feature is compatible with the most common responsive libraries, such as:
There are serious competitors to Room, such as SQL Delight or Realm, that offers a version that is compatible with Kotlin Multiplatform, which Room does not.
OUR POINT OF VIEW
You should take the time to compare Room with its competitors, but using Room on your project seems safe to us, unless you are considering a Kotlin Multiplatform Project.
HISTORY 2022
It's a new blip this year.
Fifteen years ago, Adrian Cockcroft, an architect at Netflix, introduced the concept of microservice architecture. The aim: to minimize the friction of the “server” teams. On the agenda: separation of responsibilities, optimized storage and greater agility on the part of development teams.
Today, mobile applications are more and more reminiscent of server applications because of their local relational storage, the increasing complexity of their features or even the interconnections with multiple services.
The development problems related to mobile and server applications are also similar: growing code base, increasing build time, difficulty complying with the test pyramid.
This is how engineers from several companies, such as Soundcloud and JustEat, popularized the micro-features (or micro-applications) approach by replacing a monolith with smaller modules of various types:
The benefits are manifold. If the modules are well cut, it is possible to develop on a smaller perimeter. This implies business logic that is more easily testable as well as reduced build time thanks to the cache.
In addition, if the team grows or the company develops other products, it will be possible to share common code between the various projects (for example, authentication modules).
But a good division of the modules implies good expertise in the business area. For example, the interface must be particularly worked on to increase coherence and reduce the coupling of each module with the others. It also requires architectural knowledge and good design, in addition to an initial investment.
And as with micro-services, specific tools become necessary to prevent the dream from turning into a nightmare. It is enough if the architecture is poorly implemented, or the team is not trained, for the architecture to slow down the project instead of accelerating it.
An advantage of mobile development is the packaging of micro-features in a single binary, unlike web microservices. In addition, tooling is becoming more and more stable: for example, Tuist helps on iOS.
OUR POINT OF VIEW
At BAM, micro-features have become a reference choice in new iOS projects. We have been able to test the extent to which this architecture makes it possible to simplify the evolutions or partial redesign of a major application in the field of health.
HISTORY 2022
Assess - See the Tech Radar 2022
To make code maintainable and testable, dependency injection makes it possible to determine dynamically and configurably which concrete implementation will be used at runtime.
In the previous edition of this radar, we recommended using Resolver for dependency injection, a “modern” framework created by Michael Long and using Swift 5.1 Property Wrapper.
The dependency injection ecosystem has evolved since then, and Michael Long created Factory, a new library that replaces Resolver. According to the author, it is faster, smaller, and easier to use. But above all it becomes safe at compile time: While Resolver expects dependencies to be injected at the “runtime” and issues an error if this is not the case, Factory allows you to check at “compile time” that all dependencies are indeed injected. This is a big plus for the quality of the code, but it complicates the implementation of a microframework architecture.
Recently, the author released a 2.0 version of Factory that allows you to declare dependency injection containers. The concept is subtle, but it makes it possible to perform the inversion of control, no longer with the “Service Locator” pattern like “Resolver”, but with the real pattern”Dependency Injection“. Using real dependency injection by container theoretically diversifies the use cases: while it is still possible to do what Resolver or Factory 1.x did, other use cases are possible, in particular for SwiftUI view injection.
OUR POINT OF VIEW
So there are a lot of changes to Resolver/ Factory but the direction the author is taking is clear: to make Factory more suitable for SwiftUI projects and more documented. The backlash: a more complex API, especially as part of a micro-frontend architecture. We therefore advise you to follow Factory's developments for your SwiftUI projects, but to stay on Resolver for your UIKit applications.
HISTORY 2022
It's a new blip this year.
Formerly, developing widgets on Android excluded the use of Jetpack Compose, requiring developers to use RemoteViews (a lightweight user interface that can be modified from a process external to the main application) and complex XML code. This process made creating and maintaining widgets cumbersome and less intuitive.
Building on the Jetpack Compose runtime, Glance offers a declarative API to facilitate the creation of widget user interfaces. Key features of Glance include state management and simplified integration with other Jetpack libraries, such as Jetpack DataStore for data management. Additionally, Glance allows interoperability with RemoteViews by wrapping them in AndroidRemoteViews. Finally, it allows you to define how a widget should react when scaling, thanks to the introduction of SizeMode, which solves a major difficulty that was encountered on projects before Glance, by offering three options: Single, Exact and Responsive.
OUR POINT OF VIEW
It should be noted that Jetpack Glance is still in Alpha and is not completely stable. Developers interested in using this library should try it out on non-critical projects to assess its maturity and suitability for their specific needs.
HISTORY 2022
It's a new blip this year.
iOS and Android mobile platforms have always been incompatible with each other: They don't use the same language (Kotlin vs Swift), the same runtime environment (Virtual Machine vs native iOS runtime), or the same APIs (frameworks specific to each OS). Although it has always been technically possible to share code between the 2 platforms via the Foreign Function Interfaces (FFI) languages, the latter are only used for the code of certain libraries (e.g. SQLite can be used on iOS and Android) and very rarely for application code. Indeed, the business code of an application often exposes a complex data model and numerous functions that are very tedious to interface via FFIs.
The promise of Kotlin Multiplatform Mobile is to be able to write business code and data layers. (e.g. JSON serialization or DTOs from a local database) in Kotlin and to expose these implementations via a library that can be consumed by each platform (.aar for Android and a.framework for iOS). The framework translates calls and data structures from Swift to Kotlin and vice versa. A kind of SDK dedicated to the application is thus built, on which all that remains is to implement the code specific to each platform (in particular the UI).
We spent several weeks evaluating this technology and also published several libraries using it. With a little mastery you can create a core common to both platforms and consume the same API. If you are ready to make some concessions (some Swift features are not supported and you will have to use external libraries for coroutine interoperability, for example), Kotlin Multiplatform meets expectations.
Since October 2022, KMM is now in beta, and has a new memory model for the native part to replace the old one, which was very controversial because it was complicated to handle for developers used to Kotlin/JVM. Kotlin Multiplatform allows applications that address iOS and Android natively to share code with each other. This can be done gradually, and even an application written completely in KMM allows the native APIs of these OS to be implemented if necessary. However, the KMM eco-system is still incomplete and lacks stability, which would block us from starting a project based entirely on this technology.
OUR POINT OF VIEW
We have evolved KMM from “hold” to “assess” and will continue to experiment regularly with this technology. However, wouldn't the recently announced support for Jetpack Compose for iOS be the missing element for this technology to really take off?
HISTORY 2022
Hold - See the Tech Radar 2022
Android media playback APIs, such as Jetpack Media, Jetpack Media2, and ExoPlayer, were developed independently, with different goals and overlapping features. Android developers not only had to choose which library to use, but also to write adapters when multiple API functionalities were required.
Jetpack Media3 solves this problem by merging and refining the common features of these existing APIs, including the user interface, playback management, and media sessions, into a single API that is more consistent and easy to use, while taking advantage of improved features and best development practices.
ExoPlayer's playback interface has also been updated, improved, and streamlined to serve as a common playback interface for Media3.
OUR POINT OF VIEW
Media3 is currently in beta, so we recommend considering adopting it for new projects and preparing the migration for existing projects using the previous media management APIs. At BAM, we have been waiting impatiently for this migration, as we have experienced difficulties with the old APIs and we will be able to test it on the next media project.
HISTORY 2022
It's a new blip this year.
Snapshot tests are becoming more and more common on Frontend projects and in particular mobile projects. They allow a form of unit testing on a part of the code that is often difficult to test individually. This is in particular the case on Android where the code using the framework is hardly or not usable in the context of a unit test (and therefore not on a device). The Android framework offers methods for carrying out UI tests, but they require running these tests on devices (real or emulated), which consumes a lot of CI resources and is complex to implement.
Paparazzi offers an elegant and novel solution to this last problem: instantiate Android Views without requiring a device or emulator. Internally, Paparazzi uses part of the code that Android Studio implements to offer Layout previews. Bitmap renderings are obtained for each of the selected configurations. A first utility is to preview the rendering of the screens without having to test the code on different devices. But the big advantage is to be able to easily conduct visual non-regression tests. Paparazzi offers a complete framework for conducting this type of tests, generating reference screens and detecting deviations from them.
We have integrated this library into several of our Android projects and it is really the right tool for our visual non-regression tests (without replacing unit tests). However, as it is based on a hijacking of the internal Android Studio API, it may be subject to regressions and problems, as was the case with Jetpack Compose 1.2 or Android API 3.3, which were not supported for several months by the release version of Paparazzi. On complex screens, you can also encounter problems when recomposing (for example with components that change their state causing a recomposition) on the same screen.
OUR POINT OF VIEW
This type of problem could prevent a major version upgrade of the Android or Jetpack Compose version, and that is why we recommend that you integrate this library carefully.
HISTORY 2022
It's a new blip this year.
Whether to optimize compilation time or to organize a large project, it is now very common to have modular projects in Android. However, until recently, Gradle did not offer a standard way to centralize the declaration of dependencies and their versions. Several practices co-existed in the community on this subject, but none were really satisfactory in terms of increasing dependency versions and many prevent the IDE's suggestions for new versions from working. We then find ourselves browsing the site of each dependency or Maven to check if a new version is available.
RefreshVersions offers an elegant solution to this problem: check on Maven if new versions of each dependency are available and indicate this as a comment in a file that centralizes the versions of the dependencies. The developer is free to select the latest available version of a dependency, by committing a modification to this central file.
RefreshVersions also offers an integrated catalog of most common dependencies, allowing them to be discovered via auto-completion when adding a dependency to a module. We also welcome the integrated migration tool, which makes it possible to adopt the tool in a few minutes if the project has a classical structure. It's a shame, however, that the tool is just starting to support Gradle Catalog files, which is the new solution pushed by Gradle to centralize the declaration of dependencies and does not allow it to be based solely on it.
OUR POINT OF VIEW
This project deserves to increase its reputation and must continue to evolve to be integrated into as many existing projects as possible. However, if the migration tool works for your project, it will already save you valuable time. In line with the philosophy of the project (it is up to the developer to select which libraries to update), we have adopted this tool on all of our new Android projects.
HISTORY 2022
It's a new blip this year.
When testing a program, it is difficult to test more than the unit logic without doing end-to-end testing. These are often time consuming and can be difficult to maintain when the product changes a lot.
With the aim of finding a balance between these two approaches, snapshot tests were designed and then applied to web technologies. Their use is becoming more and more widespread and that is exactly what the swift-snapshot-testing library promises. It allows indeed to take screenshots or the rendering tree of a native iOS application (SwiftUI or UIKit).
This makes it possible to provide effective display and non-regression tests at a lower cost, the library being easy to install and configure, while the tests themselves are quick to set up. This is especially true as it is possible to set the test to take captures of several different formats automatically, which is useful to ensure that the result is what you expect.
Also, we observe that swift-snapshot-testing does not introduce a loss of performance during the compilation or testing phases.
On the other hand, the library suffers from several flaws, including differences in rendering between Intel and ARM architectures. This leads to lower the accuracy of the tests or to develop the application only on a single processor architecture (which also applies to CI providers). It is also quite difficult to test some third-party libraries based on their use of animations, although this is increasingly better supported.
OUR POINT OF VIEW
At BAM, we have successfully used swift-snapshot-testing on several new and existing projects. This allowed us and still allows us to prevent visual regressions or to ensure that our designs match expectations on all target devices. However, although they are not major, these various problems prevent us from recommending this library blindly.
HISTORY 2022
It's a new blip this year.
JUnit is the most popular unit testing framework for Java, and by extension for other JVM languages, including Kotlin.
Introduced in 2017, JUnit 5 offers a new API that is more readable and allows you to write parameterized tests in an efficient way. Unfortunately this version is still not officially supported by the Android platform. Unofficial ports exist, for example android-junit5. Taken in isolation, this library works very well and allows you to take advantage of the new API on your project.
However, most other libraries that can be used for unit testing (Jetpack testing and Paparazzi for example) do not support the JUnit 5 API.
There is therefore a good chance that during your project you will have to use these types of dependencies, which will force you to use JUnit 4 for tests that depend on it, causing the configuration of the project to become more complex.
OUR POINT OF VIEW
For these reasons mentioned, we do not recommend using JUnit 5 until Google offers official support for Android.
HISTORY 2022
It's a new blip this year.
Formerly called AsyncDisplayKit, Texture is a framework created by Facebook and developed by Pinterest.
It allows visual components to be defined and arranged with flexboxes. The framework is very powerful and succinct compared to UIKit, and it is easy to connect it with existing UIKit components. When Swift UI was still new (coming to iOS 13 and more advanced starting with iOS 14), Texture was a good alternative for having flexboxes without sacrificing the compatibility of the oldest devices. We then chose to use it at BAM.
However, Texture has several disadvantages. The code required for the display is certainly less verbose than UIKit, but it is still longer and more complex than with Swift UI. The available documentation is very incomplete and sometimes you don't understand why something isn't working. Finally, the activity of this library is now very low: the last update dates from September 2021 and few sites outside the official documentation offer resources.
Since Swift UI is now available on a large number of devices (iOS 14 and higher being used by 94% of users in March 2023), we recommend that you use this graphics library. However, if you want to ensure strong compatibility, we recommend that you stay on UIKit, as the effort to switch to Texture is too great.
OUR POINT OF VIEW
If you are currently on a Texture project, it is not necessarily necessary to make the change today. It is a compromise to be found between maintaining uniformity in the code and limiting Texture problems.
HISTORY 2022
Assess - See the Tech Radar 2022
Retrouvez l'avis de nos experts sur les techniques, plateformes, outils, langages et frameworks associés aux principales technologies mobiles que nous utilisons au quotidien chez BAM : React Native, Flutter et Native.