Правильный подход к покупке iPhone-in-App
У меня есть это новое приложение, которое я создаю, которое будет использовать потребительские покупки в приложении.
Мой вопрос: как это работает? Я имею в виду, представьте, что пользователь покупает расходные материалы. Итак, после завершения продажи я установил флаг в базе данных приложений, разрешающий использование этого объекта. Я где-то читал, что я должен предоставить пользователю кнопку для восстановления старых транзакций, если пользователь по какой-то причине теряет свое устройство и должен восстановить все.
Представьте, что пользователь уже использовал эту покупку, и после этого он восстанавливает старые покупки в приложении. Что происходит тогда? Будет ли у пользователя одинаковые ресурсы снова, поэтому он может использовать второй раз без оплаты? Как это работает и как я должен подходить к этому?
спасибо
Ответы
Ответ 1
Я хотел поделиться некоторым неортодоксальным решением, которое я нашел для этой проблемы, у которого есть ОГРОМНОЕ преимущество, не требующее сервера. Этот метод позволяет пользователям восстанавливать свои расходные элементы, если приложение удаляется и переустанавливается, но не позволяет им перемещать элементы на новое устройство (если все данные их приложений не скопированы).
Данные, хранящиеся в цепочке ключей, сохраняются, когда приложение удаляется и переустанавливается. Брелок предназначен для хранения имен пользователей и паролей, но вы также можете хранить информацию о потребляемых им покупках. Я использовал класс KeychainItemWrapper, доступный здесь: https://developer.apple.com/library/content/samplecode/GenericKeychain/Introduction/Intro.html
Вот пример кода, в котором я храню и получаю количество платных подсказок, оставшихся у пользователя:
//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];
Примечания:
-
ключ (id) kSecValueData не может быть произвольной строкой, существует набор констант, которые вы можете использовать в качестве ключа.
-
Вам нужно будет добавить инфраструктуру безопасности
Ответ 2
StoreKit предоставляет только функции восстановления для неиспользуемых элементов (и, в некоторых случаях, для подписки). Поэтому для расходных материалов восстановление с помощью restoreCompletedTransactions
не приведет к транзакциям в вашем случае. Любая обработка восстановления информации о потребляемых продуктах должна выполняться внутри вашего приложения и/или сервера.
Для справки о природе различных продуктов проверьте Руководство по программированию покупки приложений: проектирование продуктов ваших приложений. Продукты Расходуемые, которые необходимо приобретать каждый раз, Не потребляемые продукты, приобретенные только один раз, и предоставляются всем устройствам, связанным с этой учетной записью iTunes пользователей, Авто-возобновляемые и Не обновлять Подписки
Ответ 3
Для людей, которые ищут способ хранения расходных материалов локально в iOS, посмотрите на PDKeychainBindingsController (https://github.com/carlbrown/PDKeychainBindingsController).
Он работает как NSUserDefaults и может использоваться для хранения купленного счетчика расходных материалов в цепочке ключей iDevice (элементы, хранящиеся в цепочке ключей, не удаляются при удалении приложения).
Используйте код, как показано ниже, чтобы сохранить и получить значение из связки ключей:
- (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"];
}