packages icon indicating copy to clipboard operation
packages copied to clipboard

[google_maps_flutter_ios]: Add swift package manager compatibility

Open jokerttu opened this issue 11 months ago • 19 comments
trafficstars

Makes google_maps_flutter_ios available as a Swift Package to Flutter for iOS 15+ while maintaining compatibility with CocoaPods for iOS 14+.

It follows the same pattern used for other packages in the repository to ensure consistency.

The GoogleMapsUtils library introduces a separate target for Objective-C when using Swift Package Manager (SPM). As a result, package imports are handled differently depending on whether CocoaPods or SPM is used. This is controlled using the FGM_USING_COCOAPODS flag, which is defined in the package's Podfile.

Closes #146920

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

jokerttu avatar Dec 13 '24 13:12 jokerttu

@cbracken Swift Package Manager (SPM) works only with iOS15+ But CocoaPods still can be used with iOS14 with older GoogleMaps and GoogleMapsUtils versions.

Seems like the CI runs tests with flutter config --enable-swift-package-manager meaning that tests for iOS14 will fail as it GoogleMaps and GoogleMapsUtils for SPM require iOS15.

NOTE: There is two integration test sets, one for iOS14 and one for iOS15,

I removed 'OCMock' pod only for iOS15 example (and replaced with swift package) as SPM cannot be used with iOS14 example.

TestRunnerUI is not available for iOS15, so these tests are runned only for iOS14 at the moment (with cocoapods packages).

Should iOS14 support be dropped for CocoaPods as well (even while it works?) (and should there be iOS16 tests as well?)

jokerttu avatar Dec 13 '24 14:12 jokerttu

@jokerttu Apologies for the review delay!

FYI, this PR by @vashworth is excellent prior art for migrating this plugin: https://github.com/flutter/packages/pull/6639/files

The implementation files' #imports need to be updated to work for both SwiftPM and CocoaPods. For example:

- #import "GoogleMapMarkerController.h"
+ #import "./include/google_maps_flutter_ios/GoogleMapMarkerController.h"

It looks like the .modulemap should also be updated:

  explicit module Test {
-   header "GoogleMapController_Test.h"
-   header "GoogleMapMarkerController_Test.h"
+   header "./google_maps_flutter_ios/GoogleMapController_Test.h"
+   header "./google_maps_flutter_ios/GoogleMapMarkerController_Test.h"
  }

loic-sharma avatar Jan 22 '25 00:01 loic-sharma

@loic-sharma, @stuartmorgan

Would you have suggestions how to solve the issue with tests and minimun supported GoogleMaps SDK versions between cocoapods and swift package manager discussed here: https://github.com/flutter/packages/pull/8288#issuecomment-2541530979

So should we keep support for ios14 for cocoapods, or drop the support as ios14 is not supported if swift package manager is used? The tests are runned with swift package manager enabled, and therefore ios14 build always fails. But without swift package manager enabled, ios14 tests pass (as they have before).

jokerttu avatar Jan 22 '25 08:01 jokerttu

So should we keep support for ios14 for cocoapods, or drop the support as ios14 is not supported if swift package manager is used?

Let's move this discussion to the issue, as there are important policy and technical questions to resolve that I want to have captured in a central place even if the PRs change.

stuartmorgan-g avatar Jan 22 '25 14:01 stuartmorgan-g

The tests are runned with swift package manager enabled, and therefore ios14 build always fails. But without swift package manager enabled, ios14 tests pass (as they have before).

(Mechanically, once we resolve the policy questions about what we want to do with support in general, if we need to fix this it should be doable with some repo tooling adjustments.)

stuartmorgan-g avatar Jan 22 '25 14:01 stuartmorgan-g

@stuartmorgan pointed out here that iOS14 support should/might work after all, https://github.com/flutter/flutter/issues/146920#issuecomment-2607423983

I re-tested with package range supporting iOS 14 and it seems to use proper supported version of the package without build issues that I had earlier... I'll update the package range to have SPM support for iOS14 after all, making this PR much easier to be approved.

I will need to update the package later, to match the current state of the repo, as this moves quite a lot files that have changed after initial commit. I will address rest of the @loic-sharma review comments later as well.

