How to determine the owner of a SOPE object?

NSString *login = [soObject ownerInContext:_ctx];

Note that most SOPE objects currently have not associated owner or just return the login account.

The authenticator can be retrieved using:

[soObject authenticatorInContext:_ctx];

How to I find out the current login?

SoUser *user = [[soObject authenticatorInContext:_ctx] userInContext:_ctx];
NSString *login = [user login];

Note: user lookup depends on the object! SoUser is a protocol and a default implementation.

You can find out the active roles for a login using:

[[soObject authenticatorInContext:_ctx] rolesForLogin:@"donald"];

Or Using:

[soUser rolesInContext:_ctx];
[soUser rolesForObject:soObject inContext:_ctx];

Why doesn't WebDAV work in my SOPE application?

Note that the SOPE WebDAV support requires that proper URLs are build. So you need to ensure to implement either -baseURLInContext: or -container and -nameInContainer.

How do I reset state in my SOPE traversal object?

Implement the -sleep method, this is called by SoObjectRequestHandler. There is also a private method called -_sleepWithContext: which may become a public method later on.

My objects cannot be located, how can I debug?

Its often necessary to debug object path traversal to understand why subobjects are not found, why wrong objects are found or why objects are found at all.
Those options come to rescue:

-SoDebugObjectTraversal YES
-SoObjCClassDebugEnabled YES
-SoDebugKeyLookup YES

Traversal debug shows how an object "path" is processed, eg the path submitted as part of the URL.
ObjC class debug shows what "action" methods are found directly in the classes (eg viewAction: or GETAction:).
Key lookup debug logs the individual name lookups and their results.

How do I invoke a method without changing the URL?

Like in ASP you can use the ?Cmd query parameter to specify a method to call:

http://myhost/myapp/so/Calendar/134/view

Can be written as:

http://myhost/myapp/so/Calendar/134?Cmd=view

The latter has the advantage that all contained links are automatically correct and relative to the clientObject instead of the method.

How can I invoke different methods depending on the submit button?

If you have multiple submit buttons, you probably want to invoke different actions ;-) Especially for someone coming from WebObjects it might be non-obvious that this isn't so simple in HTML because an HTML form only has one URL attached to it!

So to trigger methods by submit buttons you need to detect a value submitted and this is supported by SOPE. Just give the submit button a name like:

<input type="submit" value="save" name="saveIt:method"/>
<input type="submit" value="move" name="moveIt:method"/>

This will call add saveIt or moveIt to the form URL to invoke the appropriate method.
Note that the element name is used because the submit button value is actually the label of the button displayed in the user interface.

How do I invoke a different method depending on a popup?

This is similiar to the trick above. SOPE supports a special form parameter :method which can be used to trigger a different method depending on a form value.
(actually this is something not supported by WebObjects ;-)

<select name=":method">
<option value="saveIt">save</option>
<option value="moveIt">move</option>
</select>

This will add moveIt or saveIt to the object activation path depending on the selection.

When I try to access my new SOPE object, I get a 403

If you get a HTTP 403 status code, you probably have your object permissions mixed up. You can use the SoSecurityManagedDebugEnabled default to debug the permission processing.

A common cause for 403 is a new SOPE class which has no proper security declarations in product.plist.