Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
132 views
in Technique[技术] by (71.8m points)

ios - InApp Purchase manage product type coming from plist inside package library

I created a package library to manage InAppPurchase. I don't know if my approach is correct

Before that, normally I used the file copied from project to project. I've a doubt when I'd like to use something like enum to quickly identify the product purchased.

For example, before the package, my product was inside an Enum:

public struct InApp {       
    enum ProductType: String, CaseIterable {        
        case unlockSection1 = "it.site.AppName.unlockSection1"
        case unlockSection2  = "it.site.AppName.unlockSection2"
        case unlockSection3 = "it.site.AppName.unlockSection3"        
        static let allValues = ProductType.allCases.map { $0.rawValue }
    }    
}

Class to manage product (only some func):

class IAPSwiftUIModel: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
        
    @Published var allProducts = [SKProduct]() 
    @Published var purchasedProductIdentifiers: Set<String> = [] 
    
    override init() {
        super.init()
        fetchAvailableProducts()
        isPurchaseDisabled = canMakePurchases()
    }

    func isProductPurchased(product: InApp.ProductType) -> Bool {
        return purchasedProductIdentifiers.contains(product.rawValue)
    }


    func fetchAvailableProducts() {          
        let productIdentifiers = Set(InApp.ProductType.allValues)
        print(productIdentifiers)
       
        productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
        productsRequest.delegate = self
        productsRequest.start()
    }
}

Now, with Package, I can't use an enum to identify the product, so I created a Plist with all the identifiers:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>it.site.AppName.unlockSection1</string>
    <string>it.site.AppName.unlockSection2</string>
    <string>it.site.AppName.unlockSection3</string>
</array>
</plist>

IN PACKAGE

///get productsIdentifiers from plist "InAppProducts.plist"

public class IAPProducts {
    
    public static var sharedInstance = IAPProducts()
    
    init() {
        productsIdentifiers = getProductsFromPlist()
    }
    
    public var productsIdentifiers: [String] = []
    
    private func getProductsFromPlist() -> [String] {
        if let url = Bundle.main.url(forResource:"InAppProducts", withExtension: "plist") {
            do {
                let data = try Data(contentsOf:url)
                if let swiftDictionary = try PropertyListSerialization.propertyList(from: data, format: nil) as? [String] {
                    return swiftDictionary
                }
            }
            catch {
                print("getDicFromPlist: (error.localizedDescription)")
                return []
            }
        }
        fatalError("no found InAppProducts.plist")
    }
}

Changing the fetch inside IAPSwiftModel

public func fetchAvailableProducts() {        
    let allProduct = IAPProducts.sharedInstance.productsIdentifiers **//this line**
    let productIdentifiers = Set(allProduct)
    print(productIdentifiers)
   
    productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
    productsRequest.delegate = self
    productsRequest.start()
}

INSIDE THE APP

**/// This to substitute the enum ProductType**
/// I can't use an enum dynamically
struct AppProductsIdentifiers {
    static let unlockSection1 = IAPProducts.sharedInstance.productsIdentifiers[0]
    static let unlockSection2 = IAPProducts.sharedInstance.productsIdentifiers[1]
    static let unlockSection3 = IAPProducts.sharedInstance.productsIdentifiers[2]
}


public struct IAPViewTest: View {
    
    public var inAppModel = IAPSwiftUIModel()
    public init() {}
    public var body: some View {
        VStack {
            /// All products from apple fetch                
            List(inAppModel.allProducts, id:.self) { product in
                Text(product.localizedTitle)                        
            }
            /// All productIdentifiers from plist
            Text("lista nomi da plist")
            List(IAPProducts.sharedInstance.productsIdentifiers, id:.self) { product in
                Text(product)
            }
            Text(inAppModel.isProductPurchased(productIdentifier: AppProductsIdentifiers. unlockSection1) ? "Section1 purchased" : "Section1 blocked")
Text(inAppModel.isProductPurchased(productIdentifier: AppProductsIdentifiers. unlockSection1) ? "Section2 purchased" : "Section2 blocked")
Text(inAppModel.isProductPurchased(productIdentifier: AppProductsIdentifiers. unlockSection1) ? "Section3 purchased" : "Section3 blocked")
            }
    }
}

struct IAPViewApp_Previews: PreviewProvider {
    static var previews: some View {
        IAPViewTest()
    }
}
question from:https://stackoverflow.com/questions/65869788/inapp-purchase-manage-product-type-coming-from-plist-inside-package-library

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...