Hello,
I have followed Bill Cheeseman sampe code “pairs” to script mu Objective C application called “SolarMaxOsX”
In Objective C code I have used message logs to understand what happens.
Below the error I get:
tell application "/Users/guydesbief/Library/Developer/Xcode/DerivedData/SolarMaxOsX-cgcuhyptmpmtiegixfnbbhpexjhn/Build/Products/Debug/SolarMaxOsX.app" to activate
-- delay 30
tell application "/Users/guydesbief/Library/Developer/Xcode/DerivedData/SolarMaxOsX-cgcuhyptmpmtiegixfnbbhpexjhn/Build/Products/Debug/SolarMaxOsX.app"
-- set nomAppli to the name of application
-- set theWindows to windows
class of onduleurs
count of onduleurs
-- get properties
set NbWin to the count of windows
set theWindow to first item of windows
properties of the theWindow
tell window "UPS Sumary"
--click on "Statistics button"
-- click on button 1 of theWindow
-- set enabled of button1 to true
end tell
get properties
get id of first onduleur of onduleurs
The results in appleScript:
tell application "SolarMaxOsX"
activate
get class of every onduleur
--> {onduleur, onduleur, onduleur}
count every onduleur of current application
--> 3
count every window of current application
--> 1
get item 1 of every window
--> window id 9796
get properties of window id 9796
--> {closeable:true, zoomed:false, class:window, index:1, visible:true, name:"UPS Sumary", miniaturizable:true, id:9796, miniaturized:false, resizable:true, bounds:{30, 28, 530, 576}, zoomable:true}
get properties
--> error number -10000
Résultat :
error "Erreur dans SolarMaxOsX : Le gestionnaire AppleEvent a échoué." number -10000
And the results of my logging in Objective C debugger:
2014-12-01 23:56:36.040 SolarMaxOsX[37551:303] Appdelegate handles onduleursArray
2014-12-01 23:56:36.040 SolarMaxOsX[37551:303] handles onduleursArray OK
2014-12-01 23:56:36.041 SolarMaxOsX[37551:303] Appdelegate handles onduleursArray
2014-12-01 23:56:36.041 SolarMaxOsX[37551:303] handles onduleursArray OK
2014-12-01 23:56:36.042 SolarMaxOsX[37551:303] Appdelegate handles orderedWindows
2014-12-01 23:56:36.042 SolarMaxOsX[37551:303] Appdelegate handles orderedWindows
2014-12-01 23:56:36.043 SolarMaxOsX[37551:303] Appdelegate handles orderedWindows
2014-12-01 23:56:36.043 SolarMaxOsX[37551:303] Appdelegate handles orderedWindows
2014-12-01 23:56:36.044 SolarMaxOsX[37551:303] Appdelegate handles scriptingProperties
2014-12-01 23:56:36.044 SolarMaxOsX[37551:303] Appdelegate handles classCode
2014-12-01 23:56:36.044 SolarMaxOsX[37551:303] Appdelegate handles onduleursArray
2014-12-01 23:56:36.045 SolarMaxOsX[37551:303] handles onduleursArray OK
2014-12-01 23:56:36.045 SolarMaxOsX[37551:303] Appdelegate handles terminologyVersion
2014-12-01 23:56:36.045 SolarMaxOsX[37551:303] Appdelegate handles version
2014-12-01 23:56:36.045 SolarMaxOsX[37551:303] Appdelegate handles name
2014-12-01 23:56:36.045 SolarMaxOsX[37551:303] Appdelegate handles isActive
2014-12-01 23:56:36.046 SolarMaxOsX[37551:303] An exception was thrown during execution of an NSScriptCommand…
2014-12-01 23:56:36.046 SolarMaxOsX[37551:303] Error while returning the result of a script command: the result object…
{
classCode = 1667330160;
isActive = 1;
name = SolarMaxOsX;
onduleursArray = (
“<Ups: 0x6000002c0bd0>”,
“<Ups: 0x6100002c24c0>”,
“<Ups: 0x6000000df100>”
);
terminologyVersion = 1;
version = “1.1”;
}
…could not be converted to an Apple event descriptor of type ‘application properties’. The ‘onduleursArray’ entry could not be converted to an Apple event descriptor of type ‘onduleur’. This instance of the class ‘__NSArrayM’ returned nil when sent -objectSpecifier (is it not overridden?) and there is no coercible type declared for the scripting class ‘onduleur’.
It seems that my objectSpecifier method in Ups Category (or Ups class) is never called
My sdef File:
<suite name="SolarMax Suite" code="SMap" description="Apple Events supportés par SolarMaxOsX">
<!-- suppress warning for missing "savable file format" type -->
<enumeration name="savable file format" code = "savf" hidden="yes">
<enumerator name= "dummy" code="VTdm"
description="A dummy file format."/>
</enumeration>
<class name="application" code="capp" description="SolarMaxOsX's top level scripting object." plural="applications" inherits="application">
<cocoa class="NSApplication"/>
<property name="onduleurs" code="SMor" description="Array of onduleurs." access="r">
<type type="onduleur" list="yes"/>
<cocoa key="onduleursArray"/>
</property>
<property name="name" code="pnam" description="The name of the application." type="text" access="r"/>
<property name="frontmost" code="pisf" description="Is this the frontmost (active) application?" type="boolean" access="r">
<cocoa key="isActive"/>
</property>
<property name="version" code="vers" description="The version of the application." type="text" access="r"/>
<property name="terminology version" code="TEvn" type="integer" access="r">
<cocoa key="terminologyVersion"/>
</property>
</class>
// Class SolarMaxOsX to access to first window
<class name="SolarMaxOsX" code="SMos" description="main window in SolarMaxOsX.">
<cocoa class="SolarMaxOsX" />
Categories for all classes in he same file:
/
// SolarMaxOsX+AppleScriptExtensions.m
// SolarMaxOsX
//
// Created by Guy DESBIEF on 28/11/2014.
//
//
#import “AppDelegate+AppleScriptExtensions.h”
#import “Ups.h”
@implementation NSObject (MNscriptability)
(void) returnError:(int)n string:(NSString*)s {
NSScriptCommand* c = [NSScriptCommand currentCommand];
[c setScriptErrorNumber:n];
if (s)
[c setScriptErrorString:s];
}
@end
@implementation AppDelegate (AppleScriptExtensions)
#define APPLESCRIPT_TERMINOLOGY_VERSION 1
#pragma mark ACCESSOR METHODS
-(NSNumber *) terminologyVersion {
return [NSNumber numberWithInt:APPLESCRIPT_TERMINOLOGY_VERSION];
}
// For appleScript recognition
-(NSUInteger) countOfOnduleursArray
{
MyLog(@“countOfOnduleursArray”);
return [self.onduleursArray count];
}
(Ups *) objectInOnduleursArrayAtIndex : (int) index {
MyLog(@“objectInOnduleursArrayAtIndex %index”, index);
Ups *upsItem = [self.onduleursArray objectAtIndex:index];
if (upsItem != nil)
{
return upsItem;
} return nil;
}
(Ups *) valueInOnduleursArrayAtIndex:(unsigned int)i {
MyLog(@“valueInOnduleursArrayAtIndex %i”, i);
if (![[NSScriptCommand currentCommand] isKindOfClass:[NSExistsCommand class]])
if (i >= [onduleursArray count]) {
[self returnError:errAENoSuchObject string:@“No such Ups.”];
return nil;
}
MyLog(@“valueInOnduleursArrayAtIndex index OK: %i”, i);
return [onduleursArray objectAtIndex: i];
}
(BOOL)application: (NSApplication *) sender delegateHandlesKey:(NSString *)key {
MyLog(@“Appdelegate handles %@”,key);
if ([key isEqualToString: @“terminologyVersion”]) return YES;
if ([key isEqualToString: @“onduleursArray”]) {
MyLog(@“handles %@ OK”,key);
return YES;
}
return NO;
}
@end
@implementation Ups (AppleScriptExtensions)
(NSUniqueIDSpecifier *) objectSpecifier
{
MyLog(@“objectSpecifier (UPS) OK”);
return [[NSUniqueIDSpecifier allocWithZone:[self zone]]
initWithContainerClassDescription: (NSScriptClassDescription *)[NSApp classDescription]
containerSpecifier: nil
key: @“onduleursArray”
uniqueID: uniqueID];
}
@end
and category .h file:
/
// SolarMaxOsX+AppleScriptExtensions.h
// SolarMaxOsX
//
// Created by Guy DESBIEF on 28/11/2014.
//
//
#import <Foundation/Foundation.h>
#import “AppDelegate.h”
@class AppDelegate;
@class Ups;
@interface NSObject (MNscriptability)
(void) returnError:(int)n string:(NSString*)s;
@end
@interface AppDelegate (AppleScriptExtensions)
#ifdef NDEBUG
#define MyLog(f, …)
#else
#define MyLog(f, …) NSLog(f, ## VA_ARGS )
#endif
(BOOL)application: (NSApplication *) sender delegateHandlesKey:(NSString *)key;
(NSUInteger) countOfOnduleursArray;
(Ups *) objectInOnduleursArrayAtIndex: (int) index;
(Ups *) valueInOnduleursArrayAtIndex:(unsigned int)i;
//- (NSScriptObjectSpecifier *) objectSpecifier;
#pragma mark ACCESSOR METHODS
-(NSNumber *) terminologyVersion;
@end
@interface Ups (AppleScriptExtensions)
//- (NSString *) onduleurName;
//- (NSString *) onduleurUniqueID;
(NSUniqueIDSpecifier *) objectSpecifier;
//- (BOOL)application: (NSApplication *) sender delegateHandlesKey:(NSString *)key;
@end
The Delegate for application
in AppDelegate.m
/*
File: AppDelegate.m
Abstract: The sample’s application delegate object.
Version: 1.0
*/
#import “AppDelegate.h”
#import “scriptLog.h”
NSString * const DefaultApplicationExtensionPathKey = @“SolarMaxPath”;
NSString * const DefaultDataBaseNameKey = @“SqliteDatabaseName”;
NSString * const DefaultUpsFileNameKey = @“UpsListFileName”;
@implementation AppDelegate
@synthesize onduleursArray;
@synthesize myWindowController;
@synthesize myUpsDefineWindowController;
@synthesize uniqueID;
in AppDelegate.h:
/*
File: AppDelegate.h
Abstract: application delegate object.
Version: 1.0
Project: SolarMaxOsX
Created by Guy Desbief on 10/12/11.
Copyright 2011 All rights reserved.
*/
#import <Cocoa/Cocoa.h>
#import “SolarMaxMain.h”
#import “SolarMaxStatusData.h”
#import “Ups.h”
#import “UpsData.h”
#import “SolarMaxOsX.h”
#import “SolarMaxOsXProtocol.h”
@interface AppDelegate : NSObject
{
NSMutableArray *onduleursArray;
SolarMaxOsX *myWindowController;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
UpsDefineWindowController * myUpsDefineWindowController;
NSString *uniqueID;
}
@property (nonatomic, assign) NSMutableArray * onduleursArray;
@property (nonatomic, retain) SolarMaxOsX *myWindowController;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, assign)UpsDefineWindowController * myUpsDefineWindowController;
@property (nonatomic, assign) NSString * uniqueID;
(IBAction)openReadMe:(id)sender;
(NSMutableArray *)initUpsArray;
(void) saveAction;
(void) manageConfigureWindow;
(void) requestToRelaunch;
(void)applicationDidFinishLaunching:(NSNotification *)notification;
(void)applicationWillTerminate:(NSNotification *)aNotification;
(NSURL *) getCompletePathForUpsFile;
@end
[b]I wonder if there is not a coercion to make between AppleScript onduleur class to real Objective C Ups class
Thanks for your answers[/b]