directoryCopy the code
  • 1. The scripts based on CocoaPods and Podhelper. rb locally rely on FlutterModule
  • 2. Compile FlutterModule and manually add.xcFramwork to the iOS project
  • 3. Compile FlutterModule that depends on the flution.xcFramework remotely and the rest locally. Xcframwork

The “Relying on the Flutter Module in iOS Projects” series of articles and build scripts are now available on GitHub, portal 🚪

The three local dependency solutions outlined in this article are recommended in the Chapter: Adding Flutter to iOS development document, and are suitable for relying on the Flutter Module in the original iOS project. The dependency Module Flutter is divided into local dependencies and remote dependencies. Remote dependencies will be covered in a future article, but if you want to see them in advance, you can visit the portal above.

To add the Flutter Module to an existing iOS project, create a Flutter Module first.

cd some/path/
flutter create --template module flutter_module
Copy the code

The structure of the flutter_module directory is as follows… /flutter_module/lib/ is the dart file we wrote.

│ ├─ build │ ├─ flutter_module.iml │ ├─ flutter_module.iml │ ├─ flutter_module.iml │ ├─ flutter_module.iml │ ├─ flutter_module.iml │ ├─ flutter_module_android ├ ─ ─ lib │ ├ ─ ─ pubspec. Lock │ ├ ─ ─ pubspec. Yaml │ └ ─ ─ the testCopy the code

Once you have the Flutter_Module built, add some flutter code and a third party component (such as Flutter_boost) to test it.

1. The scripts based on CocoaPods and Podhelper. rb locally rely on FlutterModule

This access mode is the most common one, easy to use, convenient debugging. The iOS_module /flutter_module /andriod_module can be stored in different Git repositories. To test the code, I put iOS_Module /flutter_module/andriod_module in a Git repository/directory. Ios_module is the iOS project directory. The overall directory structure is as follows:

Some/Path / ├── Andriod_module │ ├─... │ ├── flutter_module.iml │ ├─ lib │ ├─. │ ├─ build │ ├─ flutter_module.iml │ ├─ lib │ ├─ Pubspec. Lock │ ├ ─ ─ pubspec. Yaml │ └ ─ ─ the test ├ ─ ─ ios_module ├ ─ ─ FlutterBoostPro ├ ─ ─ FlutterBoostPro. Xcodeproj ├ ─ ─ FlutterBoostPro. Xcworkspace ├ ─ ─ Podfile ├ ─ ─ Podfile. Lock └ ─ ─ the PodsCopy the code

Then add the following code to the Podfile file of the iOS project to execute pod Install or Update.

  flutter_application_path = '.. /flutter_module/'
  load File.join(flutter_application_path, '.ios'.'Flutter'.'podhelper.rb')
  install_all_flutter_pods(flutter_application_path)
Copy the code

The Podhelper.rb script compiles the Flutter component code into the.XCFramework and imports it into the Pods via a dependent local path.

This way, whether Debug run or Release packaging, is feasible, and convenient for single development and debugging of both ends, in one computer with two ides development and debugging of both ends of the code can be, the simulator can also run normally. There are obvious drawbacks, however. All iOS developers need to have the Flutter development environment installed. In addition, iOS projects can be slow to compile.

2. Compile FlutterModule and manually add.xcFramwork to the iOS project

First you need to compile The FlutterModule into the.xcFramework dynamic library for iOS using the Flutter Build ios-Framework — XCFramework instruction set. However, this directive can set the directory to export to, so we can directly export to iOS_module /. The complete directory structure is as follows. Compared to solution 1, we only added the FlutterFrameworks directory, which is used to store the XCFramework that was compiled with Flutter.

Some/Path / ├── Andriod_module │ ├─... │ ├── flutter_module.iml │ ├─ lib │ ├─. │ ├─ build │ ├─ flutter_module.iml │ ├─ lib │ ├─ Pubspec. Lock │ ├ ─ ─ pubspec. Yaml │ └ ─ ─ the test ├ ─ ─ ios_module ├ ─ ─ FlutterBoostPro ├ ─ ─ FlutterBoostPro. Xcodeproj ├ ─ ─ FlutterBoostPro. Xcworkspace ├ ─ ─ FlutterFrameworks # < - add this folder ├ ─ ─ Podfile ├ ─ ─ Podfile. Lock └ ─ ─ the PodsCopy the code

By executing this complete compilation command, you can export the Debug/Profile/ release E3 schema of the XCFramework and store it in one of the three directories. The full instructions are as follows:

This process can be a little time consuming

flutter build ios-framework --xcframework --no-universal --output=.. /ios_module/FlutterFrameworks/Copy the code

Then right-click on the root directory of the Xcode project and Add the file, that is, Add File to ‘FlutterBoostPro’, select Create Groups and remember to select Add to Targets. When added, Xcode will automatically add these XCFramework files to the Link Binary With Libraries in the Build Phases. This process is manually dragged in the Flutter documentation; adding files eliminates the need to drag files.

Then I added the framework to the Embed Frameworks. The first time I added the framework, I couldn’t find the Embed Frameworks. Under target-general, go to Frameworks, Libraries, and Embedded Content. However, the files we Add using Add File to ‘a project’ will be added to this column automatically, so we don’t have to drag them in again.

In the TARGETS of the Build Settings set inside Runpath Search Paths, add “$(SRCROOT)/FlutterFrameworks/Release”, specify the relative path. When you try to run the project, you will hear an error:

dyld: Library not loaded: @rpath/Flutter.framework/Flutter
  Referenced from: /private/var/containers/Bundle/Application/0A64CC78-D8D3- 433.C-B794-B8F928525885/FlutterBoostPro.app/FlutterBoostPro
  Reason: image notfound dyld: launch, loading dependent libraries DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Deve loper/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylibCopy the code

This is because we did Not set the Embed & Sign, the status is Do Not Embed, the Flutter documentation also specifies this operation, select the Embed & Sign, once the correct setting is set, the project will run properly.

This way of importing the framework adds the process of compiling the Flutter, setting up the Target configuration, and adding the framework again if you need to switch the Debug/Release environment. And reset the FRAMEWORK_SEARCH_PATHS and Embed & Sign, which will add a lot of manual operations during debugging. Of course, in order to facilitate debugging, the Runner project below Flutter_module /. Ios/can also rely on ios business code. It can also be quickly debugged, but having to rely on it again after the Flutter is clean is relatively tedious; In addition, because the build product is imported directly into the iOS project directory, and the vipt. xcframework file is large, it will directly increase the git file size, affecting Git push and pull, and each build will also affect the synchronization of other staff branches. However, this approach to importing the framework also has a very big advantage. Compiling and running the iOS project takes a lot less time, since the xcframework file is already compiled and there is no need to compile the Flutter code. In addition, other developers do not need to install the Flutter development environment, just run iOS projects.

3. Compile FlutterModule that depends on the flution.xcFramework remotely and the rest locally. Xcframwork

The first two methods both rely on native compilation products. If you want to share the FlutterFrameworks with colleagues, it will be time-consuming to push them directly to Git. Xcframework file is too large, exceeding Github’s 100 MB per file limit. Pushing to Github is not feasible. The internal Gitlab can but is slow. For this reason, the Official Flutter implementation has implemented a local PodSpec transfer to rely on remote ZIP files for the Flution. xcFramework. This approach to relying on the Flutter component is logically consistent with solution 2, which is to compile the Flutter_module into a framwork, store it in the FlutterFrameworks directory, and then import the project manually. The difference is that the Flution. xcFramework is imported via cocoaPods and relies on Google’s remote files, which eliminates the problem of git not being able to commit or being slow to commit.

To compile the Flutter, note the addition — Cocoapods, the compiled product contains a Flutter. Podspec, which depends on the remote file of the Flutter.

flutter build ios-framework --cocoapods --xcframework --no-universal --output=.. /ios_module/FlutterFrameworks/Copy the code

As we can see from the contents of the caption. podspec, the caption. xcframework relies on a remote ZIP file that we did not compile with the previous instructions, and the exported directory does not contain the Caption. xcFramework. Only App. Xcframework, FlutterPluginRegistrant. Xcframework and third-party plug-in library flutter_boost. Xcframework.

Pod::Spec.new do |s|
  s.name                  = 'Flutter'
  s.version               = '2.0.300' # 2.03.
  s.summary               = 'Flutter Engine Framework's.description = <<-DESC ... Some descriptions DESC S.Hemepage ='https://flutter.dev'
  s.license               = { :type => 'MIT', :text => <<-LICENSE ... Some copyright notices LICENSE} s.thor = {'Flutter Dev Team'= >'[email protected]' }
  s.source                = { :http => 'https://storage.flutter-io.cn/flutter_infra/flutter/3459eb24361807fb186953a864cf890fa8e9d26a/ios-release/artifacts.zip' }
  s.documentation_url     = 'https://flutter.dev/docs'
  s.platform              = :ios, '8.0'
  s.vendored_frameworks   = 'Flutter.xcframework'
end
Copy the code

Then we add a dependency Flutter to the Podfile and execute pod Install or Update

pod 'Flutter', :podspec => './FlutterFrameworks/Release/Flutter.podspec'
Copy the code
-> Installing Flutter (2.0300.)
 > Http download
   $ /usr/bin/curl -f -L -o /var/folders/jp/4slqd1n915b7s_dm47l0mk240000gn/T/d20210706-71545-f6gido/file.zip https://storage.flutter-io.cn/flutter_infra/flutter/3459eb24361807fb186953a864cf890fa8e9d26a/ios-release/artifacts.zip-- creation-dirs --netrc-optional --retry 2 -a 'CocoaPods/1.10.1 CocoaPods -downloader/1.4.0' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 194M 100 194M 00 10.0M 0 0:00:19 0:00:19 - : - : - 10.8 MCopy the code

The first installation will download the vipt. xcFramework from the cloud. The file size is around 200M (different versions of The vipt. xcframework have different sizes). It will test the network a bit. So be sure to add iOS_Module /Pods/Flutter/*.xcframework to.gitignore.

If we run the project at this time, we will also report an error, because we are relying on the Vibe.xcframework so far, and the other compiled artifacts are still not imported. So we need according to the scheme 2 the process of the App. Xcframework, FlutterPluginRegistrant xcframework and third-party libraries flutter_boost. Xcframework imported into the project. Instead of adding Files to ‘a project’, I’m going to drag the three Files into Frameworks, Libraries, and Embedded Content and set the Embed & Sign to the Frameworks and Embedded Content. Then in the Build Settings of Runpath Search Paths to add “$(SRCROOT)/FlutterFrameworks/Release”, can the normal operation of the project.

Compared to Solution 2, the Vipt. xcFramework uses CocoaPods dependency imports, but the rest of the.XCFramework still needs to be imported manually. So its advantages and disadvantages are basically the same as scheme 2. The xcframework is a remote static resource that needs to be changed in scenario 2 if there are custom engine requirements.