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?

A D M I N

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. // Link.mm -- 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( "http://www.bantherewind.com" ); } CINDER_APP_BASIC( LinkApp, RendererGl ) When you start this Cinder application, http://www.bantherewind.com 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.