jokerttu avatar Jan 22 '25 20:01 jokerttu

if we need to fix this it should be doable with some repo tooling adjustments

Actually, maybe we won't need tooling changes. Can we just add this to the ios14 example app project?

stuartmorgan-g avatar Jan 23 '25 01:01 stuartmorgan-g

For this error: https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8725011347110109681/+/u/Run_package_tests/build_examples/stdout

BUILDING google_maps_flutter/google_maps_flutter_ios/example/ios15 for iOS
Running command: "flutter build ios --no-codesign" in /Volumes/Work/s/w/ir/x/w/packages/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15
...
Failed to build iOS app
Target Integrity (Xcode): The package product 'GoogleMapsUtils' requires minimum platform version 15.0 for the iOS platform, but this target supports 14.0

Target Integrity (Xcode): The package product 'GoogleMaps' requires minimum platform version 15.0 for the iOS platform, but this target supports 14.0

Encountered error while building for device.

This happens because SPM strictly enforces that a package's platform requirements are equal to or higher than its dependencies. Since GoogleMaps 9.0.0+ requires iOS 15, google_maps_flutter_ios must also require iOS 15 or higher.

loic-sharma avatar Jan 23 '25 01:01 loic-sharma

@loic-sharma

This happens because SPM strictly enforces that a package's platform requirements are equal to or higher than its dependencies. Since GoogleMaps 9.0.0+ requires iOS 15, google_maps_flutter_ios must also require iOS 15 or higher.

Yes if min ios platform is set to ios14 at https://github.com/flutter/packages/pull/8288/files#diff-01027b44afff750ab5a8b199ab489f09c273ac641558c37054fc86a7ccf49784R13 This works fine with iOS 14, but not with iOS 15 because the error you mentioned.

    platforms: [
        .iOS(.v14),
    ],

But if min platform is set to .iOS(.v15), it won't work of course work with iOS 14 anymore.

I didn't find any way to have conditional setup, and for dependencies, conditions only support platform type (macOS or iOS), not platform version.

I will address the existing issues, and remove support for iOS14 for now by reverting last changes (adding support for iOS14). I will also add disable-swift-package-manager to iOS14 example for now.

As README lists iOS14 as supported platform, this change might need some note that SPM is supported only for iOS15 and above, and developers need to disable swift package manager if iOS14 is targeted?

jokerttu avatar Jan 23 '25 15:01 jokerttu

As README lists iOS14 as supported platform, this change might need some note that SPM is supported only for iOS15 and above, and developers need to disable swift package manager if iOS14 is targeted?

Right. I can do a follow-up pull request to update google_maps_flutter's README accordingly.

loic-sharma avatar Jan 23 '25 18:01 loic-sharma

@loic-sharma

It looks like the .modulemap should also be updated:

  explicit module Test {
-   header "GoogleMapController_Test.h"
-   header "GoogleMapMarkerController_Test.h"
+   header "./google_maps_flutter_ios/GoogleMapController_Test.h"
+   header "./google_maps_flutter_ios/GoogleMapMarkerController_Test.h"
  }

Are these updates really needed? As there is this for cocoapods:

-  s.source_files = 'Classes/**/*.{h,m}'
-  s.public_header_files = 'Classes/**/*.h'
-  s.module_map = 'Classes/google_maps_flutter_ios.modulemap'
+  s.source_files = 'google_maps_flutter_ios/Sources/google_maps_flutter_ios/**/*.{h,m}'
+  s.public_header_files = 'google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/**/*.h'
+  s.module_map = 'google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios.modulemap'

https://github.com/flutter/packages/pull/8288/files#diff-fd685115f0c01290b92981408de8b996eddfd83fd7f0dcfdf9f54ae1d2986a91R18

And this for SPM:

+          cSettings: [
+            .headerSearchPath("include/google_maps_flutter_ios")
+          ]

https://github.com/flutter/packages/pull/8288/files#diff-01027b44afff750ab5a8b199ab489f09c273ac641558c37054fc86a7ccf49784R40

