In-App Purchase still not working almost a week after release - ios

During tests, in-app purchasing seemed to work well, but after release it just stopped. Afer I press the 'upgrade' button, it asks for my password and then nothing. Not even an error message.
I've browsed StackOverflow for a while and found these questions:
In app purchase does not work when live
In App Purchase not working after it has been approved
I thought I just needed to wait but there was no one who waited more than 48 hours. For me, it's been 120 hours after the release. So I considered it may be something with my code.
My algorithm is based upon thus Ray Wenderlich's tutorial
http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial
Firstly, in `applicationDidFinishLaunchingWithOptions: in my app delegate
// In app
[myGuideIAP sharedInstance]; //initialize singleton
[[myGuideIAP sharedInstance] tryLoadingProduct]; //my method to load SKProduct
//SKProduct is stored as a #property in the singleton
Later, in the upgrade view controller, I check and if it didn't load the product, execute the tryloadingProduct once again.
Singleton is initialized the classic way:
+ (myGuideIAP *)sharedInstance {
static dispatch_once_t once;
static myGuideIAP * sharedInstance;
dispatch_once(&once, ^{
NSSet * productIdentifiers = [NSSet setWithObjects:
#"com.mkochukov.myguidemind.proupgrade",
nil];
sharedInstance = [[self alloc] initWithProductIdentifiers:productIdentifiers];
});
return sharedInstance;
}
This is what's inside tryLoadingProduct method:
- (void)tryLoadingProduct
{
[[myGuideIAP sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products)
{
if (success) {
if (products.count > 0)
_mProduct = products[0];
}
}];
}
When the user tries to purchase, an alert view appears, asking to buy or restore. This is how it's handled
-(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == alertView.cancelButtonIndex)
return;
if (buttonIndex == 0) {
[[myGuideIAP sharedInstance] buyProduct:[myGuideIAP sharedInstance].mProduct];
}else if (buttonIndex == 1){
[[myGuideIAP sharedInstance]restoreCompletedTransactions];
}
}
And after that when user hits the "Buy" button this is executed:
- (void)buyProduct:(SKProduct *)product {
NSLog(#"Buying %#...", product.productIdentifier);
SKPayment * payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}

Sounds like an entitlements issue, make sure they are set.

Related

GKMatchmaker findMatchForRequest invite never received

I'm trying to invite nearby players to a match, but the invite is either never sent or never received.
GKMatchMaker startBrowsingForNearbyPlayersWithHandler works and returns nearby players that are on same wifi, but then I use findMatchForRequest and it returns a match without any players, and the players I try to invite never receive an invite notification. Here is my code.
I start by authenticating the local player:
GKLocalPlayer.localPlayer.authenticateHandler= ^(UIViewController *controller, NSError *error)
{
if (error)
{
NSLog(#"%s:: Error authenticating: %#", __PRETTY_FUNCTION__, error.localizedDescription);
return;
}
if(controller)
{
// User has not yet authenticated
[pViewController presentViewController:controller animated:YES completion:^(void)
{
[self lookForNearbyPlayers];
}];
return;
}
[self lookForNearbyPlayers];
};
-(void)lookForNearbyPlayers
{
if(!GKLocalPlayer.localPlayer.authenticated)
{
NSLog(#"%s:: User not authenticated", __PRETTY_FUNCTION__);
return;
}
I register my view controller as a delegate of GKLocalPlayerListener:
[GKLocalPlayer.localPlayer registerListener:self]; // self is a view controller.
// This works. My test local player which is a second device and appleID I setup shows up when this handler is called.
[GKMatchmaker.sharedMatchmaker startBrowsingForNearbyPlayersWithHandler:^(GKPlayer *player, BOOL reachable)
{
NSArray * paPlayers= [NSArray arrayWithObject:player];
_pMatchRequest= [[GKMatchRequest alloc] init];
_pMatchRequest.minPlayers= 2;
_pMatchRequest.maxPlayers= 4;
_pMatchRequest.recipients = paPlayers;
_pMatchRequest.inviteMessage = #"Join our match!";
_pMatchRequest.recipientResponseHandler = ^(GKPlayer *player, GKInviteeResponse response)
{
// This is never called.
NSLog((response == GKInviteeResponseAccepted) ? #"Player %# Accepted" : #"Player %# Declined", player.alias);
};
// This returns with a match without any players.
[GKMatchmaker.sharedMatchmaker findMatchForRequest:_pMatchRequest withCompletionHandler:^(GKMatch *match, NSError *error)
{
if(error)
{
NSLog(#"%s:: %#", __PRETTY_FUNCTION__, error.localizedDescription);
return;
}
else if(match != nil)
{
_pMatch= match;
match.delegate = self;
NSLog(#"players count= %lu", (unsigned long)_pMatch.players.count); // Always returns 0
}
}];
}
}
I have delegate methods for GKLocalPlayerListener setup, but they are never called:
- (void)player:(GKPlayer *)player didRequestMatchWithRecipients:(NSArray<GKPlayer *> *)recipientPlayers
{
NSLog(#"%s", __PRETTY_FUNCTION__);
}
- (void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
NSLog(#"%s", __PRETTY_FUNCTION__);
}
Does anyone know how to get this to work without GKMatchmakerViewController and for iOS9? The only examples I can find have the deprecated -inviteHandler method.
This code is working in Swift if you know how you can convert it to Objective-C and to try it.
GKMatchmaker.sharedMatchmaker().findMatchForRequest(
request,
withCompletionHandler: {(match : GKMatch!, error: NSError!) -> Void in
NSLog("This works")
})
Based on multiple questions here on SO, Game Center seems to be getting stuck from time to time. In the best case, it returns "Game not recognized" errors. In the worst case, it just cheerfully returns nil to GC calls. Sometimes it resumes working on it's own, sometimes it doesn't. But it seems you can kickstart it again by logging into iTunesConnect and do any of the following:
Add a leaderboard
Change the default leaderboard
Add an achievement
I've added this to my debugging routine. If some aspect of GC stops working, or returns nil, I try making one of the above changes in iTunesConnect before proceeding. In my case, I get the "game not recognized" several times per week, but several others have noted the "nil return values."
I know this an older post, but I ran across it when trying to establish a connection between several app instances over the internet. I believe the part you're missing is that after registering for the listener, you need to receive the connected status with
- (void)match:(GKMatch *)match
player:(GKPlayer *)player
didChangeConnectionState:(GKPlayerConnectionState)state
{
NSLog(#">>> did change state");
if (state == GKPlayerStateConnected)
{
NSLog(#">>>> match:%# did change to Connected for player %# ",match, player.displayName);
}
else if (state == GKPlayerStateDisconnected)
{
NSLog(#">>>> match:%# disconnected for player %# ",match, player.displayName);
}
I find the match has 0 players when the completionHandler is called from findMatchForRequest:, but that I can successfully use the GKMatch and GKPlayer as returned in didChangeConnectionState:
Hope that helps someone who reads this long after the OP.

How to test In-app purchase in Sandbox mode iOS?

Am new to In-app purchase integration in iOS application. I have done the coding in the project level and I have created a Sandbox user in iTunes Connect. I read many tutorials and Apple Document to test the In-App purchase in DEV mode.
As per the document I have removed the APPLE ID from iPad Settings and launched the app from Xcode. But, I didn't received the Account Alert from the app. Also, my products are returning empty in SKProductRequest delegate method didReceiveResponse. I have posted my code for your reference. Can you please help me on this? Am working since last two days. Please help me. Thanks in advance.
- (void) getAvailProducts
{
NSLog(#"Fetching Available Products");
NSSet *productIdentifiers = [NSSet setWithObjects:#"com.test.testios.monthly", #"com.test.testios.yearly" ,nil];
self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
self.productsRequest.delegate = self;
[self.productsRequest start];
}
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
//SKProduct *validProduct = nil;
DebugLog(#"\n Products: %#", response.products);
NSUInteger count = [response.products count];
NSLog(#"Request Count: %lu", (unsigned long)count);
if (count > 0)
{
self.validatedProducts = response.products;
DebugLog(#“\n Products: %#", response.products);
self.validationCheck = TRUE;
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
// Check subscription
}
else
{
// No products found….
}
}
Also, I tried with "monthly and yearly" instead of "com.test.testios.monthly and com.test.testios.yearly". But, no results.
Edit: Am getting the mentioned ProductIds are invalid in the following code,
for (NSString *invalidProductId in response.invalidProductIdentifiers)
{
NSLog(#"Invalid product id: %#" , invalidProductId);
}
Thank you all.
Fixed the issue and tested the In-App purchase in Sandbox environment. Following items fixed my issue,
1. iTunes Agreement was not accepted.
2. Tax and Payment details was not added.
3. Added correct Product Identifier in project.

Issue with InApp purchase in Sandbox mode: SKProductsRequest delegate returns inconsistent response

When requesting for in-app auto renewable subscription products from apple, I sometimes get valid products but most of the times I get invalidProductIdentifiers in SKProductsResponse object. I wrote a small piece of code to verify this inconsistency in response:
-(void)viewDidAppear:(BOOL)animated{
[self getProductsFromApple];
}
-(void)getProductsFromApple{
SKProductsRequest *_productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:#"2"]];
[_productRequest setDelegate:self];
[_productRequest start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
NSLog(#"Invalid %#", response.invalidProductIdentifiers);
NSLog(#"Valid %#", response.products);
if (response.invalidProductIdentifiers && [response.invalidProductIdentifiers isKindOfClass:[NSArray class]] && response.invalidProductIdentifiers.count) {
[self getProductsFromApple];
}
}
This sometimes succeeds after n calls to apple server.Our team has escalated the issue to apple, we are waiting for there response.
Has anyone faced this issue, kindly suggest how you were able to test in-apps payment ?

In-App Purchase Product Request Method Needs Two Calls

I currently have created a series of methods that call and return In-App Purchase products that I have created. I can call the SKProductRequest without issue, I can even purchase the item and receive a successful purchase notification (SKPaymentTransactionStatePurchased).
The issue is that for whatever reason, when I initially run the app, I have to call the following methods 2 times in order to receive a non-null response from Apple:
/// In app purchases
- (IBAction)BuyProduct:(id)sender {
if ([SKPaymentQueue canMakePayments]) {
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:_productID]];
request.delegate = self;
[request start];
} else {
NSLog(#"Please enable In App Purchasing in your settings");
}
}
#pragma mark _
#pragma mark SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSArray *products = response.products;
if (products.count != 0) {
NSLog(#"Products available: %#", _product.localizedTitle);
_product = products[0];
} else {
NSLog(#"Products not found.");
}
products = response.invalidProductIdentifiers;
for (SKProduct *product in products) {
NSLog(#"Product not found: %#", product);
}
}
Every time, the first time I call the BuyProduct IBAction i receive this:
(excuse the dashes - simply clearing my personal info!)
---------- --.07.55.823 -------[2474:827710] Products available: (null)
Then the second time and onwards that I call the same IBAction button, I receive the IAP name correctly,
---------- --.08.03.142 -------[2474:827710] Products available: TEST IAP
---------- --.08.04.455 -------[2474:827710] Products available: TEST IAP
SO, I am just trying to figure out why I need to call these methods 2 times in order for Apple (or my code) to successfully return my IAP product name. If anyone could help me out I would greatly appreciate it!

InApp Purchase product list doesn't load in iPhone app

I am trying to use a consumable InApp Purchase in my iPhone app. I am using this tutorial for reference. I have followed the tutorial correctly. But my products are not loading. Here is my code.
+ (RageIAPHelper *)sharedInstance {
static dispatch_once_t once;
static RageIAPHelper * sharedInstance;
dispatch_once(&once, ^{
NSSet * productIdentifiers = [NSSet setWithObjects:
#"com.ilfmobile.hero.twohundredconnects",
#"com.ilfmobile.hero.onethousandconnects",
nil];
sharedInstance = [[self alloc] initWithProductIdentifiers:productIdentifiers];
});
return sharedInstance;
}
And my get product list code.
- (void)reload {
products = nil;
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[[RageIAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *theProducts) {
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
if (success) {
products = theProducts;
[self.tblview reloadData];
}
}];
}
And I implement the InApp purchases in Xcode Capabilities. I have attached screenshots as below.
I have enabled InApp Purchases on iTunes Connect and added both of the products in the InApp list.
Please suggest where I am wrong. Thank you for giving your precious time to suggestion. I am using Xcode5.1 and my app development target iOS7.1
It may happen if you are not running your app in Device. ios simulator cause these type or issues.
Create your certificates again and test your app in iPhone or iPad device.

Resources