I am participating in the Mid-Autumn Festival Creative Submission contest, please see: Mid-Autumn Festival Creative Submission Contest for details

preface

Hello, friends, the Mid-Autumn Festival is coming, here in advance to wish everyone a happy Mid-Autumn Festival!

Speaking of such festivals with traditional characteristics, game companies will certainly launch gold props with relevant festival elements for players to consume, such as Halloween pumpkins, Mid-Autumn Festival moon cakes, Spring Festival animals and so on. Then I will tell you how gold works in the iOS system today.

The In – App_Purchase is introduced

IOS in-app purchase: Iaps have always been an important part of paid apps, especially games, because Apple has decreed that virtual currency must be paid for with IAps, otherwise the APP will not be approved by Apple, so Iaps have always been a feature that many game developers need to integrate. Looking back over the years objective-C has slowly lost its popularity, iOS developers are embracing Swift, including myself, so take the opportunity to implement an open source IAP Framework based on Swift.

The effect

Demonstration success:

Demo gold failure:

Open source address

Don’t spare your little hands, click 🌟 with your fingers!

Demand analysis

Those of you who have integrated IAP into your iOS app know exactly how it works. If you don’t, it doesn’t matter. Here’s a mind map for a quick overview:

From the mind map above, the requirements should be clear and can be summarized as follows:

  1. Request product information according to the product ID, and call back the product information returned by AppStore to the client to display;
  2. Initiate payment, if the payment fails, send callback information to the client, and prompt payment failure; If the payment is successful, the next step is to verify the bill;
  3. Provide local authentication tickets. If the verification is successful, the callback information is sent to the client, indicating that the purchase is successful; otherwise, the purchase fails.
  4. Provide remote verification ticket. If the verification is successful, the callback message is sent to the client, indicating that the purchase is successful; otherwise, the purchase fails.

After clear demand, you can begin to develop, because this is an open source project, and the amount of code is a bit much, so I will not explain here, the main several functions below, if you are interested, you can go to read the source code.

Listen for App Store messages

First of all, the first thing to do is to register a listener. This listener mechanism allows our application to receive messages about successful, failed and resumed transactions.

I used Self as an Observer and added it to the StoreKit Payments Queue:

SKPaymentQueue.default().add(self)
Copy the code

Obtaining commodity information

Instantiate object:

var purchaseXManager = PurchaseXManager(a)Copy the code

To request product information, the interface will first read the product ID configuration file locally, save it in the form of array, and then request product information from AppStore. The callback notifies the client in the form of a closure that records the status of the requested item, which can be listed as if or switch.

purchaseXManager.requestProductsFromAppstore { notification in
    if notification = = .requestProductsStarted {
        print("Request Products Started")}else if notification = = .requestProductsSuccess {
        print("Request Products Success")}else if notification = = .requestProductsFailure {
        print("Request Products Failed")}else if notification = = .requestProductsDidFinish {
        print("Request Products Finished")}else if notification = = .requestProductsNoProduct {
        print("No Products")}else if notification = = .requestProductsInvalidProducts {
        print("Invalid Products")}}Copy the code

Finally, when the status received is requestProductsSuccess, the commodity information request is successful, and the resulting commodity is stored in the property Products of purchaseXManager, as defined below:

// MARK: Public Property
    /// Array of products retrieved from AppleStore
    @Published public var products: [SKProduct]?
Copy the code

buy

When the user initiates payment, this interface is called and the ID of the commodity to be purchased is passed in. The callback notifies the client in the form of a closure that records the status of the current purchase, which can be listed as if or switch.

purchaseXManager.purchase(product: purchaseXManager.product(from: product.productID)!) { notification in
            if notification = = .purchaseSuccess{
                print("Purchase Success")}else if notification = = .purchaseCancelled {
                print("Purchase Cancelled")}else if notification = = .purchaseFailure {
                print("Purchase Failed")}else if notification = = .purchaseAbort {
                print("Purchase Abort")}else if notification = = .purchasePending {
                print("Purchase Pending")}}Copy the code

