In-app-purchase logic in spritekit - ios

i made a game in sprite kit i thought to make full and lite one instead i made in-app purchase i thought its easy with one target, my idea is users can play upto 99 points and if they want to play rest of the game they have to buy , as i made 2 scenes 1) mainmenu scene 2) playscene i have buttons for IAP and restore in both scenes and even while users playing at 99 point i add this code.if this way is wrong which is the best way to approach please let me know as this is my first sprite kit app
if (_gameScore==99){
//added this code in buy button as well
BOOL isInappSuccess = [[NSUserDefaults standardUserDefaults] boolForKey:#"IsInAppComplete"];
if (!isInappSuccess) {
//[SVProgressHUD showWithStatus:#"Loading..." maskType:SVProgressHUDMaskTypeGradient];
[[InAppRageIAPHelper sharedHelper] buyProductIdentifier:INAPP_PRODUCT_ADV];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"InApp" message:#"Item Already Purchased" delegate:Nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}

//for non-consumable product you have to add following code in your application
//function checks whether user purchase a non-consumable or not
/*
change all function acc to your game
*/
-(void)setDone:(Boolean)status
{
[_urnsuserDefault setBool:status forKey:#“done];
[_urnsuserDefault synchronize];
}
-(Boolean)getDone
{
Boolean status=[_urnsuserDefault boolForKey:#"done"];
return status;
}
//if user already purchase non-consumable or not (check for Restore if user purchase non-consumable product);
-(void)checkForRestore
{
if([self getDone])
{
//if user successfully purchase a in app item
UIAlertView *productAlertPur = [[UIAlertView alloc]
initWithTitle:#"Restored"
message:#“your” msg
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[productAlertPur show];
}
else
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
}
-(void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
UIAlertView * removedAlert = [[UIAlertView alloc]
initWithTitle:nil message:[NSString stringWithFormat:#"Restoration failed as %#.",error.localizedDescription] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[removedAlert show];
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
purchasedItemIDs = [[NSMutableArray alloc] init];
if(queue.transactions.count==0){
UIAlertView *noproductAlert = [[UIAlertView alloc]
initWithTitle:#"Restored"
message:#"No Purchases to Restore"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[noproductAlert show];
}
else{
if(![self getDone])
{
NSString *productID = #“company.game.productid;
[purchasedItemIDs addObject:productID];
UIAlertView *restoredAlert = [[UIAlertView alloc]
initWithTitle:#"Restored"
message:[NSString stringWithFormat:#"Math Lab Restored successfully."]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[restoredAlert show];
[self viewWillAppear:YES];
[self setDone:TRUE];
}
}
}

Related

I am trying to call an UIAlertView method for particular UIButton like UpdateEmail or ForgotPassword but properly call i am use this code

I am using this code for Update Email Address and Forgot Password but their is a problem when I click on 'ForgotPassword' button it's work properly but when I click on 'UpdateEmail' button it not work properly it call the UIAlert for 'ForgotPassword' button and I am trying to call" else if (self.ForgotPassword.tag == 1) part of -(Void)alertView " for when I press 'UpdateEmail' UIButton.
//Forgot method for ForgotPassword
-(IBAction)ForgotPassword:(id)sender
{
UIAlertView * forgotPassword=[[UIAlertView alloc] initWithTitle:#"Forgot Password" message:#"Please enter your email id" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
forgotPassword.alertViewStyle=UIAlertViewStylePlainTextInput;
[forgotPassword textFieldAtIndex:0].delegate=self;
[forgotPassword show];
}
//Method for Update Email Address
-(IBAction)UpdateEmail:(id)sender
{
if ([PFUser currentUser])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Update Email"
message:#"Enter Your Email Address"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
else
{
UIAlertView *myAlert1 = [[UIAlertView alloc]
initWithTitle:#"Please First Loginig"
message:#"Please First Loging"
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok",nil];
[myAlert1 show];
}
}
// Method for Alert View
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
self.ForgotPassword.tag=0;
self.UpdateEmail.tag=1;
if (self.ForgotPassword.tag == 0){
if(buttonIndex ==1){
NSLog(#"ok button clicked in forgot password alert view");
NSString *femailId=[alertView textFieldAtIndex:0].text;
if ([femailId isEqualToString:#""]){
UIAlertView *display;
display=[[UIAlertView alloc] initWithTitle:#"Email" message:#"Please enter password for resetting password" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[display show];
}else{
[PFUser requestPasswordResetForEmailInBackground:femailId block:^(BOOL succeeded, NSError *error){
UIAlertView *display;
if(succeeded){
display=[[UIAlertView alloc] initWithTitle:#"Password email" message:#"Please check your email for resetting the password" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
}else{
display=[[UIAlertView alloc] initWithTitle:#"Email" message:#"Email doesn't exists in our database" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
}
[display show];
}];
}
}
}else if (self.ForgotPassword.tag == 1){
PFUser *user = [PFUser currentUser];
user[#"email"] = [alertView textFieldAtIndex:0].text;
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error){
if (succeeded){
UIAlertView *myAlert1 = [[UIAlertView alloc]
initWithTitle:#"Email Upadated!"
message:#"your Email is Updated"
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok",nil];
[myAlert1 show];
//NSLog(#"Success");
}else{
UIAlertView *myAlert1 = [[UIAlertView alloc]
initWithTitle:#"Email is NOT Update"
message:#"Email is alredy registred"
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok",nil];
[myAlert1 show];
NSLog(#"Error");
}
}];
}
}
You need to give tag to your two different UIAlertView like below.
-(IBAction)ForgotPassword:(id)sender
{
UIAlertView * forgotPassword=[[UIAlertView alloc] initWithTitle:#"Forgot Password" message:#"Please enter your email id" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
forgotPassword.alertViewStyle=UIAlertViewStylePlainTextInput;
[forgotPassword textFieldAtIndex:0].delegate=self;
[forgotPassword show];
forgotPassword.tag = 0; //// Here for forgot password
}
-(IBAction)UpdateEmail:(id)sender
{
if ([PFUser currentUser])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Update Email"
message:#"Enter Your Email Address"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
alert.tag =1; ///Here for email update
}
}
Then, in -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex, you can detect which alertView's button was clicked.
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
{
if(alertView.tag == 0) /// Because we assigned forgotPassword.tag = 0; above for forgotPassword
{
if(buttonIndex == YOUR_DESIRED_BUTTON_INDEX)
{
///Your code for Forgot Password.
}
}
else if(alertView.tag ==1) /// Because we assigned alert.tag = 1; above for update email
{
if(buttonIndex == YOUR_DESIRED_BUTTON_INDEX)
{
///Your code for Update Email.
}
}
}

action on textFieldDidEndEditing

I want an alert when the following text fields receive the conditions in second section of code
self.circuit.rcdAtIan = [ICUtils nonNilString:self.rcdAtIan.text];
self.circuit.rcdAt5an = [ICUtils nonNilString:self.rcdAt5an.text];
The above code works fine so now I need to fire it. Using the below method was my first thought but that fires the alert on every keyboard resignation. I only want the alert to display once.
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([_rcdAtIan.text intValue]> 200) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[alert show];
}
if ([_rcdAt5an.text intValue]> 40) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[alert show];
}
}
Im thinking maybe I need a bool with NSUserDefaults perhaps? but not sure how to implement that to check if the alert has been shown. Normally if I wanted an alert shown once I would do
if (![#"1" isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:#"alert"]]){
[[NSUserDefaults standardUserDefaults] setValue:#"1" forKey:#"alert"];
[[NSUserDefaults standardUserDefaults] synchronize];
[alert show];
}
However in this instance, when the page is reloaded I want the alerts to be shown again and in any case im not sure if thats an efficient way to solve this
Don't use NSUserDefaults, that would be inappropriate
in your #interface...
#property (assign) BOOL freshAlert1;
#property (assign) BOOL freshAlert2;
then something like this... (assuming 'page is reloaded' equates to your viewController coming back onscreen)
- (void)viewDidAppear
{
self.freshAlert1 = YES;
self.freshAlert2 = YES;
}
if (([_rcdAtIan.text intValue]> 200) && self.freshAlert1) {
self.freshAlert1 = NO;
...
}
if (([_rcdAt5an.text intValue]> 40) && self.freshAlert2) {
self.freshAlert2 = NO;
...
}
What exactly do you mean by "once"? Once per app run, once per editing step?
Or maybe simply add two BOOL flags that you can reset whenever you want and simply to
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([_rcdAtIan.text intValue]> 200 && !alert1shown) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
alert1shown = YES;
[alert show];
}
if ([_rcdAt5an.text intValue]> 40 && !alert2shown) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
alert2shown = YES;
[alert show];
}
}

iOS: In App Purchase with buying progress indicator UIActivityIndicatorView

I tried several solutions on this board but never successful. What I want is when the user click Buy Button, an UIAlertView with UIActivityIndicatorView appears waiting for the app accessing the app store. But I do not know where to dismiss this UIAlertView once the purchase is done. I know that to dismiss a UIAlertView, we use: [alert dismissWithClickedButtonIndex:-1 animated:YES];
So would you please help me answer two questions:
1) Is my code below OK or any other better to achieve it?
2) Where should I dismiss UIAlertView for all cases:
User accepts to purchase
User cancels to purchase
Purchase is not successful
Following is my code:
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
UIAlertView *alert;
for(SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
alert = [[UIAlertView alloc]initWithTitle: #"In App Purchase" message: #"Processing your purchase..." delegate: nil cancelButtonTitle: nil otherButtonTitles: nil];
UIActivityIndicatorView *ind = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhiteLarge];
[ind startAnimating];
[alert addSubview: ind];
[alert show];
[ind release];
[alert release];
break;
case SKPaymentTransactionStatePurchased:
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:#"Complete"
message:#"You have bought the full version!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[tmp show];
[tmp release];
break;
case SKPaymentTransactionStateRestored:
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
if (transaction.error.code !=SKErrorPaymentCancelled) {
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"Purchase not successful!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[tmp show];
[tmp release];
}
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
break;
}
}
}
Try add
case SKPaymentTransactionStatePurchased:
[alert dismissWithClickedButtonIndex:-1 animated:YES];
and
case SKPaymentTransactionStateFailed:
[alert dismissWithClickedButtonIndex:-1 animated:YES];

iOS Incompatible block pointer types issue

I have an implementation problem with a project using MKStoreKit. I am trying to implement an UIAlertView with various purchase options.
Here is the code where I do various things and call up UIAlertView:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if(FALSE == payWallFlag)
{
// Display Alert Dialog
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Subscription Options"
message:#"You do not have an active subscription. Please purchase one of the options below."
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:nil];
[message addButtonWithTitle:#"7 Day Subscription $0.99"];
[message show];
return FALSE;
} else if(TRUE == payWallFlag)
{
// Load content
}
}
This is the physical alertView with the code which I am trying to call:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Cancel"])
{
NSLog(#"Cancel Button was selected.");
}
else if([title isEqualToString:#"7 Day Subscription $0.99"])
{
NSLog(#"7 Day Subscription button pressed.");
//Buy a 7 day subscription
if([SKPaymentQueue canMakePayments]) {
[[MKStoreManager sharedManager] buyFeature:kFeatureAId onComplete:^(NSString* purchasedFeature)
{
NSLog(#"Purchased: %#", purchasedFeature);
// Send an alert to the user
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Purchase Successful"
message:#"Thank you. You have successfully purchased a 7 Day Subscription."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert autorelease];
[alert show];
// Show the user the content now
payWallFlag = TRUE;
return TRUE;
}
onCancelled:^
{
// Send an alert to the user
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Purchase Failed"
message:#"Unfortunately you have cancelled your purchase of a 7 Day Subscription. Please try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert autorelease];
[alert show];
// Block the content again
payWallFlag = FALSE;
}];
}
else
{
NSLog(#"Parental control enabled");
// Send an alert to the user
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Purchase Failed"
message:#"Unfortunately Parental Controls are preventing you from purchasing a subscription. Please try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert autorelease];
[alert show];
// Block the content again
payWallFlag = FALSE;
}
}
}
The issue is I get the following Xcode error message in the UIAlertView:
Incompatible block pointer types sending 'int (^)(NSString *)' to parameter of type 'void (^)(NSString *)'
It appears the problems are: onComplete:^(NSString* purchasedFeature) and onCancelled:^ but I have no idea how to fix this.
You should not return TRUE; from that block, because then the compiler assumes that block returns an int, while it should return void (hence incompatible block types).
...onComplete:^(NSString* purchasedFeature) {
NSLog(#"Purchased: %#", purchasedFeature);
// Send an alert to the user
UIAlertView *alert = [[UIAlertView alloc] ...];
[alert autorelease];
[alert show];
// Show the user the content now
payWallFlag = TRUE;
return TRUE; // <--- Remove this line.
}...
For the second block (the onCancelled one), you probably missed the NSString* parameter, or whatever it expects.

Facebook Connect Graph API get notification when successfully sharing to facebook

I use this code to share to facebook:
[appDelegate.facebook dialog:#"feed" andParams:params andDelegate:appDelegate];
How can i get the notification (like sharekit) when sharing is successful?
I want to show UIAlertView but i do not know which facebook method that i need to put the UIAlertView.
I try in this method:
- (void)dialogDidSucceed:(NSURL *)url {
if ([_delegate respondsToSelector:#selector(dialogCompleteWithUrl:)]) {
[_delegate dialogCompleteWithUrl:url];
}
UIAlertView * alert=[[UIAlertView alloc]
initWithTitle: #"Sharing to Facebook"
message: #"Success"
delegate:self
cancelButtonTitle:#"Close"
otherButtonTitles:nil, nil];
[self setAlertSuccess:alert];
[alertSuccess show];
[alert release];
NSLog(#"SUCCESS 2");
[self dismissWithSuccess:YES animated:YES];
}
It is working however, when i click cancel button, this method is also called. So where is the right one to put the success alert view?
I am new in IOS.
These are changes i made in FBDialog.m
- (void)dismissWithSuccess:(BOOL)success animated:(BOOL)animated {
if (success) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Facebook Login Sucessful!" message:#"" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
if ([_delegate respondsToSelector:#selector(dialogDidComplete:)]) {
[_delegate dialogDidComplete:self];
}
} else {
if ([_delegate respondsToSelector:#selector(dialogDidNotComplete:)]) {
[_delegate dialogDidNotComplete:self];
}
}
[self dismiss:animated];
}

Resources