Problemas para obter a versão original do aplicativo que o usuário instalou (validação de recibo)?
Eu tenho um aplicativo que atualizei recentemente para trabalhar nas compras de aplicativos. A versão anterior (paga mas sem compras de aplicativos) era 1.0 e a versão atual é 1.1.
Como a compra no aplicativo basicamente desbloqueia todos os recursos (incluídos na versão paga 1.0), eu queria que os usuários que originalmente haviam baixado a versão 1.0 fossem atualizados se pressionassem o botão Restaurar compras.
Para fazer isso, primeiro tento restaurar as compras e se a resposta para:
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
Se isso me fornecer uma fila com uma contagem de transações igual a 0, verifico o recibo para ver se a versão original instalada foi 1.0.
O código para obter o recibo é conforme a documentação da Apple
- (void)tryRestoreFromOriginalPurchase
{
// Load the receipt from the app bundle
NSError *error;
NSData *receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
if (receipt == nil) {
[self restoreFromOriginalVersionWithReceipt:nil];
return;
}
// Create the JSON object that describes the request
NSDictionary *requestContents = @{@"receipt-data": [receipt base64EncodedStringWithOptions:0]};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:&error];
if (!requestData) {
[self restoreFromOriginalVersionWithReceipt:nil];
return;
}
// Create a POST request with the receipt data
NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];
// Make a connection to the iTunes Store on a background queue
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) {
NSError *error;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (jsonResponse) [self restoreFromOriginalVersionWithReceipt:jsonResponse];
else [self restoreFromOriginalVersionWithReceipt:nil];
} else {
[self restoreFromOriginalVersionWithReceipt:nil];
}
}];
}
Isso então chama o seguinte método:
- (void)restoreFromOriginalVersionWithReceipt:(NSDictionary *)receipt
{
if (receipt == nil) {
// CALL METHOD TO HANDLE FAILED RESTORE
} else {
NSInteger status = [[receipt valueForKey:@"status"] integerValue];
if (status == 0) {
NSString *originalApplicationVersion = [[receipt valueForKey:@"receipt"] valueForKey:@"original_application_version"];
if (originalApplicationVersion != nil && [originalApplicationVersion isEqualToString:@"1.0"]) {
// CALL METHOD TO HANDLE SUCCESSFUL RESTORE
} else {
// CALL METHOD TO HANDLE FAILED RESTORE
}
} else {
// CALL METHOD TO HANDLE FAILED RESTORE
}
}
}
Agora isso não funciona. Quando alguém instala a versão 1.1 e toca em restaurar compras, ele restaura com êxito quando não deveria.
Acabei de perceber que no meu Info.plist, meu CFBundleShortVersionString é 1.1, mas meu CFBundleVersion é 1.0.
Essa pode ser uma pergunta realmente tola, mas o recibo está fornecendo uma versão_applicação_ original de 1.0 (devido ao CFBundleVersion errado), mesmo que a atualização tenha a versão 1.1?
Portanto, se eu lançar uma nova atualização com esta correção corrigida para dizer a versão 1.2 (para CFBundleShortVersionString e CFBundleVersion), o problema será resolvido?
- ATUALIZAÇÃO -
Então, acabei de enviar uma nova versão para a loja de aplicativos com o CGBundleVersion e o CFBundleShortVersionString iguais a 1,2. No entanto, ainda estou enfrentando o mesmo problema - os usuários que estão baixando a versão 1.2 pela primeira vez e tocando em compras de restauração estão sendo atualizados gratuitamente (devido à verificação de recebimento descrita acima). Parece que a versão original do aplicativo está sempre chegando à 1.0.
Nota: estou baixando o aplicativo em uma nova conta do iTunes que não foi baixada anteriormente.
Aqui está o recibo que tenho se eu instalar a partir da loja de aplicativos e tentar obter o recibo através do Xcode
2014-08-27 08:46:42.858 AppName[4138:1803] {
environment = Production;
receipt = {
"adam_id" = AppID;
"application_version" = "1.0";
"bundle_id" = "com.CompanyName.AppName";
"download_id" = 94004873536255;
"in_app" = (
);
"original_application_version" = "1.0";
"original_purchase_date" = "2014-08-26 22:30:49 Etc/GMT";
"original_purchase_date_ms" = 1409092249000;
"original_purchase_date_pst" = "2014-08-26 15:30:49 America/Los_Angeles";
"receipt_type" = Production;
"request_date" = "2014-08-26 22:46:42 Etc/GMT";
"request_date_ms" = 1409093202544;
"request_date_pst" = "2014-08-26 15:46:42 America/Los_Angeles";
};
status = 0;
}
Alguma ideia?