Skip to content

feat: Swift Package Manager dependency support for Flutter iOS/macOS SDK#804

Open
NandanPrabhu wants to merge 14 commits into
mainfrom
flutter-pod-to-spm
Open

feat: Swift Package Manager dependency support for Flutter iOS/macOS SDK#804
NandanPrabhu wants to merge 14 commits into
mainfrom
flutter-pod-to-spm

Conversation

@NandanPrabhu

@NandanPrabhu NandanPrabhu commented Apr 2, 2026

Copy link
Copy Markdown
Contributor
  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

📋 Changes

Adds Swift Package Manager (SPM) support to the iOS/macOS (darwin) native plugin, addressing #793. CocoaPods support is retained as a fallback, so this is non-breaking for existing consumers.

Packaging

  • Adds auth0_flutter/darwin/auth0_flutter/Package.swift declaring the auth0_flutter SPM target (iOS 14 / macOS 11), depending on Auth0.swift, JWTDecode.swift and SimpleKeychain via .upToNextMajor(from:) so the plugin stays co-installable with consumer apps that pull the same Auth0 packages.
  • Updates auth0_flutter.podspec source_files to point at the new shared Sources/auth0_flutter layout; version pins kept in sync with Package.swift.
  • Moves the shared Darwin sources under Sources/auth0_flutter, relying on sharedDarwinSource: true (declared in pubspec.yaml) so iOS and macOS build from a single source tree.

Removed symlink machinery

  • Deletes scripts/generate-symlinks.sh and the check-symlinks workflow — sharedDarwinSource replaces the per-platform symlink approach.
  • Removes the duplicated auth0_flutter/ios and auth0_flutter/macos symlinked source trees.

Plugin entry point

  • Removes the Objective-C shim (Auth0FlutterPlugin.h/.m) and renames the Swift plugin class SwiftAuth0FlutterPluginAuth0FlutterPlugin to match the pluginClass already declared in pubspec.yaml. No public Dart API change.

Example app

  • iOS/macOS example projects migrated from CocoaPods (Podfile, workspace) to SPM (Package.resolved, project-based build).
  • macOS AppDelegate adopts @main + applicationSupportsSecureRestorableState.

CI

  • setup-darwin: drops the Ruby/Bundler and pod install steps; enables SPM (flutter config --enable-swift-package-manager) and forces the Flutter-generated package's deployment target to match the plugin's (14.0 / 11.0).
  • unit-tests-darwin: runs against Runner.xcodeproj instead of the (now removed) workspace.
  • iOS coverage is converted from .xcresult to Cobertura XML via xcresultparser (Ruby-free) before the Codecov upload, replacing the removed slather step. The orphaned example/ios/Gemfile/Gemfile.lock (slather only) are deleted.

Tests

  • Plugin registration tests renamed to Auth0FlutterPluginTests.
  • Credentials Manager tests use credentialsManager.store(credentials:) instead of hand-built NSKeyedArchiver fixtures.

📎 References

🎯 Testing

  • iOS and macOS native unit tests run in CI via xcodebuild against Runner.xcodeproj (Xcode 26.2); Android and Windows unit suites unchanged.
  • Manual verification: from auth0_flutter/example, run flutter config --enable-swift-package-manager then flutter build ios / flutter build macos and exercise login/logout, credentials manager, and DPoP flows.
  • CocoaPods fallback can be verified by building the example with SPM disabled.

Reviewer note: this PR is large by file count because it removes the symlinked ios/macos source trees and moves sources under Sources/auth0_flutter — most files are pure moves/deletions; the substantive surface is Package.swift, the podspec, the CI actions, and the plugin/test renames.

@NandanPrabhu NandanPrabhu changed the title cocoapods to spm conversion feat: Flutter SPM support for iOS plugin Apr 2, 2026
@NandanPrabhu NandanPrabhu marked this pull request as ready for review April 8, 2026 14:08
@NandanPrabhu NandanPrabhu requested a review from a team as a code owner April 8, 2026 14:08
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 171 files, which is 21 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 117b0081-4854-4c8f-94df-a1e92c8bda35

📥 Commits

Reviewing files that changed from the base of the PR and between 37cd036 and d31ba17.

