Skip to content

Export an IPA for distribution via "flutter build ipa" without --export-options-plist - #97243

Merged
jmagman merged 7 commits into
flutter:masterfrom
jmagman:xcode-archive-options
Feb 2, 2022
Merged

jmagman merged 7 commits into
flutter:masterfrom
jmagman:xcode-archive-options

Conversation

@jmagman

@jmagman jmagman commented Jan 25, 2022 •

Copy link
Copy Markdown
Member

flutter build ipa has two stages for iOS distribution:

  1. Archive the app into an xcarchive bundle.
  2. Optionally, export the xcarchive into an ipa bundle for distribution to the App Store, or to a device, or enterprise distribution...

Currently to get to number 2 and create the ipa file users need to pass in a --export-options-plist file, which they need to create themselves, or know how to yank off a previously-build IPA. Flutter's iOS distribution docs don't say what needs to go into the plist, it just points to Apple docs, or tells them to launch Xcode and create the IPA there.

  1. Run flutter build ipa to produce a build archive.

Note: When you export your app at the end of Distribute App, Xcode will create a directory containing an IPA of your app and an ExportOptions.plist file. You can create new IPAs with the same options without launching Xcode by running flutter build ipa --export-options-plist=path/to/ExportOptions.plist. See xcodebuild -h for details about the keys in this property list.

  1. Open build/ios/archive/MyApp.xcarchive in Xcode.

