Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Friction adding swift plugin to objective-c project #16049

Open
xster opened this issue Mar 29, 2018 · 67 comments
Open

Friction adding swift plugin to objective-c project #16049

xster opened this issue Mar 29, 2018 · 67 comments

Comments

@xster
Copy link
Member

@xster xster commented Mar 29, 2018

flutter create a non-swift project

In pubspec.yaml, add a swift plugin such as flutter_iap.

  1. flutter run warns about use_frameworks! from pod install. Easy to resolve so far.
  2. Building gives The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. This setting can be set in the build settings editor. error.
    Seems like swift pod developers need to specify
    s.pod_target_xcconfig = { 'SWIFT_VERSION' => <a version above 2.3 for it to work with Xcode 9> }
    in their podspec. Added temporary hack in Podfile with
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '3.2'
    end
  end
end

and re-pod install
3.

#import "Headers/flutter_iap-umbrella.h"
            ^
   .../ios/Pods/Target Support Files/flutter_iap/flutter_iap-umbrella.h:13:9: error: include of non-modular header inside framework module 'flutter_iap': '.../.pub-cache/hosted/pub.dartlang.org/flutter_iap-1.0.1/ios/Classes/FlutterIapPlugin.h'

Add

pre_install do |installer|
  # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
  Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
end

and

post_install do |installer|
  installer.pods_project.targets.each do |target|
    # workaround for https://github.com/CocoaPods/CocoaPods/issues/7463
    target.headers_build_phase.files.each do |file|
      file.settings = { 'ATTRIBUTES' => ['Public'] }
    end
  end
end

to make it work.

Wonder if we can add some automatic handling of swift plugins in the default objective-c project's Podfile

@xster xster added the p: tooling label Mar 29, 2018
@xster
Copy link
Member Author

@xster xster commented Mar 29, 2018

@pinkfish
Copy link

@pinkfish pinkfish commented Apr 19, 2018

I tried these work arounds and it is still failing to build with the same error. Do I need to make any specific changes to the podfile that is being included or something too? I just did these in my app podfiles...

 <module-includes>:1:9: note: in file included from <module-includes>:1:
    #import "Headers/flutter_places_dialog-umbrella.h"
            ^
    /Users/ddb/git/mobile/flutter_fuse/ios/Pods/Target Support Files/flutter_places_dialog/flutter_places_dialog-umbrella.h:13:9: error: include of non-modular header inside framework module 'flutter_places_dialog': '/Users/ddb/git/flutter_places_dialog/ios/Classes/FlutterPlacesDialogPlugin.h'
    #import "FlutterPlacesDialogPlugin.h"
@dlutton
Copy link

@dlutton dlutton commented Apr 19, 2018

@pinkfish
Are you using cocoapods 1.5.0?

If so, try downgrading to 1.4.0. That's the only way I've been able to get it to work.
sudo gem install cocoapods -v 1.4.0
delete your Podfile.lock and Podfile dir in /ios and do a pod install

@mravn-google
Copy link
Contributor

@mravn-google mravn-google commented Apr 19, 2018

@dlutton @pinkfish We have been unable to make Cocoapods 1.4.0 work all the way through to app store archives, and we'll be supporting only Cocoapods 1.5.0 or later going forward.

With Cocoapods 1.5.0 and newest Flutter tooling (on master), all you should have to do is patch your Podfile as follows:

target 'Runner' do
  use_frameworks! # <--- add this
  ...
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
      config.build_settings['SWIFT_VERSION'] = '3.2' # <--- add this
    end
  end
end

Then delete ios/Podfile.lock and execute flutter run.

Filing issue that changing ios/Podfile does not cause flutter run to redo pod install #16734

@dlutton
Copy link

@dlutton dlutton commented Apr 19, 2018

@mravn-google Tried cocoapods 1.5.0 and it's failing with:

Xcode's output:
↳
    === BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Debug ===
    ld: warning: Auto-Linking library not found for -lswiftSwiftOnoneSupport
    ld: warning: Auto-Linking library not found for -lswiftCoreAudio
    ld: warning: Auto-Linking library not found for -lswiftCore
    ld: warning: Auto-Linking library not found for -lswiftQuartzCore
    ld: warning: Auto-Linking library not found for -lswiftCoreImage
    ld: warning: Auto-Linking library not found for -lswiftCoreGraphics
    ld: warning: Auto-Linking library not found for -lswiftAVFoundation
    ld: warning: Auto-Linking library not found for -lswiftCoreMedia
    ld: warning: Auto-Linking library not found for -lswiftDispatch
    ld: warning: Auto-Linking library not found for -lswiftObjectiveC
    ld: warning: Auto-Linking library not found for -lswiftCoreFoundation
    ld: warning: Auto-Linking library not found for -lswiftUIKit
    ld: warning: Auto-Linking library not found for -lswiftDarwin
    ld: warning: Auto-Linking library not found for -lswiftMetal
    ld: warning: Auto-Linking library not found for -lswiftsimd
    ld: warning: Auto-Linking library not found for -lswiftFoundation
    Undefined symbols for architecture x86_64:
[✓] Flutter (Channel master, v0.3.1-pre.35, on Mac OS X 10.13.3 17D102, locale en-US)
    • Flutter version 0.3.1-pre.35 at /Users/dlutton/development/flutter
    • Framework revision 7b163c7c0b (4 hours ago), 2018-04-18 20:31:45 -0700
    • Engine revision 3cc8d82895
    • Dart version 2.0.0-dev.48.0.flutter-fe606f890b

[✓] iOS toolchain - develop for iOS devices (Xcode 9.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 9.3, Build version 9E145
    • ios-deploy 1.9.2
    • CocoaPods version 1.5.0
@mravn-google
Copy link
Contributor

@mravn-google mravn-google commented Apr 19, 2018

@dlutton Would you be able to share your pubspec.yaml and ios/Podfile?

@dlutton
Copy link

@dlutton dlutton commented Apr 19, 2018

@mravn-google
Maybe it's my flutter_tts plugin I wrote in swift that's failing. It worked with cocoapods 1.4.

Podfile:

# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'

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

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 Pods/.symlinks')
  system('mkdir -p Pods/.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('Pods', '.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('Pods', '.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['ENABLE_BITCODE'] = 'NO'
      config.build_settings['SWIFT_VERSION'] = '3.2'
    end
  end
end

pubspec.yaml

name: fof
description: A new Flutter project.

dependencies:
  flutter:
    sdk: flutter
  connectivity:
  flutter_tts:
  share: "^0.3.1"

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter


# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  assets:
    - assets/failure.webp
    - assets/fortune.webp
    - assets/LaunchImage.png

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.io/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.io/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  fonts:
    - family: Lato
      fonts:
        - asset: fonts/Lato-Regular.ttf
          weight: 400
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies, 
  # see https://flutter.io/custom-fonts/#from-packages
@mravn-google
Copy link
Contributor

@mravn-google mravn-google commented Apr 19, 2018

The flutter_tts plugin works fine when included in a Flutter project created using -i swift.

@mravn-google
Copy link
Contributor

@mravn-google mravn-google commented Apr 19, 2018

Adding an empty Swift file to your Flutter iOS project in Xcode and accepting to add bridging header also works.

@dlutton
Copy link

@dlutton dlutton commented Apr 19, 2018

Okay I’ll try that out thank you

@dlutton
Copy link

@dlutton dlutton commented Apr 19, 2018

@mravn-google I confirmed it's working with cocoapods 1.5.0. Thank you sir

@goodis0
Copy link

@goodis0 goodis0 commented Jul 12, 2018

@mravn-google can you explain how to

Adding an empty Swift file to your Flutter iOS project in Xcode and accepting to add bridging header also works.

Where am I creating this file and what is a bridging header?

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Jul 25, 2018

@goodis0 Did you find an answer to this? Trying to add a pub package to a project I created with Flutter: New Project in Visual Studio Code and it's failing due to SWIFT_VERSION error being discussed.

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Jul 25, 2018

Can confirm that @mravn-google provided a simple and effective fix #16049 (comment)

@arctouch-matheusromao
Copy link

@arctouch-matheusromao arctouch-matheusromao commented Nov 22, 2019

Hmmm, something happened... Just tried on master, v1.12.9-pre.13 and it's working 🤷‍♂

  • Updated cocoapods to 1.8.4
  • Deleted Podfile.lock and Pods/
  • Run pod update
  • Run example from xcode

All good then. Thanks again!

@aleaforny
Copy link

@aleaforny aleaforny commented Nov 24, 2019

On my hand, I must share my experience with the plugin open_appstore, which has the same issue apparently.

When trying to flutter build ios, first issue:

[!] Automatically assigning platform ios with version 8.0 on target Runner because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.

#11000 (comment) fixed my first issue, pretty easily.

Then, second issue: I've faced this terrible error message, very complicated to get it fixed, after hours of effort :

The "Swift Language Version" (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. This setting can be set in the build settings editor.

I've added the following changes to ios\Podfile :

[...]
target 'Runner' do
  use_frameworks!       # <------ Add this line
[...]
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
      config.build_settings['SWIFT_VERSION'] = '5.0'     # <------- Add this line
    end
  end
end

Apparently, not enough - I was still facing the issue after flutter build ios (even though I deleted Podfile.lock and ios\Pods and re-run pod install)

I know the correct fix would be the one suggested by @jmagman #16049 (comment)

I guess I'm using an Objective-C project. I know I need to add s.swift_versions = ['4.0', '4.2', '5.0'] to the file flutter_open_appstore.podspec, but I cannot manage to find this file on my Mac (I assume the files are directly downloaded from git open_appstore project, so only the developer of this plugin can make the change...)

I ended up using the workaround as suggested by @mravn-google : #16049 (comment)

  1. Open Runner.xcworkspace file under ios folder
  2. On the menu: File > New -> File -> Swift File
  3. Type any name for the file (doesn't matter), make sure the file will be created in ios folder and continue
  4. When Xcode prompts dialog if you wish to create Bridging Headers, click on Yes (this is important)
  5. Still in Xcode, review the setting Swift Language Version in Runner > Targets > Runner > Build Setings and make sure the selected version is Swift 5
  6. Open a command prompt, browse to your Flutter project and type flutter clean
  7. Then, cd ios
  8. rm -Rf Pods/
  9. rm Podfile.lock (if needed)
  10. Finally: pod install --repo-update

After this, I was able to build iOS archive (flutter build ios).

Perhaps it's also important to mention that I'm using version 1.8.4 of cocoapods, Xcode version 10.2.1 and flutter version 1.9.1+hotfix4

I hope my experience can save a headache to any other iOS novice developers like me :)

Thank you all for your solutions!

@jmagman jmagman added this to Awaiting triage in Tools - Xcode review Jan 10, 2020
@jmagman jmagman moved this from Awaiting triage to Engineer reviewed in Tools - Xcode review Jan 10, 2020
@nerder
Copy link

@nerder nerder commented Mar 8, 2020

In case you follow all the steps in #16049 (comment) and running pod install --repo-update you get another error such as:

- `open_appstore` 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.

Using XCode 11.3.1 I wasn't able to find Swift Language Version you may need to add an extra step to make it work:

  1. In Xcode, under Runner > Targets > Runner > Build Settings > Add User-Defined Setting and add SWIFT_VERSION with 5.0
  2. rm -Rf Pods/
  3. rm Podfile.lock (if needed)
  4. Again: pod install --repo-update

I Hope it helps.

@aleaforny
Copy link

@aleaforny aleaforny commented Mar 8, 2020

Thanks a lot @nerder for this addition, it definitely helps!

I was also struggling with my own instructions a few days ago, I wasn't able to find Swift Language Version with the new Xcode update, but you gave the correct fix!

Thanks again!

@ssivagnanam
Copy link

@ssivagnanam ssivagnanam commented Apr 8, 2020

Hi,
I am using Flutter V1.12.13+hotfix-9 in Stable channel.
Cocoapods V1.8.4
XCode 11.3

I am getting below error while building and archiving iOS app.

" /Users//.pub-cache/hosted/pub.dartlang.org/device_calendar-3.1.0/ios/Classes/DeviceCalendarPlugin.m:2:9: fatal error:
'device_calendar/device_calendar-Swift.h' file not found
#import <device_calendar/device_calendar-Swift.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users//.pub-cache/hosted/pub.dartlang.org/device_calendar-3.1.0/ios/Classes/DeviceCalendarPlugin.m:2:9: note: did not find header 'device_calendar-Swift.h'
in framework 'device_calendar' (loaded from '/Users//build/ios/Release-iphoneos/device_calendar')"

and Sometimes
"Umbrella header 'device_calendar-umbrella.h' not found"

Any idea?

@jmagman
Copy link
Member

@jmagman jmagman commented Apr 8, 2020

@ssivagnanam If your app is Objective-C, you can add use_frameworks! to your ios/Podfile.

#16049 (comment)

More background for why #import <flutter_photokit/flutter_photokit-Swift.h> doesn't work for Swift libraries (no use_frameworks!):

https://paul-samuels.com/blog/2018/01/14/swift-static-library-in-objective-c/
https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816

If your app is Swift, you can add SWIFT_VERSION to your ios/Podfile

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
...
      config.build_settings['SWIFT_VERSION'] = '5.0' // Or whatever Swift version your app is using that works with your plugins
    end
  end
end

The real answer is that the maintainers of device-calendar update their podspec to support Swift, see #44324 and #16049 (comment)

  s.swift_version = '5.0'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Tools - Xcode review
  
Engineer reviewed
Linked pull requests

Successfully merging a pull request may close this issue.

None yet