2.6.0 - Major iOS Improvements
We're excited to announce the release of expo-iap v2.6.0! This release brings significant improvements to iOS functionality, better TypeScript support, and enhanced developer experience.
๐ What's Newโ
1. Proper iOS Subscription Data Serializationโ
The biggest improvement in this release is the proper serialization of iOS subscription data. Previously, the subscription
field would return undefined for subscription products. Now, all subscription information is properly serialized and accessible.
Before (v2.5.x)โ
const subscriptions = await getSubscriptions(['com.example.premium']);
console.log(subscriptions[0].subscription); // undefined ๐ข
After (v2.6.0)โ
const subscriptions = await getSubscriptions(['com.example.premium']);
console.log(subscriptions[0].subscription); // โ
Full subscription data!
2. Improved Type Structureโ
We've restructured how period information is returned to be more consistent and useful. The period
and subscriptionPeriod
properties now return objects with unit
and value
properties instead of just the unit string.
Before (v2.5.x):
type SubscriptionInfo = {
subscriptionPeriod: SubscriptionIosPeriod; // 'DAY' | 'WEEK' | 'MONTH' | 'YEAR'
};
After (v2.6.0):
type SubscriptionInfo = {
subscriptionPeriod: {
unit: SubscriptionIosPeriod; // 'DAY' | 'WEEK' | 'MONTH' | 'YEAR'
value: number; // e.g., 1, 3, 6, 12
};
};
This change provides more detailed information about subscription periods. For example, instead of just knowing a subscription is "MONTH", you now know if it's "1 MONTH", "3 MONTHS", etc.
3. New getStorefront() APIโ
Get the user's App Store country code:
import {getStorefront} from 'expo-iap';
const countryCode = await getStorefront();
console.log('User storefront:', countryCode); // 'US', 'GB', 'JP', etc.
4. AppTransaction Support (iOS 16.0+)โ
For premium apps or apps that were previously paid, you can now verify the initial app purchase:
import {getAppTransaction} from 'expo-iap';
const appTransaction = await getAppTransaction();
if (appTransaction) {
console.log('App Transaction ID:', appTransaction.appTransactionID);
console.log('Purchase Date:', new Date(appTransaction.originalPurchaseDate));
// Send deviceVerification to your server for validation
}
5. Comprehensive iOS Subscription Offers Documentationโ
We've added extensive documentation for handling iOS subscription offers:
- Understanding introductory and promotional offers
- Checking user eligibility
- Implementing offer UI
- Best practices and troubleshooting
Check out the new iOS Subscription Offers Guide.
โ ๏ธ Breaking Changesโ
1. Period Structure Changesโ
The period
and subscriptionPeriod
properties now return objects with unit
and value
properties:
// Before
if (offer.period === 'MONTH') {
console.log('Monthly offer');
}
// After
if (offer.period.unit === 'MONTH') {
console.log(`${offer.period.value} month(s) offer`);
}
2. Optional Subscription Fieldโ
The subscription
field in ProductIOS
is now optional to reflect that not all iOS products have subscription information:
// Before
type ProductIOS = {
subscription: SubscriptionInfo; // Always required
};
// After
type ProductIOS = {
subscription?: SubscriptionInfo; // Optional - only present for subscriptions
};
Migration: Update your code to handle the optional subscription field:
// Check if product is a subscription
if (product.subscription) {
// Handle subscription-specific logic
console.log('Period:', product.subscription.subscriptionPeriod);
}
3. Method Naming Updateโ
To improve consistency, we've updated the purchase history method naming:
- Deprecated:
getPurchaseHistory()
(singular) - New:
getPurchaseHistories()
(plural)
The useIAP
hook already uses the plural form:
const {purchaseHistories, getPurchaseHistories} = useIAP();
๐ Complete Exampleโ
Here's a complete example showing how to work with the new types:
import {useIAP} from 'expo-iap';
function ProductList() {
const {products} = useIAP();
return (
<View>
{products.map((product) => (
<View key={product.productId}>
<Text>{product.displayName}</Text>
<Text>{product.localizedPrice}</Text>
{product.subscription && (
<View>
<Text>
Subscription Period:{' '}
{product.subscription.subscriptionPeriod.value}{' '}
{product.subscription.subscriptionPeriod.unit.toLowerCase()}(s)
</Text>
{product.subscription.introductoryOffer && (
<Text>
Intro Offer:{' '}
{product.subscription.introductoryOffer.displayPrice} for{' '}
{product.subscription.introductoryOffer.period.value}{' '}
{product.subscription.introductoryOffer.period.unit.toLowerCase()}
(s)
</Text>
)}
</View>
)}
</View>
))}
</View>
);
}
๐ Bug Fixesโ
- Fixed iOS subscription data not being properly serialized
- Fixed period information returning raw values instead of structured data
- Improved error handling for platform-specific methods
- Fixed inconsistent naming between
getPurchaseHistory
andpurchaseHistories
๐ Documentation Updatesโ
- Added iOS Subscription Offers guide
- Updated type definitions documentation
- Added examples for new APIs
- Improved troubleshooting section
- Updated migration guide for naming consistency
๐ช Benefitsโ
These improvements provide several benefits:
- Better Type Safety: The TypeScript compiler can now catch more potential errors at compile time
- More Accurate Data: Period information now includes both unit and value, providing complete subscription duration details
- Clearer Intent: Optional types make it explicit which products are subscriptions
- Consistent API: Naming conventions are now consistent throughout the library
- Future-Proof: These changes align better with Apple's StoreKit 2 data structures
๐ Acknowledgmentsโ
Special thanks to:
- @Navipro70 for identifying the subscription serialization issue and providing valuable feedback
- @matthieuMay for the initial iOS type improvements
- All contributors who helped test and improve this release
๐ฆ Installationโ
Update to the latest version:
npm install expo-iap@2.6.0
# or
yarn add expo-iap@2.6.0
๐ Linksโ
What's Next?โ
We're working on:
- Android subscription offers improvements
- Better error messages and debugging tools
- Performance optimizations
- More comprehensive examples
Stay tuned for more updates! If you have any feedback or suggestions, please open an issue.
Happy coding! ๐