In this PR, if the user doesn't pass --export-options-plist, instead of bailing after the xcarchive, assume the user wants the most common case: to distribute their app to the App Store via the new --export-method option and its default app-store. Create the plist if one isn't passed in, with reasonable defaults for the most common settings for a Flutter app. If it fails (they haven't registered their app bundle ID for example), suggest they open the archive in Xcode and go through its wizard, as the docs currently suggest.

Allow the user to also specify --export-method ad-hoc or --export-method development. See https://developer.apple.com/forums/thread/100614 for the distinction.

If the user has a more complicated scenario, they can continue to create their own plist via --export-options-plist, or open with Xcode.

We can add other options in the future for other values in the generated plist, if developers request it.

Command logging examples

Success

$ flutter build ipa
Running "flutter pub get" in veggieseasons...                    1,814ms
Archiving dev.flutter.VeggieSeasons...
Automatically signing iOS for device deployment using specified development team in Xcode project: S8QB4VV633
Running Xcode build...
 └─Compiling, linking and signing...                        12.3s
Xcode archive done.                                         38.6s
Built /Users/m/Projects/samples/veggieseasons/build/ios/archive/Runner.xcarchive.

💪 Building with sound null safety 💪

Building App Store IPA...                                          32.3s
Built IPA to /Users/m/Projects/samples/veggieseasons/build/ios/ipa.
To upload to the App Store either:
    1. Drag and drop the "build/ios/ipa/*.ipa" bundle into the Apple Transport macOS app https://apps.apple.com/us/app/transporter/id1450874784
    2. Run "xcrun altool --upload-app --type ios -f build/ios/ipa/*.ipa --apiKey your_api_key --apiIssuer your_issuer_id".
       See "man altool" for details about how to authenticate with the App Store Connect API key.

Flag validation error

$ flutter build ipa --export-options-plist foo.plist --export-method ad-hoc
"--export-options-plist" is not compatible with "--export-method". Either use "--export-options-plist" and a plist describing how the IPA should be exported by Xcode, or use "--export-method" to create a new plist.
See "xcodebuild -h" for available exportOptionsPlist keys.

IPA creation failure

The bundle identifier isn't set up, which needs to be resolved in Xcode's UI:

$ flutter build ipa --export-method ad-hoc
...
Built /Users/m/Projects/test_create/build/ios/archive/Runner.xcarchive.
...
Building ad-hoc IPA...                                           2,123ms
Encountered error while creating the IPA:
error: exportArchive: Failed to register bundle identifier
error: exportArchive: No profiles for 'com.example.testCreate' were found


Try distributing the app in Xcode: "open /Users/m/Projects/test_create/build/ios/archive/Runner.xcarchive"

Help text

    --export-method                                 Specify how the IPA will be distributed.

          [ad-hoc]                                  Distribute to designated devices that do not need to be registered with the Apple developer account. Requires a distribution certificate.
          [app-store] (default)                     Upload to the App Store.
          [development]                             Distribute only to development devices registered with the Apple developer account.

Fixes #97179

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@jmagman jmagman added platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. t: xcode "xcodebuild" on iOS and general Xcode project management labels Jan 25, 2022
@jmagman jmagman self-assigned this Jan 25, 2022
@jmagman jmagman changed the title Export an App Store IPA during "flutter build ipa" without --export-options-plist Export an IPA for distribution via "flutter build ipa --app-store" without --export-options-plist Jan 25, 2022
@jmagman
jmagman force-pushed the xcode-archive-options branch from 2ee2901 to 145ac21 Compare January 25, 2022 20:16
@jmagman
jmagman marked this pull request as draft January 25, 2022 20:56
@jmagman jmagman changed the title Export an IPA for distribution via "flutter build ipa --app-store" without --export-options-plist Export an IPA for distribution via "flutter build ipa" without --export-options-plist Jan 25, 2022
@flutter-dashboard

Copy link
Copy Markdown

This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@jmagman
jmagman marked this pull request as ready for review January 25, 2022 21:27
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[

@jmagman jmagman Jan 25, 2022 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the changes in this file were moving the FakeCommands out of the overrides and into the test method body so hasNoRemainingExpectations can be checked.

@jmagman

jmagman commented Jan 25, 2022

Copy link
Copy Markdown
Member Author

Adding @cyanglaz for overall review & iOS distribution thoughts, @zanderso for help/logging word-smithing, and @christopherfujino for tool review.


final File tempPlist = globals.fs.systemTempDirectory
.createTempSync('flutter_build_ios.').childFile('ExportOptions.plist');
tempPlist.writeAsStringSync(plistContents.toString());

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never clean this temp directory up, it's really small, like 4K. Do we care?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, yes. This is probably okay though because globals.fs.systemTempDirectory is actually something like $TEMP/flutter_tool.xxxxxxxx, and the tool will clean that up on exit or when getting shutdown by a catchable signal.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tested it, the tool didn't delete it after completion. Where does that deletion mechanism happen?

Path was $TMPDIR/flutter_tools.8iosr9/flutter_build_ios.q898lp/ExportOptions.plist

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the PR to clean up the file.

Comment thread packages/flutter_tools/lib/src/commands/build_ios.dart Outdated

final File tempPlist = globals.fs.systemTempDirectory
.createTempSync('flutter_build_ios.').childFile('ExportOptions.plist');
tempPlist.writeAsStringSync(plistContents.toString());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, yes. This is probably okay though because globals.fs.systemTempDirectory is actually something like $TEMP/flutter_tool.xxxxxxxx, and the tool will clean that up on exit or when getting shutdown by a catchable signal.

@jmagman

jmagman commented Jan 27, 2022 •

Copy link
Copy Markdown
Member Author

Adding @cyanglaz for overall review & iOS distribution thoughts, @zanderso for help/logging word-smithing, and @christopherfujino for tool review.

Taking cyanglaz off, adding huan since Chris is out.

@jmagman
jmagman requested review from hellohuanlin and removed request for cyanglaz January 27, 2022 18:38

@hellohuanlin hellohuanlin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall logic looks good

Comment thread packages/flutter_tools/lib/src/commands/build_ios.dart
Comment thread packages/flutter_tools/lib/src/commands/build_ios.dart
Comment thread packages/flutter_tools/lib/src/commands/build_ios.dart Outdated
Comment thread packages/flutter_tools/lib/src/commands/build_ios.dart Outdated

@christopherfujino christopherfujino left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jmagman
jmagman merged commit 6ceb418 into flutter:master Feb 2, 2022
@jmagman
jmagman deleted the xcode-archive-options branch February 2, 2022 00:13
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 2, 2022
@jmagman jmagman mentioned this pull request Feb 2, 2022
8 tasks done
@LongCatIsLooong

Copy link
Copy Markdown
Contributor

@jmagman

jmagman commented Feb 2, 2022

Copy link
Copy Markdown
Member Author

Does the failure here https://ci.chromium.org/ui/p/flutter/builders/prod/Mac_ios%20ios_content_validation_test/3446/overview have to do with this commit?

Yes 😞

Revert at #97614

@jmagman

jmagman commented Feb 2, 2022

Copy link
Copy Markdown
Member Author

Revert at #97614

Instead of reverting I changed the test at #97615.

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 2, 2022
jmagman added a commit that referenced this pull request Feb 2, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 2, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Feb 4, 2022
clocksmith pushed a commit to clocksmith/flutter that referenced this pull request Mar 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform-ios iOS applications specifically t: xcode "xcodebuild" on iOS and general Xcode project management tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add archive->IPA export options to "flutter build ipa" to avoid opening Xcode during iOS app distribution

5 participants