NSInvocation in Objective-C++

UPDATE: This article was initially about some difficulties that I had calling some Objective-C++ code from C++ in a dynamic way using NSInvocation, which failed in the first place. I switched to directly calling the IMP pointer instead while passing C++ object pointers as arguments. Thanks to the comments that I received from bob, an obviously very experienced Objective-C++ developer, I could change the code and make it work also with NSInvocation.

Here is a C++ class that represents the details of a notifier/observer association called Observation:

    class Observation: public Object {
    public:

        void setObjcObserver(NSObject *theObserver) { _nsObserver = theObserver; }
        void setObjcSlot(SEL theSlot) { _nsSlot = theSlot; }
                
        void notify(bool complete);
        
        Observation() : _nsObserver(nil), _nsSlot(nil) {}
        
    private:

        Object *_notifier;
        NSObject *_nsObserver;
        SEL _nsSlot;
    };

First Attempt Using NSInvocation Failed

    void Observation::notify(bool complete) {

        NSMethodSignature *aSignature = [[_nsObserver class]
                        instanceMethodSignatureForSelector:_nsSlot];

        assert(aSignature);
        assert([_nsObserver respondsToSelector:_nsSlot]);

        NSInvocation *anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
        [anInvocation setSelector:_nsSlot];
        [anInvocation setArgument:this atIndex:2];
        [anInvocation setArgument:&complete atIndex:3];
            
        [anInvocation invokeWithTarget:_nsObserver];
    }

this code compiled fine but it crashed as soon as I tried to access members of the received Observation object in Objective-C.

IMP Based Solution

My approach to solve the issue is that I am directly calling the IMP of the method in the observer object. For this, I slightly change the C++ Observation model to cache the IMP pointer:

    class Observation: public Object {
    public:

        void setObjcObserver(NSObject *theObserver) { _nsObserver = theObserver; }
        void setObjcSlot(SEL theSlot) { _nsSlot = theSlot; }
                
        void notify(bool complete);
        
        Observation() : _nsObserver(nil), _nsSlot(nil), _nsSlotImpl(nil) {}
        
    private:

        Object *_notifier;
        NSObject *_nsObserver;
        SEL _nsSlot;

        typedef void (*slotImpl_t)(__strong id, SEL, lang::Observation *, BOOL);
        
        // used to cache the IMP of the objcSlot
        slotImpl_t _nsSlotImpl;

    };

Here, I simply add a typedef of the desired observer method signature called “slotImpl_t” and a member to cache the IMP function pointer. The cache would not be necessary but in my case the observer IMP will not change, so I cache it in order to save the look-up on frequent execution of the code. The notify() method now looks different:

    void Observation::notify(bool complete) {
        if(!_nsSlotImpl) {
            _nsSlotImpl = (slotImpl_t)[_nsObserver methodForSelector:_nsSlot];
            assert(_nsSlotImpl);
        }
        _nsSlotImpl(_nsObserver, _nsSlot, this, complete);
    }

This is working like a charm now. The address of the Observation object at the receiving end is correct as it should be, even in case of multiple-inheritance combined with virtual inheritance.

Correct Solution with NSInvocation

It turned out that in my original solution using NSInvocation I did it wrong. NSInvocation needs the address of the this pointer and not the this pointer itself. To make it worse, when simply doing

        [anInvocation setArgument:&this atIndex:2];

the compiler complains with the error:

Address expression must be an lvalue or a function designator

So, instead of &this it has to be an lvalue which essentially requires to copy the this pointer to a temporary variable, ‘temp’ in this case. Here is the complete and working code:

    void Observation::notify(bool complete) {

        NSMethodSignature *aSignature = [[_nsObserver class]
                        instanceMethodSignatureForSelector:_nsSlot];

        assert(aSignature);
        assert([_nsObserver respondsToSelector:_nsSlot]);

        NSInvocation *anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
        [anInvocation setSelector:_nsSlot];
        Observation *temp = this;
        [anInvocation setArgument:&temp atIndex:2];
        [anInvocation setArgument:&complete atIndex:3];
            
        [anInvocation invokeWithTarget:_nsObserver];
    }

Conclusion

There is expert knowlegde about Objective-C++ available on the planet. But it’s not easy to get access to it. Sometimes, it helps to blog about a problem and the solution will come and find you;) Again, bob, thank you very much

Multiple Inheritance in Objective-C / Core Data vs C++

Multiple inheritance is hard. In fact it is so hard, that only very few programming languages support it. Objective-C is one for instance, where support for multiple inheritance is limited to the conformance to @protocols. Behavior can only be inherited from one single base class.

If you need multiple inheritance in Objective-C you have several options to choose from. Most of the time when you are looking for answers to the question of how to do multiple inheritance in Objective-C the right way, you will be pointed into one of two directions: #1 don’t use it because it implies a flawed design. #2 do it using composition (via delegates).

