Skip to content

feat(flutter_inapp_purchase): add Swift Package Manager support for iOS and macOS#161

Open
alihassan143 wants to merge 6 commits into
hyodotdev:mainfrom
alihassan143:feat/spm-ios-macos-support
Open

feat(flutter_inapp_purchase): add Swift Package Manager support for iOS and macOS#161
alihassan143 wants to merge 6 commits into
hyodotdev:mainfrom
alihassan143:feat/spm-ios-macos-support

Conversation

@alihassan143

@alihassan143 alihassan143 commented May 19, 2026

Copy link
Copy Markdown

#160

Summary by CodeRabbit

  • New Features

    • Added macOS support for the in-app purchase library.
  • Chores

    • Updated iOS minimum deployment target to version 15.0.
    • Integrated new external dependency for enhanced in-app purchase capabilities.
    • Reorganized project structure and build configuration for improved modularity and maintainability.

…OS and macOS

- Rewrite Package.swift with proper iOS 15.0 and macOS 14.0 platform
  declarations, removing incorrect ObjC-only publicHeadersPath and cSettings
- Add OpenIAP SPM dependency (https://github.com/hyodotdev/openiap.git v2.2.1)
  so the plugin's native OpenIAP import resolves correctly under SPM
- Point the SPM target to ios/Classes which already uses #if canImport(FlutterMacOS)
  conditionals, making a single source tree compile correctly for both platforms
- Sync macos/Classes/FlutterInappPurchasePlugin.swift with the canonical iOS
  version, restoring feature parity for CocoaPods macOS builds (beginRefundRequestIOS,
  syncIOS, subscriptionStatusIOS, currentEntitlementIOS, latestTransactionIOS,
  isTransactionVerifiedIOS, getTransactionJwsIOS, getReceiptDataIOS,
  getAppTransactionIOS, verifyPurchaseWithProvider and proper availability guards)
@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Flutter in-app purchase library restructures its build system to adopt a Swift Package Manager-first architecture. Platform minimums increase to iOS 15.0 and macOS 14.0. The OpenIAP dependency (2.2.1) is integrated at the root Package.swift level. Source file locations move to Sources/flutter_inapp_purchase paths, reflected in both CocoaPods podspecs and platform-specific SPM manifests. Example applications are reconfigured to use FlutterGeneratedPluginSwiftPackage and implicit Flutter engine initialization.

Changes

SwiftPM Migration & Example Project Configuration

Layer / File(s) Summary
Root SwiftPM Configuration & OpenIAP Dependency
libraries/flutter_inapp_purchase/Package.swift
Platform targets raised to iOS 15.0 and macOS 14.0; external OpenIAP 2.2.1 dependency added; flutter_inapp_purchase target reconfigured to depend on OpenIAP product and use new source path.
CocoaPods Source Path Updates
libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase.podspec, libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase.podspec
Both iOS and macOS podspecs updated to include Swift sources from flutter_inapp_purchase/Sources/flutter_inapp_purchase/**/*.swift.
Platform-Specific SPM Manifests
libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Package.swift, libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase/Package.swift
New SPM manifests for iOS (15.0+) and macOS (14.0+) declare flutter-inapp-purchase library product and target dependencies on FlutterFramework and OpenIAP 2.2.1.
iOS Example Application Configuration
libraries/flutter_inapp_purchase/example/ios/Runner.xcodeproj/project.pbxproj, libraries/flutter_inapp_purchase/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme, libraries/flutter_inapp_purchase/example/ios/Runner/AppDelegate.h, libraries/flutter_inapp_purchase/example/ios/Runner/AppDelegate.m, libraries/flutter_inapp_purchase/example/ios/Runner/Info.plist
Runner project integrated with FlutterGeneratedPluginSwiftPackage via SPM; pbxproj wired with build files, frameworks, and target dependencies; scheme PreActions added for Flutter framework preparation; AppDelegate adopts FlutterImplicitEngineDelegate and registers plugins on implicit engine initialization; Info.plist configured with UIApplicationSceneManifest for scene-based app lifecycle.
macOS Example Application Configuration
libraries/flutter_inapp_purchase/example/macos/Runner.xcodeproj/project.pbxproj, libraries/flutter_inapp_purchase/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
macOS Runner project integrated with FlutterGeneratedPluginSwiftPackage via SPM; pbxproj build files and framework references added; target dependencies configured; legacy Embed Pods Frameworks phase removed; scheme PreActions added for Flutter macOS framework preparation.
Example Repository Configuration
libraries/flutter_inapp_purchase/example/.gitignore
Added ignore rules for local env file to exclude environment-specific API credentials.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • hyodotdev/openiap#160: This PR implements the Swift Package Manager support for flutter_inapp_purchase by adding platform-specific SPM manifests and migrating the library to a SwiftPM-first build system with structured source paths.

Possibly related PRs

  • hyodotdev/openiap#105: Main PR updates flutter_inapp_purchase SwiftPM/CocoaPods source paths and OpenIAP linkage, enabling the iOS plugin code containing PR #105's newly wired handlers (e.g., beginRefundRequestIOS) to be properly compiled and included.

Suggested labels

🎯 feature, 📱 iOS, cross-platform

Poem

🐰 A rabbit's delight—the plugins now sing!
Swift Package Manager makes iOS take wing,
macOS joins the dance, scenes aligned just right,
Implicit engines dance through the night.
In-app purchases bloom where the hoppers now spring!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding Swift Package Manager support for iOS and macOS platform in the flutter_inapp_purchase package.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
libraries/flutter_inapp_purchase/Package.swift (1)

14-18: 💤 Low value

Consider using a less restrictive version constraint for the OpenIAP dependency.

Using exact: "2.2.1" prevents downstream consumers from automatically receiving security patches (e.g., 2.2.2). If strict reproducibility isn't required, consider .upToNextPatch(from: "2.2.1") to allow patch-level updates while maintaining API compatibility.

💡 Suggested alternative
     dependencies: [
         .package(
             url: "https://github.com/hyodotdev/openiap.git",
-            exact: "2.2.1"
+            .upToNextPatch(from: "2.2.1")
         ),
     ],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libraries/flutter_inapp_purchase/Package.swift` around lines 14 - 18, Change
the OpenIAP dependency declaration in Package.swift to allow patch upgrades
instead of pinning to an exact version: locate the .package entry that currently
uses exact: "2.2.1" for the "https://github.com/hyodotdev/openiap.git"
dependency and replace the version constraint with .upToNextPatch(from: "2.2.1")
so downstream consumers can receive patch security fixes while preserving API
compatibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@libraries/flutter_inapp_purchase/Package.swift`:
- Around line 14-18: Change the OpenIAP dependency declaration in Package.swift
to allow patch upgrades instead of pinning to an exact version: locate the
.package entry that currently uses exact: "2.2.1" for the
"https://github.com/hyodotdev/openiap.git" dependency and replace the version
constraint with .upToNextPatch(from: "2.2.1") so downstream consumers can
receive patch security fixes while preserving API compatibility.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2d9560cd-b0f0-44b5-9c14-a663cde81efc

📥 Commits

Reviewing files that changed from the base of the PR and between 830d780 and 9e799a1.

📒 Files selected for processing (2)
  • libraries/flutter_inapp_purchase/Package.swift
  • libraries/flutter_inapp_purchase/macos/Classes/FlutterInappPurchasePlugin.swift

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request updates the flutter_inapp_purchase package to support macOS (14.0+) and increases the minimum iOS version to 15.0. It integrates the OpenIAP dependency and introduces several new StoreKit 2 and external purchase functionalities, including refund requests, entitlement queries, transaction verification, and subscription status. Feedback was provided regarding a potential mismatch in the package name for the OpenIAP dependency in the Swift package manifest.

Comment thread libraries/flutter_inapp_purchase/Package.swift
@alihassan143 alihassan143 reopened this May 19, 2026
@alihassan143 alihassan143 marked this pull request as draft May 19, 2026 17:04

@hyochan hyochan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for taking this on. I don't think this is ready to merge in its current form.

The OpenIAP product dependency line looks okay as written: SwiftPM resolves the URL dependency with identity openiap, and I verified swift package resolve succeeds with .product(name: "OpenIAP", package: "openiap"). So I would not apply the suggested change to package: "OpenIAP" unless Xcode/Flutter tooling proves otherwise.

The larger issue is that this does not add Flutter plugin SPM support in the layout Flutter expects. Flutter's plugin-author guide expects the manifest under the platform plugin directory, for example ios/flutter_inapp_purchase/Package.swift and/or macos/flutter_inapp_purchase/Package.swift, with sources under Sources/flutter_inapp_purchase. The Swift files also need to be moved or mirrored there, and the podspec source paths need to be updated accordingly so CocoaPods continues to work.

This manifest also removes the Flutter dependency surface rather than replacing it with the SPM equivalent. On Flutter 3.41+, the plugin manifest should include the FlutterFramework package dependency documented by Flutter; otherwise the target imports Flutter but the package has no dependency that provides it. I hit that locally:

swift build
...
error: no such module 'Flutter'

A few concrete fixes I would expect before this lands:

  • Add platform-specific SPM manifests in the Flutter-supported locations instead of only changing the repository-root plugin Package.swift.
  • Move/mirror ios/Classes into the corresponding Sources/flutter_inapp_purchase directory and update the iOS/macOS podspecs to keep CocoaPods working.
  • Add the Flutter 3.41 FlutterFramework dependency in the SPM target.
  • Keep the library product name hyphenated (flutter-inapp-purchase) per Flutter's guidance for plugin names containing underscores.
  • Re-verify with a Flutter example build with Swift Package Manager enabled for both iOS and macOS, not just swift package resolve.

References:

alihassan143 and others added 2 commits June 2, 2026 21:31
Restructure iOS and macOS Swift sources into SPM-compatible layout
under flutter_inapp_purchase/Sources/flutter_inapp_purchase/. Add
Package.swift manifests for both platforms, update podspecs to point
to the new source paths, and wire up Xcode projects in the example
app to use FlutterGeneratedPluginSwiftPackage. Fix missing env asset
that blocked macOS and iOS example builds.
@alihassan143 alihassan143 marked this pull request as ready for review June 2, 2026 17:05
@alihassan143

Copy link
Copy Markdown
Author

@hyochan now PR ready for review

@alihassan143 alihassan143 requested a review from hyochan June 2, 2026 17:07

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libraries/flutter_inapp_purchase/Package.swift`:
- Around line 17-25: The root Package.swift target "flutter_inapp_purchase" is
missing the FlutterFramework dependency required by sources that import
Flutter/FlutterMacOS (see FlutterInappPurchasePlugin.swift); either remove the
root Package.swift if it's unused to avoid divergence, or add the
FlutterFramework package+product to the target's dependencies (mirror what the
platform-specific Package.swift files do) so the target resolves imports of
Flutter/FlutterMacOS.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 808073e1-0fb6-40bf-8be7-23e1bc2e613b

📥 Commits

Reviewing files that changed from the base of the PR and between 9e799a1 and aaf5b61.

📒 Files selected for processing (20)
  • libraries/flutter_inapp_purchase/Package.swift
  • libraries/flutter_inapp_purchase/example/.gitignore
  • libraries/flutter_inapp_purchase/example/ios/Runner.xcodeproj/project.pbxproj
  • libraries/flutter_inapp_purchase/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  • libraries/flutter_inapp_purchase/example/ios/Runner/AppDelegate.h
  • libraries/flutter_inapp_purchase/example/ios/Runner/AppDelegate.m
  • libraries/flutter_inapp_purchase/example/ios/Runner/Info.plist
  • libraries/flutter_inapp_purchase/example/macos/Runner.xcodeproj/project.pbxproj
  • libraries/flutter_inapp_purchase/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  • libraries/flutter_inapp_purchase/ios/Assets/.gitkeep
  • libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase.podspec
  • libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Package.swift
  • libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterIapHelper.swift
  • libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterIapLog.swift
  • libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterInappPurchasePlugin.swift
  • libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase.podspec
  • libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase/Package.swift
  • libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterIapHelper.swift
  • libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterIapLog.swift
  • libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterInappPurchasePlugin.swift
✅ Files skipped from review due to trivial changes (3)
  • libraries/flutter_inapp_purchase/example/ios/Runner/AppDelegate.h
  • libraries/flutter_inapp_purchase/example/.gitignore
  • libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase/Package.swift

Comment on lines 17 to 25
targets: [
.target(
name: "flutter_inapp_purchase",
dependencies: [],
path: "ios/Classes",
resources: [
.process("../Assets")
dependencies: [
.product(name: "OpenIAP", package: "openiap"),
],
publicHeadersPath: "",
cSettings: [
.headerSearchPath("../Flutter"),
.headerSearchPath("../../../Flutter/Export")
]
path: "ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase"
)
]

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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate all Package.swift manifests for this plugin and inspect their dependencies/paths.
fd -t f 'Package.swift' libraries/flutter_inapp_purchase --exec sh -c 'echo "==== {} ===="; cat "{}"'

# Confirm the target sources actually import Flutter modules.
rg -nP 'import\s+(Flutter|FlutterMacOS)|canImport\(FlutterMacOS\)' libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Sources -C1

Repository: hyodotdev/openiap

Length of output: 4563


Root Package.swift is missing FlutterFramework dependency for sources that import Flutter/FlutterMacOS

The root libraries/flutter_inapp_purchase/Package.swift target depends only on OpenIAP:

targets: [
    .target(
        name: "flutter_inapp_purchase",
        dependencies: [
            .product(name: "OpenIAP", package: "openiap"),
        ],
        path: "ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase"
    )
]

…but the corresponding sources libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterInappPurchasePlugin.swift contain import FlutterMacOS / import Flutter. The platform-specific manifests in libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Package.swift and libraries/flutter_inapp_purchase/macos/flutter_inapp_purchase/Package.swift add the needed FlutterFramework dependency, while the root manifest does not.

If the root manifest is no longer used, remove it to avoid divergence; otherwise add FlutterFramework (package + product) to the root target so it can resolve Flutter/FlutterMacOS.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libraries/flutter_inapp_purchase/Package.swift` around lines 17 - 25, The
root Package.swift target "flutter_inapp_purchase" is missing the
FlutterFramework dependency required by sources that import Flutter/FlutterMacOS
(see FlutterInappPurchasePlugin.swift); either remove the root Package.swift if
it's unused to avoid divergence, or add the FlutterFramework package+product to
the target's dependencies (mirror what the platform-specific Package.swift files
do) so the target resolves imports of Flutter/FlutterMacOS.

