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

Add Swift Package Manager support #1276

Open
Tracked by #146922
loic-sharma opened this issue Jul 22, 2024 · 6 comments
Open
Tracked by #146922

Add Swift Package Manager support #1276

loic-sharma opened this issue Jul 22, 2024 · 6 comments
Assignees
Labels
package:cupertino_http Issues related to package:cupertino_http type-enhancement A request for a change that isn't a bug

Comments

@loic-sharma
Copy link

Hello,

Flutter is migrating to Swift Package Manager. Please add Swift Package Manager support to your plugin.

Flutter will eventually deprecate and then remove support for CocoaPods. Adding Swift Package Manager support future-proofs your plugins.

How to add Swift Package Manager support to your plugins

You can find the migration guide here: https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-plugin-authors#how-to-add-swift-package-manager-support-to-an-existing-flutter-plugin

If you run into issues or have questions, please reach out to the Flutter team. You can ping me at @loic-sharma, send a message to the #hackers-ios channel on Flutter’s discord, or open a GitHub issue.

Thank you for your wonderful contributions to the Flutter ecosystem!

Why is Flutter migrating to Swift Package Manager?

Swift Package Manager support is one of Flutter’s most requested features: flutter#33850.

Flutter's Swift Package Manager integration has several benefits:

  1. Access to the Swift package ecosystem. Flutter plugins can use the growing ecosystem of Swift packages.
  2. Simplifies Flutter installation. Swift Package Manager is bundled with Xcode. In the future, you won’t need to install Ruby and CocoaPods to target iOS or macOS.
@brianquinlan
Copy link
Collaborator

@loic-sharma

I followed the instructions in the migration guide and got these XCode errors after performing step 12 > 2.

Here is what the PR looked like at that point:
#1288

@loic-sharma
Copy link
Author

loic-sharma commented Aug 8, 2024

Oops the instructions were incorrect. The files in pkgs/cupertino_http/ios/Sources/cupertino_http/ should be moved to pkgs/cupertino_http/ios/cupertino_http/Sources/cupertino_http/.

I sent a docs fix here: flutter/website#11029

loic-sharma added a commit to flutter/website that referenced this issue Aug 9, 2024
This was caught by @brianquinlan while migrating the `cupertino_http`
plugin.

Review URL:
https://flutter-docs-prod--pr11029-brian-feedback-9wffzaxo.web.app/packages-and-plugins/swift-package-manager/for-plugin-authors#how-to-add-swift-package-manager-support-to-an-existing-flutter-plugin

Part of:
dart-lang/http#1276 (comment)

## Presubmit checklist

- [x] This PR is marked as draft with an explanation if not meant to
land until a future stable release.
- [x] This PR doesn’t contain automatically generated corrections
(Grammarly or similar).
- [x] This PR follows the [Google Developer Documentation Style
Guidelines](https://developers.google.com/style) — for example, it
doesn’t use _i.e._ or _e.g._, and it avoids _I_ and _we_ (first person).
- [x] This PR uses [semantic line
breaks](https://github.com/dart-lang/site-shared/blob/main/doc/writing-for-dart-and-flutter-websites.md#semantic-line-breaks)
of 80 characters or fewer.
@brianquinlan
Copy link
Collaborator

Sorry for the long delay - some unrelated changes needed to be made before I could make progress on this.

I don't understand how the header files should be organized. I initially placed all of my headers in "darwin/cupertino_http/Sources/cupertino_http/include/cupertino_http". The worked for top level includes but it did not work for includes in the "dart-sdk" directory (with the podspec build):

--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:00006000-001448641406801E, name:My Mac }
{ platform:macOS, arch:x86_64, id:00006000-001448641406801E, name:My Mac }
In file included from /Users/bquinlan/dart/http/pkgs/cupertino_http/darwin/cupertino_http/Sources/cupertino_http/CUPHTTPClientDelegate.m:5:
/Users/bquinlan/dart/http/pkgs/cupertino_http/darwin/cupertino_http/Sources/cupertino_http/include/cupertino_http/CUPHTTPClientDelegate.h:11:10: fatal error: 'dart-sdk/include/dart_api_dl.h' file not found
#include "dart-sdk/include/dart_api_dl.h"
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
** BUILD FAILED **

I didn't understand the phrase in the documentation: "You should consider whether you want all of your headers to be public." When do my headers need to be public vs. non-public? What do I do if I don't want my headers to be public?

Since, AFAIK, I don't need any of my headers to be public, I assumed that the includes should be in the same directory as the sources. That is the current state of #1288. But it can't seem to find any headers (with the podspec build):

--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:00006000-001448641406801E, name:My Mac }
{ platform:macOS, arch:x86_64, id:00006000-001448641406801E, name:My Mac }
error: /Users/bquinlan/dart/http/pkgs/cupertino_http/darwin/cupertino_http/Sources/cupertino_http/include/cupertino_http/CUPHTTPClientDelegate.h: No such file or directory (in target 'cupertino_http' from project 'Pods')
** BUILD FAILED **