Option #1 I do not like at all. There are cases where MI is very well suited and only because Objective-C doesn’t support it doesn’t mean it is bad. It just means that the language designers considered it way too complicated to implement for the benefit of a few cases where it makes sense.

For instance, my current use case with strong need for multiple inheritance support is the UML specification. UML makes heavy use of multiple inheritance and if you study the UML model you will find that the abstractions found in there make very well sense because they eliminate redundancy and the need to explain what’s going on. All those abstractions are basically orthogonal classifications which can be combined in a subclass to express things very precise and in a type-safe manner.

So, if you are forced to deal with multiple inheritance in your program you can do so with option #2 in Objective-C. However, in my opinion, this has limitations. I will give you an example: Imagine a model like this:

Let’s say we map this to the following physical implementation in Objective-C. Here, the greenish elements are Objective-C @protocol and the yellowish elements are Objective-C @class:

It follows the often heard recommendation to map inheritance using composition. Here, the Class part of an AssociationClass is mapped to a delegate called “theClassImpl”, whereas the Association base class is mapped to plain Objective-C inheritance.

Suppose now we want to map this structure to CoreData. We need to model NSManagedEntity with NSManagedProperty. CoreData does not work on top of @protocols but on actual @classes. Therefore, we have one physical implementation of the association between Class and Property (owningClass-properties).

But here comes the big BUT: This can only work if we have full control over the OR mapping! CoreData on the other hand, does not rely on interfaces but on the actual implementations. That means, we must publish the otherwise internal composition mapping of theClassImpl to CoreData. If we then have a client of Class (for instance: Property::owningClass) then it will not be possible to downcast such a Class obtained from the persistence layer into an AssociationClass. Instead, it would be necessary to navigate backwards from the Class to the actual AssociationClass. But this kind of “alternative” cast can not be implemented transparently using Objective-C language constructs. An [aClass isKindOfClass:[AssociationClassImpl class]] would yield a technical “NO” and it’s not possible to extend the language to make it yield “YES”.

Such an MI -> SI mapping scenario can only work if every consumer solely relies on the Interfaces only and makes no assumption about internal structures. This would imply that the ORM uses factories instead of instantiating from its meta information. In CoreData, this is not the case.

This is why you can pretty much ignore the advice how to map multiple inheritance at the language level if you don’t also consider the APIs you’re dealing with because those APIs will render the easy sounding solution in the context of reality useless pretty quickly. In my case, I was forced to implement the model part of the system in C++ because C++ has awesomely good support for multiple inheritance. All problems related to the mapping of multiple inheritance to the microprocessor architecture had been solved by Bjarne Stroustrup in C++ since day 1. Read here why and how: http://drdobbs.com/184402074

Here’s how the dreaded diamond from the example above would be implemented in C++:

class Element {
};

class Association: public virtual Element {
};

class Class: public virtual Element {
public:
    std::vector<class Property*> properties;
};

class Property: public Element {
public:
    Class *owningClass;
};

class AssociationClass: public Association, public Class {
};

A straight 1:1 mapping of the concept to the language. Here, class “AssociationClass” would fully inherit the behavior of Class::properties without the need to implement something special. It just works. But, in comparison to Objective-C the C++ implementation lacks support for Core Data. But: so does multiple inheritance in Objective-C with CoreData! So no real difference here.

Conclusion

Multiple inheritance with CoreData is close to impossible except for very simple cases. With C++, besides all its ugliness and controversy, at least you get multiple inheritance in the language and usually in an implementation quality without the need to waste your time thinking around the whole concept.

How to Develop a Facebook App on Your Local Server using SSH

When you develop for facebook you usually run you app on your developer machine and connect a test app in Facebook with the local installation. Once finished, you put the final app onto some dedicated server and connect the real Facebook app to that. So setting up the local development environment usually includes some network setup, for instance as described here: http://www.insidefacebook.com/2007/07/16/how-to-local-facebook-app-development/ However, I find these router and network setup design troublesome and I also want something that is flexible, especially when I switch from desktop to mobile development.

If you have access to a dedicated, root or v-server on the internet, you can achieve a very easy network setup using ssh port forwarding. You basically use the internet box as the target url for your Facebook app and forward some port from that internet port to your local test web server over the ssh tunnel. By doing so, you are totally mobile, you can open the port on the internet box from anywhere you want.

So, let’s say you configured your facebook app “myapp” like this:

You see in this example that facebook will tell your browser to load the iframe content from the URL http://my-domain.com:9090/ that is on port 9090. So you need to forward this port 9090 to your developer machine.