Purchase is successful when the callback parameter is purchaseSuccess, and ticket verification can proceed; If you receive any other status, you need to prompt the client that the current purchase is in trouble.

Return to buy

When you have non-consumable items in your app store, you need to add a restore purchase function; If users change phones or uninstall and install your App, they need to restore the purchase status of these items in the App. The restorePurchase interface can help you implement your requirements; The callback will notify you, in the form of a closure, that the purchase is restored when the callback parameter is purchaseRestoreSuccess, or you need to retry.

purchaseXManager.restorePurchase { notification in
            switch notification{
            case .purchaseRestoreSuccess:
                print("Restore Success")
            case .purchaseRestoreFailure:
                print("Restore Failed")
            default:
                break}}Copy the code

Verify the bill

Once you complete the purchase, you need to verify the receipt to ensure that the purchase process is normal. Apple provides two ways to verify the receipt. One is on the device, which is called local verification. Another way is to send the ticket to AppStore through Http for verification. Both methods are supported here.

Local validation

Callbacks will be notified to you in the form of closures. If successful, the callback parameters will contain specific ticket information for further logical processing by the developer, such as subscriptions type goods.

/// validate locally
purchaseXManager.validateReceiptLocally { validateResult in
    switch validateResult {
    case .success(let receipt):
        print("receipt:\(receipt)")
    case .error(let error):
        print("Validate Failed:\(error)")}}Copy the code

Remote authentication

Callbacks will be notified to you in the form of closures. If successful, the callback parameters will contain specific ticket information for further logical processing by the developer, such as subscriptions type goods.

/// validate remotelly
purchaseXManager.validateReceiptRemotely(shareSecret: "put your share secret key", isSandBox: true) { validateResult in
    switch validateResult {
    case .success(let receipt):
        print("receipt:\(receipt)")
    case .error(let error):
        print("Validate Failed:\(error)")}}Copy the code

Extension interface

In addition to these interfaces, PurchaseX provides extension methods that make it easier for developers to integrate in-purchase functionality, so check it out!

Whether the item has been initialized

if purchaseXManager.hasProducts {
	....
}
Copy the code

Returns the commodity object based on the commodity ID

public func product(from productId: String) -> SKProduct?
Copy the code

Refresh the bill

public func refreshReceipt(completion: @escaping(_ notification: PurchaseXNotification?) -> Void)
Copy the code

Obtain whether the commodity has been purchased according to the commodity ID

public func isPurchased(productId: String) -> Bool
Copy the code

The last

IOS in-app purchase is a feature every Apple developer can’t avoid, and it’s a pit to jump from one pit to another. Hopefully, this open source project can help you avoid those pits.

Only version 1.0 is shared this time, so some parts of the code are not very robust. I will continue to maintain this project in the future. In addition, the new StoreKit2 for iOS15 will come out soon; Finally, if you think this article has a little help for you, please remember one key three connect ah!

Please click 🌟 for my open source project: PurchaseX!

Previous articles:

  • Take you rolled a netease holding cloud music home | adapter
  • Netease Cloud Music Home Page (3)
  • Netease Cloud Music Home Page (2)
  • Netease Cloud Music Home Page (a)
  • Does the code need comments? Write and you lose
  • I would not study in Codable for a long time. They are for fun
  • IOS handles web data gracefully. Do you really? Why don’t you read this one
  • UICollectionView custom layout! This one is enough

Please drink a cup ☕️ + attention oh ~

  1. After reading, remember to give me a thumbs-up oh, there is 👍 power
  2. Follow the public number – HelloWorld Jie Shao, the first time push new posture

Finally, creation is not easy, if it is helpful to you, I hope you can praise and support, what questions can also be discussed in the comments section 😄 ~