나를 도와 주신 모든 분들께 감사드립니다! 나는 마침내 그것을 일하게 만들었다.
다른 코드가 나왔습니다. 나는 누군가가 똑같이하기를 원한다면 내가 여기 한 모든 것을 설명하려고 노력할 것이다.
주먹은 iOS 프로비저닝 포털에 앱 ID를 만들고 iTunes 연결에서 IAP 구매를 만듭니다.
그런 다음이 프로젝트를 얻고 http://xcodenoobies.blogspot.com.br/2012/04/implementing-inapp-purchase-in-xcode.html을 가져 와서 "SFHFKeychainUtils.h"및 .m 파일을 가져옵니다. SFHFKeychainUtils.m을 컴파일 소스에 추가하는 것을 잊지 마십시오 (프로젝트 -> 빌드 단계 -> 소스 컴파일).
이제 코드 :
.H
#import <StoreKit/StoreKit.h>
(...)
<SKProductsRequestDelegate, SKPaymentTransactionObserver, UIAlertViewDelegate> {
IBOutlet UIButton *feature2Btn;
IBOutlet UILabel *featureLabel, *statusLabel;
UIAlertView *askToPurchase;
int64_t coins;
IBOutlet UILabel * coinsLabel;
}
@property (nonatomic, retain) UIButton *feature2Btn;
@property (nonatomic, retain) UILabel *featureLabel, *statusLabel;
@property (nonatomic, assign) int64_t coins;
-(IBAction)button10Coins:(id)sender;
-(BOOL)IAPItemPurchased;
.m
#import "SFHFKeychainUtils.h"
@synthesize feature2Btn, featureLabel, statusLabel, coins;
#define kStoredData @"com.IAPID.10coins"
버튼 :
#pragma mark AlertView Delegate
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView==askToPurchase) {
if (buttonIndex==0) {
// user tapped YES, but we need to check if IAP is enabled or not.
if ([SKPaymentQueue canMakePayments]) {
NSLog(@"IAP: Checking if IAP Available");
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"com.IAPID.10coins"]];
request.delegate = self;
[request start];
} else {
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:@"Prohibited"
message:@"Parental Control is enabled, cannot make a purchase!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"Ok", nil];
[tmp show];
}
}
} }
요청 제품을 사용할 수있는 경우, 또는 구매를하지 않을 경우 취소 :
-(IBAction)button10Coins:(id)sender {
askToPurchase = [[UIAlertView alloc]
initWithTitle:@"IAP"
message:@"Would you like to buy 10 coins?"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"Yes", @"No", nil];
askToPurchase.delegate = self;
[askToPurchase show];
}
확인 IAP를 사용할 수있는 경우
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSLog(@"IAP: Received Response");
// remove wait view here
statusLabel.text = @"";
SKProduct *validProduct = nil;
int count = [response.products count];
if (count>0) {
NSLog(@"IAP: Available, starting transaction");
validProduct = [response.products objectAtIndex:0];
SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"com.IAPID.10coins"];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
} else {
NSLog(@"IAP: Item not found");
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:@"Internet Connection Required"
message:@"You must connect to a Wi-Fi or cellular data network to perform an In-App Purchase."
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"Ok", nil];
[tmp show];
} }
마지막으로 동작 :
#pragma mark StoreKit Delegate
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing: {
// show wait view here
NSLog(@"IAP: Processing...");}
break;
case SKPaymentTransactionStatePurchased:{
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
// remove wait view and unlock feature 2
statusLabel.text = @"Done!";
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:@"Completet"
message:@"The purchase has been completed!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"Ok", nil];
[tmp show];
NSError *error = nil;
[SFHFKeychainUtils storeUsername:@"IAPNoob01" andPassword:@"whatever" forServiceName:kStoredData updateExisting:YES error:&error];
// apply purchase action - hide lock overlay and
[feature2Btn setBackgroundImage:nil forState:UIControlStateNormal];
// Get The Coins, rock, favor points, whatever:
self.coins = coins +10;
coinsLabel.text = [NSString stringWithFormat: @"%lld", self.coins];
}
break;
case SKPaymentTransactionStateRestored:{
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
// remove wait view here
statusLabel.text = @"";}
break;
case SKPaymentTransactionStateFailed:{
if (transaction.error.code != SKErrorPaymentCancelled) {
NSLog(@"Error payment cancelled");
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
// remove wait view here
statusLabel.text = @"Purchase Error!";}
break;
default:
break;
}
} }
아주 확실하지 않음이 여부를 추가해야하는 경우 :
-(void)requestDidFinish:(SKRequest *)request {
}
-(void)request:(SKRequest *)request didFailWithError:(NSError *)error {
NSLog(@"Failed to connect with error: %@", [error localizedDescription]);
}
이 지금까지 가장 쉬운 코드입니다. 애플이 승인할지 모르겠지만 작동하고있다. 이것은 iOS 4.3 이상에서 작동합니다. 그러나 영리하다고 생각하는 아이들은 무료로 동전을 얻을 수 있습니다.
iTunes Connect에서 Consumable 항목을 생성하고 "com.IAPID.10coins"id를 거기에서 생성 한 올바른 ID로 변경하는 것을 잊지 마십시오.
"paymentWithProductIdentifier"는 더 이상 사용되지 않지만 여전히 "paymentWithProduct"로 변경하고 IAP ID를 추가하는 방법을 찾기 위해 계속 작동합니다. 나는 시도했지만 성공하지 못했습니다. http://www.leesilver.net/1/post/2011/8/disabling-arc-on-certain-files-in-xcode.html
당신은 또한 ScoreKit 및 보안 프레임 워크를 추가해야합니다
이것은 "SFHFKeychainUtils.m"을 제외한 ARC 준비, 당신은 그것을 해결하거나 하나의 파일에 ARC를 비활성화하려고 할 수있다, 여기에 튜토리얼 귀하의 프로젝트에.
소모품 인 경우 그게 다! 소모품이 아닌 경우 RESTORE 버튼을 추가해야합니다. 그렇지 않으면 Apple에서 거부합니다. 애플이 승인 및 판매, 그냥 벌금 아이폰 OS 4.3, 5, 6 개 판매오고있다 :이 사람에게 유용하고 애플이 :)
UPDATE를 승인 할 수 있기를 바랍니다
// RESTORE
- (IBAction)IAPRestore:(id)sender
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(@"Restore completed transactions finished.");
NSLog(@" Number of transactions in queue: %d", [[queue transactions] count]);
for (SKPaymentTransaction *trans in [queue transactions])
{
NSLog(@" transaction id %@ for product %@.", [trans transactionIdentifier], [[trans payment] productIdentifier]);
NSLog(@" original transaction id: %@ for product %@.", [[trans originalTransaction] transactionIdentifier],
[[[trans originalTransaction] payment]productIdentifier]);
if ([[[trans payment] productIdentifier] isEqual: @"com.AppID.IAPID"]) {
NSLog(@"Purchase Restored");
// Do your stuff to unlock
}
}
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:@"Purchases Restored"
message:@"Your previously purchased products have been restored!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"OK", nil];
[tmp show];
}
:하지만 꽤 쉽게 작동 중 :) UPDATE2 : Xcode 4.6 및 iOS 6.1.2에서 완벽하게 작동하고 테스트를 마쳤습니다.
아직도 잘 작동합니까? 내 앱에 IAP를 구현하려하지만 처음 확인하고 싶었습니다. – BrownEye