Your Max Standalone on Mac App Store


Many people enjoy sharing their Max creations with others in the form of a standalone application. To reach a broader audience, we would like to be able to submit standalone applications to Apple’s Mac App Store. Regular Cycling ’74 forum readers will likely recognize a long running thread called “Max apps in new Apple Mac App Store?” that was started in 2010 and still receives new postings. That thread documents our efforts, together with Cycling ‘74, to navigate Apple’s various guidelines and restrictions in order to get Max standalones into the Mac App Store.

Between that thread and a recent story that appeared on Create Digital Music, we’ve received lots of requests for more information on the process. This article will attempt to fill in the details so other Max creators can get in on the App Store action!

First off, you must use Max 6 to create a standalone that will satisfy Apple’s requirements, primarily because in Max 6, app-specific preference files are saved in a location permitted by Apple.

It’s also probably a good idea to make sure that your standalone has some of the basics down (custom icon, appropriate menus, etc…) before embarking on the steps below. Dan covered many of these topics in his 2011 Expo ‘74 presentation entitled “Making A Slick Max Standalone.” The slides for the presentation are available here.

After you are in the program, you will be required to follow Apple’s guidelines before your application will be accepted for inclusion. Here are some of the rules that are most likely to affect Max-based applications:

  • No use of Java (so no mxj use in your standalone)
  • No demo or limited functionality versions of your app
  • No file access (read or write) beyond “approved” locations, without specific end-user request for such (via file dialog box for example). These approved locations are:
    • ~/Library/Application Support/
    • ~/Library/
    • ~/Library/Caches/

Setting Up the Preferences File

To ensure that your application stores its preferences in one of these approved locations, do the following:

  1. Include a standalone object in your patch.
  2. Open the inspector for the standalone object, and change the “Preferences File Name” attribute to the same name as your application. For example, if your application will be called My Cool App, the Preferences File Name must also be My Cool App. This will create a folder the first time your app is launched at ~/Library/Application Support/My Cool App, and all Max’s will subsequently be stored within that folder. You can also use this folder if your app needs to store any other files (such as a custom preferences file).

Stripping Out PowerPC Code

If you are using any third party Max externals, they may contain PowerPC (PPC) code. which is not allowed in the App Store.

If you want to verify whether you have any third-party externals containing PowerPC code, you can use the following command in the Terminal that will list any problematic objects. Before executing the command, set the current directory to a folder containing your third-party externals.

find . -type f -exec lipo -info '{}' 2>/dev/null \; | grep ppc | grep MacOS | sed -e 's/.*MacOS\///g' -e 's/ are.*//g'

To get rid of the PowerPC code, you can use an application called TrimTheFat; just drop the .mxo external in question onto the TrimTheFat icon, and it will strip away the PowerPC part of the binaries. You’ll need to do this before building your application, because a Max standalone stores external object executable code in a proprietary format that can’t easily be modified. However, you need only remove PowerPC code once.

By the way, if you are using other people’s work, check to make sure the license terms are compatible with the App Store’s, and that you are allowed to use it in a closed source product (if that is your intention).

Modifying Your Standalone

The next few changes involve tweaks within your application’s bundle folder. You’ll need to make these changes after building your standalone.

To access the bundle, ctrl- or right-click on your application’s icon in the Finder, and choose Show Package Contents. This will open a new window that shows you the set of files inside the application bundle, which is actually a folder. All the items in an application bundle are inside a folder called Contents.

Apple apparently doesn’t like underscore (_) characters to be part of any bundle identifier. Within the support folder inside the Contents folder, open the ad folder where you’ll find the Core Audio driver object called ad_coreaudio.mxo. Ctrl- or right-click on the .mxo file and choose Show Package Contents. Double-click on the Info.plist file, at Contents/Info.plist and change the Bundle Identifier from com.cycling74.ad_coreaudio to com.cycling74.adcoreaudio.

