New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TIMOB-26294] TiAPI: Notify app about user-interactions #10248
[TIMOB-26294] TiAPI: Notify app about user-interactions #10248
Conversation
…ion and catch all UIEvents.
Master changes
…into feature/ios_catch_all_ui_events
Generated by 🚫 dangerJS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes required.
apidoc/Titanium/App/iOS/iOS.yml
Outdated
description: | | ||
This event will be triggered each time a UITouchPhaseBegan event is handled by the UIApplication. For more information, see https://developer.apple.com/documentation/uikit/uiapplication/1623043-sendevent | ||
osver: {ios: {min: "7.0"}} | ||
since: "7.4.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move the API to be a Ti.App
event that can be used from Android and iOS (requires a small Android change as well). Otherwise, we have two API's for the same functionality on two namespaces. Since 7.4.0 is not released so far, the changes from #10242 could still be updated in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
iphone/Classes/TiAppiOSProxy.m
Outdated
@@ -126,6 +126,9 @@ - (void)_listenerAdded:(NSString *)type count:(int)count | |||
name:kTiApplicationLaunchedFromURL | |||
object:nil]; | |||
} | |||
if (count == 1 && [type isEqual:@"userinteraction"]) { | |||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUserInteraction:) name:@"kTiUserInteraction" object:nil]; | |||
} | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move over to the Ti.App namespace. Also, lint all sources using clang-format -style=file -i Classes/<file>.m
from the /iphone
folder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
[[NSNotificationCenter defaultCenter] postNotificationName:@"kTiUserInteraction" object:nil]; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also lint here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dont!
support/iphone/main.m
Outdated
@@ -27,7 +27,7 @@ | |||
int main(int argc, char *argv[]) { | |||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |||
|
|||
int retVal = UIApplicationMain(argc, argv, nil, @"TiApp"); | |||
int retVal = UIApplicationMain(argc, argv, @"TiUIApplication", @"TiApp"); | |||
[pool release]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix the indentation here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
Updated documentation
if (activityProxy != null) { | ||
activityProxy.fireEvent(TiC.EVENT_USER_INTERACTION, null); | ||
} | ||
TiApplication.getInstance().fireAppEvent(TiC.EVENT_USER_INTERACTION, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intentation here seems wrong, please also lint with clang-format -style=file -i titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java
from your android/
dir.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
iphone/Classes/TiUIApplication.m
Outdated
|
||
for (UITouch *touch in event.allTouches) { | ||
if (touch.phase == UITouchPhaseBegan) { | ||
[[NSNotificationCenter defaultCenter] postNotificationName:@"kTiUserInteraction" object:nil]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am starting to become unsure if we should really have this in the core. I understand the purpose for you, but this was requested by maybe 5 devs over the last years, and it must have some kind of performance hit if we post an internal notification for every tap that is made in an app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do agree with your concerns about potential perfomance hit. On Android, the onUserInteraction will also loop over the event listeners in order to fire an event. It can have performance impact on both platforms, but while testing it, I wasn't able to "feel"/measure it.
I also understand that on Android, we're firing an event for a native event (onUserInteraction). iOS doesn't have this event by default, so this workaround is mentioned as a solution for this problem (https://blog.gaelfoppolo.com/detecting-user-inactivity-in-ios-application-684b0eeeef5b)
In order to improve performance, there should be an if
somewhere in order to only post internal notifications when there are listeners registered, but I wasn't able to find a way on how to implement this. This feature might be requested by 'only 5 devs', but I think this can't be fixed by using a module, as you need to extend the UIApplication class and register it in the main.m file of your project.
In a use case from our customer, we're in the need of implementing a way to automatically logout after x-seconds of non-activity. The way it's implemented now (firing events for user interctions) is the only way to catch user activity in Titanium, so we can handle further stuff in our Javascript code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use a design that has a property (let's say trackUserInteraction
) together with the userinteraction
event, we could wrap the special code out using preprocessor macros on iOS. For Android, we could maybe add the handler only if the property is set or at least use it to skip the event from firing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your comment, but I don't have any knowledge about preprocessor macros.
On Android, I think that the event is only fired when there is a listener registered.
I pushed some changes to your repo e5e1bd8 to enable conditional compiling for iOS. For Android, I need a second thought from @jquick-axway if this is a suitable change or performance overhead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iOS approved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CR: Pass
And thanks for changing the Android onUserInteraction()
method. The performance will be better this way. The hasListeners()
is a hashtable lookup, which is fine.
@hansemannn @jquick-axway IS this PR ready to merge? |
@JorenVos, this PR is currently scheduled to go into 7.5.0. The next step is that it has to go through our test team before being merged. |
apidoc/Titanium/App/App.yml
Outdated
- iOS: See the [sendEvent](https://developer.apple.com/documentation/uikit/uiapplication/1623043-sendevent) delegate | ||
|
||
platforms: [android, iphone, ipad] | ||
since: "7.4.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be updated to 7.5.0 before merge now...
property to be set explicitely. For iOS, this is done to prevent additional overhead. | ||
type: Boolean | ||
accessors: false | ||
platforms: [iphone, ipad] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably need to add a since value here for 7.5.0 as well
The build fails due to :
|
@hansemannn @jquick-axway The It looks to me like the actual proxy that would handle the event and would have a listener is the Ti.App ( |
- Fixed compiler error in "TiBaseActivity". - Modified TextField/TextArea to fire "userinteraction" event when changing text.
Updated PR:
|
@jquick-axway , I see for IOS. The volume buttons do not reset the counter means its does not fire the |
@lokeshchdhry, I think it's fine. There are going to be some native behavior differences between the 2 platforms and the handling needs to be reasonable enough to satisfy the use-case app developers are after, such as auto-logout after a period of non-use. Some differences I have seen are:
|
FR Passed.
Studio Ver: 5.1.1.201809051655 |
JIRA: https://jira.appcelerator.org/browse/TIMOB-26294
In order to create a solution for https://jira.appcelerator.org/browse/TIMOB-13884, we're trying to capture all user interaction events. For Android, there is support to capture all onUserInteraction events. (https://jira.appcelerator.org/browse/TIMOB-26278)
We want to achieve the same functionality for iOS by extending the UIApplication and trigger an event for each UIEvent. In order to avoid negative performance impact, an event will be triggered only when a touch event began.
Test:
Run the below test on both Android and iOS.
UserInteractionAutoCloseTest.js
attached to TIMOB-26294.