Skip to content

[google_maps_flutter_ios]: Add swift package manager compatibility #8288

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

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

jokerttu
Copy link
Contributor

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
Copy link
Contributor Author

jokerttu commented Dec 13, 2024

@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 jokerttu marked this pull request as ready for review December 13, 2024 14:02
@jokerttu jokerttu requested a review from cbracken as a code owner December 13, 2024 14:02
@stuartmorgan-g stuartmorgan-g added the triage-ios Should be looked at in iOS triage label Jan 14, 2025
objcHeaderOut: 'ios/Classes/messages.g.h',
objcSourceOut: 'ios/Classes/messages.g.m',
objcHeaderOut:
'ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/messages.g.h',
Copy link
Member

@loic-sharma loic-sharma Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be:

Suggested change
'ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/messages.g.h',
'ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/messages.g.h',

(It looks like the header file is already in the right location. Just this config is stale)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

objcHeaderOut:
'ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/messages.g.h',
objcSourceOut:
'ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/messages.g.m',
objcOptions: ObjcOptions(prefix: 'FGM'),
Copy link
Member

@loic-sharma loic-sharma Jan 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be:

Suggested change
objcOptions: ObjcOptions(prefix: 'FGM'),
objcOptions: ObjcOptions(
prefix: 'FGM',
headerIncludePath: './include/google_maps_flutter_ios/messages.g.h',
),

Also, the messages.g.m file should be updated to something like:

#import "./include/google_maps_flutter_ios/messages.g.h"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@loic-sharma
Copy link
Member

loic-sharma commented Jan 22, 2025

@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"
  }

Comment on lines 19 to 20
.package(url: "https://github.com/googlemaps/ios-maps-sdk", .upToNextMajor(from: "9.0.0")),
.package(url: "https://github.com/googlemaps/google-maps-ios-utils", .upToNextMajor(from: "6.1.0")),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like .upToNextMajor is deprecated. Consider:

Suggested change
.package(url: "https://github.com/googlemaps/ios-maps-sdk", .upToNextMajor(from: "9.0.0")),
.package(url: "https://github.com/googlemaps/google-maps-ios-utils", .upToNextMajor(from: "6.1.0")),
.package(url: "https://github.com/googlemaps/ios-maps-sdk", "9.0.0"..<"10.0.0")),
.package(url: "https://github.com/googlemaps/google-maps-ios-utils", "6.1.0"..<"7.0.0"),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jokerttu
Copy link
Contributor Author

@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: #8288 (comment)

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).

@stuartmorgan-g
Copy link
Contributor

stuartmorgan-g commented Jan 22, 2025

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
Copy link
Contributor

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.)

@jokerttu
Copy link
Contributor Author

@stuartmorgan pointed out here that iOS14 support should/might work after all, flutter/flutter#146920 (comment)

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.

@stuartmorgan-g
Copy link
Contributor

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?

@loic-sharma
Copy link
Member

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.

@jokerttu
Copy link
Contributor Author

jokerttu commented Jan 23, 2025

@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?

@loic-sharma
Copy link
Member

loic-sharma commented Jan 23, 2025

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.

@jokerttu
Copy link
Contributor Author

@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 jokerttu force-pushed the feat/google-maps-flutter-add-swift-package-manager-support branch from 9b6ef7e to 09adf9b Compare January 23, 2025 20:09
@@ -36,6 +36,7 @@ Downloaded by pub (not CocoaPods).
s.xcconfig = {
'LIBRARY_SEARCH_PATHS' => '$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)/ $(SDKROOT)/usr/lib/swift',
'LD_RUNPATH_SEARCH_PATHS' => '$(inherited) /usr/lib/swift',
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) FGM_USING_COCOAPODS=1'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note this FGM_USING_COCOAPODS preprocessor definition used to detect if cocoapods are used or not.
This is used for example at: https://github.com/flutter/packages/pull/8288/files#diff-dcc8100c7e606a3918ac1f3f2cd0aa16c2c6e551e09b9ff717f724a671ce5323R8

@jokerttu
Copy link
Contributor Author

@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.

@loic-sharma
Copy link
Member

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:

#if __has_include(<camera_avfoundation/camera_avfoundation-umbrella.h>)
@import camera_avfoundation.Test;
#endif

@stuartmorgan-g
Copy link
Contributor

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.

@jokerttu jokerttu force-pushed the feat/google-maps-flutter-add-swift-package-manager-support branch from a8f87db to 45e9116 Compare February 17, 2025 11:44
@stuartmorgan-g
Copy link
Contributor

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

@vashworth vashworth self-requested a review March 31, 2025 19:05
@jokerttu
Copy link
Contributor Author

jokerttu commented Apr 3, 2025

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.

],
dependencies: [
.package(url: "https://github.com/googlemaps/ios-maps-sdk", "9.0.0"..<"10.0.0"),
.package(url: "https://github.com/googlemaps/google-maps-ios-utils", "6.1.0"..<"7.0.0"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jokerttu Can you explain why the SwiftPM implementation can only be used in iOS 15+? Why can't it include google-maps-ios-utils 5.0 like the CocoaPods version?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See discussion here; apparently the SDK's SPM configuration was broken in the version of the SDK that still supported iOS 14 :(

@vashworth
Copy link
Contributor

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

@vashworth vashworth marked this pull request as draft April 9, 2025 20:10
@stuartmorgan-g
Copy link
Contributor

I filed flutter/flutter#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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[google_maps_flutter_ios] Add Swift Package Manager compatibility to google_maps_flutter_ios
4 participants