Taplytics is a native mobile A/B testing, feature flagging, and push notification platform that helps you optimize your Android / Android TV / Fire TV app!
Current Version: 3.1.1
How do I, as a developer, start using Taplytics?
- Sign up for an account at Taplytics.com.
- Install the SDK. Steps here.
- Create Experiments or send Push Notifications to your users!
The Taplytics team is available 24/7 to answer any questions you have. Just email [email protected] or visit our docs page for more detailed installation and usage information.
- Deobfuscate public listeners
- Added debug function
getAllVariables
to allow for getting information on all variables in the config at the moment.
- Fixed push opened event tracking for Android SDK versions 23-30
- Added app update checking
- Wait for activity to be created before getting settings from the server
- fixed duplicate events happening on some locales
- Fixed issue opening push notifications for Android 12+
- Added option to disable overlay
- Fix issue starting Taplytics when woken up from a foreground service
- Fix a setUserAttribute / resetAppUser race condition
- Added support for Android X
- Fixed PendingIntent warnings when publishing app with Taplytics installed
- Added dispatcher to okhttp client to make post requests sequentially
- Modifications to support the shutting down of jcenter: https://blog.gradle.org/jcenter-shutdown
- Update Volley to 1.2.1
- Update all references to jcenter into mavenCentral
- new session listener gets triggered after init has passed
- Init call now triggers on new session listener
- Potential fix for intercepting non-Taplytics network requests
- Fix an issue where client events would be posted in fastmode if disable options were present
- Fix crash during listview scroll
- Fix an issue where Taplytics.resetAppUser was not working as intended
- Fix a crash that would occur when a recyclerview was scrolled
- Fixed an issue where FireTV users were not bucketed into experiments
- Add support for the Adobe Experience SDK
- Fix broken socket connection
- Fix TaplyticsVarListener memory leak
- Log experiments received from config to Mixpanel
- Fixed new session listener not being called when a new session is started
- Fixed cached experiments not being used when timeout is reached
- Updated Amplitude integration to set user properties for experiments/variations
- Updated socket code stability
- Added a client log for button clicks
- Fixed blank sending blank user ids when a blank user id is set
- Fixed a rare crash when receiving a push notification
- Fixed rare stability issues
- Added the ability to provide a default value to Feature Flags
- Updates for upcoming speed enhancements
- Fixed minor crashes
- Added
userBucketing
option for user based bucketing enabled projects
Note: Contact [email protected] to get your project user based bucketing enabled!
- Added
logging
option to enable debug logging - Updated recycler view visual editing
- Improved functionality on the
aggressive
option for visual editing on recycler views
- Fixed upgrading issues with push notifications on devices using older versions of Android
- Added TLFirebaseMessagingServiceLite class
- Fixed intermittent crash caused by stack overflow.
- Migration from GCM to FCM push notification system.
- Added manual device tracking option.
- Fixed push notification icon image for closed and open notifications.
- Improved functionality of visual editing.
- Add large icon support for push notifications.
- Added new call to
setUserAttributes
that has a callback parameter to determine when the call has ended. - Changed the default debug check type default to
FLAG_ONLY
.
- Added support for opt-in/opt-out for compliance with GDPR.
- Modified backoffs for network attempts when app is backgrounded
- Added getRunningFeatureFlags functionality.
- Added support for feature flags.
- Improved user attribute lifecycle.
- Enhanced push support for Oreo+ setups.
- Enhanced support for views added on runtime.
- Ensured that onError callbacks are being called.
- Better support for Multithreaded Application classes.
- Improved encoding of URL parameters.
- Added support for multiline rich push notifications.
- Improved error support for creating new sessions by adding an on error callback to
TaplyticsNewSessionListener
. - Enhanced usability of
resetAppUser
. - Ensured that new session rate limit is being followed.
- Added more granular language support.
- Google Analytics integration maintenance.
- Update Adobe integration
- Updated event batching method to capture all events in a session more efficiently.
- Added support for Android TV and Fire TV!
- Properly track fragments in a fragment's
childFragmentManager
.
- Added support for notifications for Android O.
- Improved performance of app lifecycle event tracking.
- Fixed occurrences where potential memory leaks can happen.
- Ensured that visual changes get applied from disk when launching the app with no internet connection.
- Refactored Taplytics.delayLoad and Taplytics.startActivity. These now can handle multiple listeners and delay load properly short circuits when startActivity is complete.
- Improved visual editing on ListViews and RecyclerViews inside of ViewPagers.
- Modified all AsyncTasks to operate on separate thread pool for newer Android SDK versions
- Support for visual editing on ListViews and RecyclerViews with row elements that are single Views. Previously only supported rows which are ViewGroups.
- Enhanced support for visual editing on text elements with no IDs.
- Improved performance of first-page experiment goals.
- Track received push notifications immediately instead of waiting for app open.
- Added extra sdk-side verification of deeplink URLs for link pairing.
- Fixed potential crash if some actions were performed before
startTaplytics
was called.
- Updated performance of link pairing on release builds.
- Removed socket dependency for debug pushes. This is only for clients who use this lib as a push lib only. To pair device and test experiments, you must have the socket dependency in your app.
- Added ability to visual edit any TextView (or elements subclassing textviews such as buttons or your own custom views) that do not have an android identifier.
- Fix volley logging causing bad error reporting.
-
Updated the behaviour of Dynamic Variables with respect to sessions:
In the event that a new session begins, Taplytics will now ensure that async variables have their values updated in the event that they have changed in the new session. Further, sync variables will also have a new value so long as they are re-initialized.
-
Added support for ListView and RecyclerView header/footer visual editing.
-
Added manual push dismissed/received tracking. This is meant only for clients who do not use Taplytics to build notifications, but build themselves.
Use as follows:
Taplytics.trackPushReceived(tl_id, custom_keys)
Taplytics.trackPushDismissed(tl_id, custom_keys)
where tl_id and custom_keys are retrieved from the bundle within the Taplytics notification intent.
-
Greatly improved visual editing on carousels and ViewPagers.
-
Added manual push open tracking. This is meant only for clients who do not use Taplytics to build notifications, but build themselves.
Use as follows:
Taplytics.trackPushOpen(tl_id, custom_keys)
where tl_id and custom_keys are retrieved from the bundle within the Taplytics notification intent.
- Added ability to aggressively force visual changes on elements that may be modified by code in the future.
For example, a TextView that may be updated in an activity's OnCreate previously would have overridden Taplytics' changes, but now it should remain the values sent by Taplytics. This currently works for Visibility and Text changes.
Simply add the "aggressive" starting option to Taplytics will enable this feature.
- Added extra security precautions around events databases.
- Fixed problems related to geofencing push notifications under bad network conditions.
- Added another step to the check for whether a device is in dev mode or not. Previously, it only checked for the
FLAG_DEBUGGABLE
flag on the application info. Now, there is also a check on your applicationsBuildConfig.DEBUG
parameter to add extra safety around this entire process.- Also added a starting option for "
debugCheckType
" with options "flag
" or "config
" if you do not want both to be checked.
- Also added a starting option for "
- Added a "
isDebug
" starting option, which allows you to manually control the debug status of a device based on your own parameters. For example, if you were to pass inBuildConfig.DEBUG
as this option, the debug status would be determined based directly on the current value of that parameter.
- Added the ability to provide null as a default value for dynamic variables. Null values can not be supplied on the dashboard as of yet.
- Change callback timing of
getRunningExperimentsAndVariations
to be more closely tied to the completion of thepropertiesLoaded
callback. - Resetting users has improved retry logic under low and no-connectivity situations.
- Fixed bad interaction between TwinPrime SDK and Socket.io libraries.
- Added a new
startNewSession
function which allows for manually starting a new user session. This also allows for manually fetching new Taplytics experiments for the user if there are any. See the docs here
- Modified timing of propertiesLoaded callback to allow for creation / updating dynamic variables in the propertiesLoaded callback with much better reliability.
- Updated socket retry logic to back off better.
- Perform check on deep-links to improve performance in apps with many deep links and Taplytics advanced pairing.
- Fixed issue in data retrieval for apps with very short package names.
- Fixed threading issue when starting up Flurry tracking
- Fixed an issue in which some activities would not receive visual changes in race conditions. Fragments unaffected.
- Fixed an issue where new dynamic variables were not being sent from code to initialize on Taplytics website.
-
Update event saving for those who use multiple SDK keys for different environments.
Previously, stored events were not associated with a project and would be sent to the project associated with the current SDK key. This meant that stored events had the potential to be sent to the incorrect project. This mainly effected those using multiple SDK keys to debug.
-
Add some additional logs for support.
-
Add additional option to ignore fragment classnames in projects which heavily obfuscate activities and fragments, causing them to have different names upon each build.
-
Security optimizations. Taplytics will now encrypt all data. Taplytics data in of itself is not sensitive data. However, custom data appended to events as well as potential user attributes set by the client may contain sensitive data. While not easily obtained, rooted devices had the ability to view this data. This is now handled by encrypting all data saved on the device.
-
Reduced lag when editing List/Recyclers in debug mode.
-
Explicitly require HashMap in options for startTaplytics
Due to operations done within Taplytics, this can no longer be an ArrayMap and must explicitly be a HashMap.
-
Optimized and refactored ListView and RecyclerView visual editing.
Visual edits made on RecyclerViews are now far more reliable due to a change in the identification of which list cell needs to be changed. Visual edits on List/RecyclerViews also now operate much more efficiently.
-
Fixed bug in dynamic variables with numbers which are both floats or integers.
When a dynamic variable's default value was a float or integer, all variations were expected to be of the same type. This was problematic when parsing JSON, as the system saw any numbers with no decimal as an integer, even if the type was a float. This resulted in the default value always being returned. This has been handled and will no longer be an issue.
-
Various small efficiency improvements in width/height visual edits.
-
DelayLoad should no longer immediately return during liveUpdate builds.
delayLoad now waits for a pass/fail on the config request before triggering. Previously, on connected debug builds, it would trigger after visual edits have been applied, even if just from disk.
-
Track Adobe Analytics
trackState
calls.Previously Taplytics would only track
trackAction
, but now it also allows fortrackState
-
Added safety around new external integration methods.
Simple safety checks and catches to ensure no errors showing up. Errors are expected in these integrations and our attempts do deal with them, however they are squelched. This update just ensures that such errors don't reach crashlytics and cause confusion.
-
Update Taplytics internal Retrofit interceptor.
Taplytics uses a networkInterceptor to do a simple obfuscation of network traffic through Taplytics (using its own okKttpClient). This may not work depending on the app's okHttp/retrofit versions (older). While not technically an issue, extra safety has been added in this area.
-
Updated Flurry, Amplitude, Adobe, Localytics, and Mixpanel integrations to allow event handling on their newest SDK versions.
Flurry integration now also supports property maps.
-
Fixed error when user's country code does not have associated ISO language.
For example, es_LG is unknown by the Android system, and will no longer cause an error when the ISO3 language code is searched for.
-
Added additional socket call to better interact with the new experiment selector on the User Insights page.
-
Fixed ExperimentUpdatedListener returning wrong value on initial use of Shake Menu.
In a race condition for large projects, the listener was triggered before new updated values were cached fully. Additionally, if a project initially timed out, the SDK would not have the cached data to reference.
-
Decreased sensitivity of shake menu listener.
Using the most recent android build tools, it seems that the shake menu appears a lot more frequently. The low-pass filter used on the device accelerometer for detecting shakes has been increased to be far less sensitive.
-
Added startup safety for Taplytics (internal)
In past updates, safeties had been put in place during the startTaplytics call internally. More comprehensive checks, weak references for leak safety, etc. In this update, these checks and safeties have been extended to many of the static variables and their static initializations in core Taplytics classes.
-
Fixed slowdown in visual edits on ViewPagers
Previously there was a slight delay when applying visual edits to an element on a ViewPager. This slowdown has been eliminated in this update by preemptively making the visual update before the viewpager is visible.
Technical Explanation:
Android unfortunately does not contain a standard method to retrieve a fragment from a ViewPager by its position, but rather it only contains a
getCurrentFragment
method which returns the current position as an integer. Taplytics does not make use ofgetItem
orinstantiateItem
as it may incidentally create a new instance of the fragment depending on the developer's implementation, and we wish to remain as non-intrusive as possible. Its common for developers to implement methods in which to track the fragments in a ViewPager, but as a library, Taplytics does not want to make assumptions of the existence of such functions.In the past, Taplytics applied changes to every view child in the ViewPager, however this was deemed far too inefficient, especially within ViewPager with more than 5 pages. Soon after, Taplytics relied on a reflective call into the ViewPager's
mCurrentFragment
field to make visual changes, but this only allows changes to be made on the current fragment showing, which is where this mentioned delay originated.Now, Taplytics is able to identify which views within a ViewPager require changes and apply them before the ViewPager is on the screen. This is due to a tagging system that identifies which fragment needs changes, which also allows for an efficient search for these fragments. Additionally, Taplytics will only change the current fragment as well as fragments directly to the left and right of the current fragment, allowing for the most efficient visual edits of ViewPagers yet.
-
Fix Taplytics not being able to properly track fragments on newest support libraries.
This is a simple Proguard issue. Android's FragmentManager contained a
mExecutingTransactions
field which Taplytics uses to ensure that certain interactions with the FragmentManager are safe. As an extra precaution, if there is an issue surrounding this field, Taplytics will not risk interacting with fragments.In the most recent support fragment updates, this field was moved by Android, and so our tests picked up these changes and notified us of a necessary change within our own Proguard configuration which keeps this field's name.
-
Change base method used for finding views.
Taplytics previously relied on
findViewById
in base viewgroups to find views that need to be modified. This became unreliable over time as the applications changed given that ids can change.Taplytics will now first check the view identifier first before the id. This means that if the name (identifier) of the view is changed to something new, Taplytics will not be able to modify it using the old experiment, and it will need to be set up again.
-
Fragments will now too rely on the identifier of the fragment container instead of the ID for similar reasons to the ones stated above.
-
Fixed an issue in which Android studio would output many warnings surrounding Proguard and inner classes.
- Fix crash on specific Lenovo devices that do not have carrier info.
- Button click goals on buttons with same ID across multiple fragments will now be properly tracked.
- Fix variableUpdated not being called when switching variations via shake menu
- Fixed edge case in which delayComplete() could be called twice if thread containing delayComplete() is locked.
- Fixed potential google developer console warning regarding Device IDs.
- Changed button click goals to check for current fragment before tracking to avoid duplicates.
- Switched events endpoint.
- Fix support fragment tracking in 24.2.0 libs.
- No longer use
findViewById
for button click tracking. Only use resource identifiers.
- Fixed Proguard error
- Fixed networking library warnings in the ART runtime environment.
- Fixed networking library detection (Volley/Retrofit)
- Removed
getUserAttributes
for security. Replaced withgetSessionInfo
. - Internal code cleanup to make things pretty.
- Now compiling with Gradle 3.0, Android tools 2.2.0-beta1, to SDK 24
- Fixed timeouts triggering sending data to external sources more than once.
- Support library 24.2.0 support.
- Fixed timeout messaging occurring after successful load.
- getUserAttributes now contains session ID
- Updated safety around logging
- Fixed some slowdowns caused by the Taplytics overlay
- Update pairing
- Async option update to work better with fragments.
-
For example, you now can start Taplytics as such:
Taplytics.startTaplytics(Context, ApiKey, Options, TIMEOUT, listener)
When this timeout is reached, Taplytics will continue and ONLY use values stored on disk for the remainder of the session.
-
Improve code block timeout and cache interaction.
-
Make fewer socket connection calls on debug app startup.
-
Kickoff all variableUpdated and visual editor changes with disk or default values immediately after timeout.
-
Devices which have a delay to start Taplytics (such as via segment) will now track the main activity start more consistently.
-
Debug devices which time out can now kick off pairing without needing to restart the app.
- Load variables from disk faster.
- Timeout getRunningExperimentsAndVariations if the TaplyticsExperimentsLoadedListener timed out previously.
- Performance updates for applications that don't contain support libraries.
- Added the ability to retrive current user attributes. Use
Taplytics.getUserAttributes(new UserAttributesRetrievedListener)
. - If you are in a session which timed out and you are in debug mode and testing experiments via the website or shake menu, you can now properly switch between variations and experiments. Previously the timeout would make this impossible as we never used a new config, but this made testing in these situations difficult.
- Change in how timeouts are handled. Now, if the TLExperimentsLoadedListener times out, Taplytics will only use what data is stored on the disk for that entire session. Taplytics will still attempt to load the proper data in the background and will save that to disk to be ready for use for the next session. This prevents bad data in the event that an experiment did not properly load (due to bad internet). The default timeout is four seconds.
- Changed the looper that advanced pairing uses to allow more consistent pairing.
- Segment spec change.
- Added starting option to fix problems when delaying the starting of Taplytics, such as with segment.
- Added a Non Wakeful broadcast receiver that can be used for push.
- Updated Segment experiment sending to follow spec.
- Added a few proguard changes to the consumer file to ensure that taplytics functionality remains stable regardless of your obfuscations.
- Fixed a bad recursive call when searching for viewpagers.
- DialogFragment support! You can now modify dialogFragments and use them for goals just like any other view. Just make sure you add to the backstack and call
.show
using the same tag, for example:fragmentTransaction.addToBackStack("example tag"); exampleDialog.show(fragmentTransaction, "example tag");
- Time on Page goals now have consistent time tracking for Fragments.
- Minor proguard changes.
- Fixed another potential issue with Adobe events.
- Send experiment data to segment (enable on dashboard)
- Fixed Adobe event tracking to work with Adobe 4.11
- Updated geofence logic to ensure geofences won't be lost if they are not successfully added the first time.