Targeting specific pages and elements is a key feature at Helppier SDK, but there are significant differences when developing it for Android and IOS
Continuing our Helppier Mobile development article series, today we are excited to share the process of developing the detecting and targeting pages feature, and some of the challenges that our team has faced during it.
One of the main objectives of the Helppier SDK is to allow our customers to create a diverse set of experiences (banners, popups, footers, and tours) through a dynamic and flexible tool. Moreover, one of the key features is to be able to target specific pages, so our customers can show the right content at the right time. But there are major differences when developing it for Android or iOS.
Android and IOS main components
Mobile operating systems, such as iOS and Android, provide classes to control in-app screens that the developer needs to break down into subclasses. However, the two major operating systems approach this slightly differently. This article will discuss some of the concepts underlying UIViewController in iOS and Activities and Fragments in Android before considering some differences between the two platforms.
Apple defines UIViewController as “The object that manages the view hierarchy for your UIKit application.” This short description sums up the intended functionality very well; the main purpose of the view controller is to control the View and subview hierarchy within it. All classes inheriting from UIViewController have a single UIView at their root, although in some cases, UIView is replaced by a subclass such as UITableView or UICollectionView.
Views & ViewGroups
In Android, View is an atomic and indivisible element drawn on the screen. You can display pictures, text, and so on. To form chemical substances by combining periodic elements, Views are combined to form a design component that gives the user a purpose.
In iOS, views are presented as UIView sub-classes, and in Android, views are represented as View sub-classes.
ViewGroup places View (and other ViewGroup) to form a meaningful design in Android. ViewGroups is a special combination that combines Views to form a design component that serves a user’s purpose. The ViewGroups are Views and can contain other Views.
Managing a view hierarchy
The primary roles of managing the view hierarchy include updating subviews to accurately display back content, responding to user actions such as button actions and typing, and responding to layout changes such as rotation and resizing. The view controller is also responsible for coordinating with the rest of the app. Still, developers often misunderstand this responsibility, which can lead to a large amount of functionality for the view controller, resulting in bloated files and unnecessary complexity. If the interface consists of multiple logically separated parts, the view controller can have child view controllers like two panels of master/detail apps.
Activities
In Android, activity is defined as “a single focus that a user can do,” which is much broader than in iOS; managing what appears on a single screen is the same.
The activity is responsible for creating the window, and the developer can be responsible for creating a specific user interface.
In Android, activities are managed in the stack and the last activity added is deleted. This also means that only one activity appears on the screen simultaneously. Android, the equivalent of a nested view controller in iOS, requires fragments.
Fragments
Fragments of Android are defined as a representation of the behavior or part of the user interface. Fragments must be included in an activity, but it is achievable to have more than one fragment in an activity to build a UI with multiple panels. Although the life cycle of a fragment is directly linked to the parent activity, you can use the fragment transaction to add or remove fragments while the activity is running. One of the main reasons that fragments were added in 2011 was to increase the flexibility of apps designed for large screens, such as tablets. Fragments are intended to be built in a reusable module style to be used in multiple locations within the app.
There are various similitudes and differences between the two OSs regarding how to use 1 screen/1 view in the app. Unlike iOS, where the navigation controller is independent, Android activities are likely built into the navigation stack, which makes them feel more deeply integrated into the operating system. In addition, activities and fragments seem to be more closely integrated as they have more operating system callback functions and a more complex life cycle than iOS.
Elements
Android provides us a huge range of UI controls of many types such as TextView, EditText, Button, ImageButton, ToggleButton, RadioButton, RadioGroup, CheckBox, AutoCompleteTextView, ProgressBar, AlertDialog, etc.
These are the ones that we need to target.
The XML manifest file
Android relies on the XML manifest file to define your app’s overall structure, and basis, including the names of all activities, the various permissions required, and the device features required to prevent certain devices that do not have the required features from installing the app.
iOS includes a variety of subclasses of the UIViewController class to improve developer efficiency under certain circumstances. Subclasses such as UITableViewController, UITabBarController, and UINavigationController support specific features and make it easier for developers to work day-to-day. Android does not provide subclasses similar to activity classes, but you can use Android Studio to insert various templates, such as tabbed activities, scrollable activities, and master/detail navigation flows.
Lifecycle
The Android callback method and iOS life cycle stages have similarities and differences. For example, if your application runs in the background, Android has an onStop callback method, and iOS has a background stage.
Here you’ll need to know the differences and similarities between the life cycle stages of iOS and Android.
- Not Running
- Inactive
- Active
- Background
- Suspended
Not Running
Either the application is not running yet, or it was running but was terminated by the system.
Inactive
An application works in the foreground but does not receive any events. This may occur in case of a call or a message received. The application may also remain in this state while transitioning to another state. In this state, we cannot interact with the application’s user interface.
Active
An app works in the foreground and gets events. This is the normal regime for foreground applications. The only way to switch to or from Active State is through Inactive State. The user normally interacts with the user interface and can see the response/result of the user’s actions.
Background
The application works in the background and runs the code. Fresh-started applications are directly in the In-Active state and then in the Active state. Applications that have stopped will return to this background and go to the In-Active → Active state. In addition, an application that starts directly in the background is logged in instead of in the Inactive state.
Suspended
The application is in the background but does not run a code. The system automatically moves the app to this state and does not notice it. In the case of low memory, the system can clear the suspended application without notification to free up space for the application in the foreground. Usually, after 5 seconds spent in the background, applications go to Suspend, but we can extend the time if the app needs it.
Layouts
Android has Layout Editor, and iOS has Interface Builder. Both tools use XML to store the interface they created, but there is a significant difference in file format. Although Android’s XML layout files are intended to be read and edited easily, storyboard files must be purely graphical using Interface Builder.
Storyboards
A storyboard can contain multiple view controllers and be linked by a segment representing transitions between screens in the app. This makes it easy for developers to understand the overall look of the navigation flow of an entire app for specific UI flows and use cases in the app or for small projects.
Storyboards can be problematic in large projects with multiple screens and multiple developers. If you use Git, the storyboard may cause git conflicts if two developers edit part of the same storyboard simultaneously. Because the XML file is not designed for human editing, it can be very difficult to merge changes using the text-based merge tool. Keeping the storyboard small and using references to other storyboards is a way to reduce the problem and also helps reduce the time it takes to load the storyboard in Xcode.
Android Layout Editor
Each Android XML layout file contains a single element, such as an activity, fragment, or table cell. There is no equivalent for iOS segmentation, and all transitions between activities require the programmatic creation of Intent objects. As a result, it’s difficult to understand the overall flow of Android apps, but it’s not a big problem because it has other advantages.
Also, if you are familiar with the structure of an XML file, it may be faster to create or modify the UI using only XML without any graphical layout editor.
Constraints
iOS offers a layout system called Auto Layout, which Interface Builder natively supports. The idea behind Auto Layout is that the layout is defined by a system of mathematical equations known as constraints. An important concept behind this system is that constraints are not part of one View but are separate objects. Constraints can refer to one or two views, depending on the type of constraint. Constraints are mathematically solved as a linear equation system, giving you the position and size of all views in the hierarchy. Constraints can have precedence, and developers can specify which constraints to remove if they cannot solve the simultaneous equations directly. This system allows dynamic positioning with high responsiveness, called “Auto Layout.”
The Android provides a variety of ViewGroups methods for placing subviews horizontally, vertically, or horizontally, or vertically. When using a simple ViewGroup, such as LinearLayout, it is common to nest many ViewGroup into one another to create complex layouts. One of the new additions to this platform is ConstraintLayout, which allows developers to maintain a flat layout hierarchy by using constraints in the same way as AutoLayout. These constraints are different from iOS because the iOS constraints are independent objects that relate two views to each other. Still, they are unidirectional in positioning one View in a different view.
Solution for the Helppier SDK detecting/targeting pages
After understanding how the Android and IOS components work, we can get some solutions to the Helppier SDK. Although the iOS and Android layout tools have a similar idea of placing views with constraints, there are some important differences. We needed to adapt our algorithms to cope with these situations.
We do this by injecting layers on top of the application and we use several types of components that are specific to Android and iOS to add and place our content. We use an internal algorithm that will set the right x, and y constraints to place our content accurately.
We also created different listeners for all the types of experiences that our customers can create so we can understand when to show them. This is part of our targeting feature (that among other things allows us to set how many times to show, its frequency, and segment also per user type).
Solution for the Helppier SDK detecting/targeting elements
Currently, in order to achieve such behavior, there were several viable approaches to detect elements:
Identifiers: Most elements have assigned at least an unique identifier or an accessibility identifier which provide a viable approach to fetch a specific target element. Unfortunately, being aware of these identifiers requires a close interaction with the developer team in charge of assigning these identifiers.
Class Name: Every element that is rendered on Android is part of a class. TextView, Button and even Toolbar are examples of these classes. This approach would require the user to be aware of the specific class name, making him reliant on the developer team again, and this would also may not be the best approaches for complex application screens as most classes are usually used multiple times
Text: Using the element text could also be an appropriate approach if the application only supports a single language. If it doesn’t, supporting multiple languages can be become a cumbersome task.
XPath: Using XPath would provide unique identifiers for each element but has performance issues, may be affected by future layout changes and it’s dependent on the developer team yet again.
Coordinates: Another approach was to develop a way where any marketer or product manager could simply select an element in their own app. In order to do so, the user would only have to click on the element and we would determine that element specific coordinates
To make this possible, Helppier decided to use the Coordinates approach as will be adding an extra layer to the client’s application, with it, Helppier is able to detect the position selected by the user. Then, Helppier accesses the client’s application view and starts to search for the chosen element. This search is based on finding the elements around the selected element. After this process, Helppier fetches the selected element and extracts it’s coordinates. Then we save the element ID from the build so we can use it later and attach our content.
With all information gathered, Helppier is able to display the content written by user, attached to the selected element on the client’s application.