Swift SDK Changelog
This page documents version-by-version API changes for the AppCoins iOS Swift SDK. Each entry lists breaking changes, new features, and migration steps where applicable.
Version 5.x (Upcoming)
Breaking Changes
-
PurchaseIntentremoved — thePurchaseIntenttype, thePurchase.updatesstream,PurchaseIntent.confirm(), andPurchaseIntent.reject()are all removed. Purchase results are now returned directly fromproduct.purchase()asVerificationResult<Transaction>. -
Product property renames — three properties on
Producthave been renamed to align with the StoreKit 2 naming convention:Old name New name product.skuproduct.idproduct.titleproduct.displayNameproduct.priceLabelproduct.displayPrice -
Product.products()signature change — thedomain:parameter has been removed:Old New Product.products(for: ["sku"], domain: "com.example.app")Product.products(for: ["sku"]) -
Purchasetype replaced byTransaction— thePurchasetype no longer exists. All transaction data is now represented byTransaction. -
purchase()now throws — the.failed(let error)case has been removed fromProduct.PurchaseResult. Errors are now thrown. Wrap all calls toproduct.purchase()in ado/catchblock. -
Purchase.unfinished()replaced byTransaction.unfinishedstream — the function returning[Purchase]is replaced by a non-throwingAsyncStream:Old New let purchases = try await Purchase.unfinished()for await result in Transaction.unfinished { } -
transaction.finish()no longer throws — replacetry await purchase.finish()withawait transaction.finish(). -
transaction.idis nowString— previously typed asUInt64. Update any code that stores, compares, or transmits this value as a number.
New Features
-
Transaction.all— anAsyncStream<VerificationResult<Transaction>>of the full transaction history for the app, newest first. -
Transaction.latest(for:)— async static method returning the most recentVerificationResult<Transaction>?for a given product identifier. -
product.latestTransaction— async computed property onProductreturning the most recent transaction for that product. -
product.currentEntitlement— async computed property onProductreturning the current unfinished transaction for that product, if one exists.
Migration Steps
-
Replace all
Purchasereferences withTransaction. Use Xcode's Find & Replace (Cmd+Shift+H) to rename the type across your project. -
Rename product properties. Replace
product.sku→product.id,product.title→product.displayName,product.priceLabel→product.displayPrice. -
Remove the
domain:parameter fromProduct.products()calls. -
Wrap
product.purchase()indo/catchand remove the.failedcase.Before:
let result = await product.purchase()
switch result {
case .success(let verification): break
case .pending: break
case .userCancelled: break
case .failed(let error): print("Purchase failed: \(error)")
}After:
do {
let result = try await product.purchase()
switch result {
case .success(let verification): break
case .pending: break
case .userCancelled: break
}
} catch {
print("Purchase failed: \(error)")
} -
Change
try await purchase.finish()toawait transaction.finish(). -
Replace
Purchase.unfinished()with theTransaction.unfinishedstream.Before:
let purchases = try await Purchase.unfinished()
for purchase in purchases {
giveItemToUser(productID: purchase.productID)
try await purchase.finish()
}After:
for await verificationResult in Transaction.unfinished {
switch verificationResult {
case .verified(let transaction):
giveItemToUser(productID: transaction.productID)
await transaction.finish()
case .unverified(let transaction, let error):
print("Unverified: \(error.description)")
}
} -
Remove the
Purchase.updates/PurchaseIntentstream. Handle purchase results from theproduct.purchase()return value instead. UseTransaction.unfinishedon launch for recovery. -
Update
transaction.idusages fromUInt64toStringwherever the value is stored, compared, or transmitted.
Version 4.x (Current)
v4.3.3 — July 2026
Bug Fixes & Improvements
- Improved attribution reliability with exponential backoff retry logic.
- Increased log levels to ensure SDK lifecycle logs are persisted on device.
v4.3.2 — March 2026
Bug Fixes & Improvements
- Fixed a bug where
getWalletListreturned a duplicated wallet after a guest-to-user account conversion.
v4.3.0 — March 2026
Bug Fixes & Improvements
- Removed the SwiftyRSA dependency, which caused conflicts with Apple's MessageProtection framework. If you added a workaround for this conflict, it can be removed.
- Added availability checks for the MarketplaceKit
TransactionReportingAPI on Swift versions prior to 6.2.
v4.2.0 — February 2026
Bug Fixes & Improvements
- Added
installation_originandoem_idparameters to the Web Checkout URL for improved attribution.
v4.1.2 — February 2026
Bug Fixes & Improvements
- Fixed an issue where the MMP installation event was triggered regardless of installation source. The event now fires only for Aptoide-distributed installs.
v4.1.1 — February 2026
New Features
- Added CTC (Catappult Token Contribution) transaction reporting. To enable reporting, add
MKSellsDigitalGoods(YES, Boolean) to your app'sInfo.plist.
v4.0.1 — December 2025
Bug Fixes & Improvements
AppcSDK.isAvailable()now returnsfalseby default again. The previous change that altered this default has been reverted.- Raised the web3swift package dependency version for Swift 6.2 compatibility.
v4.0.0 — November 2025
Breaking Changes
-
Sandbox.getTestingWalletAddress()is nowasync— addawaitto every call site:// Before
let address = Sandbox.getTestingWalletAddress()
// After
let address = await Sandbox.getTestingWalletAddress() -
AppcSDK.initialize()is now enforced — calls toproduct.purchase()will fail at runtime ifinitialize()has not been called at every app entry point. This was previously a recommendation; it is now a hard requirement.
New Features
- Replaced the native checkout UI with a Web Checkout flow. No API changes are required beyond the breaking changes above — the SDK handles checkout presentation internally.
- Added support for older iOS versions.
Migration Steps
-
Add
awaittoSandbox.getTestingWalletAddress(). Find every call site and addawait. Mark the enclosing functionasyncif needed. -
Call
AppcSDK.initialize()at every entry point. See the integration guide for the required setup inSceneDelegateandAppDelegate.
AppcSDK.initialize() must be called at every application entry point. See the integration guide for the required setup in SceneDelegate and AppDelegate.Version 3.x
v3.2.0 — August 2025
Bug Fixes & Improvements
AppcSDK.isAvailable()now returnsfalsefor TestFlight-distributed builds. Only apps distributed through Aptoide are eligible for AppCoins billing.
v3.1.0 — May 2025
New Features
- Added a Manage Account sheet accessible from within the SDK.
- Implemented the Delete Account flow.
v3.0.0 — May 2025
Breaking Changes
-
TransactionResultrenamed toPurchaseResult— the enum returned byproduct.purchase()is renamed. Update all switch statements and type annotations:// Before
let result: TransactionResult = await product.purchase()
// After
let result: PurchaseResult = await product.purchase() -
Purchase.updatesnow emitsPurchaseIntent— previously emittedVerificationResult. The stream now delivers aPurchaseIntentthat must be explicitly confirmed or rejected before the purchase completes:// Before
for await verificationResult in Purchase.updates {
if case .verified(let purchase) = verificationResult {
giveItem(for: purchase.sku)
try await purchase.finish()
}
}
// After
for await intent in Purchase.updates {
let result = await intent.confirm()
if case .success(let verificationResult) = result,
case .verified(let purchase) = verificationResult {
giveItem(for: purchase.sku)
try await purchase.finish()
}
}
New Features
PurchaseIntent.confirm()andPurchaseIntent.reject()for explicit two-step purchase completion.
Migration Steps
-
Rename
TransactionResulttoPurchaseResultthroughout your project using Xcode's Find & Replace (Cmd+Shift+H). -
Update
Purchase.updatesobservers to handlePurchaseIntent. Callintent.confirm()to complete the purchase orintent.reject()to decline it.
PurchaseIntent is removed in v5.x. If you are upgrading directly from v3.x to v5.x, skip PurchaseIntent entirely and follow the v5.x migration steps above.Version 2.x
v2.1.1 — March 2025
Bug Fixes & Improvements
- Fixed an issue where the developer callback was not invoked when mobile data was disabled during checkout.
v2.1.0 — March 2025
Bug Fixes & Improvements
- Bug fixes and stability improvements.
v2.0.0 — February 2025
New Features
-
Purchase.updates— a newAsyncStream<VerificationResult>that delivers indirect in-app purchases initiated outside the app (for example, from a promotional link or the app's store page). Subscribe to this stream on app launch to receive and finish pending purchases:Task {
for await verificationResult in Purchase.updates {
if case .verified(let purchase) = verificationResult {
giveItemToUser(productID: purchase.sku)
try await purchase.finish()
}
}
}
Version 1.x
v1.6.1 — December 2024
Bug Fixes & Improvements
- Fixed a pagination issue where only the first page of results was returned on large product and purchase catalogs.
- Auth localization and UI improvements.
v1.6.0 — November 2024
Bug Fixes & Improvements
- Replaced
URLImagewith nativeAsyncImageto fix disappearing payment method icons. - Fixed bonus and balance amounts being rounded incorrectly.
- Improved developer error debugging with more descriptive error messages.
v1.5.0 — October 2024
Bug Fixes & Improvements
- Changed distribution format to
.xcframeworkfor improved compatibility.
v1.4.0 — October 2024
Bug Fixes & Improvements
- Added landscape orientation support for the payment sheet.
- Localization improvements with new language support.
v1.3.0 — August 2024
New Features
- Added sandbox payment support for testing without real transactions.
- Products now display prices in the user's local currency.
v1.2.0 — August 2024
New Features
- Added verification data to
Purchaseto support server-side validation.
v1.1.0 — July 2024
New Features
- Added MMP attribution support with
guest_idandoem_idtracking parameters. Sandbox.getTestingWalletAddress()is now synchronous.
v1.0.4 — July 2024
Bug Fixes & Improvements
- Bug fixes and stability improvements.
v1.0.3 — May 2024
Bug Fixes & Improvements
- Bug fixes and stability improvements.
v1.0.2 — May 2024
Bug Fixes & Improvements
- Bug fixes and stability improvements.
v1.0.1 — April 2024
Bug Fixes & Improvements
- Bug fixes and stability improvements.
v1.0.0 — February 2024
Initial Release
The first public release of the AppCoins iOS Swift SDK.
API surface:
Product.products(domain:for:)— fetches available in-app products by SKU.product.purchase(domain:payload:orderID:)— initiates a purchase, returningTransactionResult(does not throw; errors surface as the.failedcase).TransactionResult—.success(verificationResult:),.pending,.userCancelled,.failed(error:).VerificationResult—.verified(purchase:),.unverified(purchase:error:).Purchase— transaction data class withuid,sku,state,orderUid,payload,created.purchase.finish()— marks the purchase as consumed. Throws on failure.Purchase.unfinished()— returns[Purchase]of unfinished purchases. Throws.Purchase.all()— returns[Purchase]of all purchases. Throws.Purchase.latest(sku:)— returns the most recentPurchase?for a given SKU. Throws.AppcSDK.initialize()— registers the app with the SDK at launch.AppcSDK.isAvailable()— returns whether AppCoins billing is active on this device.AppcSDK.handle(redirectURL:)— processes billing deep link callbacks.