Building macOS application...
Error: Build process failed

@loic-sharma Please advise ;-)

@loic-sharma
Copy link
Author

loic-sharma commented Aug 28, 2024

Thanks for the feedback! I'll take a closer look at this tomorrow, but some initial responses:

But it can't seem to find any headers (with the podspec build):

I'll investigate tomorrow!

When do my headers need to be public vs. non-public?

If a header contains APIs that are meant to be called by code outside of your plugin, it must be public. If a header contains APIs that are only internal for the plugin, ideally the header file would be non-public.

However, it's very common for CocoaPod packages to just make all their headers public. This isn't ideal, folks could start using your internal APIs in unexpected ways; changing your implementation could be an unintentional breaking change. However, converting public header files to non-public is technically also a breaking change.

I didn't understand the phrase in the documentation: "You should consider whether you want all of your headers to be public."

Thanks that's good feedback. I'll expand that section!

@loic-sharma
Copy link
Author

loic-sharma commented Aug 29, 2024

@brianquinlan I checked out #1288, and I got different build errors than the one you reported above. I was able to fix the build errors I ran into using this patch:

diff --git a/pkgs/cupertino_http/darwin/cupertino_http.podspec b/pkgs/cupertino_http/darwin/cupertino_http.podspec
index 9e09c66..5bd2846 100644
--- a/pkgs/cupertino_http/darwin/cupertino_http.podspec
+++ b/pkgs/cupertino_http/darwin/cupertino_http.podspec
@@ -12,6 +12,7 @@ Pod::Spec.new do |s|
   s.homepage         = 'https://github.com/dart-lang/http/tree/master/pkgs/cupertino_http'
   s.license          = { :type => 'BSD', :file => '../LICENSE' }
   s.author           = { 'TODO' => 'use-valid-author' }
+  s.source           = { :http => 'https://github.com/dart-lang/http/tree/master/pkgs/cupertino_http' }

   s.source_files = 'cupertino_http/Sources/cupertino_http/**/*'
   s.ios.dependency 'Flutter'
diff --git a/pkgs/cupertino_http/darwin/cupertino_http/Package.swift b/pkgs/cupertino_http/darwin/cupertino_http/Package.swift
index 017f286..7da45e8 100644
--- a/pkgs/cupertino_http/darwin/cupertino_http/Package.swift
+++ b/pkgs/cupertino_http/darwin/cupertino_http/Package.swift
@@ -32,8 +32,9 @@ let package = Package(
             ],
             cSettings: [
                 // TODO: Update your plugin name.
-                .headerSearchPath("include")
-                .headerSearchPath("include/cupertino_http")
+                //.headerSearchPath("include"),
+                .headerSearchPath("include/cupertino_http"),
+                .unsafeFlags(["-fno-objc-arc"]),
             ]
         )
     ]