⛔ Files ignored due to path filters (1)
  • auth0_flutter/example/ios/Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (171)
  • .github/actions/setup-android/action.yml
  • .github/actions/setup-darwin/action.yml
  • .github/actions/setup-publish/action.yml
  • .github/actions/unit-tests-darwin/action.yml
  • .github/workflows/check-symlinks.yml
  • .github/workflows/main.yml
  • .gitignore
  • auth0_flutter/README.md
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/LoginWebAuthRequestHandlerTest.kt
  • auth0_flutter/darwin/.gitignore
  • auth0_flutter/darwin/Classes/Auth0FlutterPlugin.h
  • auth0_flutter/darwin/Classes/Auth0FlutterPlugin.m
  • auth0_flutter/darwin/auth0_flutter.podspec
  • auth0_flutter/darwin/auth0_flutter/Package.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/Auth0FlutterPlugin.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPICustomTokenExchangeMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPIEmailPasswordlessLoginMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPIExtensions.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPIHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPILoginUsernameOrEmailMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPILoginWithEmailMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPILoginWithOTPMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPILoginWithPhoneNumberMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPIMultifactorChallengeMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPIPhoneNumberPasswordlessLoginMethod.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPIRenewMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPIResetPasswordMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPISignupMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/AuthAPIUserInfoMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/AuthAPI/SSOExchangeMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerClearMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerExtensions.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerGetMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerHasValidMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerModels.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerRenewMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerSaveMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/CredentialsManagerUserInfoMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/CredentialsManager/SSOCredentialsMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/DPoP/DPoPClearKeyMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/DPoP/DPoPGetHeadersMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/DPoP/DPoPHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/Extensions.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/HandlerError.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/MethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/Models.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/Properties.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/WebAuth/WebAuthExtensions.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/WebAuth/WebAuthHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/WebAuth/WebAuthLoginMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/WebAuth/WebAuthLogoutMethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter/Sources/auth0_flutter/WebAuth/WebAuthModels.swift
  • auth0_flutter/example/android/gradle.properties
  • auth0_flutter/example/android/settings.gradle
  • auth0_flutter/example/ios/Gemfile
  • auth0_flutter/example/ios/Podfile
  • auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj
  • auth0_flutter/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  • auth0_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  • auth0_flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata
  • auth0_flutter/example/ios/Runner/AppDelegate.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIExtensionsTests.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIHandlerTests.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPISpies.swift
  • auth0_flutter/example/ios/Tests/CredentialsManager/CredentialsManagerExtensionsTests.swift
  • auth0_flutter/example/ios/Tests/CredentialsManager/CredentialsManagerGetMethodHandlerTests.swift
  • auth0_flutter/example/ios/Tests/CredentialsManager/CredentialsManagerHandlerTests.swift
  • auth0_flutter/example/ios/Tests/CredentialsManager/CredentialsManagerHasValidMethodHandlerTests.swift
  • auth0_flutter/example/ios/Tests/CredentialsManager/CredentialsManagerSSOCredentialsMethodHandlerTests.swift
  • auth0_flutter/example/ios/Tests/CredentialsManager/CredentialsManagerSpies.swift
  • auth0_flutter/example/ios/Tests/Mocks.swift
  • auth0_flutter/example/ios/Tests/SwiftAuth0FlutterPluginTests.swift
  • auth0_flutter/example/ios/Tests/WebAuth/WebAuthExtensionsTests.swift
  • auth0_flutter/example/ios/Tests/WebAuth/WebAuthHandlerTests.swift
  • auth0_flutter/example/lib/example_app.dart
  • auth0_flutter/example/macos/Podfile
  • auth0_flutter/example/macos/Runner.xcodeproj/project.pbxproj
  • auth0_flutter/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  • auth0_flutter/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  • auth0_flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata
  • auth0_flutter/example/macos/Runner/AppDelegate.swift
  • auth0_flutter/ios/.gitignore
  • auth0_flutter/ios/Assets/.gitkeep
  • auth0_flutter/ios/Classes/Auth0FlutterPlugin.h
  • auth0_flutter/ios/Classes/Auth0FlutterPlugin.m
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPICustomTokenExchangeMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIEmailPasswordlessLoginMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIExtensions.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPILoginUsernameOrEmailMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPILoginWithEmailMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPILoginWithOTPMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPILoginWithPhoneNumberMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIMultifactorChallengeMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPhoneNumberPasswordlessLoginMethod.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIRenewMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIResetPasswordMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPISignupMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIUserInfoMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/SSOExchangeMethodHandler.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerClearMethodHandler.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerExtensions.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerGetMethodHandler.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerHandler.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerHasValidMethodHandler.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerModels.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerRenewMethodHandler.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerSaveMethodHandler.swift
  • auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerUserInfoMethodHandler.swift
  • auth0_flutter/ios/Classes/CredentialsManager/SSOCredentialsMethodHandler.swift
  • auth0_flutter/ios/Classes/DPoP/DPoPClearKeyMethodHandler.swift
  • auth0_flutter/ios/Classes/DPoP/DPoPGetHeadersMethodHandler.swift
  • auth0_flutter/ios/Classes/DPoP/DPoPHandler.swift
  • auth0_flutter/ios/Classes/Extensions.swift
  • auth0_flutter/ios/Classes/HandlerError.swift
  • auth0_flutter/ios/Classes/MethodHandler.swift
  • auth0_flutter/ios/Classes/Models.swift
  • auth0_flutter/ios/Classes/Properties.swift
  • auth0_flutter/ios/Classes/SwiftAuth0FlutterPlugin.swift
  • auth0_flutter/ios/Classes/WebAuth/WebAuthExtensions.swift
  • auth0_flutter/ios/Classes/WebAuth/WebAuthHandler.swift
  • auth0_flutter/ios/Classes/WebAuth/WebAuthLoginMethodHandler.swift
  • auth0_flutter/ios/Classes/WebAuth/WebAuthLogoutMethodHandler.swift
  • auth0_flutter/ios/Classes/WebAuth/WebAuthModels.swift
  • auth0_flutter/ios/auth0_flutter.podspec
  • auth0_flutter/macos/.gitignore
  • auth0_flutter/macos/Assets/.gitkeep
  • auth0_flutter/macos/Classes/Auth0FlutterPlugin.h
  • auth0_flutter/macos/Classes/Auth0FlutterPlugin.m
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPICustomTokenExchangeMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIEmailPasswordlessLoginMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIExtensions.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPILoginUsernameOrEmailMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPILoginWithEmailMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPILoginWithOTPMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPILoginWithPhoneNumberMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIMultifactorChallengeMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPhoneNumberPasswordlessLoginMethod.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIRenewMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIResetPasswordMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPISignupMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIUserInfoMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/SSOExchangeMethodHandler.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerClearMethodHandler.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerExtensions.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerGetMethodHandler.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerHandler.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerHasValidMethodHandler.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerModels.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerRenewMethodHandler.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerSaveMethodHandler.swift
  • auth0_flutter/macos/Classes/CredentialsManager/CredentialsManagerUserInfoMethodHandler.swift
  • auth0_flutter/macos/Classes/CredentialsManager/SSOCredentialsMethodHandler.swift
  • auth0_flutter/macos/Classes/DPoP/DPoPClearKeyMethodHandler.swift
  • auth0_flutter/macos/Classes/DPoP/DPoPGetHeadersMethodHandler.swift
  • auth0_flutter/macos/Classes/DPoP/DPoPHandler.swift
  • auth0_flutter/macos/Classes/Extensions.swift
  • auth0_flutter/macos/Classes/HandlerError.swift
  • auth0_flutter/macos/Classes/MethodHandler.swift
  • auth0_flutter/macos/Classes/Models.swift
  • auth0_flutter/macos/Classes/Properties.swift
  • auth0_flutter/macos/Classes/SwiftAuth0FlutterPlugin.swift
  • auth0_flutter/macos/Classes/WebAuth/WebAuthExtensions.swift
  • auth0_flutter/macos/Classes/WebAuth/WebAuthHandler.swift
  • auth0_flutter/macos/Classes/WebAuth/WebAuthLoginMethodHandler.swift
  • auth0_flutter/macos/Classes/WebAuth/WebAuthLogoutMethodHandler.swift
  • auth0_flutter/macos/Classes/WebAuth/WebAuthModels.swift
  • auth0_flutter/macos/auth0_flutter.podspec
  • scripts/generate-symlinks.sh

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch flutter-pod-to-spm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sanchitmehtagit

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