You also have to add some specific entries within your app’s Info.plist file located in the Contents folder. These include a valid bundle ID, bundle version, copyright string, and application category (LSApplicationCategoryType). More information is available in the Mac App Store Developer document, in the “Requirements” section. You may wish to copy the Info.plist file to another location once you modify it, then you can replace the standard one Max puts into your standalone if you ever want to make an updated version of your application and submit it to Apple.

Once you’ve got your app completely ready to go, you need to “sign” and package it using certificates that Apple issues to you. More information on how to get those certificates on your computer is available on the Apple Developer site.

Once you’ve downloaded the certificates to your computer, you’re ready to sign your app. Within your standalone, you’ll need to sign the .app itself as well as any Max frameworks, audio drivers, midi drivers and/or extensions included within your application bundle. Here are examples of the code signing commands (to be run within the Terminal) for an app that includes the Core Audio audio driver, Core MIDI driver, and the setplugpath extension:

codesign -f -s "3rd Party Mac Developer Application: DEVELOPER_NAME" PATH_TO_YOUR_APP

codesign -f -s "3rd Party Mac Developer Application: DEVELOPER_NAME" PATH_TO_YOUR_APP/Contents/Frameworks/MaxAPI.framework/Versions/A

codesign -f -s "3rd Party Mac Developer Application: DEVELOPER_NAME" PATH_TO_YOUR_APP/Contents/Frameworks/MaxAudioAPI.framework/Versions/A

codesign -f -s "3rd Party Mac Developer Application: DEVELOPER_NAME" PATH_TO_YOUR_APP/Contents/support/ad/ad_coreaudio.mxo

codesign -f -s "3rd Party Mac Developer Application: DEVELOPER_NAME" PATH_TO_YOUR_APP/Contents/support/mididrivers/coremidi.mxo

codesign -f -s "3rd Party Mac Developer Application: DEVELOPER_NAME" PATH_TO_YOUR_APP/Contents/support/extensions/setplugpath.mxo

Once the signing is done, you need to package your application using the productbuild command, again using a Terminal command and with an Apple-provided certificate. Here is example that’s worked for us. This command will place the final package file at the root of your home directory:

productbuild \
--component PATH_TO_YOUR_APP /Applications \
--sign "3rd Party Mac Developer Installer: DEVELOPER_NAME" \
--product "PATH_TO_YOUR_APP/Contents/Info.plist" APP_NAME.pkg

Now all that’s left is application screenshots and other details which you’ll need to provide on Apple’s iTunesConnect site, and uploading the .pkg file you created in the last step using the Application Loader utility, which should be provided within Apple’s Developer tools on your hard drive.

We hope this covers most of the unique aspects of getting a Max application distributed via Apple’s Mac App Store – we look forward to seeing more Max creations available there!

Oli Larkin: pMix – A sound design, composition and performance tool that allows you to morph between VST plugin presets using an intuitive graphical interface.


View the full-sized screen shot.

Dan Nigrin: Audio Plugin Player – A lightweight VST and AU instrument plugin host, that allows you to play these instruments using either your mouse, computer keyboard, or MIDI device, with support for VST and AU effects too.

Dan Nigrin: General MIDI Player – An easy way to turn your Mac into an instrument, using its built-in General MIDI support, with options for mouse, computer keyboard, or MIDI input.

James Howard Young: TapNTempo – A fully featured metronome that offers customizable sounds, real-time tempo tapping, and beat and division capabilities.

I've tried this tutorial


Bang! Finished it!

I had some trouble, but got through it.

I did not get this tutorial at all.


Anonymous
Apr 19 2012 | 9:14 pm

Commendable work guys, highly informative.


Yozo
Apr 20 2012 | 2:14 am

Thanks for the info, it’s a great help!
Will this also work for max5 or is this max6 only?

Apr 20 2012 | 8:12 am

You *must* use Max 6. I don’t think you will ever have success in getting approved with an app compiled with an earlier version of Max, as any standalone created by those earlier versions automatically place preference files in a location that Apple does not allow.

Apr 21 2012 | 4:22 pm

Wow, so you can make like..ipad-apps?

Apr 23 2012 | 1:46 pm

No – this is for the Apple *Mac* App Store I’m afraid, not the iOS store…

Apr 26 2012 | 4:34 pm

Just made my entrance to the App Store myself! It’s a small utility called MATRIK Check it out. Great to have all these info compiled in one article.

Apr 26 2012 | 11:18 pm

Question: is using Max For Live UI objects ok for Mac App Store standalones?

Apr 27 2012 | 8:23 am

Yup, they are fine. For example, look at my Audio Plugin Player app – the volume knob is a live.dial object.


Darnell
Apr 29 2012 | 2:58 pm

Dan nilgrin I need some assistance on this is there a way I can privately message you

Apr 30 2012 | 8:04 am

Giorgio
May 11 2012 | 1:47 am

I hope that C74 will consider also a IOS export for standalones
that would be groundbreaking

May 20 2012 | 5:54 pm

Hi, just wondering how far have you gotten with sandboxing your apps. I’m about to start some testings on my app and would really like to hear about your experience (I’ll post my results on the forums when done).

May 21 2012 | 7:39 am

I too have to dig into this more now. I tried to build my App Store apps with sandboxing in mind, such that I think they should be compliant (e.g. not reading/writing for disallowed places), but I’ve done no formal testing yet…

May 21 2012 | 9:28 am

I’m a bit concerned about the "microphone" entitlement, and about the actual methods that Max implements to access audio devices, would they be "allowed" methods? The same goes for read/write methods… we’ll see


Leigh Marble
May 30 2012 | 11:16 am

I haven’t made the jump to Max 6 yet, so sorry if this is obvious… but how would you save your own custom preferences file to the ~/Library/Application Support/My Cool App folder?

This article states "You can also use this folder if your app needs to store any other files (such as a custom preferences file)," but I don’t see other info about how to do that. File path management has always been a bit sticky in Max, so I’m wondering if this has been cleaned up with the new restrictions on file locations in Lion OS X.

May 30 2012 | 12:27 pm

Hi Leigh – this is one of the few places where I use a 3rd party external – in this case, Jasch’s wonderful getpaths (Mac) and getenv (Windows) externals. http://www.jasch.ch/dl/ Hope this helps a bit.


Leigh Marble
May 31 2012 | 5:59 pm

Thanks, Dan! I’ve tried to roll my own version of something like that before just for Mac, glad to see someone else has gotten it working cross-platform.

Aug 08 2012 | 12:03 pm

just to say, Max-built apps are not currently viable on the app store due to the sand-boxing stuff. C74 are aware of it.

Aug 20 2012 | 4:38 am

what is it about sand-box?

Do we work on conforming to it?

Aug 20 2012 | 4:51 am

It is in Cycling’s hands. The problem is that upon app initialization (*any* Max app), calls get made to "inappropriate" places, that trigger sandbox violations.


Digitom
Sep 11 2012 | 8:46 am

Does anyone know if the 6.0.7 update fixes the problems now?

Sep 11 2012 | 10:11 am

Unfortunately, it does not….

Sep 26 2012 | 6:41 am

Hi Dan,
I would be interested in developing an app. What is the current state of the affairs? Can you ask Cycling to look into what is needed? What is needed, actually?

I want to ask you about your app General Midi player. Would it replace a keyboard which is needed to work with Cubase? I do ot know, if you are familiar with cubase, but in order to get the system working one has to connect a midi keyboard.

Sep 26 2012 | 7:38 am

Hi Hans – to my knowledge, standalones built with Max will not pass Apple’s new sandbox restrictions, for placement in the Mac App Store. The problem is that standalones currently place temp files in places that are not "allowed" by Apple, and there is no way to keep it from doing so at the moment. Cycling is aware of the problem, but I can’t comment on if/when they plan to address it.

