AppForShare

Codemagic iOS ad hoc builds for Flutter: ios_signing and use-profiles

· 5 min read

Codemagic iOS ad hoc builds for Flutter: ios_signing and use-profiles

An App Store signed .ipa from Codemagic is fine for TestFlight, but it will not install from a link on a tester's iPhone. For that you need an ad hoc build (or development, or enterprise) whose profile lists the tester's device. Codemagic can fetch or make that profile for you. This guide shows the workflow for a Flutter app, the one flag that trips people up, and what to do when a new iPhone joins. Codemagic facts are from docs.codemagic.io as read on November 5, 2026.

What you need first

  • An App Store Connect API key added to Codemagic. Codemagic uses it to fetch or make certificates and profiles.
  • The bundle id of the app, for example io.acme.notes, registered in your Apple Developer account.
  • The UDIDs of the test iPhones registered on Apple. Testers can find theirs with the free UDID finder, no cable or Mac needed.

The workflow

workflows:
  ios-adhoc:
    name: iOS ad hoc
    environment:
      groups: [appforshare]
      flutter: stable
      ios_signing:
        distribution_type: ad_hoc
        bundle_identifier: io.acme.notes
    scripts:
      - name: Get packages
        script: flutter pub get
      - name: Use profiles
        script: xcode-project use-profiles
      - name: Build ipa
        script: flutter build ipa --release --export-options-plist=/Users/builder/export_options.plist
      - name: Mark success
        script: touch ~/SUCCESS
    artifacts:
      - build/ios/ipa/*.ipa

What each part does, per Codemagic's iOS code signing docs:

  1. ios_signing tells Codemagic which kind of profile to get. distribution_type can be app_store, ad_hoc, development or enterprise. With an API key, Codemagic fetches the matching certificate and profile for bundle_identifier.
  2. xcode-project use-profiles applies those profiles to the Xcode project and writes /Users/builder/export_options.plist.
  3. flutter build ipa --export-options-plist=... builds and exports with that file, so the export uses the ad hoc profile.

Codemagic's own Flutter quick start says: "When using a third party app distribution service such as Firebase App Distribution, set the distribution_type to ad_hoc." The same goes for any install link service.

The --export-method trap

Many Flutter guides, including ours for local builds, say flutter build ipa --export-method ad-hoc. On Codemagic, do not combine that flag with --export-options-plist. Flutter does not accept both together, and using --export-method alone skips the export options file Codemagic wrote, so the export may not use the profile Codemagic prepared. Keep the plist and leave the method to ios_signing.

Related: since Xcode 15.4, the export method names in an options file changed from ad-hoc to release-testing and from development to debugging. When use-profiles writes the file for you, you do not have to care.

Apps with extensions

A widget, notification service or share extension has its own bundle id and needs its own profile. If the build fails with a profile error that names an extension, that target is missing a profile: check Codemagic's signing docs for how to sign more than one bundle id, and read which target the error names. Our guide to "No matching profiles found" on Codemagic walks through the usual causes.

Check the .ipa before you send it

Download the .ipa from the build and drop it into the IPA inspector, or drop the .mobileprovision and the .ipa into the provisioning profile inspector. Both run in your browser and never upload the file. Look for three things:

  • The type says Ad Hoc, not App Store.
  • The profile has not expired.
  • Each tester's UDID is in the profile.

If a UDID is missing, the iPhone will refuse the install, usually with "integrity could not be verified".

Sharing the build

Add a publishing script that uploads the file to an install page. Codemagic runs publishing scripts even after a failed build, so check the ~/SUCCESS file the last build script wrote:

    publishing:
      scripts:
        - name: Share with testers
          script: |
            if [ -f ~/SUCCESS ]; then
              npx --yes appforshare upload build/ios/ipa \
                --notes "$(git log -1 --pretty=%B)" --channel beta
            fi

APPFORSHARE_TOKEN goes in the appforshare group as a Secure variable (upload tokens are part of AppForShare Pro and Team). Testers then open an install page with an Install button on the iPhone. More on why this beats the artifact link is in Share a Codemagic build with testers.

When a new tester joins

A new iPhone means a new profile and a new build. Nothing changes an .ipa you already exported. The steps:

StepWith Codemagic onlyWith AppForShare added
Get the UDIDDevice registration link by email (a team feature)Onboarding link per iOS project; the tester installs a profile, no account (Pro)
Register on AppleCodemagic adds the device to the Apple Developer PortalAn Admin registers it in one click with your App Store Connect API key (Pro)
New profileuse-profiles on the next buildSame, or AppForShare remakes the ad hoc profile on Apple
New buildRun the workflow againRun the workflow again; the tester gets one email when that build is uploaded

Apple allows 100 devices per device type per membership year, and disabled devices keep their slot until renewal. Count before you add a whole team.

Common questions

Can I build ad hoc without a Mac?

Yes, on Codemagic: its Macs build and sign the app. That is one of the main reasons Flutter developers use it.

Should I use development instead of ad hoc?

Development builds work for your own team's devices, but testers on iOS 16 and later must turn on Developer Mode. For people outside the team, ad hoc is easier.

Can the same workflow make a TestFlight build?

Use a second workflow with distribution_type: app_store. That .ipa goes to TestFlight, either through Codemagic's publishing or by uploading it to AppForShare and letting an Admin send it (Pro and Team). See Codemagic TestFlight publishing errors.

The complete setup with Android and the Workflow Editor is in Use AppForShare with Codemagic. To see the install page your testers would get, create a free account and upload an ad hoc .ipa.

Keep reading

App Distribution Platform · · 5 min read

AppForShare File Size and Upload Limits

AppForShare limits the size of each build you upload by plan: 50 MB without an account, 150 MB on the Free plan, 2 GB on Pro and 4 GB on Team. Accounts also have a storage total, and every plan...