Here's my fork with this patch applied: loic-sharma@12c1867

With this patch, the following steps work as expected:

cd pkgs/cupertino_http/example

flutter config --no-enable-swift-package-manager
flutter build ios

flutter config --enable-swift-package-manager
flutter build ios

Could you try that patch and let me know if that fixes your build issues? If it doesn't, could you share: what steps you're using to get that build error, which Flutter SDK version you're on, which Xcode version you're on.

Also, feel free to drop something on my calendar if you want to hack on this together :)

@brianquinlan
Copy link
Collaborator

brianquinlan commented Aug 30, 2024

@loic-sharma That does fix my build issues and the CocoaPods build works fun. Unfortunately, the Swift Package Manager version fails at runtime.

$ flutter config --enable-swift-package-manager
Setting "enable-swift-package-manager" value to "true".

You may need to restart any open editors for them to read new settings.
$ flutter clean
$ flutter run
Connected devices:
macOS (desktop)                 • macos                 • darwin-arm64 • macOS 14.6.1 23G93 darwin-arm64
Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin       • macOS 14.6.1 23G93 darwin-arm64

No wireless devices were found.

[1]: macOS (macos)
[2]: Mac Designed for iPad (mac-designed-for-ipad)
Please choose one (or "q" to quit): 1
Resolving dependencies...
Downloading packages...
  _fe_analyzer_shared 67.0.0 (73.0.0 available)
  analyzer 6.4.1 (6.8.0 available)
  coverage 1.8.0 (1.9.2 available)
  crypto 3.0.3 (3.0.5 available)
  dart_flutter_team_lints 3.1.0 (3.2.0 available)
  ffi 2.1.2 (2.1.3 available)
  http 1.2.1 (1.2.2 available)
  http_parser 4.0.2 (4.1.0 available)
  leak_tracker 10.0.5 (10.0.7 available)
  leak_tracker_flutter_testing 3.0.5 (3.0.8 available)
  material_color_utilities 0.11.1 (0.12.0 available)
  mime 1.0.5 (1.0.6 available)
  shelf 1.4.1 (1.4.2 available)
  shelf_web_socket 1.0.4 (2.0.0 available)
  source_map_stack_trace 2.1.1 (2.1.2 available)
  vm_service 14.2.4 (14.2.5 available)
  web 0.5.1 (1.0.0 available)
  web_socket 0.1.5 (0.1.6 available)
  web_socket_channel 2.4.5 (3.0.1 available)
Got dependencies!
19 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
All plugins found for macos are Swift Packages, but your project still has CocoaPods integration. Your project uses a non-standard Podfile and will need to be migrated to
Swift Package Manager manually. Some steps you may need to complete include:
  * In the macos/ directory run "pod deintegrate"
  * Transition any Pod dependencies to Swift Package equivalents. See https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app
  * Transition any custom logic
  * Remove the include to "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" in your macos/Flutter/Flutter-Debug.xcconfig
  * Remove the include to "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" in your macos/Flutter/Flutter-Release.xcconfig

