It's possible with CoreGraphics (CGEventPost
), it's a C API (it doesn't work in a Cocoa-AppleScript), but it's possible to call an executable from an AppleScript.
Here is the method to create the executable with Xcode (Version 8.3.3):
You can do it yourself (you can download Xcode from the App Store), or ask a trusted person to create the executable.
1- Open Xcode, select menu "File" --> "New" --> "Project..."
2- Select macOS and Command Line Tool, click on the "Next" button.
3- Name it TypeCharacters
, select Objective-C as Language, click on the "Next" button.
4- Save the project to the desired folder.
5- In the window of Xcode, select the main.m
icon, clear the text in the window and paste one of these two codes:
The code need a loop because of a bug, the CGEventKeyboardSetUnicodeString()
method truncates a string which exceeds twenty characters, or it's a limit (not documented).
This code use a loop to type a list of characters at each iteration, the list can contain one to twenty characters. (It's fast, 1 seconds to type 2400 characters in a TextEdit's document on my computer.)
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
if (argc > 1) {
NSString *theString = [NSString stringWithUTF8String:argv[1]];
NSUInteger len = [theString length];
NSUInteger n, i = 0;
CGEventRef keyEvent = CGEventCreateKeyboardEvent(nil, 0, true);
unichar uChars[20];
while (i < len) {
n = i + 20;
if (n>len){n=len;}
[theString getCharacters:uChars range:NSMakeRange(i, n-i)];
CGEventKeyboardSetUnicodeString(keyEvent, n-i, uChars);
CGEventPost(kCGHIDEventTap, keyEvent); // key down
CGEventSetType(keyEvent, kCGEventKeyUp);
CGEventPost(kCGHIDEventTap, keyEvent); // key up (type 20 characters maximum)
CGEventSetType(keyEvent, kCGEventKeyDown);
i = n;
[NSThread sleepForTimeInterval:0.004]; // wait 4/1000 of second, 0.002 it's OK on my computer, I use 0.004 to be safe, increase it If you still have issues
}
CFRelease(keyEvent);
}
}
return 0;
}
This code use a loop to type one character at each iteration (It's slower than the first code).
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
if (argc > 1) {
NSString *theString = [NSString stringWithUTF8String:argv[1]];
UniChar uChar;
CGEventRef keyEvent = CGEventCreateKeyboardEvent(nil, 0, true);
for (int i = 0; i < [theString length]; i++)
{
uChar = [theString characterAtIndex:i];
CGEventKeyboardSetUnicodeString(keyEvent, 1, &uChar);
CGEventPost(kCGHIDEventTap, keyEvent); // key down
CGEventSetType(keyEvent, kCGEventKeyUp);
CGEventPost(kCGHIDEventTap, keyEvent); // key up (type the character)
CGEventSetType(keyEvent, kCGEventKeyDown);
[NSThread sleepForTimeInterval:0.001]; // wait 1/1000 of second, no need of this line on my computer, I use 0.001 to be safe, increase it If you still have issues
}
CFRelease(keyEvent);
}
}
return 0;
}
Note : This code works on macOS Sierra and should work on El Capitan, but not on an older OS.
6- Select menu "Product" --> "Build".
7- Select the TypeCharacters
icon in the Product folder, right-click and select the "Show in Finder" menu in the contextual menu.
8- From the Finder, move the "TypeCharacters" file to the desired folder, quit Xcode, that's all.
From an AppleScript, call the executable, like this
set myString to "ùéèà ² ³ é ½ ₭ "
do shell script "'/full path/of/TypeCharacters' " & quoted form of myString