-->

Inject system wide touch events on iOS7

2019-01-30 11:10发布

问题:

Prior to iOS7 it was possible to inject touch events with the GSSendSystemEvent and GSSendEvent private API calls, eg:

  • GSSendEvent - Inject Touch Event iOS
  • Simulating System Wide Touch Events on iOS
  • System-wide tap simulation on iOS
  • Send a global touch event on iOS 6

On iOS7 these calls seem to silently fail though. An alternative has been suggested in Simulating system-wide touches in iOS 7 but it only works on jailbroken devices. https://github.com/kif-framework/KIF looks like another option, but it appears that it only supports injecting events for the current app rather than system wide (so you couldn't inject a touch event while you're app is in the background, for example).

So how can you inject system wide touch events on iOS7, without a jailbreak?

回答1:

I assume you need to do this system-wide for a testing scenario? In which case you might be well served by Apple's UI Automation framework, a JavaScript-based tool useful for on-device testing.

While you can't do things like simulate a home-button press, you can send your app to the background for a specified duration, for example:

UIATarget.localTarget().deactivateAppForDuration(seconds);

Here are the docs:

https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef



回答2:

You can subclass UIWindow and overwrite sendEvent. I use it to implement a multiple listeners pattern, but you can also use it to fire events...

- (void)sendEvent:(UIEvent*)event {
    [super sendEvent:event];
    //NSLog(@"NSEventListenerWindow.sentEvent: %@\n", event);

    // pass all events on to those who listen
    for ( id listener in listeners) {
        if ([listener respondsToSelector:@selector(sendEvent:)]) {
            [listener sendEvent:event]; 
        }
    }
    .....


回答3:

I think you'd be better off using iOS SDK Notification service api. That would be the cleanest way to achieve what you want.

Conceptually, Apple doesn't (yet) intend third-parties to issue system wide events since that wouldn't sit well with iOS careful curating model, that's why people resort to private APIs and jailbreaking. Private APIs, as the name implies, are not supposed to be relied upon.

Think about it this way, unless you were responsible for the whole system, which a user app couldn't possibly be, you really have no business generating system wide events. I know how Android does this, but that's another story (not fit for this topic).

On the Mac, the XPC Services api for allows processes to communicate with one another, still not quite a method for generating system wide event. I'd suggest you use iOS SDK's notification API, that would probably be the cleanest method to achieve what you want. Yes, it goes out to Apple and back to the device, but that's the mechanism that is available up to now.