And on other packages, these are also without paths: https://github.com/flutter/packages/blob/ebb373e8e1f0cd51f3c92515a3da220ff714d27e/packages/image_picker/image_picker_ios/ios/image_picker_ios/Sources/image_picker_ios/include/ImagePickerPlugin.modulemap

jokerttu avatar Jan 23 '25 19:01 jokerttu

@loic-sharma

Mac_x64 ios_build_all_packages checks fail:

Failed to build iOS app Lexical or Preprocessor Issue (Xcode): 'messages.g.h' file not found /Volumes/Work/s/w/ir/x/w/packages/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.m:19:8

Not sure why, as ios14 project builds just fine locally with cocoapods and s.public_header_files = 'google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/**/*.h' should cover messages.g.h file as well.

jokerttu avatar Jan 23 '25 21:01 jokerttu

For this error:

> Failed to build iOS app
Lexical or Preprocessor Issue (Xcode): 'messages.g.h' file not found
/Volumes/Work/s/w/ir/x/w/packages/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.m:19:8

All imports to the plugin's public headers need to be updated to #import "./include/google_maps_flutter_ios/X.h" to work for both CocoaPods and Swift Package Manager. For example:

- #import "GoogleMapController.h"
+ #import "./include/google_maps_flutter_ios/GoogleMapController.h"

For this error:

/Volumes/Work/s/w/ir/x/w/packages/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m:6:33: error: no submodule named 'Test' in module 'google_maps_flutter_ios'
@import google_maps_flutter_ios.Test;
        ~~~~~~~~~~~~~~~~~~~~~~~ ^
1 error generated.

You'll need to wrap @import google_maps_flutter_ios.Test with something like #if __has_include(<google_maps_flutter_ios/google_maps_flutter_ios-umbrella.h>). See: https://github.com/flutter/packages/blob/8024c0879ff15dce450163af3b9ded06045c0117/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTest.m#L6-L8

loic-sharma avatar Jan 24 '25 00:01 loic-sharma

Mac_x64 ios_build_all_packages checks fail:

Failed to build iOS app Lexical or Preprocessor Issue (Xcode): 'messages.g.h' file not found /Volumes/Work/s/w/ir/x/w/packages/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.m:19:8

Not sure why, as ios14 project builds just fine locally

The reason why it's different is that ios14 builds an app with one plugin, while build_all_packages builds an app containing every plugin in the repository, and SPM apparently doesn't handle it well when multiple packages have files with the same name and they have includes that aren't path-scoped.

stuartmorgan-g avatar Jan 24 '25 01:01 stuartmorgan-g

From triage: @jokerttu What's the status of this PR? It looks like there are still build failures in CI.

stuartmorgan-g avatar Mar 25 '25 19:03 stuartmorgan-g

From triage: @jokerttu What's the status of this PR? It looks like there are still build failures in CI. @stuartmorgan-g Request to add __has_include check to tests caused build issues last time I worked on this and I need to figure that out before I can finalize the PR. I will try have time to work on this soon.

jokerttu avatar Apr 03 '25 07:04 jokerttu

@jokerttu Since you're still working on this, I'm marking it as a draft. Please re-request when you're ready!

vashworth avatar Apr 09 '25 20:04 vashworth

I filed https://github.com/flutter/flutter/issues/169376 with a design document to explore how we are going to handle dependency versioning in Package.swift going forward (e.g., to account for the recently-released 10.0).

In theory we could release this without addressing that design doc, since currently this PR only allows one major version of the SDK anyway, but since several of the options there impact how the plugin will be structured we should probably make a decision before landing this.

stuartmorgan-g avatar May 23 '25 18:05 stuartmorgan-g

From triage: Currently blocked on a resolution on the design document mentioned above.

stuartmorgan-g avatar Jun 24 '25 18:06 stuartmorgan-g

Greetings from stale PR triage! 👋 Did we find resolution here? :)

Piinks avatar Aug 25 '25 21:08 Piinks

Did we find resolution here? :)

I thought we did but the planned resolution didn't work, and I'm currently revisiting.

stuartmorgan-g avatar Oct 01 '25 16:10 stuartmorgan-g

@jokerttu Sorry! When will we fix this issue to support Swift Package Manager?

tony-voyager avatar Oct 30 '25 04:10 tony-voyager