The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniFocus Extras (http://forums.omnigroup.com/forumdisplay.php?f=44)
-   -   How can I create a task, using Objective C (or PyObjC)? (http://forums.omnigroup.com/showthread.php?t=9067)

Tommy@heltenkelt.se 2008-07-29 12:47 PM

How can I create a task, using Objective C (or PyObjC)?
 
In AppleScript, a new task can be created like this:
[INDENT]tell front document of application "OmniFocus"
make new inbox task with properties {name: theName}
end tell[/INDENT]
But what would be the corresponding message to create a new task in Objective C (or PyObjC)?

Tommy@heltenkelt.se 2008-07-31 04:09 PM

Partly solved - but what do i do with a future task
 
I have partly solved the problem. With PyObjC a new inbox task object can be created like this:
[INDENT]omnifocus = ScriptingBridge.SBApplication.applicationWithBundleIdentifier_('com.omnigroup.OmniFocus')

omnifocus.classForScriptingClass_('inbox task').alloc().initWithProperties_({'name': 'Computer created task'}) [/INDENT]
But, this is a "[I]future[/I] OmniFocusInboxTask", and does not show up in the inbox.

How should I do to stop it being [I]future[/I], and start showing up in the present?

curt.clifton 2008-07-31 05:53 PM

Sorry for the silence on the thread. I haven't tried to automate OF other than with AppleScript, but you seem to have crossed the syntax "bridge", as it were, so maybe I can help now.

What do you mean by "future" OmniFocusInboxTask? A "future" is a fairly arcane programming languages term, but I'm guessing you mean something else.

Wim Lewis 2008-07-31 09:02 PM

A couple of off-the-cuff ideas, from someone who's not familiar with ScriptingBridge:

Have you looked at the Python "appscript" module? It might be easier to use because there's only one layer of translation going on (Python to the AppleEvents object model)*rather than two (Python to Objective-C to AppleEvents).

My other thought is that you might have to insert the newly created object into a container before it becomes real. Applescript-accessible objects can't exist in a vacuum; they need to be "in" something (possibly just in the application object). ScriptingBridge might be waiting for you to provide the newly created task with a location before it actually sends the AppleEvent to create it.

Tommy@heltenkelt.se 2008-08-01 11:51 AM

Cache 22?
 
Curt: [QUOTE=curt.clifton;43311]What do you mean by "future" OmniFocusInboxTask? [/QUOTE]

The object created by the code above, is described by PyObjC like this:
[INDENT]<future OmniFocusInboxTask with properties { name = "Task name"; }>[/INDENT]
I suspect that "future" may be ScriptingBridge's way to indicate that the apple event to create the object is not yet sent. But that's just a theory.


Wim: [QUOTE]My other thought is that you might have to insert the newly created object into a container before it becomes real[/QUOTE]

I think you are right about this. I've tested recreating the code in F-script, and the error message I get there is "object has not been added to a container yet".

But how do I assign it to a container?

In OmniFocus applescript dictionary I found this:
[INDENT][B]assigned container[/B] (item) : Inbox tasks (those contained directly by the document) have a provisionally set container that is made final by the 'compact' command. This allows you to set and get said container. The container must be either a task (not in the inbox or contained by an inbox task), a project or 'missing value'.[/INDENT]
But despite trying a lot of different aproaches, I've not been able to make it work.

I'm not 100% sure, but the problem seams to be that
[INDENT]omnifocus.classForScriptingClass_('inbox task').alloc().initWithProperties_({'name': 'Computer created task'}) [/INDENT]
results in a object that is a ScriptingBridge proxy object. This object as such is unable to respond to messages like [I]compact()[/I], [I]setAssignedContainer_()[/I] and [I]addObject_()[/I]. Normaly, this would be easy to solve by adding a [I]get()[/I], to get the real object, but for some reason this results in an error.

Maybe it's a cache 22-like bug: To attach the object to a container you need to send a [I]get[/I] to it, but since it's not attatched to any container this is not possible....

Another, equally likely, possibility is that I haven't got the sytax quite right.

If anyone has managed to create a new task in OmniFocus, using Objective C, Python, F-script or Ruby, it would be extremely interesting to see the code.

Until then, I might try the applescript in Python workaround Wim suggested.

curt.clifton 2008-08-01 01:43 PM

A stab in the dark, but is it possible to include the assigned container in the properties list of the original init call?

Tommy@heltenkelt.se 2008-08-01 02:28 PM

[QUOTE=curt.clifton;43460]A stab in the dark, but is it possible to include the assigned container in the properties list of the original init call?[/QUOTE]

Interesting idea, but I can't get that to work.

Tommy@heltenkelt.se 2008-08-01 02:40 PM

Workaround
 
Here is a workaround, using applescript within Python, as Wim suggested:

[CODE]import os

def createInboxTask(name):
cmd = """osascript<<END
tell front document of application "OmniFocus"
set newTask to make new inbox task with properties {name: "(Placeholder)"}
end tell
END"""
os.system(cmd)

newTask = [task for task in of.application.defaultDocument().inboxTasks() if task.name()=='(Placeholder)'][0]
newTask.setName_(name)
return newTask[/CODE]

Wim Lewis 2008-08-01 04:26 PM

Actually, I was suggesting using the [url=http://appscript.sourceforge.net/py-appscript/index.html]appscript[/url] module, not using AppleScript. I really like the appscript module.

Re ScriptingBridge, check out the [url=http://developer.apple.com/documentation/Cocoa/Conceptual/ScriptingBridgeConcepts/UsingScriptingBridge/chapter_3_section_7.html]Scripting Bridge Programming Guide for Cocoa section on Creating and Adding Scripting Objects[/url].


All times are GMT -8. The time now is 09:06 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.