Platforms to show: All Mac Windows Linux Cross-Platform
/Swift/StoreKit2/StoreKit2 Test
Required plugins for this example: MBS Main Plugin, MBS Swift Plugin
Last modified Sat, 1st Aug 2025.
You find this example project in your MBS Xojo Plugin download as a Xojo project file within the examples folder: /Swift/StoreKit2/StoreKit2 Test
Download this example: StoreKit2 Test.zip
Project "StoreKit2 Test.xojo_binary_project"
Class App Inherits DesktopApplication
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
EventHandler Sub Opening()
StoreKit2MBS.QueryProducts Array("test1"), AddressOf QueryProductsCompleted
StoreKit2MBS.SetUpdates AddressOf updatesReceived
StoreKit2MBS.CurrentEntitlements AddressOf CurrentEntitlementsCompleted
End EventHandler
Sub CurrentEntitlementsCompleted(errorMessage as String, transactions() as Dictionary)
Log CurrentMethodName
If errorMessage <> "" Then
Log "Failed to get updates: "+errorMessage
End If
If transactions <> Nil Then
var today as date
For Each transaction As Dictionary In transactions
Var id As String = transaction.Value("id")
Var productID As String = transaction.Value("productID")
Var purchaseDate As date = transaction.Value("purchaseDate")
Var purchasedQuantity As Integer = transaction.Value("purchasedQuantity")
Var isUpgraded As Boolean = transaction.Value("isUpgraded")
If transaction.HasKey("verified") Then
Var verified As Boolean = transaction.value("verified")
If Not verified Then Continue // ignore
End If
Var revocationDate As date = transaction.Lookup("revocationDate", Nil)
If revocationDate <> Nil Then
// Remove access to the product identified by transaction.productID.
// Transaction.revocationReason provides details about
// the revoked transaction.
Continue
End If
Var expirationDate As date = transaction.Lookup("expirationDate", Nil)
If expirationDate < today Then
// Do nothing, this subscription is expired.
Continue
End If
If isUpgraded Then
// Do nothing, there is an active transaction for a higher level of service.
Continue
End If
// Provide access to the product identified by transaction.productID.
If productID = "test1" Then
test1Purchased = True
end if
Break // see in debugger
Next
End If
End Sub
Sub QueryProductsCompleted(errorMessage as String, products() as Dictionary)
Log CurrentMethodName
If errorMessage <> "" Then
Log "Failed to query products: "+errorMessage
End If
If products <> Nil Then
For Each product As Dictionary In products
Var id As String = product.Value("id")
Var displayName As String = product.Value("displayName")
Var description As String = product.Value("description")
Var price As double = product.Value("price")
Var displayPrice As String = product.Value("displayPrice")
Var isFamilyShareable As boolean = product.Value("isFamilyShareable")
Var type As Dictionary = product.Value("type")
Var typeValue As String = type.Value("value")
// iOS 15.4, macOS 12.3 or newer
var typeDescription as string = type.Lookup("localizedDescription", "")
log displayName+": "+displayPrice
'Break // see in debugger
Next
End If
End Sub
Sub updatesReceived(errorMessage as String, transactions() as Dictionary)
Log CurrentMethodName
If errorMessage <> "" Then
Log "Failed to get updates: "+errorMessage
End If
If transactions <> Nil Then
var today as new date
For Each transaction As Dictionary In transactions
Var id As String = transaction.Value("id")
var productID as string = transaction.Value("productID")
var purchaseDate as date = transaction.Value("purchaseDate")
Var purchasedQuantity As Integer = transaction.Value("purchasedQuantity")
var isUpgraded as Boolean = transaction.Value("isUpgraded")
if transaction.HasKey("verified") then
Var verified As Boolean = transaction.value("verified")
If Not verified Then Continue // ignore
end if
Var revocationDate As date = transaction.Lookup("revocationDate", Nil)
If revocationDate <> Nil Then
// Remove access to the product identified by transaction.productID.
// Transaction.revocationReason provides details about
// the revoked transaction.
Continue
end if
Var expirationDate As date = transaction.Lookup("expirationDate", Nil)
If expirationDate < today Then
// Do nothing, this subscription is expired.
continue
End If
If isUpgraded Then
// Do nothing, there is an active transaction for a higher level of service.
Continue
end if
// Provide access to the product identified by transaction.productID.
If productID = "test1" Then
test1Purchased = True
End If
Break // see in debugger
Next
End If
End Sub
End Class
Class MainWindow Inherits DesktopWindow
Control PurchaseButton Inherits DesktopButton
ControlInstance PurchaseButton Inherits DesktopButton
EventHandler Sub Pressed()
Var purchaseOptions As New Dictionary
purchaseOptions.value("quantity") = 2
'purchaseOptions.value("appAccountToken") = "xxx"
'purchaseOptions.value("simulatesAskToBuyInSandbox") = True
'purchaseOptions.value("customkey") = "customvalue"
StoreKit2MBS.PurchaseProduct("test1", Self, purchaseOptions, AddressOf PurchaseCompleted)
End EventHandler
End Control
Control List Inherits DesktopListBox
ControlInstance List Inherits DesktopListBox
End Control
Control SyncButton Inherits DesktopButton
ControlInstance SyncButton Inherits DesktopButton
EventHandler Sub Pressed()
StoreKit2MBS.Sync AddressOf syncCompleted
End EventHandler
End Control
Control SyncButton1 Inherits DesktopButton
ControlInstance SyncButton1 Inherits DesktopButton
EventHandler Sub Pressed()
StoreKit2MBS.RequestReview
End EventHandler
End Control
EventHandler Sub Opening()
If test1Purchased Then
// already purchased
elseIf StoreKit2MBS.CanMakePayments Then
// user can buy
PurchaseButton.Enabled = True
Else
// user can't buy
End If
End EventHandler
Sub Log(s as string)
List.AddRow s
// auto scroll
List.ScrollPosition = List.LastAddedRowIndex
End Sub
Sub PurchaseCompleted(errorMessage as String, result as Dictionary)
Log CurrentMethodName
If errorMessage <> "" Then
Log "Error: "+errorMessage
End If
var status As String = result.lookup("result", "")
Var verified As Boolean = result.Lookup("verified", False)
Var transaction As Dictionary = result.Lookup("transaction", Nil)
var verificationError as string = result.Lookup("verificationError", "")
Select Case status
Case "success"
// Successful purchase
If verified Then
// okay
Var id As String = transaction.Value("id")
Var productID As String = transaction.Value("productID")
If verified Then
// Provide access to the product identified by transaction.productID.
If productID = "test1" Then
test1Purchased = True
PurchaseButton.Enabled = false
End If
End If
Else
// Successful purchase but transaction/receipt can't be verified
// Could be a jailbroken phone
end if
case "pending"
// Transaction waiting on SCA (Strong Customer Authentication) or approval from Ask to Buy
Case "userCancelled"
Case "unknown"
case "failed"
end Select
Break
End Sub
Sub TransactionsCompleted(errorMessage as string, transactions() as Dictionary)
Log CurrentMethodName
If errorMessage <> "" Then
Log "Error: "+errorMessage
End If
End Sub
Sub syncCompleted(ErrorMessage as string)
Log CurrentMethodName
if errorMessage <> "" then
Log "Error: "+errorMessage
End If
End Sub
Property e As NSExceptionMBS
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
MenuItem WindowMenu = "Window"
MenuItem HelpMenu = "&Help"
End MenuBar
Sign
End Sign
Module Module1
Sub Log(s as string)
mainWindow.Log s
End Sub
Property test1Purchased As Boolean
End Module
End Project
Download this example: StoreKit2 Test.zip
The items on this page are in the following plugins: MBS Swift Plugin.