Skip to content

Flutter Swift plugins seems incompatible with most of Flutter plugins #25676

Closed

Description

@FrenchTastic

Hi,

I’m struggling since the last few days to understand how I can build or use Flutter Platform channel plugins that are written in Swift for the iOS part.

To my understanding plugins should not force you to set « use_frameworks! » in your PodFile, because, well, that’s make for example firebase_messaging not working (because this plugin force to comment use_frameworks).

So I try to create a plug-in by my own with the Flutter CLI :
flutter create —template=plugins -ios-language swift sample

The project is generated with the use_frameworks! In PodFile who makes it functionnal but incompatible with most from the start.

I’m not an CocoaPods expert but is it still required for Swift Library to use this flag ? I thought that starting at Cocoapod 1.5 you could remove the flag. But that’s not working at all.

So is it possible to make Flutter Swift plugins who works with firebase plugins ?
If so, can you point me to this direction ? Should the cli create command need to be updated to provide from the start the "good" example project ?

If making swift plugins working with "first party" plugins is not possible, is it not wiser to remove the ability to create swift plugins since this is not "future proof" and can produce some awkward ecosystem of plugins.

Sorry in advance if what I said is not really relevant, I'm trying to understand "the right way" to make iOS plugins...in Swift (Objective-C is not my cup of tea)

Steps to Reproduce

Create a new Flutter plugin project :

  1. flutter create --template=plugin -i swift sample

  2. In sample/example/ios/Podfile, Comment use_frameworks!

  3. In sample/example run flutter run on iOS emulator

fatal error: 'sample/sample-Swift.h' file not found
#import <sample/sample-Swift.h>

Logs

flutter doctor -v
[✓] Flutter (Channel stable, v1.0.0, on Mac OS X 10.14.2 18C54, locale fr-FR)
    • Flutter version 1.0.0 at /Users/romainpardon/Development/SDK/flutter
    • Framework revision 5391447fae (3 weeks ago), 2018-11-29 19:41:26 -0800
    • Engine revision 7375a0f414
    • Dart version 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)

