Publishing macOS and iOS Apps to the App Store from Xojo

Signing

Starting with Xojo 2025r1 you will be able to publish your macOS and iOS apps to the App Store Connect website directly from the Xojo IDE.

App Store Connect is the place where developers have to create their app records as part of the process so they can be finally available at the Mac App Store and/or iOS App Store, always these are approved by the App Reviewing process done by Apple.

Once an App record is created at App Store Connect, every new app build (new version) uploaded from the Xojo IDE will be available there.

First things, First!

But before we look into how to use the new Publish feature from the Xojo IDE itself, let's see some requirements and previous processes to better understand how everything this works and fits together.

First of all, the requirements. Very probably you already meet these, but is always a good idea to review them:

  • A paid Apple Developer membership (around US $99/yr).

  • Xcode needs to be installed on your Mac, preferably the latest one (as of this writing, Xcode 16.2, what means running macOS Sequoia 15.2 on your computer); but it also will work if you are running Xcode 13 or later on, for example, macOS Ventura.

  • You have, at least, the Developer ID Application, Apple Distribution and 3rd Party Mac Developer Installer certificates installed on your Mac Keychain.

  • An explicit App ID (Identifier) has been created for your app at developer.apple.com website

  • A Provisioning Profile has been created at developer.apple.com website, so the uploaded build can be available for users to test under TestFlight.

  • Verify you don't have any pending agreement waiting for you to be "agreed" both at developer.apple.com and appstoreconnect.apple.com website.

Handling Certificates

The best way to make sure you have the right Certificates installed on your Mac Keychain is to handle these from Xcode itself. Open Xcode, go the the Preferences > Accounts and make sure you are logged using your developer.apple.com credentials:

../../../_images/1-ManageCertificates.png

Then, click the "Manage Certificates..." button and a new window will show you the already installed Certificates (including the expired ones or those whose private key is missing, for example), and also will let you to download and add the missing ones, using for that the dropdown menu with the "+"" icon in the lower-left area of the dialog.

Once the required certificates are installed on your Mac, and in order to keep your Keychain as clean as possible, I suggest you to open the Keychain app and delete from your computer all the installed certificates that had been revoked, that had expired or have their private key missing, or that are duplicates, for example.

Handling App ID

The App ID, Identifier, or "bundle Identifier" of the app, is something you are familiar with every time a new macOS or iOS app is created from the Xojo IDE:

../../../_images/2-Identifier.png

But we need to create that same App ID at developer.apple.com website; so go ahead and use your Apple Developer credentials to access the Apple Developer portal. Next, click the "Identifiers" entry under the "Certificates, IDs & Profiles" header:

../../../_images/3-Identifiers.png

Note

You need to create a new App ID and follow these steps for every new macOS or iOS app you want to distribute through the Mac or iOS App Store.

In the page displayed as result of the previous action, click the "+" button next to the Identifiers header in order to register a new Identifier:

../../../_images/4-NewIdentifier.png

In the next page, make sure the "App IDs" is selected and click the "Continue" button:

../../../_images/5-New_AppID.png

In the new page, make sure the "App" option is selected and click the "Continue" button:

../../../_images/6-New_AppID-B.png

Finally, you will arrive to the really interesting part where you have to type the explicit Bundle ID (A) matching exactly the one used under Application Identifier when the project was created in the Xojo IDE. Also important, make sure that the App ID Prefix value matches the Team ID value (B) of the certificates installed on your computer Keychain by Xcode!

../../../_images/7-New_AppID-C.png

Of course, select any Capability and/or App Services your app may require. For the purpose of our example, none of these are selected.

Next, click the "Continue" button. This action will bring the summary page where you can review the entered data and Capabilities/App Services selected. If everything is ok, click on the "Register" button.

../../../_images/8-New_AppID-D.png

Once registered, the new Identifier will be listed among the available ones under the Identifiers section:

../../../_images/9-Registered_Identifier.png

Handling Provisioning Profiles

TestFlight is the Apple Service allowing developers to get feedback from users (and/or team mates) when an app is still under development, prior is publicly available under the Mac/iOS App Store. So, when a new app build (version) is published from the Xojo IDE, it will be also available to be tested by users via the TestFlight service.

But in order that to happen, the app itself needs to have embedded what is known as a Provisioning Profile; and these need to be created also from the developer.apple.com website as we previously did see in the App ID section.

There are several types of provisioning profiles (more on this a bit later), but I will focus here on two of them: Development and Distribution. Simplifying, the main difference among these is that Development profiles include the information about the devices an app can be installed into, so they are generally used for internal testing on the user devices or, in the case of the iOS apps, when these are run on a physical device using the "Run On Device" option from the Xojo IDE (thus, also on the registered user devices).

In this case we will focus on the creation of a "Distribution Provisioning Profile", so the apps published from the IDE are elegible for TestFlight testing when they are uploaded from the Xojo IDE.

Once logged into developer.apple.com website, select the "Profiles" entry under the "Certificates, IDs & Profiles" section. Then, click the "+" button next to the Profiles header in the resulting page:

../../../_images/11-Profiles-B.png

On the next page, make sure you select the "Mac App Store Connect" option under the Distribution header, because we are going to create a profile for the example macOS app used through this example (for iOS apps you should select the "App Store Connect" option, highlighted in blue in the screenshot), and click the "Continue" button:

../../../_images/12-Profiles-C.png

On the next page, make sure you select the App ID created in the previous section (in our example it is "com.aprendexojo.chess"). Observe how the App ID is prefixed with the Team ID we choose during the creation of the App ID (in our example "BW7PU32485"); that is: BW7PU32485.com.aprendexojo.chess. Also, make sure that the "Mac" option is selected under "Profile Type" instead of "Mac Catalyst”:

../../../_images/12-Profiles-D.png

Click on the "Continue" button and, in the next page, make sure to select the same Distribution certificate you are going to use when the Xojo app is built (i.e: the Apple Distribution certificate installed on your Mac). If you have several Distribution certificates installed on your Mac:

../../../_images/13-Profiles-E.png

Click the "Continue" button and, in the next page, give a meaningful name to the Provisioning Profile, so you are able to easily distinguish it later among other generated provisioning profiles:

../../../_images/14-Profiles-F.png

When done, click on the "Generate" button and, after a couple of seconds, you will see the Provisioning Profile summary with the "Download" button enabled. Click on it in order to download the Provisioning Profile to your Mac:

../../../_images/15-Profiles-G.png

Note

Provisioning Profiles for iOS: When it is about iOS apps, you will need to create both Development and Distribution provisioning profiles. When creating the Development provisioning profile, make sure to include all the registered devices you want to use for installing and testing the app directly from Xojo (Run On Device option, from the IDE). Also, once these Provisioning profiles are downloaded to your Mac, double-click on them so Xcode gets them installed in the right location (at the time of this writing: Library > Developer > Xcode > User Data > Provisioning Profiles).

Adding the Distribution Provision Profile to your Xojo Project

Move the just downloaded macOS Distribution Provision Profile to a better location more related with your Xojo project, and rename it as "embedded.provisionprofile". Next, open your Xojo project and add a new "Copy Files" step selecting the macOS item under Build Settings and using the contextual menu to select the "Add to 'Build Settings' > Build Step > Copy Files" option:

../../../_images/16-CopyFiles.png

Next, use the "Add file" button from the Copy Files toolbar to select your "embedded.provisionprofile" file, using the following values in the associated Inspector Panel:

  • Name: Distribution Profile

  • Applies To: Release

  • Architecture: Any

  • Destination: Contents Folder

Note

For Xojo iOS projects, the provisioning profiles will be applied automatically when building or publishing the app, from those installed by Xcode double-clicking on them when generated and downloaded from developer.apple.com.

App Store Connect: Creating the Record for the App

You need to create an App Record for every macOS or iOS app meant to be distributed through the Mac or iOS App Store.

In order an app can be uploaded from the Xojo IDE, it is not crucial to fill-in every required field from the several available sections (you can do that at your own pace); but it is, at least, to have an App Record created for it! This is done using your developer credentials to access the appstoreconnect.apple.com website.

../../../_images/17-ConnectNewRecord.png

Once logged, select the Apps icon and click the "+" button on the next page and select the "New App" option in order to create a new App Record:

../../../_images/18-ConnectNewRecord-B.png

The previous action will bring a dialog where you have to enter the essential app information so the record can be created:

../../../_images/19-ConnectNewRecord-C.png
  • Platforms: Select the "macOS" option (or "iOS" in order to create a new app record for your Xojo iOS apps!).

  • Name: Make sure to enter the same name used in your Xojo project for the app (Build Settings > macOS > Mac App Name or Build Settings > iOS > iOS App Name). Apple can be "picky" about it during the app reviewing process if they differ, because that name will be also the one used in the App Store listing.

  • Bundle ID: Select the App ID you created for the app when followed the steps under the "Handling App ID" section.

  • SKU: Type any arbitrary SKU value that makes sense for you so you can track uniquely this app.

  • User Access: If you are a "solo" developer, it doesn't make much difference the what option you decide to choose. If it is not the case, you can get more control about what members of the Development team can access the app selecting the "Limited Access" option.

Once you are confident with the provided information, click on the "Create" button so the new app record can be created. (It may be the case you get an error if something else has registered an app with the same name. If that is the case, you need to choose a new one for your app!)

Note

App Record values as the App Name and the Bundle ID can be changed later, if needed, from the General > App Information section from the App Record page.

