SK2 - why so overly complicated?

SK2 sounds so easy. I understand they're many different use cases, but why is it made to be so overly complicated?

For instance:

  1. When getting currentEntitlements, why does it return every transaction for this item, even if it is expired? Shouldn't currentEntitlements just return me one transaction which is valid, not expired? If I want all of the transactions for X Product, I should be able to query Transactions.all, or how about Transactions(for: Product)?

  2. Why does Transaction.all not conform to Sequence? Meaning, why cant I just iterate through all Transactions like: for transaction in await Transacion.all { //do stuff }, yet for await transaction in Transaction.all { //do dtuff } does work

  3. It seems so convoluted to get a status of an auto-renewing subscription. Why cant it just be: get Product X, for Product X, get the RenewalInfo, then what is the autoRenewStatus of this product? sounds simple, right? yet in reality, its much more complicated, with verifying responses and guard case and plenty of other extra nonsense that just makes the code grow for no reason. What would be nice here is: 

  • get product from app store: let product = await Product(for: "com.sample.product") (Now, I know that this product is an auto-renewable subscription item, so I want to know what the auto-renew status for it is, so I can display to the user their status)

  • get autoRenew status from this Product: let willAutoRenew = product.subscription.isAutoRenew

Now, the user may not own this product, so even better would be to be able to get this info from the currentEntitlement, latestTransaction: 

if let mySubEntitlement = try await Transaction.currentEntitlement(for: "this.productID") {
//user must have an entitlement to this item

//ensure that the response is verified:
guard case .verified(let verified) = mySubEntitlement else { return }

//give me the the RenewalInfo details of this verified response:
let myRenewalnfo = verified.subscription.renewalInfo

//print out the willAutoRenew details:
print("Will this auto-renew?: \(myRenewalInfo.willAutoRenew)")

In reality, it is really not this simple, but there is no reason that it should not be. Hoping for better in upcoming releases. 

Also, why is it so difficult to get access to the JSON data packed into the product and transaction data? I can see it all there when I print it out to the output, but I can't for instance say something like: print(product.payload.thisField)

I look forward to adding so many of the new iOS15 features to my app to assist my customers in managing their purchases, but implementation is just much more complicated than it really needs to be. I hope in the coming betas and final release, some of this will be made much more straight forward.

Replies

to further get my point across, and because I know Apple Engineers read this, something like this would be really ideal, it obviously does not work, but it should be this simple...

I have faith in you Apple!



struct MyMainView: View {

    

    @State var products: [Product] = []

    

    var body = some View {

        List {

            ForEach(products) { product in

                ThisView(product: Product)

            }

        }

    }

        .task {

            //fill up my products with my current entitlements:

            products = await Transaction.currentEntitlements

        }

}







struct ThisView: View {

    

    @State var product: Product

    @State private var productName = ""

    @State private var productStatus = ""

    @State private var expOrRenewDate = ""

    @State private var isAutoRenew = "Disabled"

    

    var body: some View {

        VStack {

            Text("You are subscribed to: \(productName)")

            Text("Current Status: \(productStatus)")

            Text("Your \(expOrRenewDate)")

            Text("Your auto-renew preference is: \(isAutoRenew)")

        }

        .task {

            

            let billingDate = product.expirationDate

            

            productName = product.displayName

            productStatus = product.subscription?.status.state

            if (product.SubscriptionInfo.RenewalInfo.autoRenewPreference) {

                isAutoRenew = "Active"

                expOrRenewDate = "next billing date is \(billingDate)"

            } else {

                isAutoRenew = "Disabled"

                expOrRenewDate = "subscription will expire on \(billingDate)"

            }

            

            

            

        }

    }

}