Re: AppleEvents: Send port for process has no send right, port=( port:37207/0x9157 rcv:1,send:0,d:0 limit:5) (findOrCreate()/AEMachUtils.cp #526)
John MacMullin wrote: > Anyone have an idea of what is causing this message in the log file? > > AppleEvents: Send port for process has no send right, port=( port:37207/0x9157 rcv:1,send:0,d:0 limit:5) (findOrCreate()/AEMachUtils.cp #526) Nope, although you're obviously not the only one. Given what an ill-documented pig the Apple event stack is (and this error is way down where it bridges to Mach messages, where even more dragons lie <https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/KernelProgramming/Mach/Mach.html>), you might want to go straight for a TSI <https://developer.apple.com/support/technical/> and see if that does any good. No guarantees - I think there's very few folk at Apple these days who give a crap about this stuff, and even fewer who know what they're doing - but if they do give a useful response it will save no end of time and frustration. > I am using scripting bridge for several Apple program interfaces. Essential troubleshooting steps for any Apple event-based IPC problem: 1. If your apps are sandboxed, disable it and see if that makes any difference. 2. If you're using Scripting Bridge or JavaScript for Automation, rewrite the relevant code in AppleScript, which is the de facto standard, and try that: * If it works in AppleScript then the problem is that SB/JXA are crappy broken junk which don't speak Apple events correctly/competently, in which case stick to using AppleScript. (It may be a rotten language, but it's the only _supported_ option that does Apple event IPC right.) FWIW, the AppleScript-ObjC bridge takes most (though not all) of the pain out of bridging between the two: Shane Stanley's the go-to guy for ASOC questions, and there's a brief how-to here: <http://appscript.sourceforge.net/asoc.html>. * If it doesn't work in AppleScript, then the problem is down in the OS, at which point all you can do is dig the web to see if anyone else has gotten a solution, or put in a TSI and hope it won't just be a waste of a perfectly good ticket. 3. If you've got some cases that are working and some that aren't, you could try running with `AEDebug` options enabled <https://developer.apple.com/legacy/library/documentation/AppleScript/Conceptual/AppleEvents/AppleEvents.pdf > and see if you can spot discrepancies in the logged messages that might give clues. At the least, it'll give you more data to include in your ticket in case they can't replicate it themselves. HTH has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Scripting Bridge Question
Dave wrote: > I’m using the Scripting Bridge to Target MS Outlook. I’m trying to figure out how to do the following AppleScript using the Scripting Bridge. Please see Full Script below, I’ve got most of the code, but I can’t seem to figure out the right Objective-C code for these two statements: Scripting Bridge doesn't work properly; never has, never will. According to the Apple developer that wrote it, it wasn't designed to work with Carbon apps (which is funny cos it doesn't work right with Cocoa ones either). Maybe your AS code will translate; maybe it won't. Maybe it'll work, maybe it won't. If it doesn't, you'll have zero clue why. For anything non-trivial, you're best sticking to AppleScript: it's the ONLY[1] solution that actually works right. Since you're using ObjC/Cocoa and already have a working AppleScript implementation, the neatest solution is to use the AppleScript-ObjC bridge to call your AppleScript code directly. Just wrap your AS code as handlers in script objects that inherit from NSObject, and you can call them pretty much as you would native ObjC methods. Quick how-to here: http://appscript.sourceforge.net/asoc.html HTH has -- [1] Specifically, it's the only *currently supported* solution that works right. I no longer support appscript, am not going to waste anyone's time promoting AppleEventBridge (which I only did in a failed attempt to prevent the Automation team screwing up JavaScript too), and I'm not interested in finishing/supporting SwiftAE unless Apple can be persuaded to adopt it for OS X. If anyone here still cares about Mac Automation, please feel free to contact me off-list with any advice/criticism/encouragement/support. http://appscript.sourceforge.net https://bitbucket.org/hhas/appleeventbridge https://bitbucket.org/hhas/swiftae (docs: http://hhas.bitbucket.org) ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Scripting Bridge Question
Dave wrote: > Ok, I hear what you are saying but I’ve almost got it working as it is and what I’m doing is not that difficult and I should be able to do it in the Scripting Bridge Only if SB lets you do it. There's lots of stuff that works perfectly in AS that you *cannot do* in SB because SB is crippled and broken *by design*. (I've long since stopped counting. Any AE bridge that pukes its guts out at mere sight of InDesign simply isn't fit for use.) Unfortunately, I have no experience scripting Outlook so cannot tell you offhand how - or even if - you can do it in SB. One thing I can say is that your AS code looks a bit odd and non-idiomatic itself (though that is often the case with Office apps as their Apple event interfaces are weird and cranky as hell): set myObjectID to the id of (object of myWindow) set myContent to the plain text content of message id myObjectID In a standard Apple Event Object Model, an `id` value is a unique identifier for a single object; thus, a by-id specifier, which is what `message id ...` is roughly analogous to a managed pointer. So I wouldn't normally expect to be able to take the id of a window object and use it as the id of a message object; but then, like I say, Office apps' AE interfaces aren't exactly standard. Oh, and realize SB is spectacularly bad at coping with the more "eccentric" scriptable apps, so it may not be possible to do the same thing in SB. If so, you won't be the first person who's had to fall back to AS for some things, or just abandon SB completely. HTH has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
o Swift generics, y no can I haz u dispatch correctly?
Hi all, So, as part of my ongoing quest to discover all the exciting ways in which Swift can perplex and frustrate me†, I'm trying to solve the last major blocker on my SwiftAE project (https://bitbucket.org/hhas/swiftae), which is how to use Swift's static typing to determine how NSAppleEventDescriptors are unpacked. The ideal solution would be to define each application command as a generic method like this: func someCommand(ARGS) -> T { let resultDesc = self.appData.sendAppleEvent(ARGS) // unpack() should introspect T and use that information to coerce // resultDesc to the corresponding AE type before unpacking it: let result = self.appData.unpack(resultDesc, returnType: T.self) return result as! T } and define a non-generic `AppData.unpack()` method that uses introspection to pull the `returnType` argument to bits. Alas, Swift 2's type introspection sucks absolutely monkey nuts, so AFAIK it currently isn't possible to pull apart parameterized types such as Array to see how they're constructed. (Except, perhaps, by getting and parsing its string representation (euwww) and I'm not quite that desperate yet.) So, as a workaround, I've been trying to overload my `unpack` methods so that the generics system pulls apart the Swift type for me. For atomic types (Bool, Int, String, NSURL, etc) this approach works fine: I can just use a big ol' conditional/switch to test if T.self==Bool.self, T.self==Int.self, etc. and use that to coerce and unpack AEDescs which are similarly atomic (typeBoolean, typeInteger, etc). The problem is how to do the same for Array<> and Dictionary<> types, since to unpack the corresponding typeAEList and typeAERecord AEDescs we also need to know the type(s) of the Array/Dictionary elements. For example, if the user writes: let result = appObj.someCommand as Array then T will be Array, so the resultDesc should be coerced to typeAEList and each of its items should be coerced to typeUnicodeText before unpacking it as the specified Swift types. After a few attempts, I finally found the following overloaded `unpack` methods †† seemed to distinguish between atomic and non-atomic Swift types: class AppData { // unpack sequence type (e.g. Array) func unpackT.Generator.Element>(desc: Any, returnType: T.Type) -> T { print("unpack sequence of \(U.self)") return desc as! T } // unpack atomic type (e.g. String) func unpack(desc: Any, returnType: T.Type) -> T { print("unpack atomic value \(T.self)") return desc as! T } } This works exactly as intended when `AppData.unpack()` is called directly: let d = AppData() d.unpack([1,2], returnType: [Int].self) // correctly calls `unpack<T:SequenceType…>()` The problem is, it all falls apart again when `AppData.unpack()` is called from another generic method: class Commands { func get(v:Any) -> T { return d.unpack(v, returnType: T.self) as T } } Commands().get([3,4]) as [Int] // incorrectly calls `unpack()` Dunno why, but this time the Swift compiler picks the less specific `unpack` implementation instead of the one that's got SequenceType stamped all over its signature. (Bet Dylan never had this problem...) Mind, it still wouldn't be the end of the world if Swift only let us express constraints such as this: // unpack atomic type (e.g. String) func unpack(...) -> T { ... } but alas, once again we hit the point where Swift's type system stops pretending to be a formal set algebra and proves to be just another bunch of ad-hoc compiler kludges in the grand old tradition of C. Adding another `returnType` parameter and plastering the calling code with ludicrous amounts of type info makes absolutely no difference either: class Commands { func get(v:Any, returnType: T.Type) -> T { return d.unpack(v, returnType: T.self) as T } } let result: [Int] = Commands().get([3,4], returnType: [Int].self) as [Int] // still incorrectly calls `unpack()` Whatever it was that made `unpack(desc, returnType:)` work the first time around appears to be a one-trick pony. So I'm kinda jiggered again by the complexities and vagaries of SwiftLang... (and this is even before I start thinking about how the smoking hell I'll ever handle sum types, as it's not uncommon for application commands to return more than one possible type of value). So please please please, anyone got any ideas, answers, magic, etc? (Swift engineers particularly - after all, this is a great opportunity to kick its tyres and figure how to make it more robust and less ornery.) Many thanks, has † This damn project is taking me far too long to complete, and it's got me cursing Swift as much
[postscript] Re: Swift generics, circular type declarations, and segfaults, oh my!
Quick follow-up for anyone interested... On Sep 8, 2015, at 5:45 PM, has <hengist.p...@virgin.net <mailto:hengist.p...@virgin.net>> wrote: I will need to spend some more time building it out and testing it, but (touch-wood) it looks like the problem might be cracked at last. Wahey! So, my first attempt to replace all my base classes with protocol extensions failed fairly quickly: trying to move instance vars and non-convenience inits into protocol extensions is a recipe for madness. However, my second attempt, where I retain the main base classes and move only the 'factory' vars/methods to protocol extensions did eventually yield successful (if slightly convoluted and confusing) results: https://bitbucket.org/hhas/swiftae/ Next up, trying to wrangle the inconsistencies and aggravations of Swift's object/non-object and type systems into something that actually works right. Wish my teeth luck - with the amount of enamel left, they will need it. :p Thanks again, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift generics, circular type declarations, and segfaults, oh my!
On 07/09/2015 02:11, Jonathan Hull wrote: I am wondering if the compiler feature which might allow this (and several other things) would be to allow implementors of a protocol to adhere to it with a more restrictive type (either a subclass or an implementer/inheritor of a returned protocol). For example: protocol Thing { var noise:String {get} } protocol MyProtocol { func returnAThing()->Thing } class SquishyThing:Thing { var noise:String {return “Squish”} var squishiness:Int = 3 } class PoppingThing:Thing { var noise:String {return “Pop”} var poppability:Float = 4.2 } class SquishyVendor:MyProtocol { func returnAThing()-> SquishyThing {return SquishyThing()} } class PoppingVendor:MyProtocol { func returnAThing()-> PoppingThing {return PoppingThing()} } This would allow you to say things like: mySquishyVendor.returnAThing.squishiness = 6 myPoppingVendor.returnAThing.poppability = 2.8 (Think you meant `mySquishyVendor.returnAThing().squishiness`, etc.) instead of: (mySquishyVendor.returnAThing as! SquishyThing).squishiness = 6 (myPoppingVendor.returnAThing as! PoppingThing).poppability = 2.8 Is there an obvious problem caused by this which I am missing? I can think of 3 or 4 places where it would shrink my code quite a bit. Looking at it in terms of set theory, your returnAThing()->SquishyThing only returns a subset of all possible Things, so in that respect it does contradict the protocol's promise to return a value in the set of all Things. OTOH, if you're asking what interface is available, it doesn't seem entirely unreasonable to gather all the available type information and use whatever is most precise in a given situation. It may just be that the type system syntax as used in your protocol needs to be more expressive, allowing you to to say 'all results ⊆ all Things'. I'm not a type theorist though. You might be better off asking over on the Lambda the Ultimate forums (http://lambda-the-ultimate.org/) or some place like that. has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift generics, circular type declarations, and segfaults, oh my!
On 06/09/2015 21:50, Charles Srstka wrote: On Sep 6, 2015, at 3:19 PM, Quincey Morris <quinceymor...@rivergatesoftware.com <mailto:quinceymor...@rivergatesoftware.com>> wrote: (But merely defining a protocol for each of your subclasses is not an improvement here.) It does, however, seem to avoid the crash: class ObjectBase { required init() {} } protocol MyProtocol { func foo() func bar() func baz() } class MyObject: ObjectBase, MyProtocol { func foo() { print("foo") } func bar() { print("bar") } func baz() { print("baz") } required init() {} } let obj = MyObject() compiles and runs without errors. Unfortunately, that doesn't help here since MyObject's methods need to return instances of the parameterized type. That's the bit that's causing the crashes. e.g. This test case compiles successfully, but crashes at runtime on instantiating YourObject: class MyObject { required init() {} func foo() -> T { return self.dynamicType.init() as! T } } class YourObject: MyObject { required init() {} } let obj = YourObject() (It's not a realistic example as I need to return types other than Self, but if it had worked I might've used it as a starting point for figuring out a solution.) This expresses my requirements, but won't compile because the compiler doesn't know what initializers T implements without more information: class MyObject { required init() {} func foo() -> T { T() } } class YourObject: MyObject { required init() {} } let obj = YourObject() But after adding a protocol to supply this information, SourceKit and swiftc crash upon reading the code: protocol Object { init() } class MyObject { required init() {} func foo() -> T { T() } } class YourObject: MyObject, Object { required init() {} } let obj = YourObject() As suggested, I'm going to write these up as a radar ticket. Thanks, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift generics, circular type declarations, and segfaults, oh my!
On 06/09/2015 21:19, Quincey Morris wrote: I'm getting that sinking Radar feeling too. But since I'm relatively new to Swift, I'm just holding out a vain hope that there's some sort of solution that's embarrassingly obvious to everyone else but me. I’ve been thinking about the implications of this for a couple of days now. Of course, you should file a Radar if you see some compiler behavior that looks like it ought to work. But I think there’s a higher order problem that’s worth noting. In my experience (which is to say, after a couple of months spent converting a fair-sized app from Obj-C to Swift), converting an Obj-C implementation to directly an “equivalent” Swift implementation is a lousy experience with poor results. Yeah, don't worry about that; it's not my first port project.:) It's already been heavily redesigned in order to simplify the implementation, and there's lots of reworking to tie it into Swift's static typing. Ironically, it's trying to Swiftify it that's causing all the pain. I'd already be done if I'd just stuck to using a single glue class as a dumb 'implements all operations, whether appropriate or not' wrapper around the real mechanics (as the prototype does), rather than have the type system intelligently enforce the rules on which operations can be performed on what (which requires more complex class and protocol structures, and circular type references). Anyway, I think this pretty much wraps it up: Swift's type system is not (yet?) as great as it ought to be (but that's maybe not surprising as the language is still not properly baked) and just isn't going to cooperate at this point. So I guess it's Plan B for now: forget about generics-based reusability, and just duplicate (ugh) all the base methods within the code-generated glues and put the correct signatures on those. What matters most is that the UX works; code purity will just have to wait. Many thanks to all, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift generics, circular type declarations, and segfaults, oh my!
On 08/09/2015 16:38, Charles Srstka wrote: On Sep 8, 2015, at 4:18 AM, has <hengist.p...@virgin.net <mailto:hengist.p...@virgin.net>> wrote: But after adding a protocol to supply this information, SourceKit and swiftc crash upon reading the code:[...] That’s true; however, adding a second “YourObjectProt" protocol, making YourObject conform to it, adding all of YourObject’s methods into the protocol, and using YourObjectProt as the parameter instead of YourObject, will solve the issue. (Bear in mind the goal is for the glue to declare the correct return types on the library class's methods. Your previous example passed a protocol to the generic BaseObject class, but your foo/bar/baz functions never used it as they don't return anything.) Ok, so trying this: class ObjectBase { required init() {} func foo() -> T.FooType { return T.FooType.init() } } protocol MyProtocol { typealias FooType func foo() -> FooType } class MyObject: ObjectBase, MyProtocol { typealias FooType = MyObject required init() {} } let obj = MyObject() I get a compiler error on the foo function's return type: 'FooType' is not a member type of 'T'. Probably just wishful thinking, that one, so let's not dwell on it. Next, trying to move the base functions into a protocol extension (which use typealiases instead of generics): protocol Init { init() } protocol BaseProtocol { typealias FooType: Init func foo() -> FooType } extension BaseProtocol { func foo() -> FooType { return FooType() } } class MyObject: BaseProtocol { typealias FooType = MyObject required init() {} } let obj = MyObject() Code looks promising, but the compiler complains "Type 'MyObject' does not conform to protocol 'BaseProtocol'." Nuts. Any ideas? Have I just missed something obvious? Swift wants you to use protocols rather than objects anyway, so perhaps the way to go is to put all the logic in the protocols and protocol extensions, and make MyObject, YourObject, etc, just bare-bones objects (or structs) that just belong to the protocol and don’t do anything else. Yeah, the goal is for each app-specific glue to subclass the concrete library classes (which provide the query-building and AE dispatch services using raw four-char codes, and already work nicely in themselves), then use protocol extensions to add the app-specific vars/funcs into those. So I don't have a problem with mixing-in the base functionality as well; just wish swiftc felt the same way as well. :p Thanks, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift generics, circular type declarations, and segfaults, oh my!
On 08/09/2015 23:06, Charles Srstka wrote: On Sep 8, 2015, at 4:43 PM, has <hengist.p...@virgin.net <mailto:hengist.p...@virgin.net>> wrote: Yeah, the goal is for each app-specific glue to subclass the concrete library classes (which provide the query-building and AE dispatch services using raw four-char codes, and already work nicely in themselves), then use protocol extensions to add the app-specific vars/funcs into those. So I don't have a problem with mixing-in the base functionality as well; just wish swiftc felt the same way as well. :p Perhaps you don’t need to provide concrete library classes at all, but simply ask your app-specific glue to implement your protocols instead of subclassing anything? Quite possibly, if I can get all the standard functionality to fit nicely into protocol extensions, I don't have a problem with the library just providing the general building blocks and the glue code generator creating the actual classes. Oh, and I've just figured why Swift was complaining that the MyObject 'glue' class didn't implement BaseProtocol - it's because its error messages are kinda crappy, and what it actually meant was that MyObject needs to implement the Init protocol too (since the typealias in the BaseProtocol uses Init as a constraint). Et voila, code that compiles and runs, seemingly without cratering, since typealiases in protocols appear to be rather less intolerant of circular referencing than generic classes: // library protocol Init { init() } protocol BaseProtocol { typealias ObjectType: Init typealias ElementsType: Init func newObject() -> ObjectType func newElements() -> ElementsType } extension BaseProtocol { func newObject() -> ObjectType { return ObjectType() } func newElements() -> ElementsType { return ElementsType() } } // glue class MyObject: BaseProtocol, Init { typealias ObjectType = MyObject typealias ElementsType = MyElements required init() {} } class MyElements: MyObject { } // test let obj = MyObject() print(obj.newObject()) // MyObject print(obj.newElements()) // MyElements I will need to spend some more time building it out and testing it, but (touch-wood) it looks like the problem might be cracked at last. Wahey! Many, many thanks (you've no idea how nuts this has been driving me), and fingers crossed I'll have a nice shiny new Apple event bridge to sell y'all shortly. :) has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift generics, circular type declarations, and segfaults, oh my!
On 05/09/2015 07:07, Charles Srstka wrote: On Sep 4, 2015, at 7:59 PM, Quincey Morris <quinceymor...@rivergatesoftware.com <mailto:quinceymor...@rivergatesoftware.com>> wrote: On Sep 4, 2015, at 16:31 , has <hengist.p...@virgin.net <mailto:hengist.p...@virgin.net>> wrote: At risk of derail... Do you mean “derail” or “detail”? I feel like I’m drowning in details. Yeah, this is why I kept the original posts light on specifics. Obviously adding these details didn't help clarify at all - but see Charles' final paragraph below. What I mean is, in: TextEdit().documents[1].text.words.get() the instances represented by ‘TextEdit()’, 'TextEdit().documents[1]’, 'TextEdit().documents[1].text’ are just setting the context for what the instance represented by 'TextEdit().documents[1].text.words’ is being asked to retrieve. Basically. Each of those intermediates describes a valid query in itself; you just keep chaining var/method calls until you build up the query you actually want. Internally, it's just adding to a linked list of AE records (in pseudocode): [every word [text [document 1 [application "TextEdit" The final 'get' command packs that query into a 'getdata' Apple event and sends it off to the app to evaluate. Kinda like sending XPath queries over XML-RPC. The way I’m reading it, he or she is wrapping an application’s scripting dictionary, creating a Swift object to wrap each construct that would represent a noun, so to speak, in AppleScript. However, these entities are expensive to obtain, involving IPC, so s/he’s loading them lazily. Nope (he). Apple event IPC isn't a proxy object-based system like DO; it's not OOP at all. (Dictionaries are a lie.) The AE bridge only models queries, not 'classes'. So I only need to define a few classes, one to represent each type of query: root node, one-to-one relationship, one-to-many relationship, insertion point. What this means is that the objects are all going to have some number of properties that, when the user accesses them, will necessitate creating a new wrapper object. Yes. And because some properties (vars) represent one-to-one relationships, others represent one-to-many, they need to instantiate different query classes: ObjectSpecifier/ElementsSpecifier. Which is why I can't just use Self - e.g. the ObjectSpecifier representing the 'text' property needs to return an ElementsSpecifier to represent the 'words' elements. I’m not the most knowledgeable about AppleScript, but what it sounds like from s/he’s saying is that the relationships between the AppleScript objects fall into three main categories, and for each type of object, there will be only one specific class to which each of the three relationships can point, so the object should be representable by a Swift generic with three parameterized types. However, if an object points to more of the same type of object, this results in something like Foo, and this causes either the compiler or the runtime to crash since it’s apparently not built to handle a generic being passed an object of its own type (honestly, this sounds like something warranting a Radar). S/he is asking if anyone knows of any way around this. Yes! Exactly this. And yeah, I'm getting that sinking Radar feeling too. But since I'm relatively new to Swift, I'm just holding out a vain hope that there's some sort of solution that's embarrassingly obvious to everyone else but me. Thanks, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift generics, circular type declarations, and segfaults, oh my!
On 03/09/2015 19:57, Quincey Morris wrote: On Sep 3, 2015, at 11:16 , has <hengist.p...@virgin.net <mailto:hengist.p...@virgin.net>> wrote: * Using an instance as a factory for its own class is contrary to general usage, so is a smell at best. It’s a job for a class func. No, it's fine. It's for an Apple event query builder. Any odd smells are probably the Apple event architecture's doing. Huh? Why is it fine to create an additional unnecessary object? And what has this got to do with Apple events? At risk of derail... Apple event queries (object specifiers) are constructed as linked lists. I'm just putting a high-level user-friendly wrapper around that. Either the wrapper vends a new object each time the list is appended to, or it creates a single wrapper object that appends the list internally. The first approach is simpler and safer to use since there's no mutable state, and the cost of instantiating a few additional objects is trivial compared to the time it takes to send an AE and receive a reply, so I'm not worried about that. It's a tested, proven design - if you really want to understand it in detail then I suggest installing the original Python version (http://appscript.sourceforge.net/) and working through the tutorial. My concern here is how to implement a Swift version, which means leveraging the Swift type system as much as practical and fighting it as little as I can. The Swift prototype (https://bitbucket.org/hhas/appleeventbridge/) currently uses a very simple class hierarchy consisting of a per-application code-generated Specifier class that inherits from a standard library-supplied base class: AbstractBase // defines standard functionality Specifier // adds app-specific properties, elements, commands, and standard selectors Since there's only one concrete Specifier class, methods (and vars) that return new Specifier instances, standard methods inherited from AbstractBase can just declare their return type as 'Self', and the compiler will figure out the correct return type automatically. The downside of the above approach is that not all specifier types (insertion, object, elements, etc.) support the same features, so some of the exposed's methods won't always work. It'd be better to represent each type of specifier as a different subclass that exposes only those methods that are valid on it, making invalid calls impossible: AbstractBase // defines standard functionality AbstractSpecifier // adds app-specific commands InsertionSpecifier ObjectSpecifier // adds app-specific properties and elements ElementsSpecifier // adds standard selectors The catch is that I can no longer declare all methods' return types as 'Self', because they now return several (albeit related) types. ObjectSpecifiers need to vend InsertionSpecifiers, ObjectSpecifiers and ElementsSpecifiers. ElementsSpecifiers need to vend ObjectSpecifiers and ElementsSpecifiers. And each scriptable application needs its own code-generated versions of these classes too. The code generator can insert the correct type for app-defined vars, but the standard inherited methods can only (afaik) specify the correct return type if they're defined as a generic class, allowing the exact types to be supplied as parameters: class AbstractBase<InsertionType,ObjectType,ElementsType> { } thus allowing each application glue to parameterize that class with its own exact types, e.g.: AbstractBase<FinderInsertion,FinderObject,FinderElements> Which takes us back to the problem described in my previous email, where the Swift compiler and runtime don't seem to like this circular referencing of related type names very much. Worst comes to the worst, I'll just have to throw _everything_ into the code generator, but that offends even my slobbish nature, so if there's a way to keep the standard functionality in a generic base class without Swift puking on it. Chained var/method calls let you build and send AE queries using a non-atrocious syntax, e.g.: let result: [String] = try TextEdit().documents[1].text.words.get() Again: huh? Where’s the factory method in this? You're looking at them (this is why I prefer not to use GoF jargon myself). The `documents` var returns a new elements specifier, `[1]` returns a new object specifier, `text` returns a new object specifier, `words` returns a new elements specifier. Very easy to use, just a pain to explain how to implement. :p Thanks, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Swift generics, circular type declarations, and segfaults, oh my!
Hi all, Stuck and looking for ideas here. I need to define a base class whose methods vends instances of its subclasses (thus enabling chained method calls; your basic query builder). Trivial to do in untyped languages like Python (where 'type safety' is a matter of mopping up _after_ the runtime craters): #!/usr/bin/python class ObjectBase: def makeNewObject(self): return self.__class__() class MyObject(ObjectBase): def foo(self): print("foo") print(MyObject().makeNewObject()) # result is new MyObject instance MyObject().makeNewObject().foo() # prints "foo" It's even somewhat doable in ObjC, as `instancetype` declares the return type to the type system without having to state an exact type: @implementation ObjectBase -(instancetype)makeNewObject { return [[self.class alloc] init]; } @end Although that only works when returning instances of the _same_ class; there's no way to express that it'll return a different type that only the subclass knows about, e.g.: @implementation ObjectBase typealias Other = OtherSubclass -(instancetype.Other)makeNewObject { // wishful thinking return [[self.class alloc] init]; } @end Swift though? Can't even get that far. Giant headaches all round. Creating new instances in itself is not a problem as we can just use `self.dynamicType` to get the subclass object and instantiate that: class ObjectBase { required init() { } func makeNewObject() -> ObjectBase { return self.dynamicType.init() } } class MyObject: ObjectBase { required init() { } func foo() { print("foo") } } print(MyObject().makeNewObject()) // result is new MyObject instance (Yay!) MyObject().makeNewObject().foo() // error: value of type 'ObjectBase' has no member 'foo' (Boo!) The problem is the base class's method's lousy type signature requires clients to force-cast the result to the actual type before they can refer to the returned subclass's own members: (MyObject().makeNewObject() as! MyObject).foo() // this works (prints "foo"), but is ugly as sin Of course, this would make a joke of usability, so isn't even a consideration. A kludy solution would be to override all of the base class's methods in the subclass, allowing the correct type signatures to be declared on its interface: class MyObject: ObjectBase { required init() { } func makeNewObject() -> MyObject { return super.makeNewObject() as! MyObject } func foo() { print("foo") } } But as this means replicating almost the entire base class each time, you have to wonder what the value of subclassing over just copying and pasting the original class each time really is. Besides, this is what we've got generics for, so we can do nice things like tailor a reusable class's method signatures to each specific use cases. And which is fine… until the type parameter happens to be part of the same inheritance tree, whereupon we tie ourselves and the compiler in recursive knots. First attempt, a simple generic class without any constraints: class ObjectBase { required init() { } func makeNewObject() -> T { return T() // error: 'T' cannot be constructed because it has no accessible initializers } } class MyObject: ObjectBase { required init() { } func foo() { print("foo") } } Um, pretty sure it does have an initializer, but okay, let's try using dynamicType again: func makeNewObject() -> T { return T.dynamicType.init() } Now it compiles successfully… and immediately crashes on execution. Okay, so take that method out for now and reduce the code to the minimum crash case: class ObjectBase { required init() { } } class MyObject: ObjectBase { required init() { } } MyObject() // crash: EXC_BAD_ACCESS on type metadata accessor for MyObject Huh. Any completely unrelated type for T, no problem. Anything self related, and swiftc and SourceKit DIAF at every turn, usually in a C++ stack-blowing infinite recursion of their own doing. And if it's not the parser or compiler, it's the runtime. So before I stagger off to write a code generator (ick) that mashes absolutely everything into single self-contained bespoke generated class every single time, can anyone see a way out of this recursive underbaked betaware hole I might've missed? Thanks, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift generics, circular type declarations, and segfaults, oh my!
On 03/09/2015 17:05, Fritz Anderson wrote: On 3 Sep 2015, at 8:55 AM, has <hengist.p...@virgin.net> wrote: Stuck and looking for ideas here. I need to define a base class whose methods vends instances of its subclasses (thus enabling chained method calls; your basic query builder). I’m assuming Swift 1.2. The following works in an OS X 10.10 playground: Swift 2 beta. class Factory: Printable { required init() {} class func makeNew() -> Self { return self() } Urgh. Usually when I try to use Self anywhere, the compiler just whines at me cos I'm thick and it's unhelpful. But yeah, Self does [annoyingly] work here, thanks: func makeNewObject() -> Self { return self.dynamicType.init() } Must've missed it during my experiments. (Ironic when I must've tried everything else under the sun.) Durr. I shall console myself with the thought I'm not the only one: SourceKit is falling over in a heap of infinite recursion [sic] whenever it tries to parse this code. (Will have to file a bug on that later.) * Using an instance as a factory for its own class is contrary to general usage, so is a smell at best. It’s a job for a class func. No, it's fine. It's for an Apple event query builder. Any odd smells are probably the Apple event architecture's doing. Chained var/method calls let you build and send AE queries using a non-atrocious syntax, e.g.: let result: [String] = try TextEdit().documents[1].text.words.get() I already prototyped the Swift API using code generation on top of an existing ObjC API <https://bitbucket.org/hhas/appleeventbridge/> and now I'm trying to simplify and reimplement the whole thing in pure Swift. In particular, I want to avoid duplicating base classes' general-purpose methods in application-specific glues and introduce a little bit of compile-time rigour, since different types of queries support different sets of operations (e.g. the compiler shouldn't allow you to ask for a range of elements on a property specifier, because that's not a valid AE query form). So I guess this brings me to my next question: what if I want the base class methods to instantiate more than one subclass? For example, a MyObject instance needs to be able to vend instances of both MyObjects and MyElements, while a MyElements instance needs to be able to do the same, e.g. much simplified pseudocode: // standard base class class ObjectBase<ObjectType, ElementsType> { func makeObject() -> ObjectType func makeElements() -> ElementsType } // custom glue subclasses class MyObject: ObjectBase<MyObject, MyElements> { // adds glue-specific methods } class MyElements: MyObject { // adds additional features only appropriate to elements, e.g. subscript } Needless to say, my only real success here appears to be setting new records for no. of Swift/SourceKit parse/compile/run crashes per hour. And that's before I even put constraints on the generic parameters (since the factory methods refuse to see the subclasses' inits without them). Ugh. I'm sure set algebra was never this painful in high school... Many thanks, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: [PSA] native AppleScripting support for Swift
Hi Alex, Thanks for the kind words. I know AEB's off to a hopeful start: I've been using appscript professionally for high-end automation for years[1], and hundreds (thousands?) of other appscript users have beaten the tar out of it over the years too, so the design has already proven itself. OTOH, there's a *lot* of roughness in the packaging and presentation - my Swift/ObjC/Xcode-fu sucks so it could really do with a more experienced hand on that side. And it's based on objc-appscript which was always the least polished and tested of the old appscript bridges, so a wide-spectrum shakedown from experienced application automators is also much needed to check I've not missed any compatibility issues. (Plus the documentation needs a damn good edit, natch; but I'm not going to worry about that until the first two issues are covered as it's in flux till then anyway.) Basically, I can do the AE-related engineering okay cos I know that narrow problem space better'n anyone, but for everything else it needs other folks to step up and assist. Partly cos those are areas I'm short on skills and time to do it and get it right all on my own; partly cos my failing to get others invested and involved in project development, or work effectively with them to evangelize and support it, was the reason it all cratered last time around. A system's only ever as good as its weakest point, which in AEB's case is the rubbishy non-redundant wetware it's currently running on, so the eventual goal would be to persuade Apple to take it over for inclusion in 10.12 [2], although that's require a heck of lot more folks to throw their weight behind it. So baby steps and bug reports first, and all help and advice is greatly appreciated. Best regards, has ... [1] And still do: http://www.mantasystems.co.uk/docs.html [2] A not entirely unrealistic goal as Mac::Glue already made it into 10.4, and appscript (alongside RubyOSA and SB) was being considered for inclusion in 10.5, and might have made it in too had dumbass here not been asleep on the job. :/ On 15/07/2015 12:53, Alex Zavatone wrote: Thanks, Has. This looks great. Sent from my iPhone On Jul 13, 2015, at 10:25 AM, hashengist.p...@virgin.net wrote: Hi all, In light of OS X 10.11 addressing some longstanding deficiencies in NSAppleEventDescriptor, I've been dusting off a fork of my old objc-appscript project, now renamed AppleEventBridge, modernizing and extending it both to take advantage of improvements to ObjC in the last few years and to add native support for Apple's new Swift language: https://bitbucket.org/hhas/appleeventbridge/ ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: [PSA] native AppleScripting support for Swift
Quick postscript: I've now posted AppleEventBridge's Swift documentation online for easier perusal: http://hhas.bitbucket.org/ It's still a bit rough, natch, but it should give a good idea of what it does and how it works without having to pull the project first. HTH has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
[PSA] native AppleScripting support for Swift
Hi all, In light of OS X 10.11 addressing some longstanding deficiencies in NSAppleEventDescriptor, I've been dusting off a fork of my old objc-appscript project, now renamed AppleEventBridge, modernizing and extending it both to take advantage of improvements to ObjC in the last few years and to add native support for Apple's new Swift language: https://bitbucket.org/hhas/appleeventbridge/ Unlike Apple's flawed Scripting Bridge and JavaScript for Automation, AEB aims to provide application scripting capabilities and compatibility that equal (if not better) AppleScript's own, along with superior documentation and developer tool support. Here's a simple example, comparing AEB's new Swift and ObjC bindings against de facto standard AppleScript: tell application TextEdit to get text of document 1 let result = try TextEdit().documents[1].text.get() as! String id result = [[TEDApplication application].documents[1].text getItem]; A simple Apple event translation tool, SwiftAETranslate, is included in the project, making it easy to convert AppleScript commands to their Swift equivalents. It's a great learning tool if you've always found AppleScript code perplexing, and well worth pulling the project just to try it out yourself: git clone https://bitbucket.org/hhas/appleeventbridge.git Swift support requires Swift 2.0 and Xcode 7 beta 3 or later, and works on 10.10+. While this release is not intended for production use (builds are rather messy and there's still rough edges and bugs), it is sufficiently mature to allow interested Swift and ObjC users to explore and experiment with it, and to offer advice, suggestions, and other feedback with a view to getting the whole thing to a production-quality 1.0 release before the end of the year. Enjoy, and I look forward to hearing what you think. has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: [Swift] best way to support 'keyword' args, symbolic values, show values as literals?
On 15/06/2015 18:39, Quincey Morris wrote: On Jun 15, 2015, at 10:17 , has hengist.p...@virgin.net mailto:hengist.p...@virgin.net wrote: the goal is to enable a user to print an object specifier and be able to copy-and-paste that straight into another script - i.e. `-description` should always return a string that represents valid Swift code I dunno about #1 or #2, but for #3 look into the “Custom…” family of protocols, especially ‘CustomStringConvertible’, which is the one that defines ‘description’ and ‘debugDescription’ as having more-or-less their Obj-C meanings. IIRC, CustomStringConvertible is also the one that allows your custom type to participate in string interpolation: “\(variableOfYourType)”, which would connect you with what I assume you mean by “printing. The standard protocols are all documented in the Swift Standard Library document for Swift 2. It’s worth browsing the list to see if there’s other stuff that might be helpful. Any of the “…Convertible” protocols might open up possibilities for streamlining your invocation syntaxes. Will give it a crack, thanks. (Just discovered the amazing answer to #1, so am off to play with that first.;) has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAppleEventDescriptor docs [was: Re: [Swift] best way to support 'keyword' args,...]
Dave wrote: Thanks to Apple actioning Radar tickets 19169736 http://openradar.appspot.com/19169736, 19169791 http://openradar.appspot.com/19169791, and 18944184 http://openradar.appspot.com/18944184, there are now modern, fully supported NSAppleEventDescriptor APIs arriving in 10.11 that will allow third-party code to do all this stuff without having to go through ancient legacy or deprecated Carbon APIs any more. I’m was about to add AppleScript Handling to my App and I’ll need to do a lot of NSAppleEventDescriptor fishing, is there any advance documentation relating to this? I’m an Apple Developer and under NDA. First things first, be aware that Apple event IPC makes *infinitely more sense* once you realize it ISN'T OOP, but remote procedure calls with simple first-class relational query values as arguments. Your app's scripting interface presents an idealized view onto its user data as a relational object graph, against which those queries are then evaluated. [1] Go read Dr William Cook's HOPL paper for excellent background on why and how it was designed that way [2]: http://www.cs.utexas.edu/~wcook/Drafts/2006/ashopl.pdf The usual way to add AE handling to a Cocoa app is to use the Cocoa Scripting framework. It has flaws, but unless you've a specific reason not to use it then it's probably the least painful option currently available. (If I ever get a spare year with nothing better to do I might write a replacement, but already I've enough mad projects on the go to keep me busy for the foreseeable.) Matt Neuburg's written some useful stuff on CS in the past, and there's docs on Apple's own site as well, including the Scripting Interface Guidelines which you should track down and read. While I don't use CS myself, I understand that the way Cocoa Scripting handles events and queries is kind of poor: each incoming AE is dispatched to a corresponding 'Command' class, one for each kind of event; and it's all a single-dispatch, nominal-typing, traditionalist OO flavored mindset, where queries tend to get unpacked into arrays of objects representing individual model objects which then frequently a pig to wrangle efficiently and correctly, e.g. try running this and see how many off-by-N errors you can identify: tell application TextEdit make new document with properties {text:one two three four five six sovon eight nine ton} set (every word where it contains e) of document 1 to ? end tell Whereas Apple events really need a multimethod-style approach to dispatching that uses structural-typing-like pattern matching to route incoming events to as many different 'handler' classes as you need to represent all the different verb(noun,noun,noun,...) combinations your app supports, and lets you decide exactly how you want to resolve queries and perform operations yourself. e.g. `move document 1 to end of documents` is a totally different operation to `move word 1 to end of paragraph 1`, so why would you want it dispatching both requests to the same NSScriptMoveCommand class? (And let's not even get into the sheer awfulness of its default Text Suite implementation.) Like I say, AEs are not OOP, and probably 80% of programmers' pain and hate comes from wrongly trying to treat them as such (the other 20% being due to a formal spec that's so hand-wavy and open-ended it's very hard to figure out how you _should_ do it). OTOH, unless you're willing (and crazy enough) to design and build your own AE handling framework from scratch, I recommend you just slum it with CS. Oh, and stick to AppleScript for _all_ your testing as that is the benchmark and the only currently supported AE bridge that actually works right[3]. As to wrangling NSAppleEventDescriptor directly (assuming you're either not using CS, or that CS is unable to pack and unpack them automatically for you), the docs on developer.apple.com haven't been updated yet, but the new methods all look to be based on my submitted patches which are taken from here, so just read the comments on those if they're not already self-explanatory: https://bitbucket.org/hhas/appleeventbridge/src NSAppleEventDescriptor+AEDescExtensions.h NSAppleEventDescriptor+AEDescMoreExtensions.h The only difference I've noticed thus far is the -send... event has a slightly different signature and a bug in the timeout argument, which I'll radar later [4]. If you're going to start packing and unpacking complex more complex descriptors (e.g. lists, records) yourself, you may find it useful to pinch code from my AEMCodecs class too. If you want to talk about stuff off-list then you're welcome to email me directly. Matt Neuburg and Shane Stanley are also well worth tracking down and picking their brains for guru treats, and both periodically appear on this list too. HTH has [1] Pin this on your wall as a reminder every day: grasping this unfamiliar but simple truth turns even
[Swift] best way to support 'keyword' args, symbolic values, show values as literals?
Hi folks, Some of the old uns here might remember that many years ago I wrote a nice little library named appscript which allowed you to control AppleScriptable applications from Python/Ruby/ObjC (and, unlike the alternatives, actually didn't suck), allowing you to write code like this (Python): app('TextEdit').documents['Read Me'].paragraphs[1].get() and this (ObjC): TEApplication *textedit = [TEApplication applicationWithName: @TextEdit]; TEReference *ref = [[textedit.documents byName: @ReadMe].paragraphs at: 1]; NSString *result = [[ref get] send]; instead of this (AppleScript): tell application TextEdit get paragraph 1 of document ReadMe end tell Thanks to Apple actioning Radar tickets 19169736 http://openradar.appspot.com/19169736, 19169791 http://openradar.appspot.com/19169791, and 18944184 http://openradar.appspot.com/18944184, there are now modern, fully supported NSAppleEventDescriptor APIs arriving in 10.11 that will allow third-party code to do all this stuff without having to go through ancient legacy or deprecated Carbon APIs any more. So I'm starting to work on an Apple event bridge for Swift 2.0, built on top of a cleaned-up fork[1] of my old Appscript.framework. So far it's able to construct basic object specifiers, e.g.: TEApplication(name: TextEdit).documents[1].name and symbolic values (AEDescs of typeType and typeEnumerated, aka 'class' and 'constant' names in AS): TESymbol.name Complex specifiers and commands are not yet up and running (once they are, I'll push the code) and this being my first substantial foray into Swift, I could do with advice and suggestions on how best to present the API. Here's 3 questions to start: ... 1. AppleScript, Apple events, etc. use optional keyword-based parameters, not ordered parameters as in ObjC and Swift. For ObjC I just used chained method calls to build up and send complex events, e.g: tell application TextEdit to make new document ¬ with properties {text:Hello World\n} translates to objc-appscript as: textedit make] new_: [TEConstant document]] withProperties: @{TEConstant.text: @Hello World}] send] which works fine but is pretty ugly compared to the Python equivalent: textedit.make(new=k.document, with_properties={k.text: Hello World}, timeout=30) Translating the ObjC API directly to Swift would result in code like this: textedit.make.new(TEConstant.document).withProperties( [TEConstant.text: Hello World]).send(timeout: 30) which isn't particularly intuitive or readable, so I'm looking for other ways to do it, preferably that allow the entire Apple event to be built and sent in a single method call. If I understand Swift, there are a couple possible approaches that would let me get much closer to the Python/Ruby syntax: optional arguments and dicts. Since optional args are only omittable from the end of the args list, that'd mean a syntax something like this: textedit.make(new: TESymbol.document, at: nil, withData: nil, withProperties: [TESymbol.text: Hello World], eventAttributes: [keyTimeoutAttr: 30]) which isn't the most beautiful (and starts to look unpleasant when constructing application commands that have really long verbose argument lists), but is possibly the most Swiftian way to do it. Another option would be to do what I did in Ruby, which was for each command to take 0, 1, or 2 of the following arguments: a direct parameter, and a dictionary containing all keyword parameters and/or event attributes: textedit.make(args: [ TESymbol.new: TESymbol.document, TESymbol.withProperties: [TESymbol.text: Hello World], TESymbol.timeout: 30]) or: textedit.make(args: [ new: TESymbol.document, withProperties: [TESymbol.text: Hello World], timeout: 30]) depending on whether one prefers parameter names to be given as symbols or strings. If anyone has any thoughts or other ideas, I'd very much like to hear them. ... 2. Does anyone have any particular thoughts on how best to present symbolic values? In Python I just had an dynamic object (`k`) that pretended to be an infinite namespace so one could write `k.document`, `k.text`, etc. and the application would figure out what AEDesc code ('docu', 'ctxt') that actually represented when packing it into the AE. For now I'm emulating the objc-appscript approach, which is to have a statically generated class (e.g. `TESymbol`) with a whole bunch of class methods on it that return the corresponding instances (e.g. `TESymbol.document`). Right now I'm defining these on the generated Swift class as static vars, but I dunno if there'd be a better way of presenting these, e.g. as lazy vars on the module itself (`TEDocument`, `TEText`, etc). (Bear in mind that these symbols are defined all over the place - some in the app's
Re: Optionals? A better option!
Jens Alfke wrote: Which is to say that, if you really want to engage in productive debate or provide alternatives, you should spend some time learning the theory behind languages and also looking at non-C-like languages, especially functional ones. This. C doesn't even have a typesystem: just a handful of compiler directives for allocating memory on the stack. If your only experience is in C and its descendents, you're simply not qualified to discuss type system design. Go learn a language like Haskell or ML that has a real type system; it'll open your eyes. Type systems are for expressing your exact requirements in terms of set theory, not checking homework of the terminally sloppy and lazy. Optionals come out of a long line of thinking in functional programming languages. The broader idea is that if a value can have multiple mutually exclusive states (in this case “has a value” vs “has no value”) then those states should be tagged and should require explicit action to select between. That’s basically what Swift enums are (and the same concept is found in a lot of other languages like Haskell, Erlang, Scala, Rust…) Indeed. The common term in FP is sum types. (Also known as variant types or tagged unions, though I dislike that last term as it emphasizes implementation rather than purpose - another easy engineer trap.) Here's a quick read: https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/sum-types Basically, just think of `FooType?` as a syntactic shorthand for writing `FooType | NoneType`, i.e. the sum of FooType and NoneType. [1] Similarly, `foo = foo_or_none as FooType!` is just shorthand for concisely expressing a common use-case where your code can't reasonably continue unless the value given is an instance of FooType: case foo_or_none of SomeType (foo) - [process the foo value as normal] NoneType - [throw a standard exception] Frankly, if you want to grouse about something, grouse about Swift's love of syntactic special forms, which makes the language look even more semantically complex and disjointed than it actually is. Having cut my coder's teeth on AppleScript, I know this special hell only too well already. There’s a school of thought that null pointers are harmful; optionals are a reaction to that. I just looked up the source — Tony Hoare gave a presentation where he formally apologized for inventing null pointers in 1965 as part of ALGOL W: [...] It’s a great quote, but I don’t think that was the first appearance of null. LISP dates back to the late ‘50s and has always had nil references (right?) Lisp has a `nil` object. That's not the same thing as a nil pointer. The first is an actual Thing; the second is a promise to give you a thing that instead drops you down a hole when you actually ask for it. HTH has [1] Pseudocode, obviously. I *really* wish Swift designers had copied FP's elegant type declaration and pattern matching syntax, instead of godawful C++ hideousness. It's so much cleaner it isn't funny. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Running AppleScripts from an App using NSAppleScript
Dave wrote: I have a number of AppleScripts I’d want to run from my App. Each Script has a couple of parameters [...] Example code here: http://appscript.sourceforge.net/nsapplescript.html The downside (one of them anyway) is that you have to do all of the Cocoa-AE packing and unpacking yourself. If you're passing complex data, I suggest pinching and adapting the AEMCodecs class from here: https://bitbucket.org/hhas/appleeventbridge/src If the scripts are part of your .app bundle, another option is to use the AppleScript-ObjC bridge, which allows you to call AS handlers directly from ObjC: http://appscript.sourceforge.net/asoc.html It's not perfect - there's no way to declare non-id signatures (you have to wrap and unwrap C primitives yourself) and some of the AE type bridging is problematic (NSDate/typeLongDateTime isn't automatically bridged, and the typeObjectSpecifier mapping is defective), but for most tasks it's the least painful option. HTH has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAppleScript Problem
Dave wrote: I’m running the following Script from a Cocoa App using NSAppleScript: For reference, some quick how-tos on calling AppleScript from ObjC/Python: * using NSAppleScript class: http://appscript.sourceforge.net/nsapplescript.html * using AppleScriptObjC framework: http://appscript.sourceforge.net/asoc.html HTH has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: prevent UIAgent with floating NSPanel stealing focus?
On 16/03/2015 22:02, Ken Thomases wrote: On Mar 16, 2015, at 4:50 PM, has hengist.p...@virgin.net wrote: Quick question as I'm guessing the answer is no, but I've a UIAgent that floats an NSPanel above other apps and I'm wondering if there's any way to avoid 1. having to click not once but twice to put the cursor in a text field when the panel isn't already active, and 2. prevent the next app - in this case Adobe Illustrator - losing all focus which causes all of its own panels to vanish? For issue 2, include NSNonactivatingPanelMask in the panel's style mask or, in IB, enable Non Activating in the Attributes inspector for the panel. Issue 2 fixed. Woot! That may also fix issue 1, but I'm not sure. It doesn't, but it's definitely a start. Just having AI stay in focus throughout makes the click-and-click-again window hopping a lot less disconcerting. You may also want to experiment with setting the panel's becomesKeyOnlyIfNeeded property, although that's more for panels which don't have many text fields. Another possible fix for issue 1 is to use a custom subclass of NSTextField which overrides -acceptsFirstMouse:, calls through to super (just in case it does something important), and then returns YES regardless of what the super implementation returned. Thanks, I'll give it a poke later and see what happens. has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
prevent UIAgent with floating NSPanel stealing focus?
Hi all, Quick question as I'm guessing the answer is no, but I've a UIAgent that floats an NSPanel above other apps and I'm wondering if there's any way to avoid 1. having to click not once but twice to put the cursor in a text field when the panel isn't already active, and 2. prevent the next app - in this case Adobe Illustrator - losing all focus which causes all of its own panels to vanish? [1] (I realize I could probably implement my NSPanel as a ObjC++ plugin which runs within the Illustrator process, but I'd rather not inject my own code into AI if possible as it's crashy enough without my shoddy C* code destabilizing it further.) Thanks, has [1] Screen recording if it helps illustrate the problem: http://mantasystems.co.uk/placepackcopy-720.mov (22MB) ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: building an AppleScript editor app
sqwarqDev wrote: As the title suggests, I'm building an AppleScript editor (Objective-C, not Swift). I've got reasonably far replicating the abilities of the in-built Script editor and have even added a few bells and whistles. However, I'm stuck, conceptually, on one particular hump. IMO you're almost certainly wasting your time. The aged AppleScript market is moribund, and the nascent JavaScript for Automation market is stymied by JXA being a total sack of crap. OSA is built upon the Carbon Component Manager, which was deprecated in 10.8. The Carbon OSA (OpenScripting) framework has been a legacy API since 10.6, and some functions also require deprecated types such as FSRef in addition to Component/ComponentInstance. OSAKit framework is supposed to be a Cocoa alternative, but is an undocumented sack of crap, and you still have to drop down to the Carbon OSA APIs for the sorts of non-trivial operations an OSA editor requires. When a script in my editor returns a record that contains the four-letter codes defined in the target application's dictionary, what is the best way to translate the code back into human readable form for display in the results window? You don't. You use the OSA to do it for you. OSAExecute and friends return an OSAID for a newly created ScriptValue object containing the raw result. You pass that ID to something like OSADisplay if you want that result as a display string, or to OSACoerceToDesc if you want it as an AEDesc. It's quite tedious, but it works. Or you use OSAScript, which has a very stupid method that returns both a display string and an AEDesc at the same time. I haven't yet got round to building my XML parser for my Dictionary viewer (that's next up), so I don't know if there are some methods that might help me in NSXML (a brief look over the class didn't suggest anything useful), but I'm imagining that I'm going to have to do something like this: i. load the applications dictionary into my code -- (I'm assuming I do this with an NSTask calling sdef...any other suggestions?) OSACopyScriptingDefinitionFromURL() is busted: documentation says both file: and eppc: URLs are accepted, but file: URLs return garbage (specifically, an SDEF for AEM's degenerate XML-RPC/SOAP support). OSACopyScriptingDefinition() requires an FSRef, which in turn requires use of deprecated functions like CFURLGetFSRef(). Honestly, calling out to `sdef` is probably the least horrid option. ii. parse the AEDescriptor result for the four-letter codes -- (currently, my thinking here is to turn the whole result into an NSString and use an NSScanner) Wut? Or are you still talking about displaying the script's return value? If so, stop shoveling and see above. As to dictionary viewers in general: OSAKit contains the dictionary viewer classes used by SE, though needless to say it doesn't work right, particularly when displaying inheritance and containment graphs which it almost invariably mucks up. I wrote some thoroughly horrible code for ASDictionary that does a much better job, although I don't think I ever finished the SDEF parser as the AS team keep mucking with the format and SDEF's always had bugs. Public domain code can be found in the old appscript svn repo. Either way, you deal with crap, insanity, or both. And you'll be pretty much on your own all the way: after a few thousand hours down the toilet I no longer provide any public appscript support (so if you want specifics you'll have to pay consultant rates), and good luck trying to get help out of any of the current AppleScript engineers (not that they understand half this stuff right anyway). As to general advice: I suggest you find yourself the original Inside Macintosh sections on Apple Event Manager and Scripting Components and read those to get some idea of how OSA works. (Be aware that even these are horribly light on specifics.) Also William Cook's HOPL paper on the early history of AppleScript is useful background. The JavaScriptOSA component I wrote after WWDC14 so the JXA devs could use it as reference (they didn't) is available at http://sourceforge.net/projects/appscript/files/. Again, unsupported, unfinished, and not 100% right (the more obscure, advanced behaviors I was semi-guessing due to lack of public Apple documentation), but it may provide some insight into how OSA is designed to operate. (I did actually start writing an OSAKit replacement as well, but a brief bout of sanity cured me in time.) Bear in mind too that OSA and the AS component are twenty year-old tech, and hopelessly obsolete by modern standards. There's no support for incremental parsing, for example, which you need to support stuff like dynamic code coloring and auto-complete which modern scripters expect. There's no hooks for debuggers or profilers, which users also expect, and you will probably go insane trying to hack your own workaround. The only person
Re: building an AppleScript editor app
sqwarqDev wrote: it's a hobby. The Aristocrats! Wasting my time on this is no worse than watching re-runs of Kung Fu and sure beats suffering on the sofa watching Leeds United getting hammered again... :( (Bradford City FTW) Or you use OSAScript, which has a very stupid method that returns both a display string and an AEDesc at the same time. Huh? Which method are you talking about? I can't see anything in OSAScript that returns much anything than various ints, none of which seem obviously useful for getting human readable text out of. -[OSAScript executeAndReturnDisplayValue:error:] As to dictionary viewers in general: OSAKit contains the dictionary viewer classes used by SE, though needless to say it doesn't work right, I was thinking I'd just build my own besoke XML viewer. Aside from the fact I won't be able to load any old dictionary files that aren't sdefs (I'm happy to forsake them) `sdef` and OSACopyScriptingDefinition...() automatically translate older formats to XML SDEF. This isn't to say they translate 100% correctly, but it's probably good enough for documentation purposes. that seems the easiest part of the job. You wish. Getting inheritance and containment graphs right in particular is a pig, since dictionaries are not validated and frequently contain errors and omissions. You may wish to install a copy of Python appscript alongside ASDictionary, and play about with its built-in help() method, which manages fairly decent graphs generated from AETE data. That alone was several hundred hours' work. The only info that's reasonably accurate is keyword names and codes, and what they represent (command, property, etc), since that's what AppleScript relies on to compile scripts, and even that can be glitchy at times, particularly in the big Carbon-based productivity apps. Plus there's stupid stuff like SDEF not being able to distinguish `text` strings from `text` application objects, and then there's the documentation element and XInclude messes, and I don't know how SDEF even deals with dynamically loaded dictionaries for scriptable plugins. Bear in mind too that OSA and the AS component are twenty year-old tech, and hopelessly obsolete by modern standards. There's no support for incremental parsing, for example, which you need to support stuff like dynamic code coloring and auto-complete which modern scripters expect. There's no hooks for debuggers or profilers, This is what first got me interested in writing a decent editor to start with... As I say, you'd be easier writing your own interpreter, then writing an editor around that. (Although the AppleScript language is such a pig to interpret correctly, I wouldn't recommend attempting that as a first choice.) well, that and I refuse to pay $199 for the only alternative. Meh, a couple hundred bucks is nothing for a product that works for a living. (Adobe'll happily gouge you ten times that, and let's not even mention the hole that the likes of AutoDesk like to make.) Heck, you could pay for SD in a few hours just by calling yourself automation consultant and hitting up the local graphic design outfits for some freelance scripting work. Or, if you're really cheap, go give Satimage's Smile editor a go. The standard version is free, and you can have hours of brain-melting fun just by exploring its own insanely deep use of OSA. http://www.satimage.fr/software/en/index.html I'll keep plugging away till TV re-runs get the better of me or Leeds go on a winning streak. Thanks for the tips, has. Amongst the discouragement, there was some useful leads. :) Just words from the wise. I know how many hours I've sunk into this crap myself, for great pain and little reward. Honestly, take up Flamenco or Taekwondo or something like that. Or get yourself a copy of Seymour Papert's Mindstorms and figure out how to make a modern Logo environment that properly rocks. Building languages is way more fun [1], and Lispy interpreters are ridiculously easy to make, yet will seriously expand your mind as you realize how deep and powerful they are. Regards, has [1] It's what I do myself now. http://www.mantasystems.co.uk/docs.html ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
What Apple event functionality is still missing from Cocoa?
Hi folks, Currently when working with NSAppleEventDescriptor it is necessary to drop down to legacy or deprecated Carbon APIs in order to perform certain tasks such as packing and unpacking date descriptors and sending Apple events. Given Apple's regular Carbon API pogroms, it's an uncomfortable foundation for building professional software products. I'm putting together a Radar feature request requesting that NSAppleEventDescriptor be enhanced to provide this missing functionality, and writing the patch myself in the hope that a. this expedites the process, and b. it gets done right. Here's what I've got so far, implemented as a category on NSAppleEventDescriptor so it's easy to test: @interface NSAppleEventDescriptor (AEDescExtensions) // Given a value, create and return an autoreleased NSAppleEventDescriptor // that contains that value, with an appropriate type (typeLongDateTime, // typeIEEE64BitFloatingPoint, or typeFileURL, respectively). + (instancetype)descriptorWithDate:(NSDate *)date; + (instancetype)descriptorWithDouble:(double)number; + (instancetype)descriptorWithFileURL:(NSURL *)fileURL; // Given a target process identifier, create and return an autoreleased // NSAppleEventDescriptor suitable for use in +appleEventWith... constructor + (instancetype)currentProcessDescriptor; + (instancetype)descriptorWithProcessID:(pid_t)pid; + (instancetype)descriptorWithApplicationURL:(NSURL *)url; // AERecords can have an abitrary descriptorType. This allows you to check if // the descriptor is truly an AERecord. - (BOOL)isRecordDescriptor; // Return the contents of a descriptor, after coercing the descriptor's contents // to typeLongDateTime, typeIEEE64BitFloatingPoint, or typeFileURL respectively. @property (readonly) NSDate *dateValue; @property (readonly) double doubleValue; @property (readonly) NSURL *fileURLValue; // Send an Apple event to a target process. On success, returns the reply event // containing the result value or error returned by the target process. If an // Apple Event Manager error occurs, returns nil and if `error` is not nil an // NSError containing the Carbon error code. - (instancetype)sendAppleEventWithMode:(AESendMode)sendMode timeout:(long)timeOutInTicks error:(NSError * __autoreleasing *)error; @end These are the methods that wrap essential legacy/deprecated Carbon APIs: +descriptorWithDate: +currentProcessDescriptor -isRecordDescriptor -dateValue -sendAppleEventWithMode:timeout:error: The rest are simply for completeness: not essential, just convenient to have. The two source files that I'll submit as a code patch are here (you can ignore the larger project): https://bitbucket.org/hhas/appleeventbridge/src/635415adc0841f07a906f834c7d269109db8ce3f/AppleEventBridge/NSAppleEventDescriptor+AEDescExtensions.h?at=master https://bitbucket.org/hhas/appleeventbridge/src/635415adc0841f07a906f834c7d269109db8ce3f/AppleEventBridge/NSAppleEventDescriptor+AEDescExtensions.m?at=master If anyone can think of any other Apple event Carbon APIs that should be added to this wrapper, please let me know. Ditto if you can see anything stupid or wrong in my implementation. I'm also open to advice on how to best present and document this code to make it as quick and painless for Apple to implement (I figure the less effort it is for them, the likelier they are to include it in [ideally] 10.11). Thanks, has p.s. Anyone know if rdar://problem/4976113 has been fixed? If it has, I can eliminate the AESendThreadSafe workaround for sending events on background threads. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: [PSA] JavaScript for Automation
On 02/09/2014 00:34, SevenBits wrote: At this late stage I think the only solution is for users to demand Apple reschedule JXA's initial release for 10.11, giving them time to [re]do it right. Although I have this, and was quickly turned away because its complexity, to be honest I really have little need for a solution like this. The principles of Apple event-based application scripting really aren't complex: it's basically RPC plus simple first-class queries. Most of the confusion arises because none of the documentation ever tells you this, so OO-trained users wrongly assume it's object-oriented and get completely confused and frustrated when it behaves in non-OO ways. (Indeed, the JXA docs actively lie: the Apple Event Object Model is connected via relations, like Core Data, not composed of objects and object arrays a-la DOM.) (I think the Cocoa Scripting docs mention relationships briefly, but only folks implementing scriptable apps read those, and I think the point is largely lost amongst all the other crud.) Most other usability problems are due to individual applications not including adequate documentation and sample code, though it's hard to blame third-party developers when Apple's own apps are some of the worst offenders so hardly provide a good example to follow. There are so many issues in Cocoa and OS X that need Apple’s attention right now (like a newly installed app breaking file associations) I don’t think that it will be a priority anytime soon. The Automation team already has its own manager, developers, and budget, so aren't affected by OS X's other problems. That’s not to say that I don’t think that Apple should delay it; I’m just saying that I have doubts that it will happen. I don't think it'll happen either, but that's because it'd be admitting they made a mistake, which Apple almost never does. But the more users push back, the more chance someone further up the management structure will start paying attention, and perhaps eventually the appropriate butts will be kicked and told to do better. Regards, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
[PSA] JavaScript for Automation
[I'm cross-posting this from the AppleScript Users mailing list - it's not a Cocoa question, but quite a few developers are extremely interested in alternatives to AppleScript for application automation so I believe it has relevance. I don't wish to risk the Cocoa Dev list mom's wrath with a longer discussion thread though, so please post any replies to ASU https://lists.apple.com/mailman/listinfo/applescript-users, not here on CD.] Folks, While there's still a couple months till Yosemite ships, it already looks as if JavaScript for Automation is going to be one more priceless opportunity down the drain. I've been testing it since DP2 and, like Leopard's Scripting Bridge, it's a half-baked, half-broken mess whose authors do not understand how AppleScript and application scripting actually work in the real world, never eat their own dog food, and ignore any criticism they don't understand or don't wish to hear. As part of my feedback to the AS team, I hacked together first a prototype JavaScript-AppleEvent Bridge and then a full JavaScript OSA component that they could use as reference, although I've no idea if they even bothered to look at it (I just got crickets). I've now uploaded a zip file containing the JavaScriptOSA component, the JAB Demo tool for translating application commands from AppleScript to JavaScript syntax, and the original Xcode project files to the old appscript project page so everyone else can have a look as well: http://sourceforge.net/projects/appscript/files Error reporting and documentation are incomplete, and there's bugs and other issues not yet resolved, but the AE and OSA support almost all works so folks already trying out JXA on Yosemite will find it useful for comparison. Folks on Mavericks can also try it if they wish as it's 10.9-compatible too. I'll try to finish it later if I've time, but as Apple have deprecated the whole OSA foundation it'll never be suitable for production use; therefore it's JXA or bust. At this late stage I think the only solution is for users to demand Apple reschedule JXA's initial release for 10.11, giving them time to [re]do it right. Bear in mind that once 10.10 ships, JXA's design defects will be effectively welded in for good. So it's up to all of you to decide if you're willing to accept something that's crippled, broken, and thoroughly inferior to AppleScript, and to make yourselves heard by those in charge if not. Regards, has ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Class OC_PythonObject: no such selector: _cfTypeID
Jonathan Mitchell wrote: On occasion I see my PyObjC scripts generating the following: Class OC_PythonObject: no such selector: _cfTypeID My app executes user supplied scripts and the error appears to be generated under a number of circumstances including inadvertently calling an object function with the wrong number of arguments. How should this error be interpreted? Is it indicative solely of argument mismatch? Hi Jonathan, The PythonMac-SIG mailing list is the probably the best place to ask Python-/PyObjC-specific questions: http://mail.python.org/mailman/listinfo/pythonmac-sig RubyCocoa is much more informative when inadvertently calling a function with the wrong argument count : wrong number of arguments (0 for 2) RubyCocoa maps ObjC method names to the same Ruby method name when there are 0 or 1 args given, e.g. -foo and -foo: both map to #foo. PyObjC, OTOH, maps -foo to foo and -foo: to foo_, so they are indeed different method names in Python. Thus, the PyObjC 'no such selector' message is technically correct, if not overly helpful, since -foo and -foo: are different names in ObjC too. I guess that's the nature of these bridges: it's not enough to understand how the local language (Python/Ruby) works, you need a good understanding how the target platform (ObjC runtime) and the bridge between the two environments (PyObjC/RubyCocoa) operate too. Although you could always submit a feature request asking for more 'intelligent' error reporting from the bridge in response to known common user errors such as forgetting the trailing underscore in PyObjC, e.g.: no such selector: _cfTypeID (did you mean _cfTypeID_?). HTH has -- Learn AppleScript, 3rd edition, Sanderson Rosenthal: http://apress.com/book/view/9781430223610 Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Simulating app termination
lorenzo7620 wrote: My question at this point is not about the dialog not displaying, not yet anyway, but how to tell my app to quit without actually restarting or shutting down the computer. Years ago under Classic, I would write an Applescript to do this, but it seems that you don't get even basic Applescript support for free anymore, so I have to add it. If your application runs off a Cocoa event loop, it ought to respond to a standard 'quit' event; all GUI processes should. If not, maybe there's something not quite right in your design? HTH has -- Learn AppleScript, 3rd edition, Sanderson Rosenthal: http://apress.com/book/view/9781430223610 Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: ScriptingBridge Commands
John Nairn wrote: I have been using ScriptingBridge to script my AppleScriptable Cocoa app using Python and Ruby. Today I noticed that commands defined on the main application do not work with error message that the application has no such attribute. I checked the header file created by the ScriptingBridge and see that all commands are defined in a generic GEDitCOM_IIItem that is subclass of SBObject: [...] Is this a bug in the ScriptingBridge framework? Probably. SB's API is heavily obfuscated and makes all sorts of accidental or deliberate assumptions about how scriptable applications operate that don't actually match up with reality. (e.g. Google scripting bridge+appscript if you want to see me tearing it various holes.) At any rate, I ran into similar problems: #!/usr/bin/python from ScriptingBridge import * iTunes = SBApplication.applicationWithBundleIdentifier_(com.apple.iTunes) iTunes.activate() # works ok iTunes.pause() # works ok iTunes.playOnce_(False) # AttributeError: 'ITunesApplication' object has no attribute 'playOnce_' Eventually, I figured out the magic invocation via sleuthing and guesswork: iTunes.play_once_(None, False) I didn't bother trying to find out if -[iTunesApplication playOnce:] works in ObjC, which is what the sdp-generated header claims it should be. But it wouldn't surprise me if it broke there - sdp's output isn't always correct either. For comparison, here's how you do it in py-appscript: #!/usr/bin/python from appscript import * itunes = app('iTunes') itunes.activate() itunes.pause() itunes.play() Much nicer, more capable native API, and far less prone to compatibility problems than SB. (I build heavy-duty workflows with it in my day job.) The only downside is that it's not present in OS X by default, but it's trivial to install via setuptools as long as you've got gcc on your system and it's MIT-licensed so redistribution isn't a problem. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: ScriptingBridge Commands
On May 5, 2010, at 7:45 PM, John Nairn wrote: My main reason to use SB is that is is there be default. I find that a surprising (maybe) percentage of my users will balk at anything that requires installation of something (even if free). Yep, it's always nice when frequently used dependencies are included in the stock OS install (koffgcc, I'm looking at you), particularly in those environments (e.g. corporate) where the politics of third-party installs can be difficult to negotiate. That said, if folks are regularly using Python or Ruby in place of AppleScript, appscript's well worth a look simply because it's so much nicer to use than SB. Application scripting's painful enough without the extra headaches that SB brings, plus you get features like interactive help and ASTranslate to make the transition from AS that much easier. Alternatively, if the majority of your users are using Python/Ruby/ObjC, then you might want to consider forgoing Apple events altogether and providing a straight ObjC API, either via NSBundle-based plugins or via Distributed Objects. Not that these approaches don't have issues of their own, but at least they will provide users with a familiar OO API rather than the weird RPC+query idioms of Apple events (with or without SB's clumsy faux-OO semantics on top). I think I know the reason the application commands do not work. It might even be solvable, but in my app all commands at application level work at document level too so that is a work around (because scripting without a document open is not very useful) I think the reason is that the base application object in the scripting definition is NSApplication and all my application commands are defined in a category of NSApplication, but not in the object itself. I am guessing the SB cannot handle that. SB does appear to generate the appropriate methods - albeit using a syntax that is neither consistent nor intuitive - but sdp is naming the methods differently when generating the corresponding header file (i.e. -commandName:nil argument:value vs. -commandNameArgument:value). Doesn't really surprise me - it's hardly the first time I've found SB and/or sdp to make a muck of things. Most of OS X's AppleScript-related technologies have been half-baked in concept and/or implementation, and their QA is completely lousy, so while it's frustrating this is nothing unusual by AppleScript standards. A potential solution might be to subclass NSApplication in my app and then define that class in the AppleScript suite. I'm very skeptical. It's not your application design that's at fault here; it's SB/sdp's doing, so trying to bend your app to suit SB will probably just backfire. As I say, SB makes all sorts of blind assumptions, so chances are that if you give your app an 'application' class by any other name it'll still work in AS (which is very forgiving) but will break even worse in SB. And don't forget that Cocoa Scripting can be very prickly too, so if the CS side is currently behaving itself then last thing you want to do is jinx that as well. If you know a significant proportion of your users will be using SB then I recommend you supply supplementary documentation that shows them how to write these commands correctly, also noting that sdp-generated headers define these method names incorrectly so that ObjC users will know to amend them accordingly. Regards, has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Scripting Bridge for GUI scripting?
Louis-Philippe wrote: I am looking around and I can't find docs about GUI scripting from the Scripting Bridge... it seems like NSAppleScript would do it, but I would like it better if I could do it with objective-c logic. Anybody has worked around something like that? Given that GUI scripting is inherently nasty and fragile, and prone to breaking whenever target applications are updated, I'd personally keep that code as compiled AppleScripts (.scpt files) stored within the .app bundle for ease of maintenance. Alternatively, if you really want to use [Obj]C, you could cut out AppleScript/System Events entirely and just talk directly to Mac OS X's Accessibility APIs (which is what System Events does). Or, you could always try poking the developer of the target application to provide some sort of externally accessible API (Apple events/Distributed Objects/SOAP/sockets/shared framework/whatever) and avoid all that nastiness entirely. That would be the best solution, of course. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: AppleScriptability Meets NSOperation
Jerry Krinock wrote: I do some lengthy, multi-step tasks in an app like this: * Wrap each of their dozen or so steps in an NSOperation. * Set dependencies so that they execute in sequence. * Add them to a suspended NSOperationQueue. * Un-suspend the queue. If an error occurs, all operations in the queue are cancelled and all ends gracefully. But many of the operations involve updating progress in the user interface, or accessing the document's managed object context, so they actually call back to performSelectorOnMainThread:, via a handy little wrapper in my NSOperation subclass. The user interface unblocks between operations, and I'm happy with the way this works. But when I invoke a task like this from AppleScript, of course, it returns immediately after loading the queue. That's no good, especially if an error occurs -- the script has already moved on. The Apple Event Manager supports suspend and resume, but I have no idea if you'll be able to take advantage of this feature in your application; I suspect it'll largely depend on how your scripting support is implemented (Cocoa Scripting?). Another option might be to use a similar approach to that used by iTunes and other applications where a task may run for an indeterminate length of time: implement a command to start the operation (c.f. iTune's play command), then provide a status property that the script can periodically poll to see if the task is complete. This also avoids the need for the user to mess around with 'timeout' blocks and won't freeze your GUI while the script is waiting for a response. (I think the SIG recommends this approach in these situations.) A third option would be to go the notification route, where you require client scripts to be run as stay-open applets; when the task completes, your application sends a command to the applet to let it know. Less common, though I have heard of it being used by scriptable backup software (I forget the name). HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Messaging Cocoa apps through Terminal
Ulai Beekam wrote: How can I send messages to my Cocoa app through the terminal? Say something like MyGreatMp3Player.app --sendAdvancedMessageThatIsNotInTheUI create100EmptyPlaylists I think the simplest way would be to write yourself a simple command line tool that uses Distributed Objects. I do this to control one of my own Cocoa-based apps from the command line. See: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/DistrObjects/DistrObjects.html DO is no panacea, mind; e.g. see: http://jens.mooseyard.com/2009/07/the-subtle-dangers-of-distributed-objects/ but if you understand and can work within its limitations, it's a very quick and easy way to get 'low-level' access to the known innards of Cocoa apps. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Extract keys, values from 'usrf' Record Type NSAppleEventDescriptor?
Jerry Krinock wrote: I create an NSAppleScript to read the current window name and URL from Safari and return it as a record [1]. When I execute it, I get a nice-looking NSAppleEventDescriptor with the following -description (line breaks added for readability): NSAppleEventDescriptor: { 'usrf': [ 'utxt'(aNam), 'utxt'(Apple), 'utxt'(aUrl), 'utxt'(http://www.apple.com;) ] } As you can see, the desired keys and values are all in there. How can I get them out? (Spent an hour reading documentation to no avail.) ObjC-appscript has an AEMCodecs class that includes code for packing and unpacking AppleScript-style records, if you don't mind embedding the Appscript framework or extracting the classes you want by hand. (I've received a patch from another appscript user to break out AEMCodecs and some other bits for this sort of use, but I've been too busy recently to apply it.) tell application Safari set aName to name of front document set aUrl to URL of front document end tell set aRecord to {aNam:aName, aUrl:aUrl} Unless the script needs to be user supplied, you could skip the NSAppleScript bit altogether. e.g. Running the above script through ASTranslate (from the appscript website) gives me the following raw code, which'd clean up nicely: #import SFGlue/SFGlue.h SFApplication *safari = [SFApplication applicationWithName: @Safari]; SFReference *ref = [[[safari documents] at: 1] name]; id result = [ref getItem]; #import SFGlue/SFGlue.h SFApplication *safari = [SFApplication applicationWithName: @Safari]; SFReference *ref = [[[safari documents] at: 1] URL]; id result = [ref getItem]; Or there's Apple's own bridge - not as good, but I'm guessing it would work for this. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to access iTunes using cocoa
Jens Alfke wrote: On Jan 26, 2010, at 9:41 AM, Paul Sanders wrote: I use Cocoa's NSAppleScript class. This seems to work fine on Tiger, Leopard and Snow Leopard. Yup, it just has the limitation that you have to run the script synchronously, which sucks since many iTunes commands can take a long time. There's no workaround to this that I've been able to find, since NSAppleScript is not thread-safe. AppleScript and NSAppleScript are thread-safe in 10.6. As for slowness, iTunes may not be a speed demon when it has many tens of thousands of tracks to wade through, but in a lot of cases the performance problems are primarily due to inefficient design in your own code. The Apple Event Object Model was optimized for System 7, where IPC was extremely expensive, so generally works best if you can use a few complex commands rather than lots of simple commands. e.g. This is dog slow because it sends 3*N+1 Apple events (where N is the number of tracks), each of which takes time for iTunes to process: set the_result to {} tell application iTunes repeat with track_ref in every track of library playlist 1 set end of the_result to {name, album, artist} of track_ref end repeat end tell the_result whereas this returns the same data (albeit in a different arrangement) using just 3 Apple events, so is blazing fast by comparison: tell application iTunes set the_result to {name, album, artist} of every track of playlist 1 end tell Apple event IPC is based on RPC + first-class queries, not OOP as most folks assume (a rough analogy would be XPath queries over XML-RPC). If you try to apply OO idioms to it when moving large numbers of values between processes, performance will suck even by IPC standards. Similarly, if you want to filter for specific tracks, you'll get much better performance if you can formulate a more complex query for iTunes to resolve rather than pull out all of the data and search it yourself: tell application iTunes make new user playlist with properties {name:Post} duplicate (every track of library playlist 1 whose album = Post and artist = Björk) to playlist Post end tell If you're curious, running that through ASTranslate formats each Apple event in objc-appscript syntax (which is handy as a starting point for developing your own ObjC code, and avoiding off-topic moderation:): #import ITGlue/ITGlue.h ITApplication *itunes = [ITApplication applicationWithName: @iTunes]; ITMakeCommand *cmd = [[[itunes make] new_: [ITConstant userPlaylist]] withProperties: [NSDictionary dictionaryWithObject: @Post forKey: [ITConstant name]]]; id result = [cmd send]; #import ITGlue/ITGlue.h ITApplication *itunes = [ITApplication applicationWithName: @iTunes]; ITReference *ref = itunes libraryPlaylists] at: 1] tracks] byTest: [[[ITIts album] equals: @Post] AND: [[ITIts artist] equals: @Björk]]]; ITDuplicateCommand *cmd = [[ref duplicate] to: [[itunes playlists] byName: @Post]]; id result = [cmd send]; HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to access iTunes using cocoa
Jens Alfke wrote: On Jan 26, 2010, at 11:13 AM, has wrote: The Apple Event Object Model was optimized for System 7, where IPC was extremely expensive I know; I was on the AppleEvents engineering team at the time :) IPC is still extremely expensive, by the way, although not quite as much so. The actual OS-level process switch is faster, but there is still a lot of work involved in marshalling and unmarshalling data. I think a big hit comes from the time it takes to evaluate Apple event object specifiers. The cost-benefit tradeoff of having a complex, query-driven IPC system is much poorer on OS X, both in terms of performance and ease of implementation (one of the reason so many apps have lousy AE interfaces is because they're so damn hard to implement). The main bottleneck on OS 7-9 was the OS-level messaging system; in OS X, it's evaluating those complicated messages in the target application process. Apple missed an opportunity in not designing Cocoa Scripting to be simple, fast, robust and dumb. (But perhaps that's an opportunity for some third-party developers with good knowledge of server-side Apple events to step in...?) so generally works best if you can use a few complex commands rather than lots of simple commands. Agreed. The problem is that iTunes doesn't implement the complex commands well. A lot of them either fail, or are implemented using linear search instead of querying the database. For example, you can't get properties of multiple items: album of every track of every playlist whose artist is The Beatles fails with error Handler only handles single objects. Instead you have to remove the album of part, get back a list of object specifiers, and loop over them getting the album names. Which of course involves lots of IPC calls. Or you could factor it so that you get a list of playlist references, then iterate over that. Mind you, all tracks should be in your main library playlist, so you really only should need to query that, which iTunes can manage. (Another iTunes wrinkle to watch for: if a playlist contains no matching tracks, iTunes will return an error rather than an empty list; so be prepared to deal with that.) There are other cases of 'whose' queries that take extremely long to run, depending on the size of your library, because they do a linear search. Try this: id of every track whose played count is 1234 On my 2.4GHz MacBook Pro this takes 15 seconds to run, with iTunes consuming 100% CPU. (I do have 10,000 tracks in my library.) By comparison, creating a smart playlist in iTunes with the same criteria is instantaneous. Apple have put little apparent effort into maintaining and updating iTunes' AE support over the years. (And iTunes is probably one of Apple's most heavily scripted apps.) So it wouldn't surprise me if the GUI is taking full advantage of the underlying database's capabilities while the AE interface isn't. But that's a rant for the AppleScript list. For your particular example, I would try grabbing all track ids and all played counts, then iterating over them yourself. I've not tried it here, but it might go a bit faster. But aside from grumbling about Cocoa Scripting, we're getting OT for cocoa-dev. If anyone wants to discuss this stuff further, we should take it to the AppleScript-users list: http://lists.apple.com/mailman/listinfo/applescript-users Regards, has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to access iTunes using cocoa
Michael Ash wrote: I think a big hit comes from the time it takes to evaluate Apple event object specifiers. [...] Complex AE object queries have the same benefit that SQL queries do: they let the data source perform an efficient search. [...] Would this actually matter in reality, though? A quick experiment (on my 2006 Mac Pro) indicates that CFMessagePort has a round-trip latency of roughly 100us, and with 1MB messages can transfer about 500MB/sec. On a more emperical level, some apps use Distributed Objects as an AppleScript alternative, and the first thing you notice when going from an AppleScript-based technique to a DO-based technique is that DO is way, way faster. DO uses pointers, not queries, so that wouldn't surprise me, given that the AE bottleneck nowadays is query evaluation, not message passing. And there are other ways to achieve query-driven efficiencies in that sort of environment - e.g. F-Script's array-oriented programming model comes to mind. Mind you, DO comes with its own set of problems, most of which step from its pretense that remote objects can be treated like local objects, so I'd be very leery of promoting it as the solution to AE's shortcomings: http://jens.mooseyard.com/2009/07/the-subtle-dangers-of-distributed-objects/ It may be the answer lies somewhere in-between: an explicit network messaging API with the ability to perform [read-only?] queries, but which mostly uses safe pointer and one-message-one-object semantics for simplicity, speed and safety. Some sort of session/transaction management would be nice too (to avoid multiple clients manipulating objects at the same time). And no more four-char-codes, of course. Regards, has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Bundle and window server interaction
Dave Keck wrote: That seems like a silly requirement for UI interaction... It seems you can get around it by making your app bundled and setting the LSUIElement key in your Info.plist, though. Or use TransformProcessType to elevate your Unix style executable to GUI status: OSStatus err = 0; ProcessSerialNumber psn = {0, kCurrentProcess}; err = TransformProcessType( psn, kProcessTransformToForegroundApplication); (This is what rb-appscript calls the first time a standard GUI-less ruby process tries to display a Standard Additions dialog.) HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Bundle and window server interaction
On Jan 18, 2010, at 10:04 PM, jonat...@mugginsoft.com wrote: Or use TransformProcessType to elevate your Unix style executable to GUI status: [...] Looking at rb-appscript [...] the process is transformed only when error -1713 occurs. Correct, errAENoUserInteraction = -1713. Ideally I would like to examine my AppleScript for the presence of syso/dlog et al and transform it accordingly. Searching has revealed that a custom send proc might be suitable. Ignorance prevents me from proceeding further. The goal is: if my script aeDesc contains eventid:{dlog, aleR, chcl, chlt, chra, chur, disA, nwfl, ppcb, stdf, stfl) transform_process_to_foreground_application procee end if As you say, install a custom send proc into the AppleScript component. Personally, I would have it send the event and sniff for errAENoUserInteraction in the reply event, as third-party osaxen may run into the same problem and you can't reasonably check for every possible event code beforehand. If an errAENoUserInteraction is found, elevate the process then resend the event. (Since it's already been responded to, I think it'll be safe to reuse the original AppleEvent descriptor as-is without having to futz with obtaining a new return ID.) You can't install custom send procs via NSAppleScript. Can't recall offhand if OSAKit allows it, otherwise you'll need to get down and dirty with the crusty old Carbon OSA API. Which isn't all that hard, though OT for this list. Alternatively, you could just be a pedant and insist anyone running AppleScript targets dialog commands at System Events. This avoids the need to elevate your GUI-less process in the first place, which also has side-effects such as creating a menubar and Dock icon; that's what ASers do when using dialog commands from osascript. We can switch this to applescript-implementors if required. I would suggest taking further emails there - quieter and better suited to the subject. Regards, has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Using AppleEvents to copy and past text from any application
Jesse Grosjean wrote: I'm developing a small open source app called QuickCursor. [...] Services no good? Only alternative I can think of would be to send Cmd-C/Cmd-V keystrokes, and hope that the user has the right text selected at the time. has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Using AppleEvents to copy and past text from any application
On 5 Jan 2010, at 21:41, Jesse Grosjean wrote: Last, how would I go about sending Cmd-C/Cmd-V keystrokes directoy to another application? Haven't done it myself, but I would guess CGEventCreateKeyboardEvent() and friends would be simplest. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Scripting Bridge running method passing an array
On 30 Oct 2009, at 21:38, Kyle Sluder wrote: On Fri, Oct 30, 2009 at 2:35 PM, has hengist.p...@virgin.net wrote: No, the OP's code is passing a *single* reference that identifies *all* of the speaker objects that match the specified condition. No. Here is the OP's code: NSArray *setTheSpeaker; setTheSpeaker = [[NSArray alloc] initWithObjects:connectToThisSpeaker, nil]; [Airfoil connectTo:setTheSpeaker password:nil]; The OP's ObjC code was wrong. His AS code was correct. His understanding of how the AS code worked may have been incorrect; that's not uncommon - many AppleScript users don't properly grok it either. You are confusing that with the AppleScript he tried to emulate. I accurately described what the code he posted did, and that it did not line up with what he was trying to do. I think there's some confusion over the confusion. :) You stated: the command wants an NSArray containing references to speaker objects, which is wrong. The command wants a *single reference* that identifies one or more speaker objects. i.e. Even if the OP's ObjC code had passed an NSArray of SBObjects, it would still be wrong. To emulate his AS code, he'd need to use an NSElementArray (which isn't really an array at all, but only pretends [badly] to be one) to as the argument to -connectTo:. Like I say, Apple event IPC makes absolutely no sense if you try to think about it in OOP terms. AppleScript syntax looks a bit OO-like, which lulls unwary OO programmers into all sorts of misconceptions. But this particular bit of mechanics actually draws on ideas from the world of relational databases, so you'll have more luck viewing it through SQL-coloured glasses than Cocoa-coloured ones. Hope that clarifies (inasmuch as anything AppleScript-related ever can be), has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAppleScript error
Marco Cassinerio wrote: I tried a lot of AS and the error is related to the AS request. For example, this to get the current playing track in iTunes: tell application iTunes set curr_path to get location of current track return POSIX path of curr_path end tell The error: NSAppleScriptErrorAppName = iTunes; NSAppleScriptErrorBriefMessage = Can\U2019t get location of current track.; NSAppleScriptErrorMessage = iTunes got an error: Can\U2019t get location of current track.; NSAppleScriptErrorNumber = -1728; That suggests the iTunes player is currently stopped, in which case a 'current track' reference usually isn't available. If you need to, you can find out iTunes' current state by querying the application's 'player state' property. Or you can trap the -1728 error raised if that's easier using a 'try' block. FWIW, it's always a good idea to double-check AppleScript-related problems in the [Apple]Script Editor before posting for help. If the issue is NSAppleScript itself, post here or to the applescript- implementors list for help. If it's a general AppleScript query, you will have most luck posting it to applescript-users as that's where most of the AppleScripting experts reside. http://lists.apple.com/mailman/listinfo/applescript-implementors http://lists.apple.com/mailman/listinfo/applescript-users HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Scripting Bridge and multiple attachments
On 1 Sep 2009, at 11:29, cocoa-dev-requ...@lists.apple.com wrote: Israel Chauca Fuentes wrote: I'm using scripting bridge to send emails with Mail.app and I have managed to do so, but I still have a little problem. When adding attachments, the first one is placed at the beginning of the message, while the rest of them are placed at the end of the message, which is certainly odd. I would like to place all attachments at the end of the message, which is how I use to place them by hand, but I don't know how. Works in AppleScript: property linefeed : character id 10 set the_paths to {/path/to/image1.jpg, /path/to/image2.jpg} tell application Mail set msg to make outgoing message ¬ with properties {subject:test, content:test test, visible:true} make new paragraph at end of content of msg with data linefeed linefeed repeat with path_ref in the_paths make new attachment at end of paragraphs of content of msg ¬ with properties {file name:path_ref} end repeat end tell With objc-appscript, it'd be something like this (untested code and without error handling added; I just ran the above AppleScript through ASTranslate and tidied the result a bit): #import MLGlue/MLGlue.h MLApplication *mail = [MLApplication applicationWithName: @Mail]; MLMakeCommand *cmd = [[[mail make] new_: [MLConstant outgoingMessage]] withProperties: [NSDictionary dictionaryWithObjectsAndKeys: @test text, [MLConstant content], ASTrue, [MLConstant visible], @test subject, [MLConstant subject], nil]]; MLReference *msg = [cmd send]; [mail make] new_: [MLConstant paragraph]] at: [[msg content] end]] withData: @\n] send]; for (path in paths) { cmd = mail make] new_: [MLConstant attachment]] at: msg content] paragraphs] at: -1] after]] withProperties: [NSDictionary dictionaryWithObject: path forKey: [MLConstant fileName]]]; [cmd send]; } Scripting Bridge imposes all sorts of restrictions on how object specifiers and events can be constructed via glues, so I suspect the only way you could do it there is by messing around with raw AE codes. (My opinions on SB are pretty well recorded though, so I'm not going to go into that.) HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: AppleScript Record and NSDictionary
Steve Cronin wrote: From my Cooca app I want to call an AppleScript with several parameters one of which is an AppleScript record. I've got everything about calling and return values working smoothly. What I can't seem to get is how to create that parameter record. ObjC-appscript's AEMCodecs class provides two-way mappings between NSDictionaries and other common Foundation classes and their NSAppleEventDescriptor equivalents. There's also an example project in the svn repository showing how it can be used in conjunction with NSAppleScript. When specifying record keys in your NSDictionary, use AEMType instances to signify AppleScript-defined property names, and NSStrings for user-defined identifiers. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: sending email form Cocoa app using Mail
Reza Farhad wrote: I want to update my app from using NSMailDelivery to using scripting Bridge with Mail to take care of all my emailing from my Cocoa app. I just have this question, what happens if the user is not using Mail and has only setup an alternative email client such as entourage. Using Mail (or any other email client) is a lousy solution for exactly the reason you describe. If you want to send emails from your application, there are various open-source email frameworks that'll let you do that directly; off the top of my head: http://www.collaboration-world.com/pantomime http://www.theronge.com/mailcore http://www.mulle-kybernetik.com/software/EDFrameworks Or, you might consider switching to some other mechanism, e.g. HTTP[S] POST. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Best Strategy to Control iTunes
On Apr 1, 2009, at 8:15 PM, Ammar Ibrahim wrote: I'm afraid I'm new and don't quite understand, do you recommend I use appscript? I'm biased, of course, but yeah, it's probably the best choice. It's more powerful and reliable than Scripting Bridge, can be used in background threads so won't block your GUI on lengthy operations, and avoids the extra complexity of using a sub-process if you need to pass non-trivial data. If so, what's the difference between the following methods: 1- NSAppleScript Runs AppleScript code within your process. Pros: - Nothing speaks Apple events better than AppleScript. Cons: - It can only be used on your main thread, so will block your GUI on lengthy operations. - While AppleScript itself is very fast at sending events, if you have to invoke it repeatedly then you will pay a performance penalty due to the overheads of calling into it. - If you have to pass complex data between ObjC and AppleScript, you'll probably spend as much time packing and unpacking that than if you just called AESendMessage directly with it, unless you use something like appscript's AEMCodecs class to do that for you. Notes: - Generally recommended only for situations where you need to run user- supplied scripts. 2- Cocoa Scripting Bridge Sends Apple events directly from Objective-C. Pros: - Included in Mac OS X 10.5 and later, which is convenient. Cons: - Less capable than AppleScript due to the way its API is designed. - More prone to application compatibility problems for the same reason. - Obfuscated API doesn't follow good Cocoa design practices (e.g. SBElementArray claims to be descended from NSArray, but does not behave as one). Notes: - SB tries to disguise Apple events - which are basically RPC plus first-class queries - to make them look like object-oriented Cocoa. This makes it look more familiar - and therefore more attractive - to existing ObjC/Cocoa developers. However, there is significant impedance mismatch between the two systems, so this resemblance is only skin-deep. While SB tries to hide these differences from the user beneath a thick abstraction layer, they tend to leak out whenever a target application does not behave exactly according to SB's in-built assumptions. Thus commands that work perfectly in AppleScript may fail when translated to SB, and as SB's internal magic is not publicly documented, it is considerably harder to troubleshoot the problem and develop workarounds. 3- AppScript Sends Apple events directly from Objective-C. (Python and Ruby versions are also available, and a MacRuby version is under development.) Pros: - Mature design has been heavily field-tested and refined over the last five years, so application compatibility is very nearly on par with AppleScript and functionality is equal or better (e.g. thread support). - Open-source MIT licensed. Cons: - Third-party solution, so you will have to build and include it in your application bundle yourself. - Does not hand-hold you or try to make Apple event IPC appear any less difficult or confusing than it actually is. (Whether this is really a con, or just refreshing honestly, is a decision left to the user.) - Not quite as polished as the Python and Ruby versions, so you may encounter the odd implementation bug, e.g. I've had a report of problems in 64-bit processes. - Single developer - that'd be me - currently up to the neck in work, so development and support of unpaid projects such as appscript isn't as active as I'd like (although I wouldn't say it was any worse than SB support). Notes: - Deliberately mimics AppleScript's own behaviours as much as possible in order to avoid application compatibility problems (i.e. quirk-for- quirk compatibility), so feels quite unlike normal Cocoa APIs. Still occasionally runs into compatibility problems, but the design is sufficiently open and flexible that workarounds are usually straightforward. - Some knowledge of AppleScript is recommended. (Actually, I would strongly recommend some knowledge of AppleScript regardless of what platform you use - you will need it in order to understand existing example scripts, get help from applescript-users, etc.) - Make sure you get the ASDictionary and ASTranslate dev tools too. 4- Command line invocation of osascript Runs AppleScript code within a subprocess. Pros: - This avoids the threading problems of calling AppleScript in-process. Cons: - It's a traditional command line tool, so you are very limited in what you can pass in and out - i.e. UTF8-encoded data. ... Other options to be aware of: - OSAKit -- more capable, though undocumented, alternative to NSAppleScript - Carbon OSA -- more capable than OSAKit, but gnarly Classic-style C APIs - AEBuild* functions -- lower level API that constructs Apple events via printf-style format strings - Carbon
Re: Best Strategy to Control iTunes
Michael Ash wrote: On Tue, Mar 31, 2009 at 3:57 PM, Luca C. luca.pazzere...@gmail.com wrote: 2009/3/31 Ammar Ibrahim ammar.ibra...@gmail.com If I want to add a track to iTunes, I need to make sure iTunes is responsive. Are you sure it is that important? Actually, if you run an AS script wich, say, opens with the Finder some mp3 files whilst iTunes has dialog windows opened, the command will be automatically enqueued. Â In other words, your tracks will be added after the user closes the dialog window. Â Run the script in a separate thread so it won't block your application's interface in any case. No, don't do this. AppleScript is not safe to use outside the main thread. If you must run AppleScript asynchronously, either spawn a subprocess to run it or, better yet, don't use AS at all but send Apple Events in some other way, such as with ScriptingBridge. Scripting Bridge apparently isn't thread-safe either: http://www.dribin.org/dave/blog/archives/2009/02/01/main_thread_apis/ ObjC-appscript is almost entirely thread-safe. You'll need to watch when using methods that rely on the Carbon Process Manager (some initializers, -isRunning) as the PM APIs don't appear to be thread- safe itself, but the main query builder and event dispatch methods should work fine on any thread (e.g. I use Python appscript in a background thread without problems). For example: tell application iTunes set newPlaylist to make new playlist with properties {name:Rock- n-Roll, shuffle:true} duplicate (every track of library playlist 1 whose artist is Chuck Berry) to newPlaylist end tell #import ITGlue/ITGlue.h int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int err = 0; // create a new application object ITApplication *itunes = [ITApplication applicationWithBundleID: @com.apple.itunes]; // create a new playlist ITMakeCommand *cmd = [[[itunes make] new_: [ITConstant playlist]] withProperties: [NSDictionary dictionaryWithObjectsAndKeys: ASTrue, [ITConstant shuffle], @Rock-n-Roll, [ITConstant name], nil]]; ITReference *newPlaylist = [cmd send]; // duplicate all tracks that match the given criteria to the new playlist ITReference *ref = itunes libraryPlaylists] at: 1] tracks] byTest: [[ITIts artist] equals: @Chuck Berry]]; NSError *error; NSArray *tracks = [[[ref duplicate] to: newPlaylist] sendWithError: error]; if (!tracks) { // check for errors NSLog(@%@, [error localizedDescription]); err = [error code]; } else // display result NSLog(@%@, tracks); [pool drain]; return err; } The ASDictionary application on the appscript site has options for exporting application dictionaries in both human-readable HTML format and as ObjC glue files. Not surprisingly, the ObjC code's a bit more verbose, but straightforward enough to construct once you understand the general principles behind Apple event-based IPC. Appscript respects the original Apple event semantics and doesn't obfuscate them under piles of fake Cocoa-isms, so if you already know how to do it in AppleScript then it's pretty much a straight translation: there's even a free tool, ASTranslate, that will help you with that. Apple event IPC is kinda weird and very different to Cocoa/OOP (a rough analogy would be to using XPath queries over XML-RPC) but is usually serviceable once you get your head around it. Apple docs do a lousy job of explaining how it all works, but there's an introduction to the basic concepts in the appscript manual and links on the appscript site to further information. Oh, and as for checking if an application is responsive - I'd suggest just sending an event and seeing if it times out (timeouts may be reported as either error -609 or -1712, depending on what sort of mood AESendMessage is in at the time). The launch event (ascr/noop) is basically a no-op that will return error -1708 if 'successfully' handled; handy if you don't want to send a 'work' event. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Best Strategy to Control iTunes
On Apr 1, 2009, at 3:57 PM, Sean McBride wrote: On 4/1/09 12:25 PM, has said: ObjC-appscript is almost entirely thread-safe. You'll need to watch when using methods that rely on the Carbon Process Manager (some initializers, -isRunning) as the PM APIs don't appear to be thread- safe itself Looking through Processes.h, it would appear that all public Process Manager APIs claim to be thread safe since 10.3. Huh. Thanks for the heads-up. Very annoying though that Apple put this information in the HTML documentation for some APIs (e.g. Apple Event Manager), yet omit it from others (e.g. Process Manager). Clearly I lack the instinctive Apple developer-fu to always check headers as well. I guess there can always be bugs... True; but are they Apple's, mine, or the user's...? :) (I had a report a while back from a user who couldn't get the - isRunning method to work correctly from a background thread, but haven't investigated in depth due to lack of time. I figured that since Apple docs usually state when something is thread-safe, the PM APIs weren't. Oh well, back to the ol' drawing board now) Cheers, has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Send events to AppleScript
On Mar 21, 2009, at 12:09 PM, Тимофей Даньшин wrote: Well, I'm writing a translation memory application, which is a program that grabs sentence by sentence from a given text (that needs translating), asks the user to translate that sentence and stores the translation and the original in a database. If the user comes across the same sentence again in the future, he or she will not need to translate it again. I thought i would take the TextEdit app as the text editing part of my project, but as I wrote the database management and the search parts, it turned out that TextEdit is not capable of correctly interpreting word files or RTF's (ie it ignores footnotes, headers/ footers and a lot of other stuff). That is why I am trying to find out how i can communicate with Word or Pages. As far as what I would want from an AppleScript (if I were to use AppleScript) is to be able to receive notifications from Word when, for example, the user has hit a certain key combination, to know where the insertion point (or selection) is in Word and to receive notifications when it moves, to be notified when a user is trying to edit something and prevent him/her from doing so if that part of the text should not be edited. Receiving those notifications, that script would just redirect them to my application and receive responses to them and redirect them to Word. It is rare to find applications that provide notifications, and almost unheard of for them to provide notifications of minor events such as text edits. You certainly won't get the sort of notifications you describe from TextEdit, Word or Pages. ISTR a third-party tool that allows you to attach AppleScripts to the GUI objects of another application, but that sort of thing is inherently hackish, prone to breakage, and liable not to go down too well with increasingly security conscious software and users. I suspect your best bet would be to poll the application, bearing in mind that might create its own issues (e.g. performance/responsiveness). HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Send events to AppleScript
Re: Send events to AppleScript Is it at all possible to have an application send actions to a particular AppleScript script, Yes. See NSAppleScript/OSAKit/Carbon OSA APIs. There's a sample project in the objc-appscript repository, CallAppleScriptHandler, that provides a simple demonstration of calling script handlers from ObjC, using appscript's AEM APIs to simplify the process of converting Cocoa objects to/from NSAppleEventDescriptors. or set that script as a delegate of that application Depends exactly what you mean by 'delegation'. The OSA API provides a whole bunch of arcane selectors and callbacks for two-way intra- process integration between application and scripts, but whether it's appropriate/how to use it will depend on exactly what you're trying to achieve. or to have an AppleScript as a means of communication between two applications (one of which is mine, and the other isn't)? Yes, although if you don't need the IPC code to be user-configurable, you'll likely find it simpler to use an ObjC-Apple event bridge: either Scripting Bridge, which is included in 10.5+, or objc- appscript, which you'll need to build yourself, but is more capable, compatible and portable, and doesn't obfuscate everything to heck. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Send events to AppleScript
On Mar 21, 2009, at 1:06 AM, Тимофей Даньшин wrote: On Mar 21, 2009, at 3:34 AM, has wrote: Is it at all possible to have an application send actions to a particular AppleScript script, Yes. See NSAppleScript/OSAKit/Carbon OSA APIs. There's a sample project in the objc-appscript repository, CallAppleScriptHandler, that provides a simple demonstration of calling script handlers from ObjC, using appscript's AEM APIs to simplify the process of converting Cocoa objects to/from NSAppleEventDescriptors. Sorry for misleading you, i rather meant receive events from third party applications. If you want to run an AppleScript as a standalone application and send it events from other applications, save your script in Script Editor as a 'stay open' application. As for sending events from Cocoa(?) apps to this applet; there's a couple ways you could arrange that, but you'd need to provide more details on what the setup needs to do if you want specific advice. Or do you mean that you want to write a Cocoa application that forwards some/all incoming events to an embedded AppleScript? In that case you want either NSAppleEventManager, or possibly Cocoa Scripting, to handle incoming events, and NSAppleScript or OSAKit to host the script, and write some glue code to go inbetween. or set that script as a delegate of that application Depends exactly what you mean by 'delegation'. The OSA API provides a whole bunch of arcane selectors and callbacks for two-way intra- process integration between application and scripts, but whether it's appropriate/how to use it will depend on exactly what you're trying to achieve. By delegation I mean the form of delegation that is present in Objective-C, when one can register one's object with another object as it's delegate and receive messages from in on certain occasions, such as textViewDidChangeSelection: That's pretty much what the OSA API was designed to do [1] - allow a C/ C++/ObjC application to load a script and invoke its handlers (what AppleScripters call 'attachability'). See Folder actions, Mail rule scripts, etc. Satimage Smile, for example, provides a great demonstration of just how far you can go with this sort of thing. HTH has [1] With the caveat that the OSA API is somewhat over-complicated, under-documented, lame in parts, and only really practical for AppleScript despite being theoretically language agnostic. -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Get the list of Places in Finder?
Oleg Krupnov wrote: I wonder if there is a programmatic way in Cocoa to get the list of Places from the left panel of Finder? (by default populated with Documents, Desktop, Home, Application, but can be customized with drag and drop). Thanks! There's no public API, unfortunately. You could try scraping Finder's preferences file (this info must be stored somewhere, most likely as serialised AliasHandles), or manipulating its GUI via the Accessibility APIs/GUI Scripting. Both would be hacks, however, and prone to breakage, so YMMV. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Termination Running Applications ...
Mic Pringle wrote: Is it possible to terminate other running applications (not my own) from within my application ? OSStatus QuitApplicationProcessWithPID(pid_t pid) { AppleEvent evt, res; AEDesc errDesc; OSStatus err; // build and send a 'quit' event err = AEBuildAppleEvent(kCoreEventClass, kAEQuitApplication, typeKernelProcessID, pid, sizeof(pid), kAutoGenerateReturnID, kAnyTransactionID, evt, NULL, ); if (err) return err; err = AESendMessage(evt, res, kAEWaitReply, kAEDefaultTimeout); AEDisposeDesc(evt); // note: process may quit without replying if (err == connectionInvalid) return noErr; if (err) return err; // check if reply event contains an error number, e.g. userCanceledErr err = AEGetParamDesc(res, keyErrorNumber, typeSInt32, errDesc); if (err == noErr) { AEGetDescData(errDesc, err, sizeof(err)); AEDisposeDesc(res); } else if (err == errAEDescNotFound) err = noErr; return err; } HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Calling Script Objects in Applescript
Karen van Eck wrote: We have a lot of code in libraries in Applescript. Now starting to look at using Cocoa to move forward, as we are really using Applescript to pretty much its limit. But it is not a short term solution to rewrite all our Applescript libraries in Objective-C. We need to be able to use Objective-C programs to load and execute our Applescripts. I've managed to get a program to execute an Applescript and to execute a handler in an Applescript. But most of our libraries are saved as Script Objects. Please could someone point me in the right direction for executing a subroutine inside a script object in an Applescript. Neither NSAppleScript nor OSAKit wrappers expose the APIs you need for this, therefore, you will need to use the Carbon OSA APIs directly. Use OSALoadFile to load the script, OSAGetProperty to copy the script object into a new slot, and OSAExecuteEvent to invoke its handlers. You can save yourself a bunch of work if you use objc-appscript's AEMCodecs class to convert your Cocoa objects (NSStrings, NSArrays, etc.) to/from NSAppleEventDescriptors, which in turn are easily converted to Carbon AEDescs. There's an example project, CallAppleScriptHandler, in the objc-appscript repository that shows how to do most of this. BTW, best place for these sorts of questions is applescript- implementors: http://lists.apple.com/mailman/listinfo/applescript-implementors More focused, less crowded. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: preparing HTML email content for Mail.app like safari does
Ferhat Ayaz wrote: I like it how safari prepares email contents with cmd-i. I would like to know how to do this programatically in cocoa. Is this possible? I want to send local html files with all linked images as html email. Safari uses an undocumented Apple event API (mail/mlpg) in Mail. I guess you could sniff some event traffic using AEDebug and try to reverse engineer the data format used, then construct your own copycat events. Given that it's a private API though you've no guarantee that the format won't change in future releases. Creating a plain text message with attachments via the public Apple event ('AppleScript') API is pretty straightforward - e.g. there's an example Xcode project in the objc-appscript repository that does this. You can even apply rudimentary styles, one run at a time, if you're patient enough. (Unfortunately, there's no standard for passing styled text/RTF/HTML/etc. directly between processes; a longstanding deficiency.) I'm not sure if you can create an HTML email or not via Mail's public scripting interface - best thing would be to ask on the AppleScript users mailing list as that's where you'll find most experienced Mail scripters. http://lists.apple.com/mailman/listinfo/applescript-users HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Odd crash
Reza Farhad wrote: Paul I switched on Guard Malloc from the Run Menu in Xcode It appears that I am getting the crash for a call that is trying to load an AppleScript. NSDictionary*errors = [ NSDictionary dictionary ]; NSAppleScript *script = [[ NSAppleScript alloc ] initWithContentsOfURL:url error:errors ]; One point, which may or may not be related: as with **NSError arguments, you do not need to allocate an NSDictionary instance yourself. If there is an error to report, initWithContentsOfURL:error: will create it for you. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: sdp generating empty header
Mark Munz wrote: I'm not getting any useful results when I try to generate Scripting Bridge headers. [...] The sdef file seems to be valid enough to allow me to actually script the application via AppleScript w/o issue. Anyone else run into this type of problem? Or how to get some indication as to the source of the problem that sdp is having with the sdef file? Can't really comment on your own particular problem without seeing the sdef/sdp commands you're running, though as a general point sdef, sdp and Scripting Bridge are all prone to various compatibility problems (some caused by bugs, some due to their design) with applications that work fine from AppleScript. I've previously found sdp to produce buggy headers for Word and Excel headers, and fail completely on InDesign, and it's pretty much guaranteed to produce flawed headers for any application whose dictionary isn't 100% perfectly formed. By comparison, AppleScript is very forgiving of dictionary imperfections, and that and the lack of formal validation tools from Apple mean that minor flaws are not common in application dictionaries as they don't show up when tested against AppleScript. You might also want to take a look at objc-appscript (see my sig). Unlike SB, appscript's behaviour is much closer to that of native Apple events and AppleScript and tries to be quirk-for-quirk compatible as much as possible. While it's still not completely immune to compatibility issues with some particularly funky applications, problems are pretty rare these days and there are generally compatibility options and other ways of working around them when they do occur. You also get feature parity with AppleScript plus extra benefits such as being able to send events on background threads, better tool support and documentation (ASTranslate is particularly useful when you're starting out), and an API that doesn't obfuscate everything it does. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Programatically Uncheck Change Picture In Desktop Settings?
Chunk 1978 wrote: when running my apple script i get this error: -=-=-=- System Events got an error: Access for assistive devices is disabled. -=-=-=- so if i goto system prefs and check Enable access for assistive devices, then running the script i get this error: -=-=-=- System Events got an error: Can't get application process System Preferences. Did you remember to activate System Preferences first? activate application System Preferences tell application System Events tell application process System Preferences ... end tell end tell However, before going down the GUI Scripting route, which is brittle and prone to failure, check out the Desktop Suite in System Events. The APIs a bit schlonky, but it may do what you want. Example using objc-appscript: #import SEGlue/SEGlue.h SEApplication *systemEvents = [SEApplication applicationWithName: @System Events]; SEReference *ref = [[systemEvents currentDesktop] pictureRotation]; id result = [ref setItem: [NSNumber numberWithInt: 0]]; HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: iTunes Scripting Bridge examples?
On 1 Jan 2009, at 04:57, Scott Anguish wrote: heh, no. This is a personal project I'm messing with. Nothing work related. Have fun. FWIW, a few tips to get you started: - Despite the superficial appearance of AppleScript/appscript/SB/ etc.'s APIs, Apple event IPC does not operate according to object- oriented rules (a very common misconception) - it's actually RPC +queries, roughly analogous to using XPath over XML-RPC. There are some aspects of the Apple Event Object Model that are derived from OO (e.g. its tree-shaped structure), which is why even folks who think it's OO manage to be somewhat functional in it; sooner or later though the procedural and relational behaviours will drive you nuts if you don't appreciate what's actually going on. Oddly, Apple's own documentation never seems to explain this to users, which is probably one of the reasons that so many programmers - especially those with a strong OO background - end up hating AppleScript and Apple event IPC so much. - Following on from the above point, the reason that iTunes' selection property holds a reference (query object), not a list, is that it allows you to construct requests like this: tell application iTunes get name of selection end tell -- {It's Oh So Quiet, Enjoy, Isobel, Possibly Maybe, I Miss You} and this: tell application iTunes duplicate selection to playlist user choice end tell -- {file track id 56362 of user playlist id 56283 of source id 43 of application iTunes, file track id 56363 of user playlist id 56283 of source id 43 of application iTunes, ...} Note that neither of these examples will translate to SB (short of doing everything with raw AE codes), though they work fine in appscript: ITApplication *itunes = [ITApplication applicationWithName: @iTunes]; id names = [[[itunes selection] name] getList]; // will be nil if no items selected (i.e. Can't get ref error) NSLog(@%@, names); id newTracks = itunes selection] duplicate] to: [[itunes playlists] byName: @user choice]] send]; NSLog(@%@, newTracks); - The ability of a single command to operate on multiple objects gets pretty important when dealing with large playlists - the main bottleneck being the time it takes iTunes to resolve each query (the inter-process messaging isn't free either). Example: #!/usr/bin/python from time import time from appscript import * playlist = app('iTunes').playlists['stress test'] print playlist.count(each=k.track) # 40960 tracks t = time() names = [] for track in playlist.tracks(): names.append(track.name()) print time() - t # 39.9 sec t = time() names = playlist.tracks.name() print time() - t # 1.3 sec - Most applications' Apple event APIs are appallingly under- documented, so most of the time you have to figure out what they can and can't do via educated guesswork, scraping through third-party scripts for tips and asking for advice on applescript-users. If you're not already familiar with AppleScript then I'd recommend getting a basic grasp on the beast - Matt Neuburg's 'AppleScript: The Definitive Guide' provides the best programmer-friendly guide to the language that I know of, and isn't shy of discussing the platform's many faults as well as its benefits. The current edition (2nd) doesn't cover the changes in 10.5, but I believe Matt has an errata section on his website. Oh, and there's also a couple of very enlightening papers by Dr William Cook discussing AppleScript's original philosophy and design that should help to make sense of a lot of the weirdness - you can find them via the appscript site's links page. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: iTunes Scripting Bridge examples?
Scott Anguish wrote: Does anyone have any examples of using the Scripting Bridge with iTunes? Specifically how you get the currently selected tracks returned as an array of iTunesTrack items. FYI, appscript's ASTranslate tool is pretty good at converting application commands from AppleScript to ObjC syntax, e.g.: tell application iTunes selection end tell produces: #import ITGlue/ITGlue.h ITApplication *itunes = [ITApplication applicationWithName: @iTunes]; ITReference *ref = [itunes selection]; id result = [ref getItem]; which you can then clean up or rewrite into whatever form you need. Won't help you with SB specifically, of course, but I think my views on SB are sufficently recorded by now. If you need any specific help with iTunes' scripting interface, best ask on applescript-users or go have a rake through http://dougscripts.com/itunes for existing examples. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Scripting Bridge and System Events
Kevin Wojniak wrote: I am trying to write a method to set the Desktop picture using Scripting Bridge and System Events. [...] The working AppleScript is: set picture of desktop 1 to POSIX file /Some/file.jpg FWIW, running your AppleScript through appscript's ASTranslate tool produces the following code: #import SEGlue/SEGlue.h SEApplication *systemEvents = [SEApplication applicationWithName: @System Events]; SEReference *ref = [[[systemEvents desktops] at: 1] picture]; id result = [ref setItem: [NSURL fileURLWithPath: @/Some/file.jpg]]; Dunno about Scripting Bridge - I have a fairly low opinion of it and avoid it myself. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Announce the time every 30 minutes
Mr. Gecko wrote: I'm trying to find out how to announce the time every 30 minutes, You could run 'say `date`' as a cron job. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Writing a more usable AppleEvent logger
Ken Tozier wrote: I've been working with AppleEvents and discovering their internals by setting the following in the terminal export AEDebugSends=1; export AEDebugReceives=1 What I'd like to be able to do is observe apple events exactly like this tool but format them into an NSDictionary so they can be used to easily build complex events. Since the above tool observes events, it must be possible, but how would I capture these events in my own tool? Is this something that needs to be a kernel extension? Or is there a higher level way to do it? Have you looked at AE Monitor? http://software.oxalyn.com/AEMonitor Not aware of public APIs for sniffing AE traffic myself (if any exist, they aren't advertised), but at worst you could always capture and parse AEDebug output yourself. It's pretty straightforward, and most of it could probably be massaged to pass to the Apple Event Manager's AEBuild* functions and reconstitute that way. There's also ASTranslate, which allows you to run AppleScript commands and get the equivalent Python/Ruby/ObjC appscript code (basically the same trick as Script Editor's 'Event Log' pane uses): http://appscript.sourceforge.net/tools.html Mike Ash's AEVTBuilder might also be of some interest to you, being an ObjC version of the AEBuild* functions. HTH has p.s. None of this is specific to Cocoa, so might be a good idea to move future discussion to applescript-implementors. -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Calling a script with parameters failing with error -1708
Ken Tozier wrote: I've been trying off and on for a couple of days to run a script that requires parameters. [...] My code is running as a Quark XTension so I may be setting up the targetAddress incorrectly. If you're constructing Apple events to pass to - executeAppleEvent:error:, the address isn't important and a null descriptor will do. Could someone take a look at the following snippet and point out where I'm messing up? The event class and id for invoking a script handler whose name is a user-defined identifier should be kASAppleScriptSuite and kASSubroutineEvent. (e.g. There's an example project, CallAppleScriptHandler, in the objc-appscript repositorythat shows how to do this.) Though as you're using OSAKit and your subroutine takes positional parameters, you could just use -[OSAScript executeHandlerWithName:arguments:error:] instead. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: ObjC data structure for C++/ObjC++ objects?
Jonathan Bailey wrote: I am trying to find a way to create a dynamically-growable objective C data structure within objective C++ code, such as a NSMutableDictionary, that can store values that are pointers to an objective C++ or straight-up C++ object. NSMutableDictionary seems to only accept pointers to objective C objects, however, and not to arbitrary objects. This seems like a simple thing to do but I am a bit stumped. Does anyone know of a way to do this? You could wrap your C++ pointers in NSValues and store those. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Use PPPOE to load net
Adam Penny wrote: Actually, I just tried the link I mentioned and it didn't work. I'm guessing that script uses Internet Connect.app, which was dropped in 10.5. There's an example of how to do exactly what you want on this page though. http://developer.apple.com/releasenotes/AppleScript/RN-AppleScript/index.html That'll only work on 10.5 and later. If the OP also needs to support 10.4 or earlier, they'd need to implement both and then check the OS version to decide which one to run. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: External Program Control from within Cocoa App
Ronald Ramdhan wrote: I am working on a project where I would like to control external programs from within my Cocoa Application. For example, the ability to control a program like PowerPoint from within my code. Is there anyway to do this programmatically without the use of Apple Script? I have already looked at NSWorkspace and noticed the commands to launch files, but what I need is the ability to control the launched program(e.g. Start a Slideshow). Using objc-appscript (runs on 10.3.9+; most reliable solution after AppleScript itself; see my sig for link; yada-yada-yada): #import MPGlue/MPGlue.h int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; MPApplication *powerpoint = [MPApplication applicationWithName: @Microsoft PowerPoint]; [[powerpoint activate] send]; MPReference * slideShowSettings = [[powerpoint activePresentation] slideShowSettings]; [[slideShowSettings showType] setItem: [MPConstant slideShowTypeSpeaker]]; [[slideShowSettings advanceMode] setItem: [MPConstant slideShowAdvanceUseSlideTimings]]; powerpoint activePresentation] slideShowSettings] runSlideShow] send]; [pool drain]; return 0; } (Error handling omitted for simplicity. See documentation and examples in the objc-appscript repository for more.) The glue code was generated via ASDictionary 0.11.0 (it's easier than using objc-appscript's osaglue tool which requires extra installation): just select the application(s) you want glues for, check the 'objc-appscript glue' option, edit the class name prefixes for each application in the table view if you want (I'll do nicer default prefixes in the next release), and hit 'Export'. ASDictionary can also export application dictionaries in objc-appscript format, which is much easier to read than Script Editor's dictionary viewer (which only supports AppleScript syntax) or the raw ObjC headers (which only contain the information that objc-appscript actually needs). Also, I will confess that I've never scripted Powerpoint before, so just did a web search to find an existing AppleScript example for running slide shows at http://aron.ahmadia.net/article/30/script-and-application-for-starting-a-powerpoint-show : tell application Microsoft PowerPoint set mySSS to slide show settings of active presentation set show type of mySSS to slide show type speaker set advance mode of mySSS to slide show advance use slide timings set sShow to run slide show mySSS end tell I then ran this script in ASTranslate to convert each Powerpoint command to ObjC syntax, then refactored that raw output into the form you see above. The only other thing was that I noticed Powerpoint wouldn't start the show unless I inserted an 'activate' command to bring it frontmost first. This extra requirement wasn't obvious (unless it's in the Powerpoint scripting manual, which I think you can get from the MS website), but after using AppleScript a few years you get used to doing this sort of guesswork. Depending on your exact requirements you may need to change it a bit, but at least it's a starting point. For getting help with automating specific applications you're best asking over on AppleScript-users as that's where most of the experts are (you'll generally get AppleScript-based solutions, of course, and will need to convert to ObjC yourself), or maybe the Mac Office newsgroups if it's Office in particular. Oh, and while I get the impression that you probably don't like AppleScript very much (fair enough), if you do need to do much automation work then as a practical matter you're going to have to learn it a bit anyway. It's what the vast majority of documentation and examples are written in, and what most experienced application scripters use, and you'll have a hard time understanding them without it. Personally I'd recommend getting a copy of Matt Neuburg's 'AppleScript: The Definitive Guide', 2nd ed. [1] which provides a programmer-friendly introduction to AppleScript, and isn't shy about discussing the language's many flaws as well as its features. HTH has [1] Covers up to 10.4; hopefully Matt'll do an update for 10.6 as text handling changed a bit in 10.5, but still full of good and useful information. -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Passing Variables to AppleScript
Pierce Freeman wrote: I am attempting to create a little application that will take an application name from the user, and then close it for them. I am attempting do this by getting the string in Cocoa, then passing this to AppleScript... But I don't know if Cocoa can pass variables to AppleScript. There are ways of passing values to AppleScript, and there are ways of sending Apple events directly from ObjC. Those are probably overkill for sending a basic 'quit' event though, which is a simple cut-n-paste solution. Here's what I use: #include Carbon/Carbon.h OSStatus QuitApplicationProcessWithPID(pid_t pid) { AppleEvent evt, res; AEDesc errDesc; OSStatus err; // build and send a 'quit' event err = AEBuildAppleEvent(kCoreEventClass, kAEQuitApplication, typeKernelProcessID, pid, sizeof(pid), kAutoGenerateReturnID, kAnyTransactionID, evt, NULL, ); if (err) return err; err = AESendMessage(evt, res, kAEWaitReply, kAEDefaultTimeout); AEDisposeDesc(evt); // note: process may quit without replying if (err == connectionInvalid) return noErr; if (err) return err; // check if reply event contains an error number, e.g. userCanceledErr err = AEGetParamDesc(res, keyErrorNumber, typeSInt32, errDesc); if (err == noErr) { AEGetDescData(errDesc, err, sizeof(err)); AEDisposeDesc(res); } else if (err == errAEDescNotFound) err = noErr; return err; } Use -[NSWorkspace launchedApplications] to look up the application's process id based on its name. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Faceless background app that uses NSAppleScript
Scott Ribe wrote: I need to write an app whose purpose is to drive other apps, using NSAppleScript. No UI is needed. But I'm unclear on what kind of environment needs to be set up in order for NSAppleScript to work. I suspect it needs at least NSRunLoop event processing; I wonder if it might also need an NSApplication around. Installing Apple event handlers that receive incoming events from other processes requires an event loop, of course, but I'm not aware of any limitations in NSAppleScript or the AppleScript component that force you to create one for outgoing events. You certainly don't need an event loop to use AESend() or AESendMessage() unless you want to receive replies asynchronously. I've written scads of event loop-less Python/Ruby/ObjC code that uses both of these APIs synchronously. I've also written the occasional Python shell script to run AppleScripts via the Carbon OSA or Cocoa NSAppleScript APIs without problems. FWIW, I think the AppleScript component may require a Window Manager connection, but you're unlikely to be running it in an environment without WM access anyway (as scriptable desktop applications invariably require WM access as well). Past use of NSAppleScript has revealed that it's somewhat quirky about event handling, in that what looks like a blocking synchronous call (executeAndReturnError), seems to allow the event loop to keep processing while it's waiting for a response. I don't think so - AppleScript is normally used on the main thread on account of it being a PITA to use anywhere else, and anything running on your main thread will block your event loop until it returns. (There is an ancient and convoluted mechanism in AESend() from pre-OS X days that allows it to yield to other routines while waiting on a response, but let's not go there.) You could also try asking on the applescript-users or applescript- implementors mailing lists; someone like Chris Nebel (AppleScript engineer) could tell you for sure what AS's limitations are. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Play Playlist in iTunes
On 4 Oct 2008, at 03:54, Mr. Gecko wrote: I am not using AppleScript to do this, I am using AppleEvents, as you can see in code below. Aware of that. You'll often find that folks use the name AppleScript as a catch-all term for anything relating to Apple event IPC. It's easy to lapse into the habit; apologies if it caused any confusion. Anyway, regardless of whether you use AppleScript or C to build and send events, the underlying RPC+query semantics are the same as they're defined by the Apple Event Manager and by the event handling code in scriptable applications. The AppleScript language sticks a thin layer of syntactic sugar [1] over the existing Apple Event Manager API in order to make it easier to use, but the way it behaves is virtually [2] identical. This is way faster than using AppleScript. It's the extra overhead of calling into the AS component that slows things down, particularly if you're compiling from source each time. There shouldn't actually be much speed difference between AppleScript and other APIs where building and sending events is concerned; it's the one area where AppleScript's performance is about as good as it can be. AS, appscript and SB all seem to be about equal here; the Carbon C API might be a little faster as it's closest to the metal, but I doubt the difference is significant by the time you've packed your Cocoa values into AEDescs and back. BTW, regardless of what API you use, you can also speed up or slow things down massively depending on the number of Apple events you use to perform a given task. This can be particularly noticeable with iTunes, since playlists can often run into thousands of tracks. Apple event IPC traditionally optimises for fewer, more complex events over many simple ones, so each event you send is relatively expensive but, depending on the application, you can often perform multiple operations in a single event. For example: #import Foundation/Foundation.h #import ITGlue/ITGlue.h int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; ITApplication *itunes = [ITApplication applicationWithBundleID: @com.apple.itunes]; // This sends 3 Apple events: NSDate *time1 = [NSDate date]; ITReference *tracksRef = [[[itunes playlists] byName: @stress test] tracks]; NSArray *names = [[tracksRef name] getList]; NSArray *albums = [[tracksRef album] getList]; NSArray *artists = [[tracksRef artist] getList]; printf(time 1 = %.3f sec\n, -[time1 timeIntervalSinceNow]); // This sends N * 3 + 1 Apple events (where N is the number of tracks in the playlist): NSDate *time2 = [NSDate date]; NSArray *tracksList = itunes playlists] byName: @stress test] tracks] getList]; NSEnumerator *iterator = [tracksList objectEnumerator]; ITReference *track; while (track = [iterator nextObject]) { NSString *name = [[track name] getItem]; NSString *artist = [[track artist] getItem]; NSString *album = [[track album] getItem]; } printf(time 2 = %.3f sec\n, -[time2 timeIntervalSinceNow]); [pool drain]; return 0; } gives the following times for a 4000-track playlist: time 1 = 0.137 sec time 2 = 5.779 sec and for a 40,000-track playlist: time 1 = 2.116 sec time 2 = 82.634 sec I'm not sure which approach EyeTunes uses, but it's something to bear in mind if performance is an issue for you. I would prefer using AppleEvents because it is the right way to communicate with different things in the os, using cocoa. It's all Apple events under the hood. Some APIs just make them easier to work with than others. HTH has [1] Plus a few magical behaviours such as 'implicit gets' which do unfortunately muddy comprehension a bit. But I won't claim that AppleScript is a perfect pedagogical tool, just a convenient one. [2] See [1]. -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Play Playlist in iTunes
Michael Ash wrote: On Thu, Oct 2, 2008 at 9:52 PM, Mr. Gecko wrote: I know but I can't find out the AppleEvent for Play Playlist. Is there some sort of a program that will parse the AppleScript and make an cocoa AppleEvent code. If you just want the raw four-char-codes from an application's dictionary so you can construct NSAppleEventDescriptors yourself, you can obtain them in various ways: ASDictionary (on the appscript site) can export raw application dictionaries as fairly readable UTF8 files; Late Night Software's Script Debugger provides a very nice GUI that can extract and display just about anything you can think of; OS X's Script Editor or sdef tool can dump out application dictionaries in raw XML format. Not quite, but you can get pretty close. Go to the section titled An Example on this page: http://www.cocoadev.com/index.pl?AEVTBuilder It shows how to make Script Editor dump the Apple Events it's sending, and then how to translate this into code. FWIW, the approach that ASTranslate uses is to install a custom AESendProc into an AppleScript component and have the user run an AppleScript. Any events sent by the script are intercepted by the custom callback, which pulls the event apart and formats its constituent parts as Python/Ruby/ObjC-style code; no manual translation required. Pretty easy to do if you're interested in providing a similar converter for AEVTBuilder; you could probably hack one from its existing ObjC translator if you know any Python. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Play Playlist in iTunes
On 3 Oct 2008, at 17:09, Mr. Gecko wrote: On Thu, Oct 2, 2008 at 9:52 PM, Mr. Gecko wrote: I know but I can't find out the AppleEvent for Play Playlist. Is there some sort of a program that will parse the AppleScript and make an cocoa AppleEvent code. If you just want the raw four-char-codes from an application's dictionary so you can construct NSAppleEventDescriptors yourself, you can obtain them in various ways: [...] I already looked at that but it doesn't have an actual code for Play Playlist I found this though class name=playlist code=cPly description=a list of songs/streams inherits=item plural=playlists which if you look at the output of AEDebugSends than you can see that that is called when running the play playlist command. I think you're a bit confused about how iTunes' Apple event API works. This is understandable, given how hopelessly inadequate 99% of scriptable applications' documentation is, along with the rather unusual, counter-intuitive way that Apple event IPC works in the first place. Suffice it to say: nothing in AppleScript makes sense except in the light of RPC plus queries[1][2]. IOW, you can either approach it on its own terms and accept it for what it is, which will weird you out till you get your head around it; or else you can try to approach it in conventional OO terms, in which case it will frequently confuse and frustrate you whenever it behaves in a non-OO fashion (which is quite often). Regarding the playing of iTunes playlists, here's a quick attempt to clarify: iTunes has no 'play playlist' command as you suggest. There is, however, a 'play' command (Apple event), and various kinds of playable objects: sources, several kinds of playlists (audio CD playlists, library playlists, user playlists, etc), and several kinds of tracks (file tracks, URL tracks, etc). To use the 'play' command, you construct a query (reference in AppleScript jargon) identifying the object you want played, then pass that query as the 'play' command's direct parameter. e.g.: play (source 1) play (source Library) play (playlist My Top Rated) play (first playlist whose name is My Top Rated) play (user playlist My Top Rated) play (user playlist My Top Rated of source 1) play (track 1 of user playlist My Top Rated) play (file track id 56315 of user playlist id 520 of source id 41) etc. As you can see, queries can be pretty flexible in how they identify objects. But whatever query you use, it's up to iTunes' 'play' event handler to evaluate that query in order to locate the object or objects to act upon, and do its funky thing. Oh, and BTW: one thing you will almost never find provided by applications' scripting documentation (be it built-in dictionaries and/ or supplementary files) is any formal indication of which commands can operate on which objects, so expect to use some intelligent guesswork and trial-and-error testing to figure this out for yourself. (Yes, this sucks; AppleScripters have been kvetching about it for the last decade, without notable effect. It's just something you'll have to deal with; the AppleScript-users list is good for advice, and there's a whole stack of existing iTunes scripts at http://dougscripts.com to learn from.) ... If you want to try to wrap your head around the AppleScript way, chapter 2 in the appscript manual tries to provide a quick summary of the concepts involved. There's also an excellent paper by William Cook (one of the original AppleScript designers), which describes both the language and the Apple event-based IPC system created around it, and provides significant insights into the original motives and decisions behind its design. It dates back to the early days of AppleScript so doesn't discuss the more recent related Cocoa-based APIs, but the underlying principles are unchanged: http://www.cs.utexas.edu/users/wcook/Drafts/2006/ashopl.pdf Matt Neuburg's AppleScript: The Definitive Guide also provides a good, critical, programmer-friendly guide to AppleScript and application scripting principles; obviously a big chunk of the book is about AppleScript itself which might not be of so much interest to you, but I've heard at least one other non-AppleScript user say that they've found it helpful, albeit after a slow start (presumably the basic AppleScript language chapters). HTH has [1] (With apologies to Theodosius Dobzhansky.) [2] FWIW, it is an odd and unfamiliar way to do IPC, and there are a lot of real-life design and implementation shortcomings that make it much more difficult than it ought to be, but at a basic level it is a logical and self-consistent - and even somewhat elegant (if unusual) - system. The nearest analogy I can think of is using XPath queries over XML-RPC, if that helps. -- Control AppleScriptable applications
Re: Python, Mac OS X 10.5.5 and CoreGraphics
Ronny Reichmann wrote: to make it short: Does anyone accidentally know why CoreGraphics doesn't work any more on conjunction with Python? The directory that contains the CoreGraphics bindings is still there, but not in the PYTHONPATH anymore. Setting it by hand and trying to import CoreGraphics leads to a Fatal Python error: Interpreter not initialized (version mismatch?) Seems to work here (10.5.5). Are you using Apple's own Python installation, or a third-party one? (Apple's own CoreGraphics bindings are only intended to work with Apple's own Python installation.) That's the only thing I can think of offhand. If that's not it, you could also try asking for help over on the PythonMac-SIG mailing list: http://mail.python.org/mailman/listinfo/pythonmac-sig HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Play Playlist in iTunes
Mr. Gecko wrote: Ok I now read everything in the programming guide for Scripting Bridge and it is really cool, Now I can't seem to find out how to play a playlist from a name id or anything. If you know how to write an application command in AppleScript, e.g.: tell application iTunes to play playlist Top 25 Most Played you can use the appscript project's very handy ASTranslate tool [1] to convert it to equivalent objc-appscript syntax: // To create glue: osaglue -o ITGlue -p IT iTunes ITApplication *itunes = [ITApplication applicationWithName: @iTunes]; ITReference *ref = [[itunes playlists] byName: @Top 25 Most Played]; id result = [[ref play] send]; which you can clean up as needed for use in your own code. ASTranslate doesn't do Scripting Bridge syntax, but that's because SB is mince (and inadequately documented mince at that). Obviously I'd recommend using appscript over SB as appscript's better technology in pretty much every way that counts (more powerful, more mature, significantly better application compatibility, also supports Panther and Tiger, equal or better performance, better documentation, better tool support, doesn't manage to obfuscate and confuse Apple event IPC even worse than AppleScript does). SB's only noticeable advantage is that it's installed as standard in OS X (10.5+) whereas you'll need to build and bundle appscript yourself in any products you release (a fairly trivial task, and appscript's license is very liberal). But you pays your money, etc. HTH has [1] http://appscript.sourceforge.net/tools.html -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Play Playlist in iTunes
Michael Ash wrote: On Wed, Oct 1, 2008 at 10:16 PM, Mr. Gecko [EMAIL PROTECTED] wrote: I think I would just use this AppleScript call [[[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:@tell application \iTunes\ to play playlist \[EMAIL PROTECTED], [self replace:@\ with:@\\\ source:[sender title executeAndReturnError:nil]; Works fast enough for me and it would work with because I use my replace function to make it \. You'll also want to replace \ with \\ (make sure you do this *before* you replace with \) and *possibly* some others as well, I'm not completely familiar with exactly what AppleScript allows in strings. You may also have problems with non-ASCII characters, as AppleScript is notoriously Unicode-unsavvy. AppleScript 2.0 in Leopard is fully Unicode; older versions could handle Unicode strings, but the source code itself used your system's primary encoding (e.g. MacRoman, MacJapanese; a classic Mac OS throwback). That said, code generation is fundamentally evil (unless you're in Lisp, where it's completely normal). If you need to parameterise an AppleScript, define an AppleScript handler that'll receive your values as parameters, then pack your ObjC values into NSAppleEventDescriptors and pack those into an event descriptor that calls your handler via - [NSAppleScript executeAppleEvent:error:]. You can probably find some examples online if you rummage around, e.g. there's one in appscript's subversion repository that uses objc-appscript's AEMCodecs class to do ObjC-AEDesc conversions (it's rather more powerful than OS X's anaemic NSAppleEventDescriptor class). Last time I had to do something like this (although it was considerably more complex), I built a library to make it easy to build raw Apple Events to mimic AppleScript without the mess that comes with actually using AppleScript itself. If you want to check it out, you can find more information about it here: http://www.cocoadev.com/index.pl?AEVTBuilder Neat. FWIW, objc-appscript lets you build and send events using straight ObjC method calls in both human-readable and raw four-char- code forms, e.g.: - using human-readable syntax: // tell application TextEdit to word 1 of document 1 // To generate glue: osaglue -o TEGlue -p TE TextEdit #import TEGlue/TEGlue.h TEApplication *textedit = [TEApplication applicationWithName: @TextEdit]; TEReference *ref = textedit documents] at: 1] words] at: 1]; NSError *error; id result = [ref getItemWithError: error]; - using raw four-char codes // tell application TextEdit to «class cwor» 1 of «class docu» 1 #import Appscript/Appscript.h AEMApplication *textedit = [[AEMApplication alloc] initWithName: @TextEdit]; AEMQuery *ref = AEMApp elements: 'docu'] at: 1] elements: 'cwor'] at: 1]; AEMEvent *evt = [textedit eventWithEventClass: 'core' eventID: 'getd']; [evt setParameter: ref forKeyword: '']; NSError *error; id result = [evt sendWithError: error]; [textedit release]; has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Finding the iTunes Music Library
Mr. Gecko wrote: Hello I am needing to know how to find the iTunes Music Library. I know people could have it in places other than ~/Music/iTunes/ because I moved mine to /Volumes/Music/ by holding down option at iTunes start. How would I determine where it is located. I looked in com.apple.iTunes.plist and it contained alis:1:iTunes Library Location as a NSData, but I can't figure out how to get the data from the NSDictionary and it could also be alis:2 so on so how would I get that? 'alis' is the OSType for a Carbon Alias type, so I'm guessing that's probably what's in your your NSData. See the Carbon Alias Manager documentation for more info. Of course, poking around in an application's (presumably) private preferences file probably isn't the best way to find out where its library lives, but I don't see anything in its scripting interface that can provide this information directly (although you could maybe kludge it), so you might not have much choice. Any particular reason you're wanting this stuff? HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: sending email with attachement from cocoa
Alexander Cohen wrote: Is there a way to use a url request to open mail with all its fields completed but most importantly, contain an image attachement? Nope. If you want to send an email in the background, you'll need to look into a third-party framework option: http://www.collaboration-world.com/pantomime http://www.theronge.com/mailcore http://www.mulle-kybernetik.com/software/EDFrameworks If you're talking specifically about creating an outgoing message in Mail.app, you'll need to control it via its Apple events ('AppleScript') interface. It's somewhat buggy (chronically so), but can usually be coaxed into doing roughly what you want. I've got an sample project (SendEmail) in appscript's svn repository that shows how to do this using ObjC and appscript: svn checkout http://appscript.svn.sourceforge.net/svnroot/appscript/objc-appscript/trunk objc-appscript I believe there's a sample project somewhere on Apple's site that shows how to do the same sort of thing using Leopard's Scripting Bridge (but I'll not link to that here as I don't have a very high opinion of Scripting Bridge:). HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: appleScriptWithContentsfFile wipes out Quark's Applescript dictionary
[EMAIL PROTECTED] wrote: I wrote a Quark XTension that displays scripts in a floating palette and have found that the following wies out most of Quark's AppleScript dictionary NSAppleScript *script = [[NSAppleScript appleScriptWithContentsfFile: inPath] retain]; I think you need to define wipes out a bit more precisely. You might also want to try asking on the applescript-implementors list; I think you'll have a better chance of finding help there. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: EPS
Georg Seifert wrote: [NSView dataWithEPSInsideRect:] does not seem to help, unless I build a dummy view, draw in it and then use this method. I believe that's the general idea. An NSBezierPath instance by itself doesn't really do anything unless/until you draw it into a suitable graphics context. Read the Cocoa Drawing Guide; in particular, the 'Creating Graphics Contexts' chapter. but this seems to be quite complicated. I'm no graphics guru (so try not to laugh), but here's a simple example: /// CustomView.h /// #import Cocoa/Cocoa.h @interface CustomView : NSView { } - (NSEPSImageRep *)epsImageRep; @end /// CustomView.m /// #import CustomView.h @implementation CustomView - (void)drawRect:(NSRect)rect { // do all your drawing here... e.g. to draw a black rectangle in middle of view: [[NSBezierPath bezierPathWithRect: NSMakeRect(10, 10, 20, 20)] fill]; } - (NSEPSImageRep *)epsImageRep { NSData* theData = [self dataWithEPSInsideRect: [self bounds]]; return [NSEPSImageRep imageRepWithData: theData]; } @end /// main.m /// int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // create a custom view of the desired size CustomView *view = [[CustomView alloc] initWithFrame: NSMakeRect(0, 0, 40, 40)]; // extract an EPS image rep from it NSEPSImageRep *epsRep = [view epsImageRep]; // do some stuff with the EPS image rep here... e.g. to write to file: [[epsRep EPSRepresentation] writeToFile: @/Users/foobar/test.eps atomically: NO]; [view release]; [pool release]; return 0; } HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: EPS
Georg Seifert wrote: is there a way to create EPS data from code? I need it to put in in pastboard. Does anyone can point my to some docs as I cant find any. http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaDrawingGuide What I want to do, is to copy a NSBezierPath to Illustrator and back. Depending on what you're doing, another option might be to draw your path directly in Illustrator using its Apple event (AppleScript) interface. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Trouble with Scripting Bridge
Tommy Nordgren wrote: On 31 aug 2008, at 03.12, Peter Stirling wrote: I've been trying to do some python scripting of iTunes using pyobjc and ScriptingBridge, and I've been having some problems (I reduced everything to objective-c on its own in order work out if it was caused by pyobjc). [...] However it doesn't seem to work, the code provided in the zip archive (when executed on my machine), produces a list of all the gapless tracks in my mp3 collection, but every line ALSO claims that the track is 'not gapless'. [...] tester.zip From test.m : NSPredicate* predicate = [NSPredicate predicateWithFormat:@gapless=YES]; this should probably be : . predicateWithFormat:@gapless==YES]; According to the NSPredicate Programming Guide, '=' and '==' are synonyms so either should work in principle. That said, NSPredicates don't actually function as NSPredicates in Scripting Bridge but are, by some mysterious invisible magic, mapped to Apple event filter clauses for the target application to handle. Given that there isn't a 1:1 correlation between NSPredicate and AE filter clause functionality, this mapping is already somewhat lossy... and it's always possible that it's buggy as well. At any rate, filtering for gapped/gapless tracks seems to work fine in AppleScript and appscript (or as well as most things work in iTunes scripting), so at least it isn't an iTunes bug, e.g.: #!/usr/bin/python from pprint import pprint from appscript import * tracksref = app('iTunes').library_playlists[1].tracks ref = tracksref[its.gapless == True] if ref.exists(): pprint(zip(ref.album(), ref.id(), ref.gapless())) else: print 'No gapless tracks found.' ref = tracksref[its.gapless == False] if ref.exists(): pprint(zip(ref.album(), ref.id(), ref.gapless())) else: print 'No gapped tracks found.' (Bear in mind that the above may take a few seconds for extremely large playlists; depending on how you want to pick/organise/play your random tracks there may be more efficient ways of approaching the task.) HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: AppleScript on a Context Menu
David Orriss Jr wrote: OK, it's not Cocoa, per se... but I thought someone here might know. I want to create an AppleScript that is on the Context (Ctrl+Click/ Right Click) menu. I've seen ways to do it with Automator - but that puts the script in the automator menu. I want it top-level. Anyone have an example on how to do this that doesn't involve Automator and will still create an AppleScript plugin? This the sort of thing you're looking for? http://free.abracode.com/cmworkshop/on_my_command.html HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Objective-C and AppleScript
John Love wrote: I am trying to convert as much as I can of my former Studio code over to Obj-C and thanks to this Mailing List I have been successful so far .. but here's a stumper or two: Here are 2 AppleScript statements that work in Studio: -- #1 works in Obj-C, so my question is = isn't there a more *direct* Obj-C call to do the same thing, -- rather than call NSAppleScript's executeAndReturnError method? It just seems that a one or two -- system calls should effect the same result? 1) tell application System Events to return (name of every application process contains Microsoft Excel) -- see ExcelAppActive below If you use objc-appscript (I won't suggest the sdef/sdp/Scripting Bridge toolchain as an alternative as I know it has problems with Excel), you can check if Excel is running by calling the MEApplication object's -isRunning method: // To create glue: osaglue -o MEGlue -p ME Microsoft\ Excel MEApplication *microsoftExcel = [MEApplication applicationWithBundleID: @com.microsoft.excel]; if ([microsoftExcel isRunning]) { // do stuff here... } -- If I hard-code the actual name of the file stringByAppendingString:@some title (see theWorkbookActive method below), -- everything works dandy. -- -- But ... this name is actually a instance parameter, NSString* itsFileName, defined in my .h file, and dynamically set in my .m file. -- So, I type stringByAppendingString:itsFileName -- but then my app crashes. Code generation is fundamentally evil; if you need to pass values to a script, pack them into an NSAppleEventDescriptor and pass them to a handler in a compiled script via -[NSAppleScript executeAppleEvent:error:]. That said, appscript should suffice for general Apple event IPC, so the only time you should need to mess about with NSAppleScript is if you need to execute user-supplied scripts (appscript is pretty handy for that too, btw). 2) tell application Microsoft Excel to return (name of every window contains some title) I would suggest doing: tell application Microsoft Excel to return (exists window some title) as it's a bit clearer in meaning. The objc-appscript equivalent would be: MEReference *ref = [[microsoftExcel windows] byName: @some title]; id result = [[ref exists] send]; BOOL windowExists = [result boolValue]; The ASTranslate tool on the appscript website is very handy if you need help translating application commands from AppleScript to ObjC syntax; there's also ASDictionary for exporting application dictionaries in appscript format. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
re: NSAppleScript shies away from porcupines
Jason Coco wrote: I did a test with this... it seems that the code to resolve the alias in AppleScript doesn't like non-latin encoded pathnames. I think you're right - from dim and distant memory I seem to recall that AppleScript's 'value as alias' coercion often doesn't work with non-ASCII paths, and you have to use an alias specifier, i.e. 'alias value' instead. (The other common cause of errors is trying to create aliases for non- existent paths, of course, but I'll assume the OP already checked for that.) Anyway, unless the OP is needing to run user-supplied scripts, I'd suggest ignoring NSAppleScript and just use a Cocoa-Apple event bridge instead. For example, here's the objc-appscript version after using ASTranslate to get an approximate ObjC translation of the original AppleScript's Finder commands, then tweaking and tidying to suit: // To create glue: osaglue -o FIGlue -p FI Finder #import FIGlue/FIGlue.h int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int err = 0; NSURL *file = [NSURL fileURLWithPath: @/path/to/file]; FIApplication *finder = [FIApplication applicationWithBundleID: @com.apple.finder]; FIReference *ref = [[[finder items] byIndex: file] informationWindow]; NSError *error; id result = [[ref open] sendWithError: error]; if (result) [[finder activate] send]; else { err = [error code]; NSLog(@%@, [error localizedDescription]); } [pool drain]; return err; } HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: NSAppleScript shies away from porcupines
Gerriet M. Denkmann wrote: When I try in Script Editor: set macpath to POSIX file /Volumes/เม่น/Users as Unicode text and do Compile, then this gets transformed into: set macpath to file ‘ßÀÏ:Volumes:‡¡Ëπ:Users as Unicode text Sounds like you're on 10.4 or earlier. AppleScript only supports Unicode source code in 10.5+; previously it used the host system's primary encoding, which is why your non-MacRoman(?) characters are getting mangled. If you must use AppleScript for some reason, either write your unicode string literals using raw «data utxt...» format, or pass in unicode strings as parameters to an Apple event constructed via NSAppleEventDescriptor. has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Opening an external file in a external application
John Love wrote: Really though, what's best/practical/possible all depends on what you're trying to do, so if you want more advice then you'll need to provide more information. Very short info list is as follows (stuff I need to do from within my Cocoa app): 1) be able to save the Excel spreadsheet Opening and saving Excel workbooks can be done with Apple events, e.g. using objc-appscript [1]: // To create glue: osaglue -o MEGlue -p ME Microsoft Excel MEApplication *microsoftExcel = [MEApplication applicationWithName: @Microsoft Excel]; // open file specified by HFS path MEOpenWorkbookCommand *cmd = [[microsoftExcel openWorkbook] workbookFileName: @Mac HD:Users:foo:Workbook1.xlsx]; id result = [cmd send]; // result is a by-name reference to the new workbook, or nil if an error occurred // save in new file MEReference *ref = [[microsoftExcel workbooks] byName: @Workbook1.xlsx]; MESaveWorkbookAsCommand *cmd = [[ref saveWorkbookAs] filename: @Mac HD:Users:foo:Workbook2.xlsx]; id result = [cmd send]; // result is nil if an error occurred Two potential problems to be aware of: 1. Excel stupidly uses HFS path strings in its 'open workbook' and 'save workbook as' commands. This means you'll have big problems if you have another volume with the same name as the one you're opening from/saving to, as HFS paths can't distinguish between identically named volumes. (Better designed applications use alias and file URL types to identify filesystem objects and locations.) You might be able to work around this issue by using the standard 'open' and 'save' commands, although you lose the additional features provided by 'open workbook' and 'save workbook as'. Or you may consider using HFS paths to be an acceptable risk and just put up with them. 2. References returned by Excel only identify workbook objects by- index or by-name references. That makes it tricky to ensure you've a stable handle on the workbook for the length of time it's open. (By- index specifiers are sensitive to element order; by-name specifiers can't distinguish between two elements with the same name. Only by-id specifiers are guaranteed to be unique and stable over a target process's lifetime, but most apps don't use those.) I did wonder if using a by-test specifier would work; something like: tell app Excel tell first workbook whose full name = HFS_path_to_file -- do stuff here end end but it doesn't work, so you'll either need to iterate over elements and compare their paths yourself or else just use the existing by-name references and trust that nobody opens another file with the same name while your program is doing its thing. 2) be able to stop any calculation in progress Dunno myself; you'll need to ask someone with more Excel scripting experience. 3) be able to detect if the user closed the spreadsheet behind the back of my Cocoa app, upon which my Cocoa app would raise a NSAlert. Assuming you've figured out a way to uniquely identify your workbook element, you could poll Excel at regular intervals to see if it still exists. HTH has [1] Be aware that Office apps are a rather eccentric bunch even by AppleScripting standards, but appscript's application compatibility is very nearly as good as AppleScript's these days (and sometimes even better) so I don't think it'll have any problems. -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Should I retain a variable returned from this accessor?
Peter N Lewis wrote: I'm no Cocoa expert, but I think you're wrong on this, you've missed out a crucial line: At 3:12 PM -0400 11/8/08, Sean DeNigris wrote: // Get uid to return NSString* todoUid = [newTodo uid]; // Clean up [newTodo release]; newTodo = nil; return todoUid; [newTodo release] is not [newTodo autorelease]. So it may immediately call dealloc and dealloc the uid returned by by [newTodo uid]. I don't think so. The problem here is that you're thinking about Scripting Bridge in conventional Cocoa/proxy object terms. This is understandable given that this is the illusion that the SB API is intended to create. *However*, the thing to realise about Apple event IPC is that it's *RPC plus queries* (a very un-Cocoa-like beast), and what SB does is plaster over this mechanism with a load of obfuscations in a well- meaning (but misguided) attempt to make it look and feel like regular Cocoa (which it isn't, and never will be). For example, the whole: iCalTodo* newTodo = [[[iCal classForScriptingClass:@todo] alloc] init]; [[myCalendar todos] addObject:newTodo]; [newTodo release]; rigmarole is just a bunch of pseudo Cocoa-isms on top of a standard 'make' Apple event, which in AppleScript would appear as: tell application iCal to make new todo at end of todos and in objc-appscript - which, unlike SB, is bluntly honest about what's going on beneath - as: ICCommand *cmd = [[[iCal make] new: [ICConstant todo]]; at: [[ICApp todos] end]]; id result = [cmd send]; (I'll spare you the equivalent C though as we'd be here all day.) Basically, all that SB is doing in that first line is creating a temporary SB object representing an application object that doesn't actually exist yet. This SB object contains one or more values that will be used as parameters to a 'make' event that will be sent later. (The one parameter that's always required is 'new'; others may be optional or required depending on the application implementation, type of object being created, etc.) As soon as you pass this object to -addObject:, a 'make' event containing those parameters is sent off to the target application to handle. Once that's done, your original temporary object no longer has any real part to play; unlike Distributed Objects, there is no permanent two-way connection where a local object acts as the official proxy for a remote object as long as both objects remain live. The fact that you can subsequently refer to this temporary object to set and get properties belonging to iCal's newly created todo object is kinda incidental. All that's happening here is that SB is stuffing the object specifier (i.e. query) returned by the 'make' command into your SB object, and subsequently accessing that object's properties is sending fresh 'get'/'set' events to the application with that object specifier as their direct parameter. However, even this aspect of SB's behaviour is misleading; for example, some applications may not return a result for the 'make' event (in which case you'll be talking to air), and many that do will return a by-index or by-name reference that is not guaranteed to identify the same application object the next time you want to talk to it. Also bear in mind that setting properties after -addObject: is called is not the same as setting them as part of the 'make' event; for example, read-only properties can often have values assigned at the time the object is created, but can't be set afterwards. As for memory management of the NSString returned by [newTodo uid], remember that it's the product of a 'get' event sent to the target application, and not something that belongs to or held in an ivar of the SB object that returned it. All SB does is add the NSString to the current autorelease pool before returning it, so once that pool is dealloced the NSString will be disposed of as well unless you -retain it beforehand. Anyway, hope that's of some use, though personally if I were the OP I'd see about using Leopard's new Calendar Store framework instead, thereby avoiding the need to muck about with Apple event IPC at all. Users will also appreciate it, since it means that other applications won't be magically launching while they're running yours. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Accessing memory of another application?
Josh wrote: I'm trying to get started w/viewing/editing/interacting with the memory of another running application but I'm not where to get started. You could think of this as being a simple game trainer - which basically allows you to view and edit values in memory. Use a formal IPC mechanism to communicate between two processes. There's an overview of available options at: http://developer.apple.com/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemTechnology/chapter_3_section_5.html HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Opening an external file in a external application
John Love wrote: I still need to figure out if it is possible for Excel to communicate back to my app via some sort of NSNotification. Very much doubt it, though you always can try Tildesoft's Notification Watcher just to be sure. Depending on the sort of operation it is that you're wanting to monitor (i.e. if it's something that doesn't block the main event loop), you may be able to poll Excel via its Apple event interface; clumsy, but better than nothing. For more specific advice and suggestions, write up a complete description of what you need to do, and try asking on the AppleScript-users list as well as that's where most Excel scripters can be found. I don't have much hope of that .. so what I probably need to focus on is how to display the Excel spreadsheet in my document window. I suspect what you really want is Windows, where Office is a major embeddable application framework in itself. ;) Failing that, there are third-party Excel parsers around for various language if all you want to do is display the spreadsheet post- processing, and don't forget stuff like OpenOffice which contain full- blown spreadsheet engines and Excel file importers/exporters. Really though, what's best/practical/possible all depends on what you're trying to do, so if you want more advice then you'll need to provide more information. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Cocoa / AppleScript Folder Action
John Joyce wrote: I know I can do awkward things with AppleScript and Folder Action scripts, but is there a strictly Cocoa/Objective-C way to do something like Folder Action scripts short of a daemon? Try kqueue or FSEvents. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: How to get music list?
Eric Lee wrote: I have a problem getting the iTunes list, and then making the tableview display the iTunes list. Using objc-appscript [1], here's how to list the name, artist and album of every track in the current playlist: #import ITGlue/ITGlue.h // To create glue files: osaglue -o ITGlue -p IT iTunes int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; ITApplication *itunes = [ITApplication applicationWithBundleID: @com.apple.itunes]; ITReference *tracks = [[itunes currentPlaylist] tracks]; /* Note: if player is stopped then current playlist isn't available. * You could either test for this in advance (as shown here) or check * for nil results after sending the 'get' events. Additional NSError * info is also optionally available. */ if ([[[tracks exists] send] boolValue]) { /* * Note: Apple event IPC is query-based, allowing you to get a * property from all elements at once. This is far quicker than * iterating over elements yourself if there are lots of them. */ NSArray *names = [[tracks name] getList]; NSArray *artists = [[tracks artist] getList]; NSArray *albums = [[tracks album] getList]; int i; for (i = 0; i [names count]; i++) printf(%-60s %-60s %-60s\n, [[names objectAtIndex: i] UTF8String], [[artists objectAtIndex: i] UTF8String], [[albums objectAtIndex: i] UTF8String]); } else printf(Current playlist is not available.\n); [pool drain]; return 0; } HTH has [1] Which is a bit like Scripting Bridge, but without the application compatibility problems and with 10.3.9 and 10.4.x support, better documentation and developer tools. -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: NSDistributedNotifications and scripting languages
Jens Alfke wrote: I was wondering if anyone had any ideas about sending notifications to Cocoa applications using either Ruby, or PHP? I want to send notifications using a cocoa application to another cocoa application and / or send notifications from a web based application. Notifications are a general broadcast mechanism, used to announce that something of interest has happened when you don't know or care who's listening. If you're looking for point-to-point or two-way communication, there are other, more suitable, IPC mechanisms for that. AppleEvents are the standard way to do this. Cocoa's scriptability APIs make it pretty easy to implement AppleEvent/AppleScript support. From Ruby you can use the bridge to invoke AppleScript, and from any language you can launch an AppleScript as a separate task or use the 'osascript' tool to send raw AppleEvents. If the OP is writing both client and server applications for their own use and both are using Cocoa, I'd suggest looking at Distributed Objects first. Apple events can be a bear to do well - the main reason for using them is if you need to talk to third-party applications, or allow third-parties to talk to yours. Also, I'd strongly recommend Ruby or Python over PHP since the first two have excellent and very mature Apple event and Cocoa bindings while PHP doesn't have either. HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Learning Cocoa with RubyCocoa
Allison Newman wrote: I can't for the life of me imagine why you would think that. I mean, I'm not theorising here, I have actually done it. My very first Cocoa app was a RubyCocoa app, and my second, a true, full- featured app, is just about done. And you know what, I never did regret my decision to not really learn Objective C. FWIW, all my Cocoa apps are in PyObjC and that's how I started out too: I already knew Python and a bit of C, so picked up just enough ObjC to be able to read Hillegass and the Apple documentation and examples, and got stuck in. Slightly more hassle to use Cocoa from Python than ObjC since there is a degree of impedance mismatch between the two, plus you have to mentally translate Cocoa API docs to Python syntax. OTOH, Python's a quicker and easier language to work in than C (which Cocoa ameliorates but does not escape), plus you get scads of Python libraries to draw on as well. So I think it about balances out in the end. As for Ruby and RubyCocoa, the Prags have just released a PDF beta of Brian Marick's new RubyCocoa book: http://pragprog.com/titles/bmrc/rubycocoa I've not checked it out myself yet, but maybe some of the Cocoa/Ruby folks here will be interested in taking a look, whether for their own education or to provide corrections and suggestions for improvement. And don't forget MacRuby either, an extremely promising project by Laurent Sansonetti (the Apple engineer behind Leopard's Ruby support) which aims to make Ruby a full peer to ObjC for Cocoa development. The 0.2 release has just been announced: http://www.ruby-forum.com/topic/155593 HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: What's the NSMailDelivery replacement for Leopard and Beyond?
Buddy Kurz wrote: For me it is a hot topic because after researching this subject two years ago and reading said archives I started relying on NSMailDelivery and now the powers that be have decided that it should no longer be available. (wondering why?) So I have to rewrite functional code and use a third party framework or the scripting bridge which by the way isn't backwards compatible with Tiger. What's wrong with third-party frameworks? There's some excellent work out there and, assuming a compatible license, they're trivial to include in your application bundle for distribution. As for having to rewrite functional code; well, NSMailDelivery is only deprecated, not removed, at this point, so in principle you can continue using it for now (although it's probably good idea to look for an alternative sooner rather than later). BTW, I wouldn't recommend using SB unless you specifically intend to interact with a particular mail client (or clients, bearing in mind that not every Mac user uses the same email client), given that it's hardly a transparent process: at the very least, users will notice when your app launches their mail client. I'll also mention that SB is lame and Mail's scripting interface buggy, so depending on what you need to do there may be some grinding of teeth involved at the very least. Best to ask on AppleScript-users mailing list if you need help there. Lastly, if backwards-compatibility is an issue for controlling scriptable applications, then your choices are either to invoke AppleScripts via NSAppleScript or use objc-appscript (another third- party framework that is, shockingly, better than the Apple alternative). HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: invoking quicklook via code
Nick Zitzmann wrote: Thanks for the replies guys. What I would like to do, may be a lot simpler than what i may have explained. I just want my app to launch the quicktime movie, in what looks like exactly like the finder quicklook window - in fact if its possible to even somehow do it with an applescript or something - i.e. just tell finder to launch it! Is that possible? I'm pretty sure that can't be done with AppleScript unless accessibility is turned on. GUI Scripting is crude and brittle and really a last resort when all else fails. Unfortunately, there's nothing in Finder's scripting API for invoking quicklook (its 'open' command just opens files in the default editor, equivalent to double-clicking them), so it may be the OP's only hope if they _really_ must have it. Though FWIW, GUI Scripting is just a wrapper around OS X's existing accessibility APIs, so going through AppleScript isn't really necessary at all. It may be easier to just use QTMovieView. Yeah, I think this would be the simplest and most reliable solution. (And by all means file feature requests on Finder for 10.6; its scripting interface is lagging its graphical one a bit these days.) HTH has -- Control AppleScriptable applications from Python, Ruby and ObjC: http://appscript.sourceforge.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]