I need to send keystrokes to front most app from my cooca app.
I already have working code for it by using CGEventCreateKeyboardEvent() and AXUIElementPostKeyboardEvent(), but it only works if app is not sandboxed.
I have searched google for the same, but didn't find any working solution.
I saw that a Text app and few others doing the same thing in sandboxed environment, so i am wondering, if someone help me to figure out, that how aText.app and others are able to send keystrokes in sandbox environment.
Thanks,
This is actually possible. I have made an example app available here - SendKey at GitHub
I took the easy road and started with a simple AppleScript:
delay 5
tell application "System Events"
repeat 10 times
keystroke "#"
end repeat
end tell
The 'delay' in the script simply gives me enough time to make a text editor the frontmost application. I would suggest starting with just running this script to see what it does.
Then, I created an Xcode project using the default Application template and wrote:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSString* scriptPath = [[NSBundle mainBundle] pathForResource:#"sendkey" ofType:#"scpt"];
NSURL* scriptURL = [NSURL fileURLWithPath:scriptPath];
NSDictionary* errors;
NSAppleScript* script = [[NSAppleScript alloc] initWithContentsOfURL:scriptURL error:&errors];
NSLog( #"%#", errors );
[script executeAndReturnError:&errors];
NSLog( #"%#", errors );
}
I tested this without turning on sandboxing to verified it works and it did. Then I turned on Sandboxing and, of course, it broke. But, fortunately, there is a way around that. For now, Apple is providing a temporary entitlement called com.apple.security.temporary-exception.apple-events. And, you can request the exception be granted for 'com.apple.systemevents'. This is what my entitlements file looks like:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.temporary-exception.apple-events</key>
<array>
<string>com.apple.systemevents</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true />
</dict>
</plist>
Once I added this entitlement to my sandboxed app and signed it, it worked as expected again.
Now, if you want to send other keys, this question & answer will demonstrate how to build your script on the fly - Passing variables to an applescript.
Of course, once you have all of these working, you can probably turn to NSAppleEventDescriptor and related classes to build the event in code, but I haven't played with that technique.
Please note that Apple does suggest you do the following when using a temporary entitlement:
If you choose not to sandbox your app now or to use a temporary
exception entitlement, use Apple’s bug reporting system to let Apple
know about the issue you are encountering. Apple considers feature
requests as it develops the OS X platform. Also, be sure use the
Review Notes field in iTunes Connect to explain why the exception is
needed.
Related
I have a Xamarin iOS app that I am trying to distribute in the App Center. It will send out an email and install fine, but when you run it, you get the error
MyApp.iOS Wants to use "appcenter.ms" to sign in.
I have the option of cancelling or continuing. I hit continue and it signs in and says In-App Updates are enabled. It then returns to my app with the message:
In-App updates disabled.
This release was either side-loaded or downloaded using a browser in private mode.
I can either Ignore or Reinstall app. Ignore lets the app work, but it no longer checks for updates. If I Reinstall app, it opens App Center and I can install it, then it starts back at the beginning. It is using Safari to do the original install. I assume that when it does the Reinstall app from within my app, it is using a Safari based browser. Nothing is in private mode as far as I can tell. My startup code for App Center is
Distribute.UpdateTrack = UpdateTrack.Private;
Distribute.DisableAutomaticCheckForUpdate();
AppCenter.Start("11111111-2222-3333-4444-555555555555",
typeof(Analytics), typeof(Crashes), typeof(Distribute));
In my main view, I have the code
public override void ViewDidLoad()
{
base.ViewDidLoad();
Distribute.CheckForUpdate();
}
In my Info.plist I have
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>appcenter-11111111-2222-3333-4444-555555555555</string>
</array>
</dict>
</array>
Cookies are not disabled that I can tell. I have searched high and low and can't find anything like this. The only similar issue seemed to be someone messed up the Info.plist. Can anyone help?
OK, I finally figured this out. When I was testing the distribution of my app from the App Center, rather than spam the whole group until it worked, I just distributed it to myself. This is what caused the problem. What I had to do was to create another distribution group and only have myself in it. Automatic updates started working once I did this. The point being is that if you don't distribute it to a group, then it thinks it's side-loaded.
There are quite a few hints about how to keep programs alive, and restart them when they crash:
By using a shell script
By using launchd
They all have one restriction in common, though: They all need to be run before the to-be-monitored program.
In my case, though, I have a faceless background app that has to decide on its own whether it wants to be restarted in case it crashes. So, my app would be launched first and cannot be quit to become a child of a monitoring process (for explanation see below).
I've tried the launchd solution by writing a plist file like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>Label</key>
<string>com.mydomain.myapp.restartAfterCrash</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/MyApp.app/Contents/MacOS/MyApp</string>
</array>
</dict>
</plist>
It nearly does what I need, but in order to activate it from my app, by invoking it with launchctl load /path/to/file.plist, it wants to launch my app once more, so that my originally running app would have to quit to let the new instance run.
However, I cannot pass control to another instance of my app, because it's causing several new problems if the app was launched by double clicking a document the Finder or if it was launched by an AppleScript that wants to communicate further with my app. In those cases, my originally launched app must keep running, and thus the launchd method is not viable, nor is any other method that requires my app to run a new instance instead.
In short, are there other tested (reliable) methods that a Mac application can use to have itself restarted only if it crashes?
The only method I can think of is launching another faceless background application that monitors the first program's lifetime, e.g. via its PID.
I also wonder if it can be done with a simple shell command invocation that would periodically check whether my app is still alive, as those always run as a child process and would die along with the primary app, won't they?
I've updated XCode7 and like everyone, i have to amend a part of my code to be compliant with Swift2.
But i have a problem, when i m testing the app on the simulator i have no problem. But when i m trying directly on my real device (Iphone 5S IOS9), a black screen displays just with the level of the battery.
I have tried during 3 days to find something on stackoverflow, but nothing seems working.
This topic seems to be the same problem, but doen't work actually. IOS 7 launch image, displaying black screen on device ONLY
I' ve followed the topic iOS 9 Black Launch Screen but it doesn't bring any correct solution
Any idea, or help will be appreciated.
Its worked for me:
You can solve this problem using following steps :
First select root level of project and then go in General tab and Find that below blocks.
By default, in "Launch images Source" it shows "Use assets catalogs", click on it
It will ask you to "Migrate launch images to an asset catalog", simply click on "migrate".
Now, In same block in "Launch Screen file", remove default launch screen xib or storyboard. because we don't need to specify it. Just put blank on there.
Now it shows, "Brand Assets" in *launch Images Source", just click on right side arrow of it and set all your app launch screen assets with specific naming scheme.
Press "alt + cmd + shift + k". It will clean build folder of your application.
Now, build and run your app in device.
When your app connects to an Webserver or to a domain with localhost or non https means http , than post below into your info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>127.0.0.1</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
This let the app make an exception to use Urls without SSL / https.
I've embeded youtube videos in ios 8 many times using the following code (I intentionally replace the video code with ----). After upgrading to ios 9, the video no longer plays (go to a YouTube Help page title "Video player error message".
Does anyone know what changed in ios 9 and how to fix this?
NSString *EmbedCode = #"<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/-------\" frameborder=\"0\" allowfullscreen></iframe>";
[[self webviewer] loadHTMLString:EmbedCode baseURL:nil];
In iOS9 it is important to switch everything to HTTPS.
So I'm facing the same problems like you. Some videos are playing, some videos are not playing.
See Apple’s App Transport Security Technote for full details
(Source: WWDC 2015 session 703, “Privacy and Your App”, 30:18)
You can also ignore all app transport security restrictions with a single key:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
With adding the key everything works. But I think this is only a temporary solution. You don't know when apple starts rejecting this.
I also filed an issue at Google.
Had the same issue, but in the last few days, it has started to work on iOS 9 with no security exemptions. I think Google got their servers up to the required security levels.
XPC communication works fine when I launch the targets from my Xcode. But, when I manually launch the service and client apps by double clicking them on the icons, the connection invalidation message shows up.Whay do they work fine inside xcode and not from outside ?.What magic is Xcode doing here to make the communication work.
For all folks, who met the same problem using xpc_connection_create_mach_service: XPC works through a lot of launchd stuff; when we are debugging the app in xCode, it mediates the app and launchd connection, but without xCode we need to do it ourselves.
To get this alive, the one should start it through launchd using the launch plist file.
There is an example of such plist here, but it's not enough.
The trick is the MachServices key, which looks like:
<key>MachServices</key>
<dict>
<key>com.server.bundle-id</key>
<true/>
</dict>
This is the way we are creating the mach service, so I guess our XPC connection may have some mach port below it.