In order to forward ports on public network interfaces you will mostly need to enable the “GatewayPorts” option in the ssh server of you internet box. This is a setting in the /etc/ssh/sshd_config (Debian):

just add the following line to /etc/ssh/sshd_config:

GatewayPorts yes

and

/etc/init.d/ssh restart

Then you can start forwarding the port to your local machine. Just issue an

ssh -R '*:9090:localhost:9000' me@my-domain.com

It will look like you just only logged into the remote machine but in addition to that, a tunnel has been opened from port 9090 remote to port 9000 local. So if you have something listening on your local machine on port 9000, i.e., your development web server, than you can point the browser to your facebook app:

http://apps.facebook.com/myapp

and it will display the content as retrieved via the tunnel (9090) from your local machine (9000). As soon as you close the ssh connection, the tunnel will also be gone and you can then initiate the same ssh connection from you laptop if you are going outside.

The biggest benefit of this solution is that you will never have to change IP addresses anywhere, not in the facebook app setting, not at dyndns etc. This is especially useful if your IP address changes frequently like on mobile internet.

Pretty simple, and no need to configure multiple apps for multiple environments. Just move and reconnect via ssh. If you want, you can easily do the next step and put a web server like Apache or nginx on the internet box. From there you can reverse proxy from a certain virtual host (e.g., dev.my-domain.com) to your forwarded port on the same machine (9090). In a setup like this, you would not need to enable the “GatewayPorts” option in the ssh server, because then it would be sufficient to listen only on the local interface (127.0.0.1:9090). Such a setup would be a little closer to most production setups with load balancers and such.

Beware of this: play framework’s cascaded save() only works on loaded collections

I am currently developing a web application using the really excellent play framework. If you are a web developer with some Java background I strongly encourage you to give it a try.

However, play has taken a little different or let’s better call it an additional approach to control object synchronizations with the underlying database. Whereas JPA manages a loaded object graph and automatically persists any changes upon transaction completion, play has changed this behavior (“Explicit save”) to give the beginner more control over what is going on with the objects. This extension turns the implicit save mechanism into an explicit one where the developer is in control to call save() on the changed objects. This save() will in turn cascade (if for instance the CascadeType.ALL annotation option is present) to the reachable objects.

This might in the first place seem clever because you get control back but I have mixed feelings about it because there are cases where it does just not work as easily as expected.

As an example, imagine a 3-level parent-child object model.

@Entity
public class Item extends Model {

 @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy="item")
       @OrderBy("createdAt")
 public List<Position> positions = new ArrayList<Position>();
}

@Entity
public class Position extends Model {

 public Date createdAt = new Date();
 public int quantity;

 @ManyToOne public Item item;

 @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy="position")
 @OrderBy("createdAt")
 public List<Order> orders = new ArrayList<Order>();
}

@Entity @Table(name="Ordr")
public class Order extends Model { 
 public Date createdAt = new Date();
 public int quantity;

 @ManyToOne public Position position;
}

So far nothing complicated. But now imagine you are loading (for performance reasons) objects from the lowest level (Order) and manipulate the parent object (i.e., the Position).

public void dostuff(Item item) {

 // load orders according to some important criteria
 List<Order> orders = Order.find("position.item = ? order by createdAt", item).fetch();

 // manipulate the parent of the order (the Position)
 Order order = extractImportantOne(orders);
 order.position.quantity += 200;

 item.save();
}

Intuitively I would assume that the manipulated Position object is updated in the database through the Item.positions cascade settings. But this is not the case here! The reason is that the collection Item.positions has not been populated from the database. Thus, play sees an unintialized PersistentCollection and will simply ignore to cascade.

One solution to the problem would be to touch the cascading collection:

 item.positions.size();
 item.save();

This will make sure the ‘positions’ collection will be considered during the following call to save(). With pure JPA on the other hand, such a call to do the trick would never be necessary and also the call to save() could be avoided, because JPA knows all loaded and changed objects and automatically updates the database.

This is why I have very mixed feelings about play’s extended persistence API. It works well in simple cases but for more complex models it might be better to switch back to plain JPA mode.

Accessing the Original WebKit API in QtWebKit Hybrid Apps

Everybody wraps WebKit

For each and every port of WebKit, be it Safari, Chrome, QtWebkit, there is always a wrapper around the WebKit object model. These wrappers function as language mappers, e.g., in case of Safari C++ API is mapped to Objective-C, and as a simplification layer around the complex WebKit API. The first case makes total sense, as no developer familiar with Cocoa and Objective-C will like to take an excursion (back) to C++. On the other hand, the Chrome port as well as the Qt port expose a C++ API towards their developers and completely hide the WebKit API despite that this is also already written in C++. Within the C++ universe, I do not understand why the original WebKit API is such a bad bet and must be hidden under all circumstances (I derive this from the fact that everybody hides it)? Is it really that evil?

