Skip to main content

2.9.0 - OpenIAP Apple Integration

ยท 3 min read
Hyo
Expo IAP Maintainer

We're excited to announce 2.9.0, featuring full integration with OpenIAP Apple that reduces our Swift codebase by ~1,180 lines (73% reduction)!

๐ŸŽฏ OpenIAP Apple Integrationโ€‹

The core achievement of this release is integrating OpenIAP Apple v1.1.5 as our iOS native module.

Code Reduction Impactโ€‹

  • Before: 1,620 lines of Swift code
  • After: 440 lines of Swift code
  • Reduction: ~1,180 lines (73% less code to maintain!)

๐Ÿ—๏ธ Architecture Evolutionโ€‹

Before (2.8.x)โ€‹

Expo IAP โ†’ Custom Swift Implementation โ†’ StoreKit 2
(1,620 lines of complex logic)

After (2.9.0)โ€‹

Expo IAP โ†’ OpenIAP Apple โ†’ StoreKit 2
(440 lines) (Specialized native module)

โœจ What's Newโ€‹

Enhanced Type Systemโ€‹

Following OpenIAP v1.1.0 specification:

  • ProductRequest for product fetching
  • RequestPurchaseProps for purchase requests
  • ReceiptValidationProps for receipt validation
  • PurchaseError with native error code mapping
  • No more deep imports: ProductAndroid, ProductIOS, PaymentDiscount and other types are exported from expo-iap root

Thread Safetyโ€‹

  • All iOS operations now use @MainActor annotation
  • Prevents race conditions and ensures main thread execution

Unified Event Systemโ€‹

  • Renamed IapEvent to OpenIapEvent
  • Streamlined listeners: purchaseUpdatedListener, purchaseErrorListener
  • Added removeAllListeners() for cleanup

๐Ÿ› Bug Fixesโ€‹

  • Fixed duplicate purchase success alerts
  • Resolved restore purchase alerts on screen entry
  • Improved purchase validation logic
  • Enhanced subscription status refresh timing
  • Better deduplication of purchases by productId

๐Ÿ’” Breaking Changesโ€‹

IapEvent โ†’ OpenIapEventโ€‹

// โŒ Old
import {OpenIapEvent} from 'expo-iap';

purchaseUpdatedListener((purchase) => {}, OpenIapEvent.PurchaseUpdated);

// โœ… New
import {OpenIapEvent} from 'expo-iap';

purchaseUpdatedListener((purchase) => {}, OpenIapEvent.PurchaseUpdated);

๐Ÿš€ Looking Ahead: 3.0.0โ€‹

This release sets the foundation for 3.0.0:

  • Android: OpenIAP Android integration (Google Play Billing)
  • Bundle Size: Further optimizations through shared native libraries
  • Maintenance: Unified native module architecture

๐Ÿ’ก Benefitsโ€‹

  1. Reliability: Battle-tested native modules reduce edge cases
  2. Maintainability: 73% less code in Expo IAP layer
  3. Performance: Optimized native implementations
  4. Future-proof: Easier platform updates

๐Ÿ“ฆ Installationโ€‹

npm install expo-iap@2.9.0
# or
yarn add expo-iap@2.9.0
# or
bun add expo-iap@2.9.0

๐Ÿ“‹ Full Changelogโ€‹

Addedโ€‹

  • iOS: Integrated OpenIAP Apple v1.1.6
  • Updated types to match OpenIAP v1.1.0 specification
  • Enhanced error handling with PurchaseError type
  • New type system: ProductRequest, RequestPurchaseProps, ReceiptValidationProps
  • Improved receipt validation with ReceiptValidationResult

Changedโ€‹

  • Updated serializePurchase and serializeProduct for new OpenIAP structure
  • Updated listener setup to use new OpenIAP methods
  • Renamed IapEvent to OpenIapEvent across entire codebase
  • Added unified removeAllListeners() for cleanup
  • Avoid deep imports: import public types directly from expo-iap

Fixedโ€‹

  • Fixed duplicate purchase success alerts
  • Fixed restore purchase alerts on screen entry
  • Improved purchase validation logic
  • Enhanced subscription deduplication

Noteโ€‹

  • Android native module integration with OpenIAP Android planned for 3.0.0

๐Ÿ™ Acknowledgmentsโ€‹

Special thanks to the OpenIAP project for providing standardized, high-quality native modules.

For detailed changes, see PR #184.

Questions? Visit GitHub Issues!