Removing CocoaPods integration will improve the project's build time.
Launching lib/main.dart on macOS in debug mode...
Running pod install...                                             699ms
--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:00006000-001448641406801E, name:My Mac }
{ platform:macOS, arch:x86_64, id:00006000-001448641406801E, name:My Mac }
Building macOS application...
✓ Built build/macos/Build/Products/Debug/cupertino_http_example.app
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library 'cupertino_http.framework/cupertino_http': dlopen(cupertino_http.framework/cupertino_http, 0x0001): tried: 'cupertino_http.framework/cupertino_http' (no such file), '/System/Volumes/Preboot/Cryptexes/OScupertino_http.framework/cupertino_http' (no such file), '/Users/bquinlan/dart/http/pkgs/cupertino_http/example/build/macos/Build/Products/Debug/cupertino_http_example.app/Contents/Frameworks/FlutterMacOS.framework/Versions/A/./cupertino_http.framework/cupertino_http' (no such file), '/usr/local/lib/./cupertino_http.framework/cupertino_http' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/./cupertino_http.framework/cupertino_http' (no such file), '/Users/bquinlan/dart/http/pkgs/cupertino_http/example/build/macos/Build/Products/Debug/cupertino_http_example.app/Contents/Frameworks/FlutterMacOS.framework/Versions/A/../../../cupertino_http.framework/cupertino_http' (no such file), '/usr/lib/swift/cupertino_http.framework/cupertino_http' (no such file, not in dyld cache), '/System/Volumes/Preboot/Cryptexes/OS/usr/lib/swift/cupertino_http.framework/cupertino_http' (no such file), '/Users/bquinlan/dart/http/pkgs/cupertino_http/example/build/macos/Build/Products/Debug/PackageFrameworks/cupertino_http.framework/cupertino_http' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Users/bquinlan/dart/http/pkgs/cupertino_http/example/build/macos/Build/Products/Debug/PackageFrameworks/cupertino_http.framework/cupertino_http' (no such file), '/Users/bquinlan/dart/http/pkgs/cupertino_http/example/build/macos/Build/Products/Debug/cupertino_http_example.app/Contents/Frameworks/cupertino_http.framework/cupertino_http' (no such file), '/Users/bquinlan/dart/http/pkgs/cupertino_http/example/build/macos/Build/Products/Debug/cupertino_http_example.app/Contents/MacOS/Frameworks/cupertino_http.framework/cupertino_http' (no such file), '/usr/lib/cupertino_http.framework/cupertino_http' (no such file, not in dyld cache), 'cupertino_http.framework/cupertino_http' (no such file)
#0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:11:43)
#1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:22:12)
#2      _loadHelperDynamicLibrary (package:cupertino_http/src/utils.dart:32:27)
#3      _loadHelperLibrary (package:cupertino_http/src/utils.dart:40:15)
#4      helperLibs (package:cupertino_http/src/utils.dart:28:44)
#5      helperLibs (package:cupertino_http/src/utils.dart)
#6      URLSession._delegate (package:cupertino_http/src/cupertino_api.dart:1331:59)
#7      URLSession._delegate (package:cupertino_http/src/cupertino_api.dart)
#8      new URLSession.sessionWithConfiguration (package:cupertino_http/src/cupertino_api.dart:1460:43)
#9      new CupertinoClient.fromSessionConfiguration (package:cupertino_http/src/cupertino_client.dart:239:32)
#10     main (package:cupertino_http_example/main.dart:23:34)
#11     _runMain.<anonymous closure> (dart:ui/hooks.dart:301:23)
#12     _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#13     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

Syncing files to device macOS...                                   258ms

The Objective-C code is being built because, if I introduce a syntax error, the run fails and I see an error message.

Using CocoaPods:

$ find build/ -name "cupertino_http"
build//macos/Build/Products/Debug/cupertino_http_example.app/Contents/Frameworks/cupertino_http.framework/Versions/A/cupertino_http
build//macos/Build/Products/Debug/cupertino_http_example.app/Contents/Frameworks/cupertino_http.framework/cupertino_http
build//macos/Build/Products/Debug/cupertino_http
build//macos/Build/Products/Debug/cupertino_http/cupertino_http.framework/Versions/A/cupertino_http
build//macos/Build/Products/Debug/cupertino_http/cupertino_http.framework/cupertino_http
$ otool -t -v build//macos/Build/Products/Debug/cupertino_http_example.app/Contents/Frameworks/cupertino_http.framework/cupertino_http
build//macos/Build/Products/Debug/cupertino_http_example.app/Contents/Frameworks/cupertino_http.framework/cupertino_http:
(__TEXT,__text) section
-[CUPHTTPTaskConfiguration initWithPort:]:
...

I can't find an equivalent file with the swift build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package:cupertino_http Issues related to package:cupertino_http type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

2 participants