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?
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
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];
}
}
.....
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.
Related
Might be i am using a wrong title but i will try to explain here what i want.
In iOS i need to implement a functionality to get notify if the user is using their iOS device.
My app will be running in background using location services and i need to find out if the the user is using their device. It is doable as i have looked into this application which is sending notifications in background to the drivers who is suing their devices while driving.
https://itunes.apple.com/fr/app/cellcontrol/id661169580?l=en&mt=8&ign-mpt=uo=2
So i need similar kind of functionality to find out if a user is using iOS device or not. If anyone of you can suggest me any approach then it would be great for me to start.
Thank you!
Note: I have tried to find out touch events in background but that is not possible as i have done some research on this.
You won't be able to receive touch events when the app is in background using public API's. However, you can do that with the help of mobileSubstrate library ( http://iphonedevwiki.net/index.php/MobileSubstrate - The MobileHooker component is the one that would be used). by hooking your process to the OS. As an example, the display recorder app in Cydia tracks global gestures while recording the screen. This will be a cydia tweak and you will need to jailbreak your device to do all that.
Coming to your specific use-case, the example app you cited should be using one of the exceptions for background applications mentioned in https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html (see the section - "Implementing Long-Running Background Tasks"), probably the one to receive updates from external accessories.
I want to capture all the touch events at the system level, I do not mean capturing at one specified app, but all the apps even the SpringBoard.I tried IOHIDEvent(https://github.com/kennytm/iphone-private-frameworks/tree/master/IOKit/hid), but the runtime headers was changed after iOS4, and now I can not get them of iOS6.
May be GSEvent is also a good way, but does anyone known how to do this by GSEvent?
Thank you!
Take a look at EntryDevLevel excellent answer here on how to capture and record clicks on iOS using iOHID:
iOS touch event notifications (private API)
BTW. His solution works on non jailbroken iOS either.
Can we interrupt calls/SMSs on iPhone IOS 5? any code samples?
I am looking for some code samples for an application that gets notified when a call is incoming/outgoing to/from the phone, and gets the caller number.
Same thing for SMSs.
I know this seems like spying, but the purpose of this at the end is way far of that.
I'll take this from a non-jailbroken position (because you do not specify it in your question).
Can we interrupt calls/SMSs on iPhone IOS 5?
No. Absolutely not. In doing so, you'd need 3 things:
A Listener For Incoming Calls/SMS's
An Event Called When A Call Or SMS is Incoming.
A Responder Able To Cut Off Said Call
The first is impossible without breaking out of the app sandbox, a clear no-no in iOS development. It also presents a major security risk for the operating system as a whole. If applications could listen to each other and react any way they wanted, it would create chaos! Users wouldn't have any privacy whatsoever. The second would require some kind of listener that was always present and capable of waking/starting your app to interrupt the call, which again, is a clear case of stepping out of the sandbox. In fact, the only way to launch your application to interrupt the call would be to send a URL, which in itself requires an application... Yikes! The third is just plain impractical. If you made even a tiny mistake in the way you determined whether or not to cut off the call or SMS, you could prevent potentially important messages from getting to innocent bystanders.
I know this seems like spying
Because it is! You need a listener in order to evoke some action from your application.
Of course, this isn't to say it's impossible, but it would require a jailbroken device.
Is it possible to create an app for the mac (and iphone afterwards) that does something when it detects that the focus is on a certain object in the screen?
Meaning, the program runs in the background, and when it detects that the focus (or cursor) is on an edit box, it will run something.
Hopefully I made myself clear!
Thanks!
You can do this on the mac by using the Accessibility Framework.
Note that users will have to manually enable assistive devices and you will not be able to distribute your app on the Mac App Store due to Apple's soon-to-be-implemented sandboxing restriction.
On iOS, you can detect focus to certain but not all elements using specialized delegate methods such as textViewDidBeginEditing:. That said, as users use taps to navigate iOS apps most of the time, simple tap handling seems like a much better approach.
On the iPhone, you can only detect focus within your own app, there's no way to observe other apps from the background.
On the Mac, as 0x90 noted, the closest you'll get are the Accessibility APIs. The UIElementInspector sample code may help you to get started.
Is it possible to write an application that will block incoming and outcoming phone calls? Or is the iPhone locked down too much? Thanks!
EDIT: See Rajan Maheshwari's answer below. CallKit now provides this. Even things that seemed they would never change, can change eventually.
Anything that modifies a user's ability to make or receive phone calls is going to run afoul of Apple's basic approach to third-party apps. There are a lot of things that are questionable and you might get away with. Blocking calls is clearly forbidden.
It is now possible to detect and block unwanted phone calls from iOS 10 and above.
See the CallKit framework
The CallKit framework (CallKit.framework) lets VoIP apps integrate with the iPhone UI and give users a great experience. Use this framework to let users view and answer incoming VoIP calls on the lock screen and manage contacts from VoIP calls in the Phone app’s Favorites and Recents views.
CallKit also introduces app extensions that enable call blocking and caller identification. You can create an app extension that can associate a phone number with a name or tell the system when a number should be blocked.
A number of events will potentially interrupt an application - incoming call, SMS message or calendar alert. If the user ignores the interruption your application will continue running. If not, it will terminate.
See Apple docs for more details.
It is possible in iOS 10.
Here's how to do it ->
1.Create a call directory extension
2.Block the incoming call ->
class CustomCallDirectoryProvider: CXCallDirectoryProvider {
override func beginRequest(with context: CXCallDirectoryExtensionContext) {
let blockedPhoneNumbers: [CXCallDirectoryPhoneNumber] = [ phone Numbers here with country code! ]
for phoneNumber in blockedPhoneNumbers.sorted(by: <) {
context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
}
context.completeRequest()
}
}
Note:
If you are using callKit to receive incoming calls then there is no need to manually block other calls.
Link -> https://developer.apple.com/reference/callkit
An app has not access to the phone feature, and has no way to block a call.
The alternative is to wait for Apple to offer that feature in the future.
In the meantime, you can
Ask your provider - some providers do that
Create a custom ring tone (silent) to be associated to some number (no ring).