My own summary on submitting a standalone Mac App

Nicola De Bello's icon

I've just successfully submitted a standalone Max Mac App.

Since I read many useful articles in this Forum (which helped me a lot), and many others in many other net-places, I thought that maybe making my own summary could be of some interest.

- My App's name is MAX4LIFE
- In making my patch, I used some JavaScript and i developed an external Object in C Language. So i did not used Java.
- In making my patch I embedded all the other patches I used.
- This is my build script (I replaced the original Max.icns icon with my own one, same file name. The mxo is my external object and the js is my JavaScript code):

open thispatcher
appicon Elements:/proveRecAbleton/life/MAX4LIFEmac/Max.icns
include "Macintosh HD:/Users/den/Music/Ableton/User Library/Presets/MIDI Effects/Max MIDI Effect/MAX4LIFE.maxpat"
include "Macintosh HD:/Users/den/Music/Ableton/User Library/Presets/MIDI Effects/Max MIDI Effect/bigLife1.maxpat"
include "Macintosh HD:/Users/den/Music/Ableton/User Library/Presets/MIDI Effects/Max MIDI Effect/GlobalTransport1.maxpat"
include "Macintosh HD:/Users/den/Proj/max-sdk-7.0.3/externals/max4life1.mxo"
include "Macintosh HD:/Users/den/Music/Ableton/User Library/Presets/MIDI Effects/Max MIDI Effect/myShowNote.js"

- At this point I got a file named MAX4LIFE.app
- I signed everything using the script you can find below
- I built the package using:

productbuild --component ./MAX4LIFE.app /Applications --sign "3rd Party Mac Developer Installer: Ware's me srl (EDFE5X75WY)" --product "./MAX4LIFE.app/Contents/Info.plist” MAX4LIFE.pkg

- At this point I got a file named MAX4LIFE.pkg
- I used ApplicationLoader to submit the pkg, after creating all the needed stuff in iTunesConnect
- I got errors from ApplicationLoader, and i had to do the following adjustments
- The main info.plist file was missing the following entry:

LSApplicationCategoryTypepublic.app-category.music

- The main info.plist file had errors in the executable name and in the version short name, which I corrected manually
- The exe name was wrong also in another info.plist file located here: MAX4LIFE.app/Contents/Resources/C74/interfaces
- Each mxo file included in the package happens to have its own info.plist file
- ALL these files DO NOT contain the following entry (here is one of them as an example):

CFBundleIdentifiercoremidi.mxo

- But a Bundle Identifier itself cannot contain ~ and _
- So all the files whose name contains those two characters must be renamed
- There are two entries that must be accordingly edited (in the various info.plist files mentioned above): the newly added CFBundleIdentifier and the CFBundleExecutable
- Last but not least, there is and exe file inside each mxo (use "Show Package Content" as usual), and its name must be changed too

OK, that's all.

Please note that these are my notes about SUBMITTING. I guess that having the App approved would be another story.

Again, I hope this could be of some interest for somebody else.

Nick

=============

Code signing script:

codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Frameworks/MaxAudioAPI.framework/versions/A --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Frameworks/JitterAPI.framework/versions/A --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Frameworks/MaxAPI.framework/versions/A --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Frameworks/MaxLua.framework/versions/A --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Frameworks/libmozjs185.dylib --deep

codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/jitter/glstatus.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/m4l/live.guilib.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/autohelp.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/debugwindow.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/fseventwatcher.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/maxurl.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/maxxslt.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/maxzlib.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/objectview.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/pianoroll.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/qtimage.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/querylib.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/setplugpath.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/sqlite.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/synophrys.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/yaml.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/max/zoomer.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/msp/max.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/msp/polybuffer.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/extensions/msp/sfplay32.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/externals/ad/adcoreaudio.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/externals/ad/adnonreal.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/externals/ad/adportaudio.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/externals/ad/adrewire.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/externals/mididrivers/augraph.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/externals/mididrivers/coremidi.mxo --deep
codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" ./MAX4LIFE.app/Contents/Resources/C74/externals/mididrivers/midiadrewire.mxo --deep

codesign -f -s "3rd Party Mac Developer Application: Ware's me srl" --entitlements ./MAX4LIFE.entitlements ./MAX4LIFE.app --deep

=============

Entitlements file:

com.apple.security.app-sandboxcom.apple.security.device.microphonecom.apple.security.files.user-selected.read-write

Greg Finger's icon

totally interesting. let us know if it get's approved.

Roman Thilenius's icon

back in the days we were clicking "export application" and then drag the file we built into our favorite filesharing client to enable our friends to get a copy.

it is fantastic that today you can have so much more fun with these trivialities.

"progress" in capitalism totally rocks.

Nicola De Bello's icon

The Standalone Mac App has been approved. It is available on the Mac AppStore (name: MAX4LIFE) for free.

Nicola

riotchild's icon

Hi Nikola,

Thanks for the step by step, I'm working through it now.

In the errors you got in the Application Loader,
"-Each mxo file included in the package happens to have its own info.plist file"

I got 705 of these errors from Application Loader all stating

ERROR ITMS-90276: "Missing Bundle Identifier. The application bundle contains a tool or framework [education.audio.MYAPP.pkg/Payload/MYAPP.app/Contents/Resources/C74/extensions/jitter/glstatus.mxo] that is missing the bundle identifier in its Info.plist file."

I can edit the Info.plist for each .mxo file, but there's 705 of them. Am I missing something or do I need to edit 705 files?

riotchild's icon

Actually I have 678 ERROR ITMS-90276: "Missing Bundle Identifier.

and

27 ERROR ITMS-90334: "Bundle identifier mismatch.

To fix the ERROR ITMS-90276: "Missing Bundle Identifier. do I need to edit each Info.plist in each .mxo file and add inCFBundleIdentifiermy.bundle.identifier

The ERROR ITMS-90334: "Bundle identifier mismatch. I can fix by simply swapping what's there for my identifier.

Dan Nigrin's icon

I'm a little late finding this thread, thanks @RIOTCHILD for the pointer to it.

Congrats @NICOLA DE BELLO for getting your app approved!

I'm still trying to go through all of the posts above to weigh in (I've submitted updates to some of my existing App Store apps recently and don't recall having to do this bundle identifier correction stuff), but two other things I can comment on right away:

1) You really don't need to include all those .mxo's in your final app - I haven't updated my Making a Slick Max Standalone tutorial, and Max has changed a lot since I wrote it, but I think it's worth the effort of doing some trial and error to get rid of stuff you don't need.

2) In your code signing script, all the -- deep references got changed to -- deep by the forum software. So if someone just cut and pasted the script, it's likely that the -- deep code did not work.

Dan Nigrin's icon

Also I'm a little confused about why all the codesigning commands for the individual .mxo's didn't require specification of the entitlements file? I've been doing so in my submissions, don't know if it makes a difference or not...

girault's icon

Hi There !

First, thanks for the useful post Nicola de Bello, and thanks for your useful .pdf I used for the making of an app, Dan Nigrin !

I'm there, now, to seek for help after few days of struggling........ :(

I have an Apple Developer Certificate and bla and bla and I still got, in the terminal, the error "3rd Party Mac Developer Application: xxxxxx: no identity found"

I do have my Mac Developer certificate, and the Developer ID Certification Authority and the Apple Worldwide Developer Relations Certification Authority on my Keychain Access...
I have to admit that I'm a bit lost when it comes to quit Max and open Terminal ;)

Dunno if any of you got the same error and has a simple solution that I just didn't see...!

Thank you !

Dan Nigrin's icon

Can you post the command you're entering in the Terminal? Use the < co d e >< / c o d e > brackets around it.

girault's icon

Yeah, I took this example : codesign -f -s "3rd Party Mac Developer Application: DEVELOPER_NAME" PATH_TO_YOUR_APP

Also, I've read somewhere to put this command : certtool y | grep Developer\ ID
It's supposed to give something, but it gives me a "CSSMERR_CL_UNKNOWN_FORMAT" message...

Dan Nigrin's icon

OK, but post the exact text that YOU used for the codesign command (I'm assuming that you substituted your particular details for DEVELOPER NAME and PATH_TO_YOUR_APP ?

girault's icon

Yes, I did the substitution !
Since the developer's name is someone's else, I won't put it here without his consent but I've put the exact name that is on the Mac developer certificate (even tried with the numbers and the numbers only).
For the path, it looks like this : /Users/name/Desktop/folder-with-the-app
The folder only contains some -

So it would be :code sign -f -s "3rd Party Mac Developer Application: FIRSTNAME LASTNAME" /Users/name/Desktop/app-140716

Hope it can help.

Also I'm doing all this on Mac OS 10.11.5

Thanks..!

Dan Nigrin's icon

OK, that all seems correct. This command

certtool y | grep Developer\ ID

...should definitely not give you errors though. Can you ensure that you have the latest version of XCode installed, as well as have the XCode Command Line Tools installed (see https://developer.apple.com/library/ios/technotes/tn2339/_index.html

girault's icon

So I downloaded the "last version" (on the App Store, so not the version 8).

From what I read, the command line tools is installed when you got the last Xcode version since Mavericks.

Still not working...! I'll try to figure something out tomorrow.

Dan Nigrin's icon

I Googled a bit on "CSSMERR_CL_UNKNOWN_FORMAT", and it seems like perhaps there's a problem with how your Apple Developer ID certificates got loaded? Perhaps try deleting them via Keychain Access and re-download/install them again?

girault's icon

Yes, you were right : downloading the certificates via Xcode made the certtool command work in the terminal.
So I don't get the "no identity found" anymore : thank you ! :)

Will struggle with the rest now !
Do you know if there's any problem having '(' in the name of the app ? Cause now I got a syntax error because of the '(' in the app name, I don't know if we can go through that ?

Dan Nigrin's icon

I would definitely not have a ( in the app name - you are asking for trouble! :-)

girault's icon

Ok, I changed that ! Never asked for any trouble : it's funny how they're here even when you don't ask for it :)

So now's the time of writing stuff in the Terminal. Should I just blindly take example on what Nicola put on this post (and yes, with substitutions !) or is there more thinking involved ?
I also read here, a post you did (https://cycling74.com/2012/04/19/get-your-max-standalone-on-apple’s-mac-app-store/#.V4kQl5BvqrX) that I should sign the app before going on signing every files (almost) in the Contents..!

Now I'm just going to sign whatever files seem appropriate to sign. I guess it's not doing any harm..................

It's funny how this process is getting harder and harder and harder. Was way more easy few years ago to share max apps..!

Dan Nigrin's icon

My strong recommendation is to first trim your app bundle down to just include the files you really need. Depending on your app's complexity and what functions you use, there's a lot of stuff that can be removed. In general, I think the less stuff you include, the less chance for problems down the road, the smaller the app bundle size, etc...

Also, I usually sign the .app last, after signing all the files within Contents.

And yes - the Apple Mac App Store is very complicated for us in the Max community, mostly because we are doing stuff in "non-standard" ways, at least so far as Apple is concerned....

girault's icon

Yeah, I've followed your .pdf very carefully !

Also, for the moment, the app is not for the App Store but we are signing it because people with the "Only App Store and Authorized Developer" checked were having this "Trash this app !" message when they tried to open the app.
So do I need to package the app ? Because that's a line I'm not able to make it work. So if I can just forget this step for now, would be great !

Really appreciating the time you take to answer Dan, really : thank you !

Dan Nigrin's icon

Ah OK - so for that purpose, you don't need to go through all the signing of the stuff within the Contents folder; I just use the --deep option, and just sign the top level app. For example, here's the codesigning script I used to sign my just-finished DSX Hack app:

codesign -f -s "Developer ID Application: Daniel Nigrin" /Users/dnigrin/Desktop/DSX\ Hack.app --deep

Also note that for this purpose, you don't use the "3rd party...." certificate, you use the "Developer ID Application..." one.

Greg Finger's icon

i'm definitely looking towards creating signed apps (but also not distributing them through app store, for now) so this thread is helpful. thanks for all the info being passed around.

Sjoerd's icon

Very useful thread, I am looking for a way to get around mac's gatekeeper, I don't have to distribute it on the App Store. Still somethings are not clear to me.

I have someone else his developer id and when entering

< co d e > codesign -f -s "Developer ID Application: FIRSTNAME LASTNAME" /Users/Sjoerd/Own Projects/ ACPAD/ Standalone/ Mac tests/ACPAD Replay 0.42 - Beta.app --deep < / c o d e >

in the terminal, I get 'no identity found' back as an answer. I guess I don't understand what is meant by the "Developer ID Application" in "Developer ID Application: FIRSTNAME LASTNAME" Just type it in the terminal like this?

It is also not clear to me where to find my bundle identifier name, or where to put it to create one. I tried to start a project with Xcode, but I get 'No signing identity found'

In my Keychain Acces, in the certificate it says: this certificate has an invalid issuer

What is going on here? I appreciate every little help

Dan Nigrin's icon

You can't use someone else's identity - that's the whole point of the Apple codesigning. You have to register yourself as an Apple "developer" at which point you download the required certificates to your computer, which will allow you to sign the apps as described above. These links might be helpful to get you started:

Sjoerd's icon

Thanks for the links. This company I work for at the moment already has a developer account from which I have the username and password.
Via the xcode I added this as an apple id which I can acces in the keychain. In an example above, it worked with a same way. What am I missing?

Sjoerd's icon

Thanks for the links. This company I work for at the moment already has a developer account from which I have the username and password. So I have enrolled in an Apple Developer Program.
Via the xcode I added this as an apple id which I can acces in the keychain. In an example above, it worked with a same way. What am I missing?

Dan Nigrin's icon

The best way to ensure that your certificates are valid and loaded onto your machine is to open the Keychain Access app. On the left hand panel, in the Category section, click "My Certificates." This will show you what certificates you have successfully loaded onto you Mac. If you see them there, then the codesign command *should* work, at least in my experience.

Sjoerd's icon

It says that 'this certificate has an invalid issuer' Could that be because of your point that I am using the id of someone else? How I can I change this in a valid certificate?

Dan Nigrin's icon
Sjoerd's icon

Ok, in my keychain Acces, the certificate I use is valid. I am using this command:

codesign -f -s "Developer ID Application: FIRSTNAME LASTNAME (1XX11XX1XX)" /Users/Sjoerd/Own\ Projects/\MY.app --deep

But somehow I get this error back:

Developer ID Application: FIRSTNAME LASTNAME (1XX11XX1XX): no identity found

I have experienced with the location of where I put the --deep command, without result. I tried several combinations with the developer id, without the number, only the number, I tried the user id, the organization name, etc all with the same result; no identity found.

I work on 10.9, so the deep command should work. Still no identity found. Ideas?

Dan Nigrin's icon

When looking with Keychain Access, do you see the certificate listed and valid (e.g. not expired or otherwise with a red "x" on it) in the My Certificates section?

Sjoerd's icon

The certificate wasn't in the My Certificates section, it was just in Certificates. It took a while to figure out that that was a problem and how to get it in the other section. Eventually, I made a new certificate and that one worked.

Sjoerd's icon

After signing the app with my Certificate, it takes minutes to load at a friends computer, what should be seconds. I even created a small splash screen that doesn't show anymore.

This is what I do:

I make the standalone, copy some files in the 'show package contents' resources (incl. another vst), ditto --arch x86_64 'path' 'new path', delete the 32 bit string in my architecture priority in the info.plist and finally I codesign the whole thing.

The goal is just to bypass the gatekeeper, I am not interested in putting it on the App Store.

What should I do different? Thanks!

Dan Nigrin's icon

Why don't you first try to do everything except the "ditto" process and deletion of the 32 bit string, and then codesign, and see how it works on your friend's machine. If that works normally, then you know where to focus your efforts - those are two steps that I don't normally do.

misho's icon

This is super helpful info. Thanks, Dan. This is my first time with code-signing..

May I ask which version of Max you were using? I'm trying with latest 8.0.5....

When running this on the app:

codesign -f -s "Developer ID Application: FirstName LastName" /path-to-app/MyApp.app --deep

The first message I get is "replacing existing signature". Ok....
Then I get an error - "code failed to satisfy specified code requirements".

Any idea what that's about? Wondering if it's a Max 8 issue....

Dan Nigrin's icon

I don't know which version I was using back when I posted above, but currently I *am* using 8.0.5, and have signed something as recently as last week without problems. I don't recall ever seeing that "failed to satisfy..." error.... If you're willing, I'd be happy to take a look at your standalone and see if I can sign it on my system, simply to see if it's something that you've included in your app bundle, that I don't usually include in mine, which is causing the problem.... Email me at dan @ defectiverecords . com

misho's icon

Hey Dan, thanks for the offer for help. I think I got it sorted. Not exactly sure what the issue was. I had originally built the standalone on a different machine (with different OS), maybe that caused an issue. Now rebuilt on the codesigning machine. Or maybe it was a machine restart that ultimately helped... not quite sure! In any case, all seems good now. Thanks again!

Dan Nigrin's icon

Great, glad you got it sorted!