How to pass messages from one class to another through NSNotification - iphone

Ha-ii ,am doing an in-app purchase in my application,i need to disable a button when the in-app content purchase is success,so i put the NSuserdefault to my code to identify weather its success or not,but NSUserDefault works only when i refresh the page,i didnt get the button enabled when the content success message is come ,i get enabled when i go back to another page and came back,my need is to pass instance message to the viewcontroller through notification.my code is
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for(SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
// Item is still in the process of being purchased
break;
case SKPaymentTransactionStatePurchased:
// Item was successfully purchased!
// --- UNLOCK FEATURE OR DOWNLOAD CONTENT HERE ---
// The purchased item ID is accessible via
// transaction.payment.productIdentifier
// After customer has successfully received purchased content,
// remove the finished transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Transsucess"];
break;
case SKPaymentTransactionStateRestored:
// Verified that user has already paid for this item.
// Ideal for restoring item across all devices of this customer.
// --- UNLOCK FEATURE OR DOWNLOAD CONTENT HERE ---
// The purchased item ID is accessible via
// transaction.payment.productIdentifier
// After customer has restored purchased content on this device,
// remove the finished transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
break;
case SKPaymentTransactionStateFailed:
// Purchase was either cancelled by user or an error occurred.
if (transaction.error.code != SKErrorPaymentCancelled) {
// A transaction error occurred, so notify user.
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Transsucess"];
}
// Finished transactions should be removed from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction:
transaction];
break;
}
}
}
in my anothervierwcontroller i want to pass the Notification value insted of Nsuserdefault value.
How to do this.please help me.

in your first view vieDidLoad add the line ..
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ContentPurchased) name:#"Purchased" object:nil];
( do remove the observer in dealloc)
then when you have successful purchase in your question code..
Post the notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"Purchased" object:nil userInfo:nil];
You can pass an object..but i believe you should store the purchase transaction detail in NSUserdefautls..since it will be needed in the next runs of the app..
When you post the notification ContentPurchased method is called in first view ( you have to add that in the view controller)

Related

completeTransaction:(SKPaymentTransaction *)transaction runs multiple times

I am using below typed code to handle in app purchases in my app. In completeTransaction I unlock premium content by calling provideContentForProductIdentifier. Mostly it runs only one time but, some times it runs multiple times.
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
NSLog(#"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[self validateReceiptForTransaction:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
Please help!
I've had this same problem. In my case I forgot to removeTransactionObserver. So it still contained the earlier product id. Add this to remove the purchased product id after finishing the transaction.
- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
{
NSLog(#"Purchase removedTransactions");
// Release the transaction observer since transaction is finished/removed.
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

Restoring subscribed purchase for Auto-Renewable Subscriptions

When I purchase a previously purchased "Auto-Renewable Subscriptions" in my app, it said
You're currently subscribed to this...
When I clicked the OK, in the delegate of the payment queue..
- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction * transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction]; // Why this is called?
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
}
}
The transaction.transactionState returned is SKPaymentTransactionStateFailed instead of SKPaymentTransactionStateRestored, is it normal?
So how do I handle this correctly?
I have the same issue and I don't think there's any way to distinguish this event from other errors (it returns error code SKErrorPaymentCancelled). I think the only way you can handle it is by having a "Restore Purchases" button, and call [[SKPaymentQueue defaultQueue] restoreCompletedTransactions] when the user presses it.
Actually, you can't determine if the user is already subscribed. You should have Subscribe button that new users use to subscribe, and Restore button for already subscribed users.
And when you get SKPaymentTransactionStateFailed you can show a message that suggests to use Restore button in case the user is already subscribed.

Turning off an in-app purchase?

We currently have a live app that features episodic content in the App store.
We're re-working our pricing, and instead of offering individual episodes for purchase, we want to have it as simply an entire pack of episodes.
My question is this: If I set my old identifiers to NOT cleared for sale, would a user who previously purchased that content still be allowed access to it? (Meaning if I query whether they've purchased it, will it return true)
I'm new to the in-app purchase side of apps, and I'm not entirely sure how that works.
Also, if I delete the identifier from iTunesConnect, what happens? Should this even be done?
Thanks in advance for any insight
When using [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];, Apple will return all completed transactions in a SKPaymentQueue which is a collection of transactions. The transaction will contain the the payment object. The payment object will contain the productIdentifier. This info is available despite your deletion. Thus you may honor past purchases that are no longer for purchase.
Here is some example code:
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
#pragma mark SKPayment Observer Delegate methods
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(#"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions)
{
NSLog(#"tran for product: %# of state: %i", [[transaction payment] productIdentifier], [transaction transactionState]);
switch ([transaction transactionState])
{
case SKPaymentTransactionStateRestored:
NSLog(#"found restored transaction: %# productIdentifier: %#", transaction.transactionIdentifier, transaction.payment.productIdentifier);
[self yourRestoreProcessSelector:transaction];
break;
default:
break;
}
}
}

MKStoreKit how to change the purchase confirm dialog title

I am using in-app purchase to buy a set audiobooks.
I am using MKStoreKit wrapper for in-app purchase. my products are of non consumable type.therefore bought only once.
However whenever i press the buy button the message "Do you want to buy one {audiobook name} for {price}" .
how to change this message?
if any one has used MKStoreKit, how to know if the purchase is completed.(I need to change the title of button only if the purchase is complete).
I'm not really sure, but I think you can't customize this alert, it's specific to Apple.
And about how to know if the purchase is completed, I suggest you to take a look at this website, and specially at this method :
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
break;
default:
break;
}
}
}
You also have to call this before ( again, take a look on the website above ) :
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
When the transaction.transactionState is SKPaymentTransactionStatePurchased, this means that the transaction is completed.
Hope it helps

differentiate between different in app purchases iphone paymentQueue

I have just managed to integrate in app purchases into my ios application however i have know run into a problem that i can't really ask google about.
I have an app with 2 products to purchase but once payment is complete i need to differentiate between the 2 products purchased to then fire another method.
please see the paymentQueue method below:
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for(SKPaymentTransaction *transaction in transactions)
{
switch(transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
break;
case SKPaymentTransactionStatePurchased:
//do crediting here
NSLog(#"transactionid = %#",transaction);
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
if(transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(#"Error Encountered");
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
When the SKPaymentStatePurchased is hit it needs to find the initial product that was purchased to then fire the method for the product to credit an account set up on a remote server.
I hope someone can help!
Thanks in advance :)
You can get that from the transaction itself
transaction.payment.productIdentifier
This will give you the product identifier that the user have purchased