我正在使用 ios 进行应用程序购买,我几乎没有疑问,这些疑问将有助于像我这样的新手,所以了解应用程序购买。
1)如果用户“如果他之前删除了我的应用程序,则将我的应用程序安装到新设备或同一设备中”,我的应用程序出现问题,当时用户尝试购买已购买的项目,我的代码restoreTransaction
在 switch case 中没有调用updatedTransactions
我收到消息,you ve already purchased this tap okay to downlaod it FREE Enviornment sandbox
它调用了这个SKPaymentTransactionStatePurchased
案例,但它没有调用SKPaymentTransactionStateRestored
我的案例中的问题..
所以我已经实现了单独的恢复按钮来恢复用户已经带来的所有视频项目,所以只需要知道它会在苹果商店拒绝我的应用程序吗?
2) 购买商品时只询问一次密码,之后不再询问购买密码。它直接显示带有确认按钮的对话框,但我的项目经理说它应该为每次购买商品询问密码。
每次我尝试恢复购买时它都会要求输入密码..奇怪。
3)目前我正在沙盒中测试,当我尝试使用真实的苹果 ID 购买时,它显示购买失败(我必须使用测试帐户来测试购买,如苹果文档所述)但我的项目经理说如果它应该要求新的测试用户名您正在沙箱中进行测试(如文档所述,您必须手动退出设置,但我的项目经理希望它应该自动执行),
所以只需要问是否可以通过编码退出并显示标志框(我知道这是不可能的,但我问的信息)
4)目前我的应用程序在沙盒环境中工作,但我需要为我的应用程序更改一些实际购买的东西吗?..或者当苹果验证我的应用程序并对其进行签名并在应用商店中可用时,苹果会自动将沙盒更改为实际购买?
5)我正在我自己的服务器上验证交易,所以如果我在沙箱环境中,我将发送沙箱 1,否则我必须发送 0(目前我将沙箱值硬编码为 1)所以有什么方法可以检测环境是沙箱还是真实的?
这是我的购买代码和恢复按钮代码任何帮助表示赞赏
购买代码
- (IBAction)PaymentButton:(id)sender {
loadingHUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
loadingHUD.labelText = NSLocalizedString(@"Loading", nil);
[loadingHUD show:YES];
[self startPurchase];// call the restore Purchase method
//[loadingHUD showWhileExecuting:@selector(startPurchase) onTarget:self withObject:nil animated:YES];// call the restore Purchase method
}
- (void)startPurchase {
if([SKPaymentQueue canMakePayments]) {
NSLog(@"IN-APP:can make payments");
[self requestProductData];
}
else {
NSLog(@"IN-APP:can't make payments");
loadingHUD.hidden=YES;
}
}
- (void)requestProductData {
NSLog(@"IN-APP:requestProductData");
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject:myIdentifier]];
request.delegate = self;
[request start];
NSLog(@"IN-APP:requestProductData END");
NSLog(@"Productdata is %@",myIdentifier);
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
@try {
SKProduct *product = [response.products objectAtIndex:0];
SKPayment *newPayment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:newPayment];
NSLog(@"IN-APP:productsRequest END");
}
@catch (NSException *exception) {
// Failed to purchase Hide the progress bar and Display Error Dialog
loadingHUD.hidden=YES;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Error in Product id can not purchase" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
}
}
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"Transaction Completed");
// Finally, remove the transaction from the payment queue.
[self verifyReceipt:transaction]; // Call the verifyReceipt method to send transaction.bytes
NSLog(@"Purchase Transaction finish");
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
NSLog(@"Transaction Restored %@",transaction.originalTransaction.payment.productIdentifier);
// You can create a method to record the transaction.
// [self recordTransaction: transaction];
loadingHUD.hidden=YES;
// You should make the update to your app based on what was purchased and inform user.
// [self provideContent: transaction.payment.productIdentifier];
// Finally, remove the transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
loadingHUD.hidden=YES;// hide loadingHUD
if (transaction.error.code != SKErrorPaymentCancelled)
{
// Display an error here.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Purchase Unsuccessful"
message:@"Your purchase failed. Please try again."
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
为了恢复它简单
-(void)startRestore
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
if ([queue.transactions count] == 0)
{
HUD.hidden=YES;
UIAlertView *restorealert = [[UIAlertView alloc]
initWithTitle:@"Restore"
message:@"There is no products purchased by you"
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[restorealert show];
}
else
{
NSLog(@"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions)
{
NSString *temp = transaction.payment.productIdentifier;
NSString *testID = [temp stringByReplacingOccurrencesOfString:projectIdString withString:@""];
NSString *productID = [testID stringByReplacingOccurrencesOfString:@"." withString:@""]; // remove Dot
NSLog(@"cutted string is %@",productID);
[purchasedItemIDs addObject:productID];
NSLog(@"** Purchased item is %@",purchasedItemIDs);
}
HUD.hidden=YES;
HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.labelText = NSLocalizedString(@"Restoring", nil);
[HUD showWhileExecuting:@selector(restorePurchasedItem) onTarget:self withObject:nil animated:YES];// call the restore Purchase method
}
}