Pergunta

Eu nunca implementei o In App Purchase antes, então usei o wrapper MKStoreKit e tenho uma implementação funcional.O MKStoreKit mantém todos os recibos no .plist UserDefaults como um BOOL, portanto, é muito simples para os piratas distribuirem as compras no aplicativo em um estado "crackeado".Assim que a primeira compra for feita, o pacote pode ser distribuído e o .plist pode ser recriado para permitir desbloqueios IAP.

Gostaria de estender o MKStoreKit para criar os dados de validação de compra no aplicativo nas chaves do iOS.Existe alguma desvantagem ou possível motivo para que isso falhe para usuários pagantes, não seja confiável ou qualquer outro motivo pelo qual seria uma má ideia fazer isso?Entendo que a pirataria é inevitável e definitivamente não quero alienar usuários pagantes, mas sinto que o .plist UserDefaults é uma maneira muito fácil de contornar.

No meu cenário, um barbante simples seria colocado no chaveiro no momento da compra.Dessa forma, se o binário for distribuído, os desbloqueáveis ​​ainda não estarão habilitados.Claro, seria possível encontrar uma solução alternativa, mas seria necessário um pouco mais de esforço e saber como encontrar o sinalizador TRUE/FALSE e fazer com que ele sempre retornasse o valor correto.Através da ofuscação, eu poderia até tornar um pouco mais difícil rastrear isso.

Obrigado por todos os seus insights e agradeço as respostas que evitam as respostas obrigatórias de pirataria inevitável e de lidar com isso.Estou mais interessado nas viabilidades técnicas desta solução.

Foi útil?

Solução

Fazemos exatamente isso em nossos aplicativos e funciona muito bem. É um aplicativo gratuito que você pode atualizar para uma versão completa e armazenamos o indicador de atualização no chaveiro.O indicador de atualização é uma string arbitrária que você escolhe, mas para fins de chaveiro ele é tratado como uma senha, ou seja,o valor de kSecValueData é criptografado nas chaves.Um bom bônus sobre essa abordagem é que se o usuário excluir o aplicativo e depois reinstalá-lo, tudo será reativado como mágica porque os itens das chaves são armazenados separadamente do aplicativo.E é tão pouco trabalho adicional armazenar algo nos padrões do usuário que decidimos que valeu a pena.

Veja como criar o item de segurança:

NSMutableDictionary* dict = [NSMutableDictionary dictionary];

[dict setObject: (id) kSecClassGenericPassword  forKey: (id) kSecClass];
[dict setObject: kYourUpgradeStateKey           forKey: (id) kSecAttrService];
[dict setObject: kYourUpgradeStateValue         forKey: (id) kSecValueData];

SecItemAdd ((CFDictionaryRef) dict, NULL);

Veja como encontrar o item de segurança para verificar seu valor:

NSMutableDictionary* query = [NSMutableDictionary dictionary];

[query setObject: (id) kSecClassGenericPassword forKey: (id) kSecClass];
[query setObject: kYourUpgradeStateKey          forKey: (id) kSecAttrService];
[query setObject: (id) kCFBooleanTrue           forKey: (id) kSecReturnData];

NSData* upgradeItemData = nil;
SecItemCopyMatching ( (CFDictionaryRef) query, (CFTypeRef*) &upgradeItemData );
if ( !upgradeItemData )
{
    // Disable feature
}
else
{
    NSString* s = [[[NSString alloc] 
                        initWithData: upgradeItemData 
                            encoding: NSUTF8StringEncoding] autorelease];

    if ( [s isEqualToString: kYourUpgradeStateValue] )
    {
        // Enable feature
    }
}

Se upgradeItemData for nulo, então a chave não existe, então você pode assumir que a atualização não existe ou, o que fazemos, é colocada em um valor que significa que não foi atualizada.

Atualizar

Adicionado kSecReturnData (Obrigado @Luis por apontar isso)

Código no GitHub (variante ARC)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top