42

以前にアプリ内購入を実装したことがないので、MKStoreKit ラッパーを使用して実装しました。MKStoreKit はすべてのレシートを UserDefaults .plist に BOOL として保持するため、海賊版がアプリ内購入を「ひびの入った」状態で配布するのは非常に簡単です。最初の購入が行われると、バンドルを配布し、.plist を再作成して IAP のロック解除を有効にすることができます。

MKStoreKit を拡張して、iOS キーチェーンに In App Purchase 検証データを作成したいと思います。有料ユーザーにとってこれが失敗する、信頼性が低い、またはこれを行うことが全体的に悪い考えであるその他の理由はありますか? 著作権侵害が避けられないことは理解しており、有料ユーザーを疎外したくはありませんが、UserDefaults .plist はバイパスするのに簡単すぎると感じています。

私のシナリオでは、購入時に単純な文字列がキーチェーンに入れられます。そうすれば、バイナリが配布されても、ロック解除可能なものはまだ有効になっていません。確かに、回避策を考え出すことは可能ですが、もう少し努力が必要で、TRUE/FALSE フラグを見つけて、常に正しい値を返す方法を知る必要があります。難読化することで、追跡を少し難しくすることさえできました。

あなたのすべての洞察に感謝し、義務的な必然的な著作権侵害、それに対処する返信を避けた回答に感謝します. 私は、このソリューションの技術的な実行可能性にもっと興味があります。

4

1 に答える 1

54

私たちのアプリでまさにそれを行い、それはうまく機能します.フルバージョンにアップグレードできる無料のアプリであり、キーチェーンにアップグレードインジケーターを保存します. アップグレード インジケータは選択した任意の文字列ですが、キーチェーンではパスワードとして扱われます。つまり、kSecValueData の値はキーチェーンで暗号化されます。このアプローチの良い点は、ユーザーがアプリを削除してから再インストールした場合、キーチェーン アイテムがアプリとは別に保存されるため、魔法のようにすべてが再び有効になることです。また、ユーザーの既定値に何かを保存するための追加作業はほとんどないため、それだけの価値があると判断しました。

セキュリティ アイテムを作成する方法は次のとおりです。

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);

セキュリティ項目を見つけてその値を確認する方法は次のとおりです。

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
    }
}

upgradeItemData が nil の場合、キーは存在しないため、アップグレードが存在しないか、アップグレードされていないことを意味する値が設定されていると想定できます。

アップデート

kSecReturnData を追加しました (指摘してくれた @Luis に感謝します)

GitHub のコード (ARC バリアント)

于 2011-02-18T21:55:48.577 に答える