iOS Incompatible block pointer types issue

justinhartman picture justinhartman · Apr 9, 2012 · Viewed 9.8k times · Source

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.

Answer

user1203803 picture user1203803 · Apr 9, 2012

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.