NandanPrabhu and others added 14 commits June 4, 2026 09:49
flutter config --enable-swift-package-manager must run after Flutter
is installed and before flutter pub get so that SPM-based dependencies
(Auth0.swift resolved via Package.swift) are properly set up when
building and running native iOS/macOS unit tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The FlutterGeneratedPluginSwiftPackage (created during flutter pub get)
picks up the iOS deployment target from the Xcode toolchain. When Xcode
was configured after pub get, the generated Package.swift defaulted to
iOS 13.0 instead of reading the project's IPHONEOS_DEPLOYMENT_TARGET
of 14.0, causing:

  error: The package product 'auth0-flutter' requires minimum platform
  version 14.0 for the iOS platform, but this target supports 13.0

Fix: move "Setup Xcode" and "Save Xcode version" steps before
"Enable Swift Package Manager" and "flutter pub get".
…id test

LoginWebAuthRequestHandlerTest referenced CustomTabsOptions and
BrowserPicker (both in com.auth0.android.provider) without importing
them, causing compileDebugUnitTestKotlin to fail with unresolved
references. Importing WebAuthProvider from the same package does not
bring in its siblings.

Verified with ./gradlew koverXmlReportDebug.
@@ -1 +0,0 @@
../../../darwin/Classes/AuthAPI/AuthAPIMultifactorChallengeMethodHandler.swift No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do we need to delete this file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Swift Package Manager support

2 participants