5

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.

nbloqs
  • 3,152
  • 1
  • 28
  • 49

2 Answers2

1

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

Zeusox
  • 7,708
  • 10
  • 31
  • 60
  • Do you mean in my_plugin/example/ios/Runner.xcworkspace? (there is no XCode workspace inside the my_plugin/example/ios/Runner folder) – nbloqs Apr 19 '19 at 15:34
  • Yes that same directory, but open it with your Xcode program instead of what you are using to build your flutter apps – Zeusox Apr 19 '19 at 15:40
  • I did it on the workspace from my previous comment, and it didn't work (exactly the same error). Just in case, after having done so, I went to my Flutter app and run "flutter packages get". Also, the runner example runs on the simulator (just a blank screen, but it seems that this is a pod problem, not an XCode one) – nbloqs Apr 19 '19 at 15:40
  • Could you paste your podfile to see what's inside of it? – Zeusox Apr 19 '19 at 15:43
  • Thanks. I edited the question in order to include the plugin's podfile (there is another one in the Flutter app itself). – nbloqs Apr 19 '19 at 15:47
  • Please see edited answer. Try to copy the master file and paste it into yours. Then rerun app and see if it solves your error – Zeusox Apr 19 '19 at 15:48
  • I will try to paste that file on my own, but the file was not modified, since I tried this very same process several times, and took care of just using things "as were generated by the Flutter tools". The modifications that I did were only after things had not worked. – nbloqs Apr 19 '19 at 15:50
  • Also, we are talking about the plugin's "example" Podfile, right? – nbloqs Apr 19 '19 at 15:50
  • @nbloqs Yes that is true – Zeusox Apr 19 '19 at 15:51
  • I pasted it and compared the files. The only difference is the absence of "use_frameworks!" in Google's canonical file. So I tried first pasting the file, and now it even fails when running "flutter build ios --no-codesign", with a complex error that can't be pasted on a comment. After comparing the files, I tried my original one with the line "use_frameworks!" commented out. Got the same error. If I put that line back, the "flutter build ios..." succeeds, but I'm in the same situation as in the beginning. – nbloqs Apr 19 '19 at 15:58
  • Another interesting thing is that this should be easy to reproduce, since I'm just trying to add a raw generated plugin to an arbitrary app and it fails without any kind of modifications having done at all. – nbloqs Apr 19 '19 at 15:58
  • Well, practically it should not fail, unless the plugin's version is not compatible with what is going on in your app! – Zeusox Apr 19 '19 at 16:07
  • The app is nearly an empty one that I use for testing things like this. It's only dependencies right now, aside of this very same package and some other pure dart code that I wrote, is: dependencies: flutter: sdk: flutter – nbloqs Apr 19 '19 at 16:10
  • Try a clean and rebuild! If that does not solve your issue and since the app can easily be reproduced, I would just go for that... – Zeusox Apr 19 '19 at 16:11
  • Thanks! I ran "flutter clean" (both in the app and in plugin itself), then rebuilt the plugin with "flutter build ios --no-codesign", then went to the app's dir and ran "flutter packages get", and finally tried to run the app itself from where I was always running it before the plugin (VCS's Flutter debug run button). Same original problem. – nbloqs Apr 19 '19 at 16:15
  • I just did another test: created an empty app using VSC's "Flutter: New Project" command (which creates the "Flutter 101" increment counter example). Then followed again the steps from here to create the plugin package: https://flutter.dev/docs/development/packages-and-plugins/developing-packages, and got the same error when included that package an ran the project 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 first app, but both were created by Flutter's tools. – nbloqs Apr 19 '19 at 17:13
0

After having tried several things, none of which worked, I found this solution on a GitHub thread:

https://github.com/ko2ic/image_downloader/issues/9#issuecomment-471608482

Having followed these steps strictly, did finally work.

A few interesting thing were:

  1. I also tried to create the plugin from Android Studio (instead of from the command line or from VSC). It did not work without the steps described in the previous link, but the steps were finally done on that Android Studio created plugin (so I just don't know if this would work with a VSC created plugin, must I would say that most likely yes, since I did not see any difference on the outcome of the commands). I mention this because this answer was suggesting that that may fix the problem: https://stackoverflow.com/a/54919007/6348097

  2. There are 2 Podfile files in the sources: one for the plugin, and another one for the app itself. I modified both and I opened both XCode (automaticall generated) projects.

  3. I also added the following line to the Podfile: config.build_settings['SWIFT_VERSION'] = '4.2', right before the only occurrence of the following line: config.build_settings['ENABLE_BITCODE'] = 'NO'

  4. In both Podfile files, uncommented the platform :ios, '8.0', and changed the versino to 9.0. This did not solve the problem, but at some point fixed a warning when running pod install

nbloqs
  • 3,152
  • 1
  • 28
  • 49