iPhone - in-App purchase consumable correct approach
I have this new app I am creating that will use consumable in-app purchases.
My question is this: how does that work? I mean, imagine the user buys a consumable stuff. So, after finalizing the sell I set a flag on the app's database authorizing the use of that object. I read somewhere that I have to provide the user with a button to restore old transactions in case of the user for some reason loses his device and has to restore everything.
Imagine the user has already used that purchase and after that he restores the old in-app purchases. What happens then? Will the user have the same resources again, so he can use a second time without paying? How it works and how should I a开发者_如何学编程pproach that?
thanks
I wanted to share a somewhat unorthodox solution I found to this problem that has the HUGE advantage of not requiring a server. This method allows users to restore their consumable items if the app is deleted and reinstalled, but does not allow them to move the items to a new device (unless all their app data is copied over).
Data stored in the keychain persists when an app is deleted and reinstalled. The keychain is intended for storing usernames and passwords, but you can also store information about consumable purchases in there. I used the KeychainItemWrapper class, available here: https://developer.apple.com/library/content/samplecode/GenericKeychain/Introduction/Intro.html
Here is some sample code where I store and retrieve the number of paid hints that a user has remaining:
//Storing the consumable hint item count
int hintsLeft = 100;
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Hints" accessGroup:nil];
NSString *hintsString = [NSString stringWithFormat:@"%i",hintsLeft];
[wrapper setObject:hintsString forKey:(id)kSecValueData];
[wrapper release];
//Retrieving it
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Hints" accessGroup:nil];
NSString *numHints = [wrapper objectForKey:(id)kSecValueData];
[wrapper release];
int retrievedHints = [numHints intValue];
Notes:
the key (id)kSecValueData can't be an arbitrary string, there is a set list of constants that you can use as the key.
You will need to add the security framework
StoreKit only provides recovery functionality for non-consumable items (and to some extend for subscriptions). So for consumable products, recovering using restoreCompletedTransactions
will not deliver any transactions in your case. Any handling of restoring information about consumable products must be done within your app and/or server.
For reference of the various products' natures check the In App Purchase Programming Guide:Designing Your App’s Products. There are Consumable products which must be purchased each time, Non-consumable products purchased only once and provided to all devices associated with that user’s iTunes account, Auto-Renewable subscriptions and Non-Renewing Subscriptions
For people who come hare searching for the way to store consumable items locally in iOS, have a look at PDKeychainBindingsController (https://github.com/carlbrown/PDKeychainBindingsController).
It works like NSUserDefaults and can be used to store the purchased consumable item count in iDevice's keychain (the items stored in keychain do not get removed while deleting the app.).
Use the code something like below to store and retrieve the value from keychain:
- (NSUInteger)hintCount {
PDKeychainBindings *wrapper=[PDKeychainBindings sharedKeychainBindings];
NSString *valueString = [wrapper objectForKey:@"hintCount"];
int value = [valueString intValue];
return value;
}
- (void)setHintCount:(NSUInteger)starCount {
PDKeychainBindings *wrapper=[PDKeychainBindings sharedKeychainBindings];
NSString *valueString = [NSString stringWithFormat:@"%i",starCount];
[wrapper setObject:valueString forKey:@"hintCount"];
}
精彩评论