WebKit API is very stable as it is a reflection of HTML and XML and all the things used in the browser for years and which do rarely change, so a dependency should be acceptable. The only benefit is that the Qt developer works solely with the Qt API or the Chromium developer with a Chromium API. This is ok in case of very simple integration with WebKit, like displaying some external web content in an otherwise traditional application or when implementing a browser. But not in a hybrid application! In a hybrid application I want much more control over the internals of the browser. I do not consider it evil. I consider it as a very nice work horse doing most of the rendering and layout work. I want to reference DOM elements from my application and I want the DOM to interact with my application. I want to replace the excessive use of JavaScript found in Web 2.0 apps with excessive C++ – I do not want JavaScript in a hybrid app, I want C++ only!

In case of QtWebKit, how hard is to get access to the original WebKit API? It is very hard, as the necessary headers are all eliminated from the QtWebKit API and all WebKit symbols are local in the compiled DLL or OS X framework However, I have taken the pain and hacked me into it. The steps required to expose the WebCore API via QtWebKit are:

Get the source tree from Qt git

You will need to build from source. So, get it from http://qt.gitorious.org/qt and switch to the desired branch or tag.

Configure Qt just as normal

configure it but do not run make now!

Adjust the compiler flags for WebCore

run the following commands in the source tree

sed -i -e 's/-fvisibility=hidden//g' src/3rdparty/webkit/{Web,JavaScript}Core/Makefile.*
sed -i -e 's/-fvisibility-inlines-hidden//g' src/3rdparty/webkit/{Web,JavaScript}Core/Makefile.*

(or change these the Makfiles manually) This will compile WebCore in way to expose all internal symbols later in the DLL or framework.

Gain access to the WebKit API

In src/3rdparty/webkit/WebKit/qt/Api/qwebelement.h make QWebElement::m_element public

This is just one way to do it (see later for an alternative)

Build Qt

Now run the normal make; make install

Add WebKit header files and defines to your .pro file

The application code needs to include the WebCore header files.

DEFINES += QT_SHARED ...
release:DEFINES += NDEBUG
INCLUDEPATH += /Users/andre/src/qt/git/src/3rdparty/webkit/WebCore/bridge/qt \
    /Users/andre/src/qt/git/src/3rdparty/webkit/WebCore/page/qt \
    ...

This is a very shortened version to save space here. See the full set of defines in this file: myapp.pri

The order is important. Replace /Users/andre/src/qt/git with the home of your Qt source tree. Some defines are very important and some might be just optional, I just took all of them from the effective compile command when Qt was built.

Include WebCore headers in application code

#include <WebCore/html/HTMLElement.h>
#include <WebCore/platform/text/PlatformString.h>
#include <WebCore/platform/text/CString.h>
#include <WebCore/svg/SVGElement.h>
...

Alternative access to QWebElement::m_element

Instead of changing the visibility of the “m_element” member from private to public, it would also be possible to use a fake subclass in the application code with a public member m_element like here:

class HackWebElement: public QWebElement {
public:
WebCore::HTMLElement *m_element;
};

and then gain access to it by down-casting a QWebElement to a HackWebElement:

QWebElement webElement = ...;
HackWebElement *hwe = (HackWebElement*)&webElement;
// now we can access hwe->m_element

You can also use your preferred method to access a private member in C++ 😉

Using the WebKit API

Now I can do fancy stuff with the WebKit API. Here is an example where I create an SVG element programmatically, i.e., without the need to have WebKit parse some HTML (or XML in this case):

WebCore::QualifiedName svg("svg", "svg", "http://www.w3.org/2000/svg");
RefPtr<WebCore::SVGElement> nel = WebCore::SVGElement::create(svg, hel->document());
WebCore::String s = nel->tagName();
debug(string(s.utf8().data()));
if(nel) {
    debug("it's a WebCore::SVGElement!!!");
}

Conclusion

So far, I have only gained initial access to the internal browser DOM as a first step. This way I can create DOM elements programmatically. In the future, I will experiment with event handlers on DOM objects written in C++ in order handle all UI events in the C++ part of my application. This will reduce the browser part to act as a pure layout and rendering engine which I think should be its sole role in a hybrid application.

Regarding the little “hacky” approach I can say that there is only one place on the whole application code where access to WebKit is gained. This can be in the document, in the frame, or like here in the general element. From then on, no further hacks are required, it is just used and QtWebKit is not needed any more.

I would also wish that in ports like QtWebKit the WebCore API is preserved and exposed to the application developer. I think there are 2 aspects in a WebKit port: One is the physical rendering and display and the other one is the kind how WebKit embeds into the application and is access. Both concerns should be considered separately and I want to be free to consume only the first one and live with the original in the latter one.