Once the App Record has been created, there is a lot of required information to fill in so the app can go through the App Store Review Process and be publicly listed in the Mac / iOS App Store when approved. But, as I said before, you can add it at your own pace. The important thing, by now, is that once the record is created you have everything setup to start uploading your app builds (versions) from the Xojo IDE.

Publishing Mac Apps from the Xojo IDE

General Information

Open your Desktop Xojo project in the IDE and select Build Settings > macOS. Then, make sure you have the right/expected values in the associated Inspector Panel for the following fields:

../../../_images/20-XojoPublish.png
  • Mac App Name: Matches the one entered for the App Record at appstoreconnect.apple.com

  • Bundle Identifier: Matches the App ID created for the app.

  • Category: Select the category that better fits into your app, among the available ones.

App Store Connect Setup

In order the IDE can upload the app to App Store Connect, it requires an app-specific password. You can add it clicking on the App Store Connect > Setup button. If you created such app-specific password in a previous release of Xojo (under Build Settings > Sign > Notarization > Setup), then it is not required to do it again. Also, remember that this setup only needs to be done once, for all your Desktop (macOS) and iOS projects.

Signing and Sandboxing

Select Build Settings > macOS > Sign in the project browser in order to access the associated Inspector Panel:

../../../_images/21-XojoPublish-B.png
  • Developer ID: Type (or paste) the full string from the Apple Distribution certificate installed on your Mac. In this example it is (without the quotes): "Apple Distribution: Francisco Javier Rodriguez Menendez (BW7PU32485)". Also this certificate should match the same selected when the Distribution Provision Profile was created, and the Team ID (the value between the parenthesis) should match the same selected when the App ID (Identifier) was created for the app at developer.apple.com.

  • Sandboxing: Apps uploaded to the App Store Connect do require to have Sandboxing enabled. So switch-on that option and click the associated "Edit" button in order to enable the required sandboxed features for the purpose of your app. In our example, we only enabled the ability to read/write the selected user files.

../../../_images/22-XojoPublish-C.png

Shared Settings

Select Build Settings > Shared in the project browser in order to access the associated Inspector Panel:

../../../_images/23-XojoPublish-D.png

If you are going to publish the final (release) version of your app, after it has been thoroughly tested, then you probably would want to set the Stage Code value to "Final". Also, make sure to enter the short version string under the Version field, and the copyright information for the app under the Copyright field.

Note

Did you forget something? Every time you click on the the Publish button (or select the equivalent "Build and Publish to App Store Connect" menu item from the Project menu), the IDE will run a "check list", so if something is needed to be set in the IDE, prior to uploading the app to App Store Connect, the errors will be shown in the IDE's Error Panel pointing the "what" and "where" to fix them!

../../../_images/macOS_ErrorPanel.png

App Icon

Nothing new here apart from building your macOS app for a regular or "web based" distribution. That is...your app needs an icon in the expected sizes! But when it is about publishing to the Mac/iOS App Store, this requirement is even enforced and we catch it even before we start the app building process to save you compilation and uploading time just to find that an error happened as result. So, make sure you add all the required sizes selecting the App item in the project browser and, then, clicking the Appearance > Icon option in the associated Inspector Panel.

../../../_images/24-XojoPublish-E.png

That action will open the Icon Editor where you can drag & drop the different icon files for every size or just paste them from your preferred image editor.

Publishing!

Click on the Publish button. After the "check list" passed without throwing errors, you will see a confirmation dialog. Click the "OK" button to start the process and uploading your app new build to App Store Connect.

../../../_images/PublishButton.png ../../../_images/ConfirmationDialog.png

If everything went ok, you will see a "Success" dialog at the end of the process; otherwise, if there is some error during the several steps involved in the process, an error message dialog will provide more information about the detected problem and the process will be interrupted bringing you back to the IDE.

In both cases, either if your new app build has been successfully sent to App Store Connect or not, you can find the created Log file in the same folder of the built app; so, in case of errors, you can open such Log file in order to find all the received information about the problem(s) so you have more hints in order to fix them before trying it again. For example:

2025-01-23 12:54:35.030 *** Error:
[ContentDelivery.Uploader.6000028E01C0] The provided entity
includes an attribute with a value that has already been used
(-19232) The bundle version must be higher than the previously
uploaded version: ‘1.0.6’. (ID: d422b9bf-049f-4263-af43-8357c2fe5f00)

In this case, the Log file entry is telling us that we tried to publish a build having the same version number than one of the already uploaded builds to App Store Connect. So if this new build has, in effect, changes or new features, the way to fix this problem is simply increasing the version number (also for the short version string) before publishing it.

Note

