OMAC - Open Music App Collaboration Application Registry Resources

Developer's Guide - Step by step

Firstly, an app can implement one or more (but usually/preferably all) of the following concepts:
  • Fast Switch Receiver - you want other (sender) apps to be able to fast switch to your app and include your app in their own list.
  • Fast Switch Sender - you want to be able to fast switch from your app to registered receivers and list other apps in your app.
  • Fast-switch MIDI Receiver - you want to allow users to switch to and from your app via MIDI messages.

Implementing Fast Switch Receiver

Step 1 - update your app's Info.plist

First, your app's Info.plist needs an URL Name and Scheme. The following code snippet can be copied/pasted into your own Info.plist. This is the example entry. Make sure that you change the two values to match your application.

<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLName</key> <string>com.example.appname</string> <key>CFBundleURLSchemes</key> <array> <string>appname</string> </array> </dict> </array> Change the CFBundleURLName and CFBundleURLSchemes array
to match your app!

Note: The value you specify in the string of CFBundleURLSchemes should be all lower case, as it will translate to an URL of appname://

Step 2 - register your app with the OMAC Registry

Use the quicklink at the top of this page to request your app be added to the registry. Detailed instructions for the information that should be provided are on the registration form.

Once your app is registered and released with corresponding changes to the Info.plist in the AppStore, sender apps will be able to detect and fast-switch to your application.

Implementing Fast Switch MIDI Receiver

A free to use class is available (use quicklinks above) that you may download and use in your own application code. This guide will assume you use the free class and have downloaded the zip file, unpacked it somewhere and added to your project.

Obviously your app needs either its own virtual destination or it should listen to a virtual source that will produce the messages. Currently this is 'MidiBridge', but you're best off declaring an OMAC compliant virtual CoreMIDI pair for your own app.

Step 1 - use the OMACApplicationRegistry class to process switching messages in your app's MIDI engine

// Code snippet to be included in an app's MIDI Engine when a new MIDI // message is received. You can use a static pointer for efficiency in // creating an omac registry object. // Assuming that your MIDI message is in an unsigned char array like so: // unsigned char midi_message_data; // unsigned short midi_message_length; #import "OMACApplicationRegistry.h" // check/process OMAC app switching message static OMACApplicationRegistry* omac = nil; // use OMAC macro to avoid function call overhead if (IS_OMAC_MIDI_MESSAGE(midi_message_data)) { // create a static omac instance if not already done. Only pass nil // as AppName if you instantiate the omac instance in your app startup if (omac == nil) omac = [OMACApplicationRegistry instanceWithAppName:nil]; // ask the object to process the OMAC switching message [omac processMIDIMessage:midi_message_data:midi_message_length]; }

Step 2 - Notify the registry that your app supports MIDI switching

Use the email address below to let us know and we'll update the registry entry for your app to indicate that it supports MIDI switching. Best to do this once your app is released, though!

Implementing Fast Switch Sender

A free to use class is available (use quicklinks above) that you may download and use in your own application code. It includes DNS versioning and background thread updating. Of course, you can create your own class if you prefer. This guide will assume you use the free class and have downloaded the zip file and unpacked it somewhere.

Step 1 - Add the class and plist to your project You should add the OMACApplicationRegistry.[hm] and omac_apps.plist to your project. In particular, the plist will be included in your app bundle so that in the event of a user not having internet connectivity to access the registry, there will still be something for the class to use.

Step 2 - Implement the class in your code

This is best explained by example and assumes that you have a ViewController class that you will be using the registry with:

In your ViewController's header file:

#import "OMACApplicationRegistry.h" // your ViewController should confirm to the OMACApplicationRegistryDelegate // protocol if you want to update the shared property list in the background. // If you don't want background thread updates (ie. you're OK with updating the // plist on your main thread when you start, then no need to conform to the // protocol. However, background thread updates are recommended @interface myViewController : UIViewController <OMACApplicationRegistryDelegate> { ... }

In your ViewController's implementation file:

- (void)viewDidLoad { ... // OMACApplicationRegistry initialisation // You can set the following global variable to YES and the class // will log/trace to the console. Don't leave this as YES in a // production build!!!! OMACTrace = NO; // Obtain the shared instance of the registry object. The name // you pass in *must* match the Application Name that you registered // your app with in the registry. You only need to pass this name in // once (first call to instanceWithAppName). If the instance failed // then it will return a nil. OMACApplicationRegistry* omac; omac = [OMACApplicationRegistry instanceWithAppName:@"MyApp"]; if (omac != nil) { // If you are going to perform any plisgt update in a background // thread, then specify a delegate (you must conform to the // protocol). If no delegate is specified then the update method // will execute on the current thread. omac.delegate = self; // update (if necessary) the property list. If current version of // the property list is up-to-date, then no update will be fetched // NB. Any updated property list is stored in the application's // Library/Caches directory enum OMACUpdateStatus status; status = [omac update]; // you can check the return status of update. If running the update // in the background, this will return eOMACUpdateStarted and your // completion method (see below) will receive the actual status on // completion. If not backgrounding the status will be one of the // OMACUpdateStatus values in the header if (status > eOMACUpdateStarted) { // something went wrong } } ... } // update completion method - (void)OMACUpdateComplete:(enum eOMACUpdateStatus)status { NSLog(@"OMACUpdateComplete status: %i", status); // get a filtered list of app objects and do something with // them in UI code oir something. The filtered list will be // sorted by installed apps first, then other apps, both in // app name alpha order. Our own app and apps that are not // supported on the current device/IOS will be excluded NSArray* apps = [omac filteredApps]; NSLog(@"%i OMAC app(s)", apps.count); for (OMACApplication* app in apps) { NSLog(@"app: '%@', dev: '%@', url: '%@'",, app.developer, app.launchURL); NSLog(@" desc: '%@', virt_port: '%@'", app.description, app.virtualPortName); NSLog(@" installed: %i, min_ios: %f", app.installed, app.minimumCoreFoundation); NSLog(@" app_store: '%@', vid: '%@'", app.appStoreURL, app.videoURL); NSLog(@" platforms: %@", app.supportedPlatforms.description); } // To switch/launch an OMAC app from your own app, locate the // OMACApplication object in the filteredApps list and call the // launch method, eg: [app launch] } - (void)dealloc { // cleanup OMAC [OMACApplicationRegistry shutdown]; ... }

Once you have implemented the OMACApplicationRegistry class in your app, the shared property list will be updated automatically when a new version is published.

google group
Site Admin:
Last updated 24 October 2012