All   Archive   Code   News   Projects  


My name is Stephen Schieberl. I live in the woods near Portland, Oregon. Hit me up to work together.

Ban the Rewind?


When working with C++ on iOS, it is sometimes necessary to rely on UIKit and other Objective-C libraries. Or vice-versa -- where you want to implement a C++ library in your Objective-C application. The trick to doing this is to create two headers, one for each language, and a single mixed implementation file. To demonstrate this, I put together a class which allows you to open a link in mobile Safari from C++. Below is the header for a C++ class with one static method which accepts a URL to open externally. // Link.h - C++ #pragma once #include <string> class Link { public: static void openUrl( const std::string &url ); }; This is the header for the Objective C file which will actually open the URL using UIKit. // Url.h -- Obj-C #pragma once #import <CoreFoundation/CoreFoundation.h> @interface Url : NSObject { } + ( void )open:( NSString* )url; @end Below is the implementation file. Make the extension "mm", which will tell XCode to compile it as "Objective C++" (you can set this manually, as well). You can write C++ and Objective C interchangeably without error. Here, we include both headers, as well as UIKit. Url::open is implemented in Objective C. Link::openUrl is implemented in C++. The C++ function creates a Url instance with a mix of Objective C and C++, then passes its argument Url::open. Essentially, the static C++ method is merely acting as a delegate to get to the greater functionality in the Objective C. // -- Obj-C++ #include "Link.h" #import "Url.h" #import <UIKit/UIKit.h> @implementation Url + ( void )open:( NSString* )url { [ [ UIApplication sharedApplication ] openURL:[ NSURL URLWithString:url ] ]; } @end void Link::openUrl( const std::string &url ) { [ Url open:[ NSString stringWithCString:url.c_str() encoding:[NSString defaultCStringEncoding ] ] ]; } Now include only the C++ header in your application. Being Cinder-centric, the code sample below is in Cinder, but this will work in any framework or standard C++ application. // LinkApp.cpp -- Cinder C++ application #pragma once #include "cinder/app/AppBasic.h" #include "Link.h" class LinkApp : ci::app::AppBasic { public: void setup(); }; void LinkApp::setup() { Link::openUrl( "" ); } CINDER_APP_BASIC( LinkApp, RendererGl ) When you start this Cinder application, will open in mobile Safari via UIKit. If your main application is in Objective C, you would swap the functionality between the two languages and import the Objective C header. If, for example, you want to do some image processing in Cinder from an application with a UIKit interface, you'd write your functionality in C++ and use Objective C as a delegate.