Re: General MIDI Player, I don’t think it will do what you want. It can *receive* MIDI signals, but is not meant to transmit those signals to another app. If you have more questions – feel free to ask on my web forum (this is probably not the right place!). http://defectiverecords.com/forum .


Tom M
Nov 13 2012 | 12:35 pm

Could it be there’s something more than just the place where the temp files are stored? It seems that it has not been fixed in the 6.0.8 either. Perspnally, I think it’s a great opportunity for the community to be able to share their creations in the app store and it’s hard for me to see why it has such a low priority in the c74 fix list.

Nov 14 2012 | 9:28 am

I completely agree with you, but Cycling must have their reasons I guess. That said, there was an interesting development recently, a Max-built app was newly released on the Mac App Store (Batcrack: https://itunes.apple.com/us/app/batcrack-radio-delay/id570527951?mt=12 ), and apparently it still triggers the sandboxd errors we have been seeing, but nonetheless it got through the store fine. All this time I was reluctant to even submit anything to the store for approval fearing rejection because of those errors, but now I might just give it a shot and see what happens…


rarasmus
Jan 31 2013 | 6:52 am

After over a month of codesigning and endless trial and error, numerous rejections, I can now confirm that max built apps can currently go through.

Some up to date hints:
*you have to provide @2x icons for retina as well. (use the iconutil command in terminal, more info http://developer.apple.com/library/mac/#documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html)

* if you codesign with entitlements include some audio related stuff(like the mic i/p) in as well, even if your not using it, otherwise the app will crash. (more details here http://cycling74.com/forums/topic.php?id=44476 )

* if you’re recording to disk (sfrecord), then in the .plist file leave a third document type for .aiff as well. otherwise, if you delete it, your app will record a unreadable file.

* if you get something like "object file format unrecognized, invalid, or unsuitable)" when you try to codesign use this before you start: export CODESIGN_ALLOCATE="/Applications/Xcode.app/Contents/Developer/usr/bin/codesign_allocate"

* use the most recent application loader. I got some weird errors that I could not fix in a old version of application loader (1.4.1)

*there’s lot of trial and error, and it seems there’s a human element involved in the review process… so, just resubmit until you get approved, I guess.

The apps (targeting the so called ‘regular user’) are here: a simple keyboard piano https://itunes.apple.com/ee/app/shibo-the-keyboard-piano/id586990285?mt=12
and a sound effects app.
https://itunes.apple.com/ee/app/effectogram/id595632594?mt=12

Jan 31 2013 | 1:59 pm

Fantastic! Really appreciate the details – now just have to get off my butt and submit some updates to my apps that I have had waiting…

Mar 27 2013 | 8:13 am

Wanted to update everyone that I too have gotten a significant update (more than just bug fixes) through the Mac App Store for one of my apps (Audio Plugin Player). Rarasmus details above were all correct. I can also add some info on what needs to be included in the .entitlements file for both MIDI support, as well as plugin hosting:
com.apple.security.temporary-exception.mach-lookup.global-name

com.apple.midiserver
com.apple.midiserver.io

com.apple.security.temporary-exception.audio-unit-host

Of note, my app also still triggers some sandboxd violations, seen in the Console. I believe these occur at the time that standalone starts up, and Max does some stuff to initialize audio and MIDI. See snipped Console output below, where all the /private/var/temp/ files are created. But, for now at least, Apple seems to ignore these (or perhaps we all just got lucky)….

3/27/13 10:57:50.469 AM Audio Plugin Player: startup call: startup_load(extensions)
3/27/13 10:57:51.067 AM _spotlight: audit warning: allsoft
3/27/13 10:57:51.068 AM _spotlight: audit warning: soft /var/audit
3/27/13 10:57:51.070 AM _spotlight: audit warning: closefile /var/audit/20130327145322.20130327145751
3/27/13 10:57:51.245 AM com.apple.SecurityServer: Session 100883 created
3/27/13 10:57:58.283 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:00.873 AM Audio Plugin Player: startup call: startup_load(init)
3/27/13 10:58:00.905 AM Audio Plugin Player: startup call: sched_midiinit
3/27/13 10:58:01.253 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:01.335 AM MIDIServer: MIDIServer [17064] starting; arch=x86_64
3/27/13 10:58:01.693 AM MIDIServer: PlugIn MIDI%20Monitor.plugin -- file://localhost/Users/dnigrin//Library/Audio/MIDI%20Drivers/ does not contain a supported architecture.
3/27/13 10:58:01.693 AM MIDIServer: MIDIServer relaunching because a 32-bit driver was found
3/27/13 10:58:01.707 AM MIDIServer: MIDIServer [17064] starting; arch=i386
3/27/13 10:58:02.819 AM Audio Plugin Player: startup call: ad_load
3/27/13 10:58:02.869 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:02.979 AM Audio Plugin Player: jaudiowrapper_createdevice Built-in Line Input Built-in Line Output
3/27/13 10:58:03.010 AM Audio Plugin Player: jaudiowrapper_createdevice Built-in Line Input Built-in Line Output
3/27/13 10:58:03.028 AM Audio Plugin Player: startup call: path_buildcache
3/27/13 10:58:03.509 AM Audio Plugin Player: startup call: defaults_startup
3/27/13 10:58:03.511 AM Audio Plugin Player: startup call: sched_start
3/27/13 10:58:03.533 AM Audio Plugin Player: startup call: sysmenu_init
3/27/13 10:58:03.534 AM Audio Plugin Player: startup call: interface_init
3/27/13 10:58:03.569 AM Audio Plugin Player: startup call: prototype_init5
3/27/13 10:58:03.571 AM Audio Plugin Player: startup call: post_init
3/27/13 10:58:03.571 AM Audio Plugin Player: startup call: bitwrap_init
3/27/13 10:58:03.578 AM Audio Plugin Player: startup call: internals_initclass
3/27/13 10:58:03.579 AM Audio Plugin Player: startup call: globalsymbol_initclass
3/27/13 10:58:03.580 AM Audio Plugin Player: startup call: single_open
3/27/13 10:58:03.589 AM Audio Plugin Player: startup call: path_setdefault
3/27/13 10:58:03.590 AM Audio Plugin Player: startup call: kernel_init
3/27/13 10:58:03.591 AM Audio Plugin Player: startup call: pathcache_new
3/27/13 10:58:03.591 AM Audio Plugin Player: startup call: translation_getpreferredlanguage
3/27/13 10:58:03.592 AM Audio Plugin Player: code: en, name English
3/27/13 10:58:03.592 AM Audio Plugin Player: startup call: eventreporter_init
3/27/13 10:58:03.593 AM Audio Plugin Player: startup call: eventcontext_end
3/27/13 10:58:03.732 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/tmp/com.cycling74.501/mfl2
3/27/13 10:58:03.771 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:03.924 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:03.941 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:03.983 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.018 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.037 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.056 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.076 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.094 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.113 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.132 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.152 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.169 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.195 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.215 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.247 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.262 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:04.277 AM sandboxd: ([17046]) Audio Plugin Pla(17046) deny file-write-create /private/var/tmp/tmp.0.Awi6c7
3/27/13 10:58:05.898 AM Audio Plugin Player: jaudiowrapper_createdevice Built-in Line Input Built-in Line Output
3/27/13 10:58:05.930 AM Audio Plugin Player: jaudiowrapper_createdevice Built-in Line Input Built-in Line Output

Mar 27 2013 | 8:16 am

OK, well the formatting of that post didn’t quite work out, and don’t see a way to edit it. But anyway, just ask me if you have questions… If I get some time, I may update this entire article with some of this newer information, to make it easier for people…

Jun 15 2013 | 4:25 am

About to try and get something on the Mac store, an updated article would be fantastic to take into account all of the changes detailed. Whats the story getting things into the Windows app store?

Jun 15 2013 | 9:59 am

No experience on the Windows side – that said, I’m not even sure I know what the Windows app store is? Any pointers?

Re: the updated article, sorry, just haven’t had time to do it yet. Primarily because I’m still finding new nuances to the process (which seems to be constantly evolving on the Apple side). If you have specific questions, please feel free to ask them and I’ll do my best to answer, based on my experiences…

Jun 17 2013 | 10:33 am

Just a quick note here to point out that Cycling was kind enough to fix some errors that slipped in when this article was originally posted – there were extra set of quote marks in the various codesign statements in the Modifying Your Standalone section. Thanks also to Thomas Sandberg for spotting the errors!

Jun 25 2013 | 11:44 am

Hello guys, I see this comment of Rarasmus:
if you get something like "object file format unrecognized, invalid, or unsuitable)" when you try to codesign use this before you start: export CODESIGN_ALLOCATE="/Applications/Xcode.app/Contents/Developer/usr/bin/codesign_allocate".
I have the same problem, but i can’t solve it. :(

Jun 25 2013 | 12:55 pm

So when you type:

export CODESIGN_ALLOCATE="/Applications/Xcode.app/Contents/Developer/usr/bin/codesign_allocate

into the Terminal, press return, and then try the codesign command again, it doesn’t work? What error do you get? For me, that command fixes the problem as it did for Rarasmus…

Jun 25 2013 | 5:01 pm

Yes Dan, I don’t know why but now it works perfectly this terminal command ;) Now I have only a problem with Sandbox, I read that a common error. But Application Loader works fine now, and that is very important for me xD

Jun 25 2013 | 7:10 pm

OK cool, keep us posted on how things go at the App Store!

Sep 23 2013 | 4:53 am

I started a thread to keep track of all the Max apps for sale on the Mac App Store – if you get your app on there, please add to the list!

Dec 16 2013 | 10:10 am

I encountered a problem on submit to the Mac App Store.

Deprecated API Usage – Apple no longer accepts submissions of apps that use QuickTime APIs.

My App uses jit.qt.movie. What can I do for this problem ?

Apr 30 2014 | 4:50 am

There’s discussion of this problem towards the bottom of this thread.

Apr 02 2015 | 11:48 am

I just went through the process of codesigning a Max standalone app for the first time, and found this article to be helpful. However, there have been a couple changes to the codesigning process since this was written that I’d like to point out. (I was preparing an app for my own distribution, not putting it on the App Store, but the codesigning part to make Gatekeeper happy is the same.)

1. Starting in OS 10.9, the codesign command now has a "–deep" option available. This will automatically handle signing all those "Max frameworks, audio drivers, midi drivers and/or extensions" included inside your app bundle. This cuts out a good chunk of work in tracking all those includes, and having to run a separate command for each.

Ex: codesign -f -s "Developer ID Application: Primus, Inc." -v --deep /abs/path/to/my/app/PorkSoda.app

For more, see of course the codesign docs

2. To make Gatekeeper happy, you must now sign with OS 10.9 or later! This really tripped me up for a while (my primary system is still 10.8), since it was telling me that my codesigning had worked just fine, yet I was getting blocked by Gatekeeper.

To check this issue, use the diagnostic command:
codesign -dvv /path/to/yourapp.app

In addition to listing the certificates used in the signing, near the bottom it will print a line like this:

Sealed Resources version=2 rules=[something] files=[something]

"If the Sealed Resources version is 1 or not listed, you signed it with an old version of OS X, and recent versions will reject the signature format." – from this StackOverflow thread

When I first tried the codesigning on a 10.8 system, that line read as "Sealed Resources rules=4 files=2". Checking it on a 10.9 system, that line read as "Sealed Resources version=1 rules=4 files=2".

(edit: more about those 10.9 code signing changes here)

Hope that helps!

May 28 2015 | 6:00 am

Wow, big Thanks to LEIGH MARBLE!!
<quote>"I was preparing an app for my own distribution, not putting it on the App Store, but the codesigning part to make Gatekeeper happy is the same."</quote>
This info alone would have saved us many (frustrating) hours searching through the web, trying to find out more about "Distributing Apps outside the Mac App Store" (like Apple defines it in their documentation).

Also, your example code seems to work!
We now try to test it, but we cannot find a documentation on how to do it.
I remember reading it somewhere on the Apple documentation, but I cannot find it anymore…
If someone finds a link it would be awesome!!
Cheers,
Robert

Jul 05 2016 | 1:02 pm

Hi folks,

I’m looking for a single, up to date set of instructions on how to

1) Prepare and upload a Max standalone app to the App store, and
2) Prepare a Max standalone app for distribution outside of the App store.

Does anyone know of such a thing?

Jul 05 2016 | 2:44 pm

1) A few other people and I had started to write up an updated set of instructions, but never finished. It was a moving target at the time, which made it that much harder. I *have* recently gotten some of my existing app updates approved, so it *is* possible with the latest Max version (currently 7.2.3). This thread has the most updated info, scattered as it might be. Just ask questions as you go is the best I’ve got for you now at this point.

