2012-02-08 21 views
5

Tôi cố gắng thực hiện mua ứng dụng trên ứng dụng của mình. Nhưng tôi không có kết quả khi tôi cố gắng chạy nó trong thiết bị.Trong giao dịch mua ứng dụng không hoạt động trên thiết bị

Mã của tôi đang theo dõi:

Đây là đối tượng cần thiết để nhận thông tin về sản phẩm và mua sản phẩm.

.h

#import <Foundation/Foundation.h> 
#import "StoreKit/StoreKit.h" 

#define kProductsLoadedNotification   @"ProductsLoaded" 
#define kProductPurchasedNotification  @"ProductPurchased" 
#define kProductPurchaseFailedNotification @"ProductPurchaseFailed" 

@interface StoreManager : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver> 

@property (strong, nonatomic) NSMutableSet * _purchasedProducts; 
@property (strong, nonatomic) NSArray *products; 
@property (strong, nonatomic) NSSet *_productIdentifiers; 
@property (strong, nonatomic) SKProductsRequest *request; 

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers; 
- (void)requestProducts; 
- (void)buyProduct:(SKProduct *)product; 

- (void)completeTransaction:(SKPaymentTransaction *)transaction; 
- (void)restoreTransaction:(SKPaymentTransaction *)transaction; 
- (void)failedTransaction:(SKPaymentTransaction *)transaction; 
- (void)provideContent:(NSString *)productIdentifier; 
- (void)recordTransaction:(SKPaymentTransaction *)transaction; 

@end 

.m

#import "StoreManager.h" 

@implementation StoreManager 
@synthesize _purchasedProducts; 
@synthesize products; 
@synthesize _productIdentifiers; 
@synthesize request; 

// Initializes the request object with the set of product identifiers. 
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers{ 
    self = [super init]; 
    if(self){ 
     self._productIdentifiers = productIdentifiers;   
     NSMutableSet *purchased = [NSMutableSet set]; 
     for(NSString * productId in self._productIdentifiers){ 
      BOOL flag = [[NSUserDefaults standardUserDefaults] boolForKey:productId]; 
      if(flag){ 
       [purchased addObject:productId]; 
       NSLog(@"Previously purchased: %@", productId); 
      } 
      NSLog(@"Not purchased: %@", productId); 
     } 
     self._purchasedProducts = purchased; 
    } 
    return self; 
} 

// Request info for the product. 
- (void)requestProducts{ 
    self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:self._productIdentifiers]; 
    self.request.delegate = self; 
    [self.request start]; 
} 

// Request fail. 
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{ 
    NSLog(@"Fail request! Error: %@", error); 
} 

// Delegate method - did receive responce. 
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ 
    self.products = response.products; 
    self.request = nil; 
    [[NSNotificationCenter defaultCenter] postNotificationName:kProductsLoadedNotification object:self.products]; 
} 

// Buy product. 
- (void)buyProduct:(SKProduct *)product{  
    SKPayment *payment = [SKPayment paymentWithProduct:product]; 
    [[SKPaymentQueue defaultQueue] addPayment:payment]; 
} 

// Payment transactions 
- (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)recordTransaction:(SKPaymentTransaction *)transaction {  
    // TODO: Record the transaction on the server side...  
} 

- (void)completeTransaction:(SKPaymentTransaction *)transaction{ 
    [self recordTransaction: transaction]; 
    [self provideContent: transaction.payment.productIdentifier]; 
    NSLog(@"completeTransaction..."); 
} 

- (void)provideContent:(NSString *)productIdentifier { 

    NSLog(@"Toggling flag for: %@", productIdentifier); 

    [[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:productIdentifier]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
    [self._purchasedProducts addObject:productIdentifier]; 

    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier]; 

} 

- (void)restoreTransaction:(SKPaymentTransaction *)transaction { 

    NSLog(@"restoreTransaction..."); 

    [self recordTransaction: transaction]; 
    [self provideContent: transaction.originalTransaction.payment.productIdentifier]; 
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 

} 

- (void)failedTransaction:(SKPaymentTransaction *)transaction { 

    if (transaction.error.code != SKErrorPaymentCancelled) 
    { 
     NSLog(@"Transaction error: %@", transaction.error.localizedDescription); 
    } 

    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseFailedNotification object:transaction]; 

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 

} 

@end 

Singleton đối tượng

.h

#import <Foundation/Foundation.h> 
#import "StoreManager.h" 

@interface StoreWrapper : StoreManager 

+ (StoreWrapper *)sharedInstance; 

@end 

.m

#import "StoreWrapper.h" 

@implementation StoreWrapper 
static StoreWrapper *gInstance = NULL; 

