Skip to content

Commit

Permalink
Adds video, fixes structure to iOS project setup page (#10699)
Browse files Browse the repository at this point in the history
Fixes #10655 -- Refactors page to use standard Markdown and fixes the
captioned images include.

---------

Co-authored-by: Loïc Sharma <[email protected]>
Co-authored-by: Jenn Magder <[email protected]>
  • Loading branch information
3 people committed Jun 17, 2024
1 parent 2d1bd6f commit d506c77
Show file tree
Hide file tree
Showing 22 changed files with 662 additions and 371 deletions.
142 changes: 142 additions & 0 deletions src/_includes/docs/add-to-app/ios-project/embed-cocoapods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
### Use CocoaPods and the Flutter SDK {:#method-a .no_toc}

#### Approach {:#method-a-approach}

This first method uses CocoaPods to embed the Flutter modules.
CocoaPods manages dependencies for Swift projects,
including Flutter code and plugins.
Each time Xcode builds the app,
CocoaPods embeds the Flutter modules.

This allows rapid iteration with the most up-to-date
version of your Flutter module without running additional
commands outside of Xcode.

To learn more about CocoaPods,
consult the [CocoaPods getting started guide][].

#### Watch the video

If watching a video helps you learn,
this video covers adding Flutter to an iOS app:

<iframe class="full-width" src="{{yt-embed}}/IIcrfrTshTs" title="Learn about how to add Flutter to an existing iOS app" {{yt-set}}></iframe>

[Watch this video on YouTube]({{yt-watch}}/IIcrfrTshTs).

#### Requirements {:#method-a-reqs}

Every developer working on your project must have a local version
of the Flutter SDK and CocoaPods installed.

#### Example project structure {:#method-a-structure}

This section assumes that your existing app and
the Flutter module reside in sibling directories.
If you have a different directory structure,
adjust the relative paths.
The example directory structure resembles the following:

```plaintext
/path/to/MyApp
├── my_flutter/
│ └── .ios/
│ └── Flutter/
│ └── podhelper.rb
└── MyApp/
└── Podfile
```

#### Update your Podfile

Add your Flutter modules to your Podfile configuration file.
This section presumes you called your Swift app `MyApp`.

1. _(Optional)_ If your existing app lacks a `Podfile` config file,
navigate to the root of your app directory.
Use the `pod init` command to create the `Podfile` file.

1. Update your `Podfile` config file.

1. Add the following lines after the `platform` declaration.

```ruby title="MyApp/Podfile"
flutter_application_path = '../my_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
```

1. For each [Podfile target][] that needs to embed Flutter,
add a call to the
`install_all_flutter_pods(flutter_application_path)` method.
Add these calls after the settings in the previous step.

```ruby title="MyApp/Podfile"
target 'MyApp' do
install_all_flutter_pods(flutter_application_path)
end
```

1. In the `Podfile`'s `post_install` block,
add a call to `flutter_post_install(installer)`.
This block should be the last block in the `Podfile` config file.

```ruby title="MyApp/Podfile"
post_install do |installer|
flutter_post_install(installer) if defined?(flutter_post_install)
end
```

To review an example `Podfile`, consult this [Flutter Podfile sample][].

#### Embed your frameworks

At build time, Xcode packages your Dart code, each Flutter plugin,
and the Flutter engine into their own `*.xcframework` bundles.
CocoaPod's `podhelper.rb` script then embeds these
`*.xcframework` bundles into your project.

* `Flutter.xcframework` contains the Flutter engine.
* `App.xcframework` contains the compiled Dart code for this project.
* `<plugin>.xcframework` contains one Flutter plugin.

To embed the Flutter engine, your Dart code, and your Flutter plugins
into your iOS app, complete the following procedure.

1. Refresh your Flutter plugins.

If you change the Flutter dependencies in the `pubspec.yaml` file,
run `flutter pub get` in your Flutter module directory.
This refreshes the list of plugins that the `podhelper.rb` script reads.

```console
flutter pub get
```

1. Embed the plugins and frameworks with CocoaPods.

1. Navigate to your iOS app project at `/path/to/MyApp/MyApp`.

1. Use the `pod install` command.

```console
pod install
```

Your iOS app's **Debug** and **Release** build configurations embed
the corresponding [Flutter components for that build mode][build-modes].

1. Build the project.

1. Open `MyApp.xcworkspace` in Xcode.

Verify that you're opening `MyApp.xcworkspace` and
not opening `MyApp.xcodeproj`.
The `.xcworkspace` file has the CocoaPod dependencies,
the `.xcodeproj` doesn't.

1. Select **Product** > **Build** or press <kbd>Cmd</kbd> + <kbd>B</kbd>.

[build-modes]: /testing/build-modes
[CocoaPods getting started guide]: https://guides.cocoapods.org/using/using-cocoapods.html
[Podfile target]: https://guides.cocoapods.org/syntax/podfile.html#target
[Flutter Podfile sample]: https://github.com/flutter/samples/blob/main/add_to_app/plugin/ios_using_plugin/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
The following example assumes that you want to generate the
frameworks to `/path/to/MyApp/Flutter/`.

```console
$ flutter build ios-framework --output=/path/to/MyApp/Flutter/
```

Run this _every time_ you change code in your Flutter module.

The resulting project structure should resemble this directory tree.

```plaintext
/path/to/MyApp/
└── Flutter/
├── Debug/
│ ├── Flutter.xcframework
│   ├── App.xcframework
│   ├── FlutterPluginRegistrant.xcframework (only if you have plugins with iOS platform code)
│   └── example_plugin.xcframework (each plugin is a separate framework)
├── Profile/
│ ├── Flutter.xcframework
│ ├── App.xcframework
│ ├── FlutterPluginRegistrant.xcframework
│ └── example_plugin.xcframework
└── Release/
├── Flutter.xcframework
├── App.xcframework
├── FlutterPluginRegistrant.xcframework
└── example_plugin.xcframework
```

:::warning
Always use `Flutter.xcframework` and `App.xcframework` bundles
located in the same directory.
Mixing `.xcframework` imports from different directories
(like `Profile/Flutter.xcframework` with `Debug/App.xcframework`)
causes runtime crashes.
:::
37 changes: 37 additions & 0 deletions src/_includes/docs/add-to-app/ios-project/embed-frameworks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
### Link and Embed frameworks in Xcode {:#method-b .no_toc}

#### Approach {:#method-b-approach}

In this second method, edit your existing Xcode project,
generate the necessary frameworks, and embed them in your app.
Flutter generates iOS frameworks for Flutter itself,
for your compiled Dart code, and for each of your Flutter plugins.
Embed these frameworks and update your existing application's build settings.

#### Requirements {:#method-b-reqs}

No additional software or hardware requirements are needed for this method.
Use this method in the following use cases:

* Members of your team can't install the Flutter SDK and CocoaPods
* You don't want to use CocoaPods as a dependency manager in existing iOS apps

#### Limitations {:#method-b-limits}

{% render docs/add-to-app/ios-project/limits-common-deps.md %}

#### Example project structure {:#method-b-structure}

{% render docs/add-to-app/ios-project/embed-framework-directory-tree.md %}

#### Procedures

How you link, embed, or both the generated frameworks
into your existing app in Xcode depends on the type of framework.

* Link and embed dynamic frameworks.
* Link static frameworks. [Never embed them][static-framework].

{% render docs/add-to-app/ios-project/link-and-embed.md %}

[static-framework]: https://developer.apple.com/library/archive/technotes/tn2435/_index.html
48 changes: 48 additions & 0 deletions src/_includes/docs/add-to-app/ios-project/embed-split.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
### Use frameworks in Xcode and Flutter framework as podspec {:#method-c .no_toc}

#### Approach {:#method-c-approach}

This method generates Flutter as a CocoaPods podspec instead of
distributing the large `Flutter.xcframework` to other developers,
machines, or continuous integration systems.
Flutter still generates iOS frameworks for your compiled Dart code,
and for each of your Flutter plugins.
Embed these frameworks and update your existing application's build settings.

#### Requirements {:#method-c-reqs}

No additional software or hardware requirements are needed for this method.
Use this method in the following use cases:

* Members of your team can't install the Flutter SDK and CocoaPods
* You don't want to use CocoaPods as a dependency manager in existing iOS apps

#### Limitations {:#method-c-limits}

{% render docs/add-to-app/ios-project/limits-common-deps.md %}

This method only works with the `beta` or `stable` [release channels][].

[release channels]: /release/upgrade#switching-flutter-channels

#### Example project structure {:#method-c-structure}

{% render docs/add-to-app/ios-project/embed-framework-directory-tree.md %}

#### Add Flutter engine to your Podfile

Host apps using CocoaPods can add the Flutter engine to their Podfile.

```ruby title="MyApp/Podfile"
pod 'Flutter', :podspec => '/path/to/MyApp/Flutter/[![build mode]!]/Flutter.podspec'
```

:::note
You must hard code the `[build mode]` value.
For example, use `Debug` if you need to use `flutter attach`
and `Release` when you're ready to ship.
:::

#### Link and embed app and plugin frameworks

{% render docs/add-to-app/ios-project/link-and-embed.md %}
18 changes: 18 additions & 0 deletions src/_includes/docs/add-to-app/ios-project/limits-common-deps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

Flutter can't handle [common dependencies with xcframeworks][common].
If both the host app and the Flutter module's plugin define the
same pod dependency and you integrate Flutter module using this option,
errors result.
These errors include issues like `Multiple commands produce
'CommonDependency.framework'`.

To work around this issue, link every plugin source in its `podspec` file
from the Flutter module to the host app's `Podfile`.
Link the source instead of the plugins' `xcframework` framework.
The next section explains how to [produce that framework][ios-framework].

To prevent the error that occurs when common dependencies exist,
use `flutter build ios-framework` with the `--no-plugins` flag.

[common]: https://github.com/flutter/flutter/issues/130220
[ios-framework]: https://github.com/flutter/flutter/issues/114692
Loading

0 comments on commit d506c77

Please sign in to comment.