2) This is pretty easy. You need an Apple Developer ID signing certificate, and then use this command in the Terminal (substituting your appropriate info into the string below):

codesign -f -s "Developer ID Application: YOUR DEVELOPER NAME" /PATH/TO/YOUR/APP/YOUR_APP.app --deep

Hope this helps.

Dan

Jul 05 2016 | 3:54 pm

Many thanks Dan, I really appreciate it.

I did actually find a recent post that appears to be current also:

https://cycling74.com/forums/topic/my-own-summary-on-submitting-a-standalone-mac-app/

Thanks again.

Jul 05 2016 | 4:15 pm

Is YOUR DEVELOPER NAME simply Mark Bassett in the attached screenshot?

Jul 05 2016 | 4:32 pm

All sorted now. Thanks

Jul 07 2016 | 11:28 am

Application Loader tells me I have 678 ERROR ITMS-90276: "Missing Bundle Identifier.

The Missing Bundle Identifiers are from all the .mxo files in my app.

There’s a lot of these, does this mean that I need to manually go in and edit the Info.plist files contained within the .mxo files and add in the bundle identifier?

Jul 08 2016 | 6:51 pm

As I posted in the other thread, first try to reduce the number of .mxo’s you have, so you can narrow the problem down… As an example, here’s all the codesigning necessary for one of my recent App Store submissions that was approved. Note that you don’t need the -- deep command:

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Frameworks/JitterAPI.framework/Versions/A --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Frameworks/MaxAPI.framework/Versions/A --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Frameworks/MaxAudioAPI.framework/Versions/A --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Frameworks/MaxLua.framework/Versions/A --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Frameworks/libmozjs185.dylib --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Resources/C74/extensions/max/setplugpath.mxo --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Resources/C74/extensions/max/sqlite.mxo --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Resources/C74/externals/ad/ad_coreaudio.mxo --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app/Contents/Resources/C74/externals/mididrivers/coremidi.mxo --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

codesign -f -s "3rd Party Mac Developer Application: Daniel Nigrin" /Users/dnigrin/Desktop/General\ MIDI\ Player.app --entitlements /Users/dnigrin/Desktop/General\ MIDI\ Player.entitlements

Viewing 49 posts - 1 through 49 (of 49 total)

Explore More

Subscribe to the Cycling ’74 Weekly Newsletter

Let us tell you about notable Max projects, obscure facts, and creative media artists of all kinds.

* indicates required