Skip to content

Instantly share code, notes, and snippets.

@industriousonesoft
Last active October 25, 2019 11:03
Show Gist options
  • Save industriousonesoft/2ca36453b41985201cd3d62fc5c5abb0 to your computer and use it in GitHub Desktop.
Save industriousonesoft/2ca36453b41985201cd3d62fc5c5abb0 to your computer and use it in GitHub Desktop.
Interact with the Reminders app in AppleScript
<?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.app-sandbox</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.scripting-targets</key>
<dict>
<key>com.apple.reminders</key>
<array>
<string>com.apple.reminders</string>
</array>
</dict>
<key>com.apple.security.temporary-exception.apple-events</key>
<array>
<string>com.apple.reminders</string>
</array>
</dict>
</plist>
//Privacy - AppleEvents Sending Usage Description
//Privacy - Reminders Usage Description
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSString *bunldeId = @"com.apple.reminders";
[self requestAppPermissonWithBunldeId:bunldeId completedHandler:^(BOOL success) {
if (success) {
[self interactWithTheMacBuildInRemindersAppinAppleScript:nil];
}else {
NSLog(@"Failed to request permission...");
}
}];
}
- (void)interactWithTheMacBuildInRemindersAppinAppleScript:(NSURL *)scriptURL {
// NSString *directory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
// NSURL *directoryURL = [NSURL fileURLWithPath:directory];
// NSURL *scriptURL = [directoryURL URLByAppendingPathComponent:@"InteractWithReminders.scpt"];
// NSString *source = @"tell application \"Reminders\"\nend tell";
NSString *source = @"tell application \"Reminders\"\n\
set reminderList to {}\n\
if (count of (reminders whose completed is false)) > 0 then\n\
set reminderList to name of reminders whose completed is false\n\
end if\n\
\n\
quit\n\
return reminderList\n\
end tell";
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:source];
NSDictionary *errorInfo = @{};
/*
NSLog(@"scriptURL => %@", scriptURL.path);
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithContentsOfURL:scriptURL error:&errorInfo];
if (errorInfo.count > 0) {
NSLog(@"1 - errorInfo => %@", errorInfo);
return;
}
*/
NSAppleEventDescriptor *eventDesc = [appleScript executeAndReturnError:&errorInfo];
if (errorInfo.count > 0) {
NSLog(@"2 - errorInfo => %@", errorInfo);
return;
}
if (eventDesc != NULL) {
if (kAENullEvent != [eventDesc descriptorType]) {
if (cAEList == [eventDesc descriptorType]) {
NSLog(@"result is a list of other descriptors");\
NSMutableArray *list = [NSMutableArray arrayWithCapacity:[eventDesc numberOfItems]];
for (NSInteger i = 0; i<[eventDesc numberOfItems]; i++) {
id theItem = [[eventDesc descriptorAtIndex:i+1] stringValue];
if (theItem)
[list addObject:theItem];
}
NSLog(@"%@", list);
}else {
NSLog(@"coerce the result to the appropriate ObjC type");
}
}
}else {
NSLog(@"no script result, handle error here");
}
}
- (void)requestAppPermissonWithBunldeId:(NSString *)bundleId completedHandler:(void(^)(BOOL success))compeletedHandler {
// [[[NSWorkspace sharedWorkspace] runningApplications] enumerateObjectsUsingBlock:^(NSRunningApplication * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
// if (obj.bundleIdentifier)
// }];
// [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"]];
[[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:bundleId options:NSWorkspaceLaunchDefault additionalEventParamDescriptor:nil launchIdentifier:nil];
NSAppleEventDescriptor * eventDesc = [NSAppleEventDescriptor descriptorWithBundleIdentifier:bundleId];
OSStatus status = AEDeterminePermissionToAutomateTarget(eventDesc.aeDesc, typeWildCard, typeWildCard, YES);
NSLog(@"status => %d", status);
switch (status) {
case noErr:
compeletedHandler(YES);
return;
case errAEEventNotPermitted:
break;
case errOSAInvalidID:
case errAEEventWouldRequireUserConsent:
case procNotFound:
break;
default:
break;
}
compeletedHandler(NO);
}
- (void)installAutomationScript
{
// NSError *error;
// NSURL *directoryURL = [[NSFileManager defaultManager] URLForDirectory:NSApplicationScriptsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];
NSString *directory = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0];
directory = [directory stringByAppendingPathComponent:@"Application Scripts"];
NSURL *directoryURL = [NSURL fileURLWithPath:directory];
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setDirectoryURL:directoryURL];
[openPanel setCanChooseDirectories:YES];
[openPanel setCanChooseFiles:NO];
[openPanel setPrompt:@"Select Script Folder"];
[openPanel setMessage:@"Please select the User > Library > Application Scripts > com.iconfactory.Scriptinator folder"];
[openPanel beginWithCompletionHandler:^(NSInteger result) {
if (result == NSModalResponseOK) {
NSURL *selectedURL = [openPanel URL];
if ([selectedURL isEqual:directoryURL]) {
NSURL *destinationURL = [selectedURL URLByAppendingPathComponent:@"InteractWithReminders.scpt"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSLog(@"destinationURL => %@", destinationURL);
NSURL *sourceURL = [[NSBundle mainBundle] URLForResource:@"InteractWithReminders" withExtension:@"scpt"];
NSError *error;
BOOL success = [fileManager copyItemAtURL:sourceURL toURL:destinationURL error:&error];
if (success || [error code] == NSFileWriteFileExistsError) {
NSString *bunldeId = @"com.apple.reminders";
[self requestAppPermissonWithBunldeId:bunldeId completedHandler:^(BOOL success) {
if (success) {
[self interactWithTheMacBuildInRemindersAppinAppleScript:destinationURL];
}else {
NSLog(@"Failed to request permission...");
}
}];
}else {
NSLog(@"%s error = %@", __PRETTY_FUNCTION__, error);
// the item couldn't be copied, try again
[self performSelector:@selector(installAutomationScript) withObject:self afterDelay:0.0];
}
}
else {
// try again because the user changed the folder path
[self performSelector:@selector(installAutomationScript) withObject:self afterDelay:0.0];
}
}
}];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment