Search Unity

The nightmare of submitting to App Store (Steps included) [Dec 2016]

Discussion in 'OSX' started by bdovaz, Dec 2, 2016.

  1. bdovaz


    Dec 10, 2011
    Yesterday I was fighting with the F****** codesigning in macOS because as you know Unity has abandoned this platform years ago and the support it's really sh** and instead of generating a Xcode project it generates the *.app that you need later to:

    Note: DON'T ever look at Unity's Manual page:

    It's obsolete, ancient, abandoned... Whatever you want to name it.

    1. Enable Player settings checkbox: UseMacAppStoreValidation.

    2. Apply a code snippet to fix a bug on retina displays:

    Code (CSharp):
    1. void IEnumerator Start() {
    2.     //
    3.     if (Screen.fullScreen) {
    4.         //MacBook Pro Retina 15: width = 2880 , MacBook Pro Retina 13: width = 2496 ?
    5.         //could check device model name, but not sure now about retina 13 device model name
    6.         //if last resolution is almost retina resolution...
    7.         Resolution[] resolutions = Screen.resolutions;
    9.         if (resolutions.Length > 0 && resolutions[resolutions.Length - 1].width > 2048) {
    10.             Screen.fullScreen = false;
    12.             yield return null;
    14.             Screen.fullScreen = true;
    16.             yield return null;
    17.         }
    18.     }
    19. }
    Really? There is no fix by Unity that doesn't involve this?

    3. Generate icons on png format with sRGB color profile and preserving the alpha channel following the table in this page:

    If your icons are not in sRGB or don't have alpha channel you can (on macOS terminal):

    Why Unity doesn't do this step for us???

    4. Use this commands to generate iconset file (*.icns):

    Why Unity doesn't do this step for us???

    5. Generate a UnityPlayerIcon.png (64x64) for your app.

    Why we need to do it separately and doesn't use PlayerSettings "Default icon"?

    6. Make a PostProcessBuild script to:

    Code (CSharp):
    1. [PostProcessBuild(1)]
    2. public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
    3.     bool isOSX = target == BuildTarget.StandaloneOSXIntel || target == BuildTarget.StandaloneOSXIntel64 || target == BuildTarget.StandaloneOSXUniversal;
    5.     if (!isOSX) return;
    7.     string plistPath = string.Format("{0}/Contents/Info.plist", pathToBuiltProject);
    9.     PlistDocument plist = new PlistDocument();
    10.     plist.ReadFromString(File.ReadAllText(plistPath));
    12.     PlistElementDict rootDict = plist.root;
    14.     rootDict.SetString("CFBundleGetInfoString", PlayerSettings.companyName);
    15.     // Set something like this if you also have a iOS version because you can't reuse an identifier for two apps. If you don't have a iOS version you can set "PlayerSettings.bundleIdentifier" directly
    16.     rootDict.SetString("CFBundleIdentifier", string.Format("{0}.{1}", PlayerSettings.bundleIdentifier, "osx"));
    17.     rootDict.SetString("CFBundleShortVersionString", PlayerSettings.bundleVersion);
    18.     // Change this value
    19.     rootDict.SetString("CFBundleSignature", "{FOUR_LETTER_STRING}");
    20.     rootDict.SetString("CFBundleVersion", PlayerSettings.bundleVersion);
    21.     // Full table:
    22.     rootDict.SetString("LSApplicationCategoryType", "");
    24.     PlistElementArray platformsArray = rootDict.CreateArray("CFBundleSupportedPlatforms");
    25.     platformsArray.AddString("MacOSX");
    27.     File.WriteAllText(plistPath, plist.WriteToString());
    29.     // Changes each plugin CFBundleIdentifier to your app identifier
    30.     foreach(string pluginPlistFilePath in Directory.GetFiles(string.Format("{0}/Contents/Plugins", pathToBuiltProject), "Info.plist", SearchOption.AllDirectories)) {
    31.         PlistDocument pluginPlist = new PlistDocument();
    32.         pluginPlist.ReadFromString(File.ReadAllText(pluginPlistFilePath));
    34.         PlistElementDict pluginRootDict = pluginPlist.root;
    36.         // Editor your value
    37.         pluginRootDict.SetString("CFBundleIdentifier", string.Format("{0}.{1}", PlayerSettings.bundleIdentifier, "osx"));
    39.         File.WriteAllText(pluginPlistFilePath, pluginPlist.WriteToString());
    40.     }
    42.     // Edit the source of your generated *.icns file
    43.     string icnsSource = Path.Combine(Application.dataPath, "{ICNS_FILE_PATH}");
    44.     string icnsDestination = string.Format("{0}/Contents/Resources/PlayerIcon.icns", pathToBuiltProject);
    46.     File.Copy(icnsSource, icnsDestination, true);
    48.     // Edit the source of your generated *.png file
    49.     string playerIconSource = Path.Combine(Application.dataPath, "{PNG_FILE_PATH}");
    50.     string playerIconDestination = string.Format("{0}/Contents/Resources/UnityPlayerIcon.png", pathToBuiltProject);
    52.     File.Copy(playerIconSource, playerIconDestination, true);
    54.     // Remove meta files (I think that only happens in Plugins folder)
    55.     foreach(string filePath in Directory.GetFiles(string.Format("{0}/Contents/Plugins", pathToBuiltProject), "*.meta", SearchOption.AllDirectories)) {
    56.         File.Delete(filePath);
    57.     }
    58. }
    • Copies your generated "*.icns" file to "{YOUR_APP}.app/Contents/Resources/PlayerIcon.icns". If you don't do this you will get the Unity editor default iconset with default icons.
    • Copies your "UnityPlayerIcon.png" file to "{YOUR_APP}.app/Contents/Resources/UnityPlayerIcon.png". If you don't do this you will get the Unity editor default icon.
    • Edits "Info.plist" on "{YOUR_APP}.app/Contents" to:
      • Change values of: CFBundleGetInfoString, CFBundleIdentifier, CFBundleShortVersionString, CFBundleSignature, CFBundleVersion.
      • Add the following keys and values: LSApplicationCategoryType and CFBundleSupportedPlatforms.
    If you don't do this you will have many errors uploading it with Application Loader. For example if you don't add "CFBundleSupportedPlatforms" key you will get an error saying that your package it's an ipa or something like that because it seems that it default's to iOS if that key it's not present.
    • Edit other "*.bundle"s Info.plist that has a "CFBundleIdentifier" to point to your identifier also. I had a problem with AVPro that had it's own identifier that was not valid. If you don't do this you will have many errors uploading it with Application Loader saying that the identifier it's duplicated or it's not valid.
    • Remove the "*.meta" files that Unity don't remove from "*.bundle" files (aka plugins). If you don't do this you will get codesigning error files like: Invalid Signature. A sealed resource is missing or invalid.
    7. Publish your app (in my case in x86_x64).

    8. Fix permissions:

    Code (csharp):
    1. chmod -R a+xr "{YOUR_APP}.app"
    9. Create an entitlements file (Example: "my_app.entitlements") with the following content (the most basic one):

    10. Create the certificates (Mac App Store > Mac App Distribution and Mac Spp Store > Mac Installer Distribution):

    11. Download the certificates and open them to add it to the keychain.

    12. Open the keychain and copy (to a txt) from the two certificates the "common name" that you see when you open it (Including "3rd Party Mac Developer...").

    13. Open a terminal on the folder you publish your app and type (there is a "--deep" flag that didn't work for me so I need to sign every one manually. There is also a "--verify" flag to check for errors):

    14. Build your product:

    15. Upload it with Application loader.

    16. If you see warning or errors in any step you need to fix them.

    17. Despite of having a green tick saying that it's okay you can get later an email from Apple regarding some issues with codesigning or similar.

    18. If all it's ok, go to your app and submit it for review.
    Last edited: Dec 5, 2016
  2. bdovaz


    Dec 10, 2011
    I hope that this helps anyone trying to do this and don't want to throw computer out the window or have thoughts on setting on fire Apple HQ.

    I also think that Unity staff should make some of this steps built-in and update the manual.

    If you think that something is missing (I made the post from what I remembered) tell me to update the post.
  3. VIC20


    Jan 19, 2008
    [QUOTE="N3uRo, post: 2872290, member: 76909“] …want to throw computer out the window or have thoughts on setting on fire Apple HQ.[/QUOTE]

    Those kind of feelings belong to it when using Unity today. I miss the good old times.
  4. bdovaz


    Dec 10, 2011
    Post updated with the needed PostProcess script. You only need to change a couple of things.
  5. boxels


    Oct 5, 2016
    Please... Can you create a version for us noobies who are still learning Unity?

    For example (noobie questions):

    2. Apply a code snippet to fix a bug on retina displays:
    Where and how do we apply this? Where do we put this code and how do we use it?

    5. Generate a UnityplayerIcon.png (64x64) for your app.
    OK, where do we put it?

    6. Make a PostProcessBuild script to:
    Where and how do we apply this? Where do we put this code and how do we use it? I've read the unity manual on it without much success.

    9. Create an entitlements file...
    Where do we save this file to? Do you make it in text edit (format plain text)?

    thank you in advance - have spent 3 days of time working to try and get an app submitted.
    Cromfeli likes this.
  6. bdovaz


    Dec 10, 2011
    2. In a new script or existing script that it's your app "main entry point".

    5. Depends of what you put on step 6. It's used on line:

    string playerIconSource = Path.Combine(Application.dataPath, "{PNG_FILE_PATH}");

    6. See this to understand it:

    9. Entitlements file is a simple text file with that content inside of it.
    Last edited: Dec 31, 2016
    Cromfeli and boxels like this.
  7. Chris_Figueroa


    Aug 14, 2014
    Can you explain to me the retina bug and how your code fixes it?
  8. bdovaz


    Dec 10, 2011
    "The retina fix" it's not mine, it's described here:

    Are you from Unity staff? Can you fix some problems described in my steps so we can publish easier on this platform? Thanks.
  9. koochy_rat


    Oct 26, 2011
    I have recent encountered a message "resource fork, Finder information, or similar detritus not allowed" while codesigning. In case anyone else encounters it, the fix is as below:

    Basically when you browse and edit files like your Info.plist or .icns, Finder adds extended attributes to it. If those attributes are included in your app bundle, signing will fail. Use the xattr command to clear it.
  10. maubar


    May 27, 2015
    I've been dealing with this error for two weeks, and I do not detect where it may be.
    Does anyone have any ideas?

    error 2.jpg

    i will apreciate so much any help.
  11. Raumgleiter


    Jun 22, 2017
    Thank you for this thread, it is really helpful.

    It's May 2018, I use Unity 2017.2.
    I still needed a few hours to get around all hurdles for my first update on an app. It still took 40+ lines of code in unity and another 40+ lines of code in bash.
  12. bdovaz


    Dec 10, 2011
    I'm glad that it's still useful and it helps to others so that you don't have to waste time on this.

    On the other hand I don't understand why unity didn't fix this already... It's been almost two years...
  13. UNSH


    Jul 2, 2012

    Has anybody checked the Icns file in preview because for the life of me I cannot get an iconset with all 10 icons inside.

    I have tried all that I could find. If I create it through a dummy Xcode I only get 4 icons in the file. If I build it myself through the terminal icon_16x16 and 16x16@2x are always missing. I'm slowly getting hopeless at what seems to be the first step. All PNG's are in sRgb IEC61966-2.1 with alpha, sizes are correct, if followed the correct naming convention, png's are not saved for web, I've tried everything I found, ...

    Even worse if I start from a new PNG and create the size files fresh through the terminal the same thing happens so I'm not sure where to go from here. Again do you have all 10 of them in your Iconset?

    Update : Even if I unpack and repack another official icon with IconUtil the lowest 2 are just not repacked into the .icns file. So I end up with again 8 icon files instead of the original 10.

    Update: So the X-code version has 16X16 the iconutil method does not, x-code doesn't have a version larger than 256@2. I have read it is not necessary to have all of them, but its a bit confusing that there both methods exclude specific versions so I'm at a loss.

    I'm not sure how much of a problem this is, but when you use the terminal method above (to generate all the required images) the dimensions are set correct but not the pixel density it basically copies the dpi from the original file. Not that it has helped my problem in any case.

    And just a heads up if you downscale the dpi with sips. you first need to convert the image to tiff, apply the dpi changes there and create your PNG's from that file. Otherwise the dpi stays the same, at least for Preview and the .ICNS file (not for photoshop confusingly enough).

    I made these changes, based on the link correct me if I'm wrong;

    Code (C-Sharp):
    1.     mkdir MyIcon.iconset
    3.     sips Icon1024.png -s format tiff -s dpiHeight 72.000 -s dpiWidth 72.000 --out Icon1024_72dpi.tiff
    5.     sips -z 16 16 Icon1024_72dpi.tiff -s format png --out MyIcon.iconset/icon_16x16.png  
    7.     sips -z 32 32 Icon1024.png -s dpiHeight 144.000 -s dpiWidth 144.000 --out MyIcon.iconset/icon_16x16@2x.png
    9.     sips -z 32 32 Icon1024_72dpi.tiff -s format png --out MyIcon.iconset/icon_32x32.png
    11.     sips -z 64 64 Icon1024.png -s dpiHeight 144.000 -s dpiWidth 144.000 --out MyIcon.iconset/icon_32x32@2x.png
    13.     sips -z 128 128 Icon1024_72dpi.tiff -s format png --out MyIcon.iconset/icon_128x128.png
    15.     sips -z 256 256 Icon1024.png -s dpiHeight 144.000 -s dpiWidth 144.000 --out MyIcon.iconset/icon_128x128@2x.png
    17.     sips -z 256 256 Icon1024_72dpi.tiff -s format png --out MyIcon.iconset/icon_256x256.png
    19.     sips -z 512 512 Icon1024.png -s dpiHeight 144.000 -s dpiWidth 144.000 --out MyIcon.iconset/icon_256x256@2x.png
    21.     sips -z 512 512 Icon1024_72dpi.tiff -s format png --out MyIcon.iconset/icon_512x512.png
    23.     cp Icon1024.png MyIcon.iconset/icon_512x512@2x.png
    24.     iconutil -c icns MyIcon.iconset
    26.     rm -R Icon1024_72dpi.tiff
    27.     rm -R MyIcon.iconset
    28.     echo "DONE"
    Last edited: Jun 14, 2018
  14. greay


    Mar 23, 2011
    What I wouldn't give for the option to generate an Xcode project for macOS builds.

    I'm running into a similar issue. It passes the initial validation check, and pretty much any check I can run on the commandline. But after submitting, I get an email about an invalid signature. The weird thing is, the errors sound like not errors? e.g.:

    There's a few of these in the email, but they all follow the same pattern. I've deleted all the meta files, tried a whole slew of different ways to sign the app, and all the DLLS and bundles inside; nothing seems to work.
    skullthug likes this.
  15. UNSH


    Jul 2, 2012
    We’ve written an automated workflow / guide to prepare distribution for OSX (from start to finish) in and outside of the Appstore. Based on all the guides & bits ‘n pieces we could find on threads like these. Together with an extensive full guide that’s ( hopefully) accessible for beginners & useful for people who are troubleshooting. We also included DIY if the scripts scare you :)

    If anyone wants to become a collaborator please PM me even if its to update the documentation page. Obviously there are not a lot of people developing for OSX but with a bit of help it could be a place to find all info needed on this enigma. We’ve incorporated everything we could find, but for sure there are still many troubleshooting pieces missing.

    Also we wrote the words, but rather like a compilation, credit for all the ground work goes to threads/people described in the credits in the readme.

    You can read the full text guide with DIY here and get the git here.

    You can find the Unity forum thread here.
    Last edited: Jul 28, 2018
  16. hippogames


    Feb 5, 2015
    I'm stucked with Unity manual too ((( Apple just doesn't accept the build created with it. Gonna try your instructions...
  17. hippogames


    Feb 5, 2015
    Here is my instruction after I was able to upload my app to Mac App Store. Actual on 27/09/2019

    Official manual:

    1) Enable Mac validation from Unity, build APP (in my case as /Users/admin/Documents/GitHub/PixelStudioMacBuild/
    2) Remove all .meta files from bundle inside APP (for each plugin, if you have), they may cause "ITMS-90303: Unable to Sign" after uploading your app
    3) Open terminal
    4) cd /Users/admin/Documents/GitHub/PixelStudioMacBuild
    5) chmod -R a+xr
    6) codesign -f --deep -s \"3rd Party Mac Developer Application: YOUR_NAME\" --entitlements PixelStudio.entitlements (create empty Xcode project to get any .entitlements file)
    7) productbuild --component /Applications --sign \"3rd Party Mac Developer Installer: YOUR_NAME\" PixelStudio.pkg
    8) Use Application Loader to submit the package to the App Store