Is very common for complex Xojo macOS projects to add build steps under the Build Settings > macOS section, as for example those in charge of copying additional required resources to the compiled app bundle. If that is the case, make sure that the Sign build step to be the last one in the list! (That is, the last one to be executed during the build process); otherwise, if “something” else is copied into an already signed app, such action will invalidate the sign of the app… and will lead to errors when publishing the app (and probably even when running the final build even locally).

../../../_images/SignAsLastStep.png

Publishing iOS Apps From the Xojo IDE

Publishing iOS apps from the Xojo IDE is not much different from what we already did see for macOS apps. In this case, when you click the Publish button the first thing done by the IDE is running a “Checklist” and show any of the detected errors (as for example missing icons, or the lack of a previously created app record at appstoreconnect.apple.com), and display them in the Errors Panel of the IDE if that is the case.

But before everything that can happen, make sure you have Build Settings > iOS > Code Signing > Build for set to the “AppStore” value; otherwise, even the Publish button will be disabled in the Xojo IDE Toolbar.

../../../_images/iOSBuildSettings.png

Also, make sure you have a registered App ID at developer.apple.com website that matches the one entered under the Bundle Identifier field. Also, both a Development and Distribution profile needs to be created, downloaded and properly installed on your Mac. Finally, make sure there is a Team selected.

If there are no errors during the Publish process, the new iOS app build will be available on the appstoreconnect.apple.com website as we did see previously for published macOS apps.

If there are errors during the upload process, then these will be shown in a dialog and, as we did see for macOS apps, also available in the generated Log file that is saved under the same folder used for the app build.

Testing with TestFlight

When you create a new app record in App Store Connect and access to it, you will see one of the tabs in the upper area of the page is named "TestFlight". Click on it, and you will see all the uploaded builds of your app that are elegible to be tested:

../../../_images/25-TestFlight.png

As you can see, there is a warning icon associated with our just uploaded app build (A). That is because Apple requires a bit of additional information from you about the Encryption Export Regulations compliance of the app; so click the associated "Manage" link to access the dialog where you can make your choice about it:

../../../_images/26-TestFlight-B.png

Once the requirement has been completed, the build status will change to "Ready to Submit" and, as you can see there, it is also telling you that that build will be available for your testers for the next 90 days before expiring. Probably time enough before you send new test builds for them, anyway.

../../../_images/27-TestFlight-C.png

Note

If your apps meet the “None of the algorithms mentioned above” option, then it is possible to surpass this extra step of “Missing Compliance” for new uploaded builds adding an additional key/value pair for the generated .plist file. You can do that using the Plist Editor in the Xojo IDE —Build Settings > macOS > Property List > Edit, on Desktop projects; or Build Settings > iOS > Property List > Edit for iOS projects—, with the following values: ITSAppUsesNonExemptEncryption set to :docs:`False</api/language/false>`.

../../../_images/PropertyListEditor.png

For every one of your apps, it is possible to create as many tester groups as you need. Initially there is only one entry: "Internal Testing". You can create there the groups to add any of the members of your Apple Development Team to any of the groups you decide to create. Clicl on the "+" icon to create the first of these groups.

../../../_images/28-TestFlight-D.png

Give the new group a name and disable the "Enable automatic distribution" checkbox. Then, click on the "Create" button.

../../../_images/29-TestFlight-E.png

Once the new internal testing group has been created, you will be able to assign any of the uploaded (and not expired) builds of your app to it, and also add the members for that group (remember, those under your Apple Developer Team!):

../../../_images/InternalTestingBuildAndInvite.png

But having Internal testing groups is not of much help when you are a solo or small development Team. The good news is that, as soon you did create the first, mandatory, Internal group, a new option will be added to the TestFlight barside: External Testing.

../../../_images/ExternalTestingSidebar.png

In this case, you will be able to invite up to 10,000 members to test it. Probably the main difference compared with the Internal groups, is that once you select the build to be tested in any of the external groups, it needs to go through the Beta App Review process. That is, won't be immediately available for your testers until the review process is completed; but this process only is required for the first build, so successive ones will be available immediately as it happens for the ones of the Internal groups.

When it is about inviting members for a external group you have several choices, from creating and sharing a public link to manually adding them or even importing them from a .csv formatted file.

../../../_images/ExternalTestingPublicLink.png ../../../_images/ExternalTestingInvite.png

TestFlight from the User Side

Both for Internal Testing groups and External Testing groups, when the members receive an Invitation to join (by email or using the public link), they will be able to see some generic information about the app to be tested, and also the main required step in order to be able to test it: install the TestFlight app for macOS through the provided link (in case it is not installed already on the user’s Mac):

../../../_images/TestFlightInvitationByEmail.png

Once the TestFlight app is installed on the Mac, it will bring the “Install App” dialog, so the invited testing member only needs to click on it in order to install the app under the usual Applications folder:

../../../_images/TestFlightInstallApp.png