[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
    • Android SDK at /Users/romainpardon/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
    • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.1, Build version 10B61
    • ios-deploy 1.9.4
    • CocoaPods version 1.5.3

[✓] Android Studio (version 3.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 31.3.1
    • Dart plugin version 181.5656
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)

[✓] VS Code (version 1.30.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 2.21.1

[✓] Connected device (1 available)
    • iPhone XR • DDB601C1-5AEC-47B3-999A-2D6E72FAF466 • ios • iOS 12.1 (simulator)

• No issues found!

Activity

  1. Sh1d0w commented on Dec 22, 2018

    @Sh1d0w

    As the creator of multi_image_picker plugin I would like to say I feel the same way. There are a lot of tickets in my repo, regarding developers struggling to use the plugin, simply because they haven't created their project with Swift template flag, thus missing !use_frameworks in their Pods file.

    Cocoapods 1.5 suggests that this flag should not be mandatory anymore when writing Swift code and including it in Objective-C project, but if you don't include it in the Flutter project the build fails with errors similar that the OP pointed out.

    As I am not an iOS developer, I would like to follow this topic to find a better approach to this, keeping the Swift code and providing the best experience for the developers, who want to use the plugin in the same time.

    FYI the firebase plugins should not require removing !use_frameworks anymore according to #25172 , but the problem with creating new flutter project without Swift flag (and so missing !use_frameworks by default) still exists when you try to add Swift plugins. All projects should have this flag by default, or we need to find why the build fails when it is missing.

    The other pain point is the Bridging Header. For projects created without the Swift flag, it is missing, and then I have to explain how to create that before using the Swift plugin.

    For me using plugins, either created by Swift or Objective-C should not require the developer to dig into native code in order to use the plugin, in a perfect world they would just install the package from the PUB and use it straight away. At least this is my experience with other cross platform frameworks I've used before Flutter.

  2. added
    toolAffects the "flutter" command-line tool. See also t: labels.
    p: toolingAffects the flutter_plugin_tools package
    on Dec 22, 2018
  3. added this to the milestone on Dec 22, 2018
  4. FrenchTastic commented on Dec 22, 2018

    @FrenchTastic
    Author

    Thanks Sh1d0w for pointing me out that commented the tag is no longer required.

    But my understanding of the #25172 is that like the new project template commented this line by default (like this comment said) the step 4 of the plugin firebase_messaging is no longer required (because line is already commented).

    I totally agree with what you say and i'm still a little bit confuse about that's need to be done.

    Like you said we as "Flutter developer" should not to worry if the plugin that we are gonna use is written in Swift or Objective-C.

  5. Sh1d0w commented on Dec 23, 2018

    @Sh1d0w

    @FrenchTastic Ah, you are right, I've must misinterpreted the issue I've linked, so the problem is still in place.

    Would be nice to hear some opinions from the Google team on this.

  6. zoechi commented on Jan 8, 2019

    @zoechi
    Contributor

    #16049 seems related

  7. modified the milestones: , on Jan 10, 2019
  8. dvaldivia commented on Jan 26, 2019

    @dvaldivia

    I have a problem with my project, most plugins have Objective-C code for iOS but trying to add plugins that use swift like flutter_photokit causes a build problem.

    Is it a safe assumtion that a work around would be to rebuild my whole project with the swift flag?

  9. dingjianjaja commented on Jul 4, 2019

    @dingjianjaja

    The easiest way to solve this problem is to create a new. swift file under the iOS file.

  10. jmagman commented on Sep 18, 2019

    @jmagman
    Member

    I was testing Swift plugins for add-to-app with both use_frameworks! (dynamic and static frameworks) and without (static libraries). I tested with flutter_photokit, CocoaPods 1.7.5 and Xcode 11 Seed 1.

    As-is, only the existing Swift app succeeded when use_frameworks! was present. Without use_frameworks! I saw 'flutter_photokit/flutter_photokit-Swift.h' file not found. And the Objective-C host couldn't get past pod install:

    [!] Unable to determine Swift version for the following pods:
    
    - `flutter_photokit` does not specify a Swift version and none of the targets (`ScaryBugs`) 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.
    use_frameworks! no use_frameworks!
    Obj-C host [!] Unable to determine Swift version for the following pods: [!] Unable to determine Swift version for the following pods:
    Swift host ✅ 'flutter_photokit/flutter_photokit-Swift.h' file not found

    Then I tried adding s.swift_versions = ['4.0', '4.2', '5.0'] to the flutter_photokit.podspec. Now the Objective-C host builds.

    use_frameworks! no use_frameworks!
    Obj-C host ✅ ✅
    Swift host ✅ 'flutter_photokit/flutter_photokit-Swift.h' file not found

    Then I tried this __has_include hack. CocoaPods/CocoaPods#7594 (comment)
    I updated https://github.com/kmorkos/flutter_photokit/blob/master/ios/Classes/FlutterPhotokitPlugin.m to:

    #import "FlutterPhotokitPlugin.h"
    #if __has_include("flutter_photokit-Swift.h")
    #import "flutter_photokit-Swift.h"
    #else
    #import <flutter_photokit/flutter_photokit-Swift.h>
    #endif
    
    @implementation FlutterPhotokitPlugin
    + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
      [SwiftFlutterPhotokitPlugin registerWithRegistrar:registrar];
    }
    @end

    But that broke Objective-C and fixed Swift:

    Undefined symbol: protocol conformance descriptor for Swift.String : Swift.CVarArg in Foundation
    Undefined symbol: Darwin._convertDarwinBooleanToBool(Darwin.DarwinBoolean) -> Swift.Bool
    Undefined symbol: _swift_getWitnessTable
    Undefined symbol: protocol descriptor for Swift.CVarArg
    Undefined symbol: _swift_getExistentialTypeMetadata
    Undefined symbol: _swift_getForeignTypeMetadata
    Undefined symbol: _swift_projectBox
    etc
    
    use_frameworks! no use_frameworks!
    Obj-C host ✅ Undefined symbol: protocol conformance descriptor for Swift.String : Swift.CVarArg in Foundation
    Swift host ✅ ✅

    I am running Xcode 11 and I found this note https://stackoverflow.com/a/57126566 and added "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)" to my app target's LIBRARY_SEARCH_PATHS and that gets me down to two undefined symbols:

    Undefined symbol: __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements
    Undefined symbol: __swift_FORCE_LOAD_$_swiftCompatibility50
    

    And now I'm in the bowels of Swift: https://github.com/apple/swift/blob/master/lib/IRGen/GenDecl.cpp#L454

    So I added "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)" to my app target's LIBRARY_SEARCH_PATHS.

    use_frameworks! no use_frameworks!
    Obj-C host ✅ ✅
    Swift host ✅ ✅
  11. jmagman commented on Oct 10, 2019

    @jmagman
    Member

    I can see two things to update in the Swift plugin templates, which may unfortunately require a migration for existing plugins:

    1. Edit the implementation import:
      TestSwiftPlugin.m
    #if __has_include(<test_swift_plugin/test_swift_plugin-Swift.h>)
    #import <test_swift_plugin/test_swift_plugin-Swift.h>
    #else
    #import "test_swift_plugin-Swift.h"
    #endif
    1. Add swift_versions to the podspec so Objective-C apps can pod install and avoid
    [!] Unable to determine Swift version for the following pods:
    

    I'm hoping the Pod::Validator::DEFAULT_SWIFT_VERSION trick makes it more future-proof when the SDKs 3+ year from now stop supporting Swift 5.1:

    Pod::Spec.new do |s|
      s.name = 'flutter_plugin'
    ...
      swift_versions = ['4.0', '4.2', '5.0', '5.1']
      swift_versions << Pod::Validator::DEFAULT_SWIFT_VERSION if Pod::Validator.const_defined? "DEFAULT_SWIFT_VERSION"
      s.swift_versions = swift_versions
    end
  12. ened commented on Oct 21, 2019

    @ened
    Contributor

    @jmagman after following your steps, I ended up with

    This copy of libswiftCore.dylib requires an OS version prior to 12.2.0.
    2019-10-21 09:29:46.179124+0100 Runner[4609:1101773] This copy of libswiftCore.dylib requires an OS version prior to 12.2.0.
    

    once running the App on iOS 13.1.3.
    Following the instructions on SO fixed it.

  13. jmagman commented on Nov 7, 2019

    @jmagman
    Member

    @jmagman after following your steps, I ended up with

    This copy of libswiftCore.dylib requires an OS version prior to 12.2.0.
    2019-10-21 09:29:46.179124+0100 Runner[4609:1101773] This copy of libswiftCore.dylib requires an OS version prior to 12.2.0.
    

    once running the App on iOS 13.1.3.
    Following the instructions on SO fixed it.

    Bleh, you're right. I don't see a better way to do this than the /usr/lib/swift LD_RUNPATH_SEARCH_PATHS suggestion. And it's not like I can even make it conditional on the LD_RUNPATH_SEARCH_PATHS[sdk=iphoneos13*] since the error is specifying a particular OS version.

    Fortunately it doesn't emit a warning when if the directory isn't found (before Swift shipped in the OS), like the linker does.

  14. jmagman commented on Nov 8, 2019

    @jmagman
    Member

    I'm using this issue to track the plugin-side of this work (podspec, imports).
    The Objective-C app work (LIBRARY_SEARCH_PATHS, LD_RUNPATH_SEARCH_PATHS) is being tracked with #16049.

  15. joecks commented on Apr 12, 2021

    @joecks

    Just FYI for whomever tries to extend a existing flutter pod (like in my case the webview_flutter ) with XCode 12.4:

    podspec:

      s.swift_version = '5.0'
      s.xcconfig = {
         'LIBRARY_SEARCH_PATHS' => '$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)/ $(SDKROOT)/usr/lib/swift',
         'LD_RUNPATH_SEARCH_PATHS' => '/usr/lib/swift',
    
         }
    1. Create empty Classes/webview_flutter-Bridging-Header.h
    2. run pod install
    3. Sample valid swift file
    import Foundation
    
    @objc public class HelloWorld : NSObject {
        @objc static public func hello() {
            print("hello world")
        }
    }
    1. Import auto-generated (run build once) header to .m file:
    #import <webview_flutter-Swift.h>
    ...
    
    // Hello World
    [HelloWorld hello];
    
  16. github-actions commented on Aug 3, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  17. locked as resolved and limited conversation to collaborators on Aug 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    p: toolingAffects the flutter_plugin_tools packagepackageflutter/packages repository. See also p: labels.platform-iosiOS applications specificallytoolAffects the "flutter" command-line tool. See also t: labels.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions