xcode 您的应用程序 ID 的应用程序内购买权利
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25357634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In-app purchase entitlement to your app id
提问by PatrikD
i am really confused, I dont know how can add In-app purchase to my existing app. When in 'Capabilities' i choose on In-app purchase it show me only error add the in app purchase entitlement to your app id
. I added app id in dev center and in-app purchase in itunesconnect. My Bundle ID is sk.freetech.zatracenacestina.intro
and in-app purchase i set up to sk.freetech.zatracenacestina.intro.package
but I dont know where can I fill it?
我真的很困惑,我不知道如何将应用内购买添加到我现有的应用中。当我在“功能”中选择应用内购买时,它只显示错误add the in app purchase entitlement to your app id
。我在开发中心添加了应用程序 ID,在 itunesconnect 中添加了应用内购买。我的 Bundle ID 是sk.freetech.zatracenacestina.intro
我设置的应用内购买,sk.freetech.zatracenacestina.intro.package
但我不知道在哪里可以填写?
Thank you
谢谢
回答by BHASKAR
you can follow these tutorial 1. http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial2. http://www.tutorialspoint.com/ios/ios_in_app_purchase.htm3. http://code4app.net/ios/In-App-Purchase/4fc85be56803fa4a49000000
您可以按照这些教程 1. http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial2. http://www.tutorialspoint.com/ios/ ios_in_app_purchase.htm3. http://code4app.net/ios/In-App-Purchase/4fc85be56803fa4a49000000
Create a class name it IAPHelper subclass NSObject
创建一个类名 IAPHelper 子类 NSObject
#import <StoreKit/StoreKit.h>
UIKIT_EXTERN NSString *const IAPHelperProductPurchasedNotification;
typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products);
@protocol inAppPurchaseDelegate <NSObject>
@optional
-(void)transactionSucsess:(NSString *)transactionId;
-(void)transactionOnRestore:(NSString *)transactionId;
-(void)transactionOnFail;
@end
@interface IAPHelper : NSObject
@property(nonatomic,readwrite)id<inAppPurchaseDelegate> delegate;
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers;
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler;
- (void)buyProduct:(SKProduct *)product;
- (BOOL)productPurchased:(NSString *)productIdentifier;
- (void)restoreCompletedTransactions;
@end
in IAPHelper.m
在 IAPHelper.m
import "IAPHelper.h"
导入“IAPHelper.h”
#import <StoreKit/StoreKit.h>
NSString *const IAPHelperProductPurchasedNotification = @"IAPHelperProductPurchasedNotification";
@interface IAPHelper () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
@end
@implementation IAPHelper {
SKProductsRequest * _productsRequest;
RequestProductsCompletionHandler _completionHandler;
NSSet * _productIdentifiers;
NSMutableSet * _purchasedProductIdentifiers;
}
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {
if ((self = [super init])) {
// Store product identifiers
_productIdentifiers = productIdentifiers;
// Check for previously purchased products
_purchasedProductIdentifiers = [NSMutableSet set];
for (NSString * productIdentifier in _productIdentifiers) {
BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];
if (productPurchased) {
[_purchasedProductIdentifiers addObject:productIdentifier];
NSLog(@"Previously purchased: %@", productIdentifier);
} else {
NSLog(@"Not purchased: %@", productIdentifier);
}
}
// Add self as transaction observer
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
return self;
}
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
_completionHandler = [completionHandler copy];
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate = self;
[_productsRequest start];
}
- (BOOL)productPurchased:(NSString *)productIdentifier {
return [_purchasedProductIdentifiers containsObject:productIdentifier];
}
- (void)buyProduct:(SKProduct *)product {
NSLog(@"Buying %@...", product.productIdentifier);
SKPayment * payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(@"Loaded list of products...");
_productsRequest = nil;
NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
}
_completionHandler(YES, skProducts);
_completionHandler = nil;
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
NSLog(@"Failed to load list of products.");
_productsRequest = nil;
_completionHandler(NO, nil);
_completionHandler = nil;
}
#pragma mark SKPaymentTransactionOBserver
- (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(@"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
if(_delegate)
[_delegate transactionSucsess:transaction.payment.productIdentifier];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"restoreTransaction...");
[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
if(_delegate)
[_delegate transactionOnRestore:transaction.payment.productIdentifier];
}
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"failedTransaction...");
if (transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
if(_delegate)
[_delegate transactionOnFail];
}
- (void)provideContentForProductIdentifier:(NSString *)productIdentifier {
[_purchasedProductIdentifiers addObject:productIdentifier];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)restoreCompletedTransactions {
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
@end
Create a class RageIAPHelper subclass of IAPHelper
创建一个类 RageIAPHelper 的 IAPHelper 子类
#import "IAPHelper.h"
@interface RageIAPHelper : IAPHelper
+ (RageIAPHelper *)sharedInstance;
@end
In RageIAPHelper.m
在 RageIAPHelper.m
#import "RageIAPHelper.h"
@implementation RageIAPHelper
+ (RageIAPHelper *)sharedInstance {
static dispatch_once_t once;
static RageIAPHelper * sharedInstance;
dispatch_once(&once, ^{
NSSet * productIdentifiers = [NSSet setWithObjects:
@"your identifier",@"your identifier",
nil];
sharedInstance = [[self alloc] initWithProductIdentifiers:productIdentifiers];
});
return sharedInstance;
}
@end
[[RageIAPHelper sharedInstance] setDelegate:(id)self];
[[RageIAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) {
if (success) {
totalProduct_Arr =products;
for (SKProduct *s in totalProduct_Arr) {
NSLog(@"product Identifier %@",[s productIdentifier]);
if ([[s productIdentifier]isEqualToString:FULLVERSION]) {
[self.btnFullVersion setEnabled:YES];
}
else if ([[s productIdentifier]isEqualToString:REMOVE_ADS]) {
[self.btnRemoveAd setEnabled:YES];
}
}
}
else{
UIAlertView *alertFail=[[UIAlertView alloc] initWithTitle:@"Product Not Found" message:@"Fails to load product.." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alertFail show];
}
}];
and to buy product
并购买产品
[[RageIAPHelper sharedInstance] buyProduct:product];
回答by Monikanta
This link will help you. Follow this linkstep by step.
You can use this code also.
您也可以使用此代码。
- Add the StoreKit.framework, Accounts.framework, MobileCoreServices.framework, QuartzCore.framework, CFNetwork.framework, SystemConfiguration.framework.
- In .h file import 'StoreKit.h' #import
- Add these delegate on .h class
- Declare a property for SKProductsRequest @property(nonatomic,strong)SKProductsRequest *request;
- 添加 StoreKit.framework、Accounts.framework、MobileCoreServices.framework、QuartzCore.framework、CFNetwork.framework、SystemConfiguration.framework。
- 在 .h 文件中导入 'StoreKit.h' #import
- 在 .h 类上添加这些委托
- 为 SKProductsRequest @property(nonatomic,strong)SKProductsRequest *request 声明一个属性;
Now In .m class copy this code for in-app purchase
现在在 .m 类中复制此代码以进行应用内购买
-(void)startpurching
{
NSArray *arrPackageproductIdentifier=[NSArray arrayWithObjects:@"Your Product Id",nil];
NSString *strPrductIdentifier=[arrPackageproductIdentifier objectAtIndex:0];
request= [[SKProductsRequest alloc]
initWithProductIdentifiers: [NSSet setWithObject:strPrductIdentifier]];
NSLog(@"%@",request);
request.delegate = self;
[request start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
NSArray *myProduct = response.products;
if ([myProduct count]==0) {
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:nil message:@"Cannot connect !! Please check your internet connection." delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];
[alt show];
} else {
NSLog(@"pro...%@",[[myProduct objectAtIndex:0] productIdentifier]);
SKPayment *newPayment = [SKPayment paymentWithProduct:[myProduct objectAtIndex:0]];
[[SKPaymentQueue defaultQueue] addPayment:newPayment];
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
NSLog(@"Transaction....%@",transactions);
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
NSLog(@"%d",transaction.transactionState);
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
}
NSLog(@"=======%@",transactions);
}
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
NSLog(@"Transaction Completed");
NSUserDefaults *remvAddSttr = [NSUserDefaults standardUserDefaults];
// saving an NSString
NSString *chkRemVal=@"10";
[remvAddSttr setObject:chkRemVal forKey:@"revAdd"];
UIAlertView *alrt=[[UIAlertView alloc]initWithTitle:@"" message:@"Transaction completed" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alrt show];
}
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"Transaction Restored");
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
if (transaction.error.code != SKErrorPaymentCancelled) {
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];
}
Now need to design a Restore button for non-consumable product. For Restore button clicked copy this code.
现在需要为非消耗品设计一个恢复按钮。单击“恢复”按钮复制此代码。
//*****************************************************************************
//*****************************************************************************
-(void)restoreBtnClicked
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
if (error.code == SKErrorPaymentCancelled) {
NSLog(@"error.code");
}
}
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
// NSMutableArray* purchasableObjects = [[[NSMutableArray alloc] init] autorelease];
for (SKPaymentTransaction *transaction in queue.transactions) {
NSString *productID = transaction.payment.productIdentifier;
NSLog(@"productID...%@",productID);
if ([productID isEqualToString:@"Your Product Id"]) {
UIAlertView *alt12=[[UIAlertView alloc]initWithTitle:nil message:@"Product Restored" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];
[alt12 show];
}
}
//Block Call to access the products
}
回答by Andriy Shchudlo
For me this error appears because of having NO registered device in member center. Here is the case that help for me.
对我来说,出现此错误是因为会员中心没有注册设备。这是对我有帮助的案例。
- Register device in member center.
- Set your development team in "Your target" -> General -> "Team" After that this error disappear for me.
- 在会员中心注册设备。
- 在“您的目标”->“常规”->“团队”中设置您的开发团队之后,此错误对我来说消失了。
回答by Jon Cook
I know this is really old, but I just had the same issue (I was following a Ray W. tutorial https://www.raywenderlich.com/122144/in-app-purchase-tutorial)... When I added my signing team (Targets > General > Signing > Team) it was resolved. This is not mentioned in the tutorial (no slight on Ray W. - they're generally great)
我知道这真的很旧,但我遇到了同样的问题(我正在关注 Ray W. 教程https://www.raywenderlich.com/122144/in-app-purchase-tutorial)......当我添加我的签约团队(目标> 常规> 签约> 团队)它已解决。教程中没有提到这一点(对 Ray W 不轻描淡写 - 他们通常很棒)