@alihassan143

Copy link
Copy Markdown
Author

@hyochan can you review the PR

@hyochan hyochan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for updating the Flutter SPM layout. The platform-specific manifests and example SPM wiring look much closer now, and I verified the example builds after creating the local env file from env.example.

I still cannot approve this yet because the root Swift package is still broken. now points the target at , but that source imports / while the root target only depends on OpenIAP. Running Building for debugging...
[0/3] Write sources
[1/3] Copying openiap-versions.json
[2/3] Write swift-version--58304C5D6DBC2206.txt
[4/21] Compiling OpenIAP OpenIapStore.swift
[5/21] Compiling OpenIAP OpenIapVersion.swift
[6/21] Compiling OpenIAP SubscriptionToken.swift
[7/21] Compiling OpenIAP OpenIapModule.swift
[8/21] Compiling OpenIAP OpenIapProtocol.swift
[9/22] Compiling OpenIAP resource_bundle_accessor.swift
[10/22] Compiling OpenIAP OpenIapLog.swift
[11/22] Compiling OpenIAP OpenIapModule+ObjC.swift
[12/22] Compiling OpenIAP OpenIapSerialization.swift
[13/22] Compiling OpenIAP ReceiptValidationCompat.swift
[14/22] Compiling OpenIAP ProductManager.swift
[15/22] Compiling OpenIAP StoreKitTypesBridge.swift
[16/22] Compiling OpenIAP TypesConformance.swift
[17/22] Compiling OpenIAP OpenIapError.swift
[18/22] Compiling OpenIAP IapState.swift
[19/22] Compiling OpenIAP OpenIapConnectionLifecycle.swift
[20/22] Emitting module OpenIAP
[21/22] Compiling OpenIAP TypeAliases.swift
[22/22] Compiling OpenIAP Types.swift
Build complete! (7.83s) from fails with:

default
error: no such module 'Flutter'
/private/tmp/openiap-pr161/libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterInappPurchasePlugin.swift:5:8: error: no such module 'Flutter'

Please either remove the root if Flutter should only consume the platform-specific manifests, or make the root manifest compile by providing the proper FlutterFramework dependency/path. Leaving a checked-in manifest that cannot build makes the package look SPM-ready while direct SwiftPM tooling still fails.

Verified locally:

  • Analyzing openiap...
    No issues found! (ran in 37.9s) passes
  • passes
  • passes
  • passes
  • [0/1] Planning build
    Building for debugging...
    [0/1] Write swift-version--58304C5D6DBC2206.txt
    Build complete! (0.14s) from fails as above

@hyochan hyochan dismissed their stale review June 11, 2026 19:32

superseded by corrected review

@hyochan hyochan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for updating the Flutter SPM layout. The platform-specific manifests and example SPM wiring look much closer now, and I verified the example builds after creating the local env file from env.example.

I still cannot approve this yet because the root Swift package is still broken. libraries/flutter_inapp_purchase/Package.swift now points the target at ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase, but that source imports Flutter / FlutterMacOS while the root target only depends on OpenIAP. Running swift build from libraries/flutter_inapp_purchase fails with:

error: no such module 'Flutter'
/private/tmp/openiap-pr161/libraries/flutter_inapp_purchase/ios/flutter_inapp_purchase/Sources/flutter_inapp_purchase/FlutterInappPurchasePlugin.swift:5:8: error: no such module 'Flutter'

Please either remove the root Package.swift if Flutter should only consume the platform-specific manifests, or make the root manifest compile by providing the proper FlutterFramework dependency/path. Leaving a checked-in manifest that cannot build makes the package look SPM-ready while direct SwiftPM tooling still fails.

Verified locally:

  • flutter analyze passes
  • flutter test passes
  • cp env.example env && flutter build macos --debug passes
  • cp env.example env && flutter build ios --simulator --debug passes
  • swift build from libraries/flutter_inapp_purchase fails as above

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.

2 participants