Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: Can't create plugin packages

Tags:

flutter

I'm trying to create a plugin package in order to access some specific hardware APIs, both in Android (using Kotlin) and in iOS (using Swift). To that end, I was trying to follow the instructions here:

https://flutter.dev/docs/development/packages-and-plugins/developing-packages

I'm right now only working on the Swift side of the problem, so what has been done so far is the following:

1) Went to the directory where other Dart packages live (which are non-Flutter ones, and which work perfectly okay) and ran:

flutter create --org com.example --template=plugin my_plugin

That created the whole thing as described in the documentation, and no error was reported.

2) Then, as stated in the previous link, I went to my_plugin/example and ran flutter build ios --no-codesign, with the following (apparently okay?) output:

 Warning: Building for device with codesigning disabled. You will have to manually codesign before deploying to device.
 Building com.example.myPluginExample for device (ios-release)...
 Running pod install...                                              6.5s
 ├─Building Dart code...                                     2.9s
 ├─Generating dSYM file...                                   1.0s
 ├─Stripping debug symbols...                                0.6s
 ├─Assembling Flutter resources...                           1.0s
 └─Compiling, linking and signing...                         9.0s
 Xcode build done.                                           19.8s

3) So now with the plugin just created, tried to add it to the main project and thus, in its pubspec.yaml file, inserted the following lines (the plugin is located in ../pkgs with respect to the Flutter application I'm working in:

dependencies:
  flutter:
    sdk: flutter
  my_plugin:
    path: ../pkgs/my_plugin

4) Now just tried to run the Flutter application both in a physical device and in the simulator, and the following error always showed up:

Launching lib/main.dart on iPhone Xʀ in debug mode...
CocoaPods' output:
↳
      Preparing
    Analyzing dependencies
    Inspecting targets to integrate
      Using `ARCHS` setting to build architectures of target `Pods-Runner`: (``)
    Finding Podfile changes
      A my_plugin
      - Flutter
    Fetching external sources
    -> Fetching podspec for `Flutter` from `.symlinks/flutter/ios`
    -> Fetching podspec for `my_plugin` from `.symlinks/plugins/my_plugin/ios`
    Resolving dependencies of `Podfile`
    Comparing resolved specification to the sandbox manifest
      A Flutter
      A my_plugin
    Downloading dependencies
    -> Installing Flutter (1.0.0)
    -> Installing my_plugin (0.0.1)
      - Running pre install hooks
    [!] Unable to determine Swift version for the following pods:
    - `my_plugin` does not specify a Swift version and none of the targets (`Runner`) integrating it have the `SWIFT_VERSION` attribute set. Please contact the author or set the `SWIFT_VERSION` attribute in at least one of the targets that integrate this pod.
    /usr/local/Cellar/cocoapods/1.6.1/libexec/gems/cocoapods-1.6.1/lib/cocoapods/installer/xcode/target_validator.rb:115:in `verify_swift_pods_swift_version'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/gems/cocoapods-1.6.1/lib/cocoapods/installer/xcode/target_validator.rb:37:in `validate!'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/gems/cocoapods-1.6.1/lib/cocoapods/installer.rb:459:in `validate_targets'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/gems/cocoapods-1.6.1/lib/cocoapods/installer.rb:138:in `install!'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/gems/cocoapods-1.6.1/lib/cocoapods/command/install.rb:48:in `run'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/gems/claide-1.0.2/lib/claide/command.rb:334:in `run'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/gems/cocoapods-1.6.1/lib/cocoapods/command.rb:52:in `run'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/gems/cocoapods-1.6.1/bin/pod:55:in `<top (required)>'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/bin/pod:22:in `load'
    /usr/local/Cellar/cocoapods/1.6.1/libexec/bin/pod:22:in `<main>'
Error output from CocoaPods:
↳
        WARNING: CocoaPods requires your terminal to be using UTF-8 encoding.
        Consider adding the following to ~/.profile:
        export LANG=en_US.UTF-8

Error running pod install
Error launching application on iPhone Xʀ.
Exited (sigterm)

5) I tried to fix it by adding the following line to the only 2 Podfile files that I can see in my whole directory structure (the one that belongs to the app and the one that belongs to the new plugin "example" -both files automatically created by Flutter's tools and both not having received any edit until today-):

config.build_settings['SWIFT_VERSION'] = '4.1'

(that idea was taken from https://stackoverflow.com/a/52194702/6348097, and yes: I tried at least one different version number). The error is still the same.

The resulting plugin's Podfile is:

platform :ios, '9.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def parse_KV_file(file, separator='=')
  file_abs_path = File.expand_path(file)
  if !File.exists? file_abs_path
    return [];
  end
  pods_ary = []
  skip_line_start_symbols = ["#", "/"]
  File.foreach(file_abs_path) { |line|
      next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
      plugin = line.split(pattern=separator)
      if plugin.length == 2
        podname = plugin[0].strip()
        path = plugin[1].strip()
        podpath = File.expand_path("#{path}", file_abs_path)
        pods_ary.push({:name => podname, :path => podpath});
      else
        puts "Invalid plugin specification: #{line}"
      end
  }
  return pods_ary
end

target 'Runner' do
  use_frameworks!

  # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
  # referring to absolute paths on developers' machines.
  system('rm -rf .symlinks')
  system('mkdir -p .symlinks/plugins')

  # Flutter Pods
  generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
  if generated_xcode_build_settings.empty?
    puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
  end
  generated_xcode_build_settings.map { |p|
    if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
      symlink = File.join('.symlinks', 'flutter')
      File.symlink(File.dirname(p[:path]), symlink)
      pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
    end
  }

  # Plugin Pods
  plugin_pods = parse_KV_file('../.flutter-plugins')
  plugin_pods.map { |p|
    symlink = File.join('.symlinks', 'plugins', p[:name])
    File.symlink(p[:path], symlink)
    pod p[:name], :path => File.join(symlink, 'ios')
  }
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '4.1'
      config.build_settings['ENABLE_BITCODE'] = 'NO'
    end
  end
end

I did the same adding to the Flutter app's Podfile. Also, the first line where the iOS platform was specified, was originally commented (and that was generating a warning) so I also uncommented that line from both podfiles.

This is the output of flutter doctor:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.2.1, on Mac OS X 10.14.3 18D109, locale en-ES)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.2)
[✓] Android Studio (version 3.3)
[✓] VS Code (version 1.33.1)
[✓] Connected device (1 available)

• No issues found!

The question is just how to make this work. I did not even started adding my own code, but I'm stuck with the very basic Flutter's plugin creation tool. Also, I have no idea why I need all that dirty and complex example subdir in my package (so as a secondary question that is not really important: can I just remove it once this works?)

EDIT: I did another test: created an empty app using VSC's "Flutter: New Project" command (which creates the "Flutter 101" increment-a-counter example). Then followed again the steps described above in order to create the plugin package, and got the same error when included that package on the newly created project and ran it in the iOS simulator. So there is absolutely no code from me there, except for having added the new plugin as a dependency to the example app.

like image 843
nbloqs Avatar asked Nov 06 '22 18:11

nbloqs


1 Answers

Try to open the IOS project in the folder ios/Runner/Runner.xcworkspac with Xcode. Then create / add a new Swift file anywhere in that directory. Xcode will then automatically apply changes needed to your support your swift part of your flutter app.

The other thing could be that your PodFile was modified somehow: try to compare it to Google's master PodFile through this link: PodFile Master File

like image 131
Zeusox Avatar answered Jan 01 '23 20:01

Zeusox