- (id)init{  
    NSSet *productId = [NSSet setWithObjects:@"com.company.sb.pack1", @"com.company.sb.pack5", nil]; 
    self = [super initWithProductIdentifiers:productId]; 
    if(self){ 

    } 
    return self; 
} 

+ (StoreWrapper *)sharedInstance{ 
    if(gInstance == NULL){ 
     gInstance = [[self alloc] init]; 
    } 
    return gInstance; 
} 

@end 

Trong bộ điều khiển quan điểm của tôi tôi gọi tiếp theo:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productsLoaded:) name:kProductsLoadedNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productPurchased:) name:kProductPurchasedNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(productPurchaseFailed:) name:kProductPurchaseFailedNotification object: nil];  
    Reachability *reach = [Reachability reachabilityForInternetConnection]; 
    NetworkStatus netStatus = [reach currentReachabilityStatus];  
    if (netStatus == NotReachable) {   
     NSLog(@"No internet connection!");   
    } else {   
     NSLog(@"Internet connection available!"); 
     // Request product 
     [[StoreWrapper sharedInstance] requestProducts];   
     [activIndicator startAnimating]; 
    }  
    [super viewWillAppear:animated]; 
} 

cho thời điểm này tôi gửi một yêu cầu để biết get sản phẩm từ máy chủ với id sản phẩm của tôi

tiếp theo nếu sản phẩm được tải lớp của tôi nhận được thông báo về điều này (và gọi phương thức sau).

- (void)productsLoaded:(NSNotification *)notification{  
    [activIndicator stopAnimating]; 
    [activIndicator setHidden:YES];  
    NSArray *arr = [notification object];  
    for(int i = 0; i < [arr count]; i++){ 
     SKProduct *product = [[StoreWrapper sharedInstance].products objectAtIndex:i]; 
     UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
     [btn setFrame:CGRectMake(0, i*55, 100, 50)]; 
     [btn setTitle:product.localizedTitle forState:UIControlStateNormal]; 
     [btn setTag:i]; 
     [btn addTarget:self action:@selector(buyProduct:) forControlEvents:UIControlEventTouchUpInside]; 
     [self.view addSubview:btn];   
    }  
} 

Đối với nút i thêm selector buyProduct (như trình bày ở trên)

- (void)buyProduct:(id)sender{ 
    NSLog(@"sender tag %d", [sender tag]); 
    int tag = [sender tag]; 
    SKProduct *product = [[StoreWrapper sharedInstance].products objectAtIndex:tag];  
    [[StoreWrapper sharedInstance] buyProduct:product];  
} 

Đối với iPhone Simulator công việc này tuyệt vời, nhưng trên điện thoại tôi không có bất kỳ nút nào, vì response.products không tải.

Tất cả các phương pháp này được gọi là, nhưng phương pháp đại biểu * - (void) productsRequest: (SKProductsRequest *) yêu cầu didReceiveResponse: (SKProductsResponse ) phản ứng không trở về response.products.

Cảm ơn bạn đã dành thời gian và cảm ơn bạn đã trả lời!

+0

Nó hoạt động trên trình mô phỏng? InApp mua nên luôn luôn được kiểm tra trên một thiết bị. Và thậm chí ở đó bạn nên đăng xuất khỏi tài khoản iTunes của bạn và sử dụng một tài khoản thử nghiệm (đặc biệt được thực hiện để thử nghiệm trong AppStore) trong ứng dụng. –

+0

có điều này là đúng, nhưng trong thời gian này tôi cần phải tạo nút chỉ sau khi tôi nhận được phản hồi từ máy chủ và tôi có sản phẩm. Nếu tôi nhận được sản phẩm tôi đã gửi thông báo với đối tượng này và khi nhận được thông báo, tôi tạo nút với một sản phẩm phản hồi đếm. Đây chỉ là ví dụ thử nghiệm. Nhưng nó chỉ hoạt động trên trình mô phỏng. –

+0

Tôi muốn nói rằng tùy thuộc vào thiết bị hoặc trình mô phỏng - phương thức ủy nhiệm - (void) productsRequest: (SKProductsRequest *) yêu cầu phản hồi didReceiveResponse: (SKProductsResponse) hoặc trả lại sản phẩm hoặc không trả lại. Đây là vấn đề của tôi. –

Trả lời

5

Để giải quyết, sự cố này tôi đặt lại thiết bị của mình và chạy lại ứng dụng.

Điều này giúp ích cho tôi.

+0

Sau khi đặt lại cứng sản phẩm phương thức đại biểuYêu cầu hoạt động chính xác. –

+0

sau khi tìm kiếm lâu dài các giải pháp không hoạt động, nhưng điều này hoạt động tốt .. Cảm ơn rất nhiều – Adel

+0

Làm thế nào để "đặt lại phương thức đại biểu productsRequest"? – Jacky

Các vấn đề liên quan