Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,694
6,269
Edit #4: Error 0 Solved

I created a new test user with an email address I knew. I signed out of the store in the Settings app, then opened my app (no new install of it needed) and attempted to purchase with the new account. It said I needed to verify the account, so I did, and I went back and tried again, and it worked!

So, hopefully this thread can help someone with any of the numerous IAP issues I had.

(Resolved) Edit #3: Getting error 0?

This is the article that made me think threading might have anything to do with getting error 0:
http://blog.mugunthkumar.com/coding...annot-connect-to-itunes-store-skerrorunknown/

So I decided to replace:
Code:
[[SKPaymentQueue defaultQueue] addPayment:[SKPayment paymentWithProductIdentifier:@"quickClipsAdRemoval"]];

with:
Code:
[[SKPaymentQueue defaultQueue] performSelectorOnMainThread:(@selector(addPayment:)) withObject:[SKPayment paymentWithProductIdentifier:@"quickClipsAdRemoval"] waitUntilDone:NO];

but it appears to have resolved nothing. I still receive an error code of 0.

I could really use some help...

(Resolved) Edit #2: Fixed 5002

I resolved 5002 by deleting the app from my iPhone, then logging out from the store in settings, then installing my app on my iPhone again, and then logging in when it prompted me to in my app. Somehow it wasn't going to the sandbox environment before. And now I'm receiving error 0, which something has told me is possibly because my call to add my product to the queue isn't occurring on the main thread.

(Resolved) Edit #1: Fixed Crash

I looked through the crash log and noticed that finishTransaction: was getting called. Seemed odd, given that the Store Kit never gave me a confirmation page. I looked into my code a bit and found that in my effort to reduce how many lines I use, I moved finishTransaction: outside of the switch statement for my transaction observer. I checked the method for finishedTransaction:, and found that evidently invoking finishedTransaction: on a transaction in the middle of purchasing will cause the application to crash. So, yeah, that's the cause of the crash. I fixed that. Now I have an error 5002.

(Resolved) Original: Getting a Crash...

Okay, so this whole thing was weird.

I made an IAP for version 1.0 of my app, but forgot to attach the IAP when I uploaded the app to Apple, so it didn't ever get reviewed.

Then in 1.1, I remembered to include it for review. The app as a whole was rejected, but my IAP remained "In-Review".

Before releasing 1.2, I wanted to test my IAP, but I couldn't, because it was stuck "In-Review". When I tested my app, I always ended up with the issue that
Code:
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
the response was always an empty array while testing, I figured because of the limbo my IAP was stuck in. The empty array caused my app to display an error message, and I decided all I could do was hope that it would work when 1.2 was released, and if it didn't, at least it would have the grace to explain that it failed.

Well, 1.2 has now been released, and when users are going to get the IAP, the app doesn't throw up an error, instead, it just crashes.

Here's all the code:

In my header, I've got these:
Code:
#import <StoreKit/StoreKit.h> //The framework is included in my project.
#import "Reachability.h"

@interface HelpMenu : UIViewController <... UIAlertViewDelegate, SKProductsRequestDelegate, SKPaymentTransactionObserver>
{
    IBOutlet    UIBarButtonItem         *purchaseButton;
    IBOutlet    UIActivityIndicatorView *purchaseIndicator;
    int                                 responseStatus;
}

- (IBAction)purchase;

In main, the related portions are:
Code:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        if ([[NSUserDefaults standardUserDefaults] dataForKey:@"receipt"])
        { ... }
        
        else if ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable)
        {
            NSLog(@"No internet connection.");
        }
        
        else
        {
            if ([SKPaymentQueue canMakePayments])
            {
                [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
                SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject: @"quickClipsAdRemoval"]];
                request.delegate = self;
                responseStatus = 0;
                [request start];
            }
            else
            {
                NSLog(@"Not allowed to make purchases.");
            }
        }
        
    }
    return self;
}

Code:
- (IBAction)purchase
{
    [super viewDidLoad];
    if ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Internet Connection"
                                                        message:@"You cannot upgrade to premium because you don't have an internet connection on this device."
                                                       delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
    
    else
    {
        if ([SKPaymentQueue canMakePayments])
        {
            purchaseButton.enabled = NO;
            switch (responseStatus)
            {
                case 2: ;
                    NSLog(@"Response had been of failure already.");
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Purchase Failed"
                                                                    message:@"The response from the App Store was not as expected. Close and reopen the help menu and try again. If the problem persists, contact the developer."
                                                                   delegate:nil
                                                          cancelButtonTitle:@"OK"
                                                          otherButtonTitles:nil];
// Generally the error message I got while testing.
                    [alert show];
                    [alert release];
                    purchaseButton.title = @"Failed";
                    break;
                case 1:
                    NSLog(@"Response had been of success already.");
                    [[SKPaymentQueue defaultQueue] addPayment:[SKPayment paymentWithProductIdentifier:@"quickClipsAdRemoval"]];
                default:
                    purchaseButton.title = @"   ";
                    [purchaseIndicator startAnimating];
                    break;
            }
        }
        else
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"In-App Purchases are Disabled"
                                                            message:@"You cannot upgrade to premium because In-App Purchases are disabled on this device. To change this, go to your device Settings, choose General, then Restrictions, and enable In-App Purchases."
                                                           delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alert show];
            [alert release];
        }
    }
}

Code:
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSLog(@"The response count was %i", [response.products count]);
    if ([response.products count] == 1)
    {
        responseStatus = 1;
        if ([purchaseButton.title isEqualToString:@"   "])
        {
            NSLog(@"Purchase had been attempted already.");
            [[SKPaymentQueue defaultQueue] addPayment:[SKPayment paymentWithProductIdentifier:@"quickClipsAdRemoval"]];
        }
    }
    
    else
    {
        responseStatus = 2;
        if ([purchaseButton.title isEqualToString:@"   "])
        {
            NSLog(@"Purchase had been attempted already.");
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Purchase Failed"
                                                            message:@"The response from the App Store was not as expected. Dismiss and reopen the help menu and try again. If the problem persists, contact the developer from the bottom of the help menu."
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil];
            [alert show];
            [alert release];
            purchaseButton.title = @"Failed";
            [purchaseIndicator stopAnimating];
        }
    }
    
    [request autorelease];
}

Thus far, people have not been getting error popups, but simply crashes when they hit the button.

Here's what looks like the relevant portion of the crash log:
Code:
Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread:  0

Last Exception Backtrace:
0   CoreFoundation                	0x370f48bf __exceptionPreprocess + 163
1   libobjc.A.dylib               	0x324641e5 objc_exception_throw + 33
2   CoreFoundation                	0x370f47b9 +[NSException raise:format:] + 1
3   CoreFoundation                	0x370f47db +[NSException raise:format:] + 35
4   StoreKit                      	0x33fd9ac9 -[SKPaymentQueue finishTransaction:] + 81
5   QuickClip                     	0x00016193 -[HelpMenu paymentQueue:updatedTransactions:] (HelpMenu.m:368)
6   StoreKit                      	0x33fda7a7 __NotifyObserverAboutChanges + 59
7   CoreFoundation                	0x37043c8b CFArrayApplyFunction + 39
8   StoreKit                      	0x33fda763 -[SKPaymentQueue _notifyObserversAboutChanges:] + 119
9   StoreKit                      	0x33fda453 -[SKPaymentQueue _addLocalTransactionForPayment:] + 251
10  StoreKit                      	0x33fd994d -[SKPaymentQueue addPayment:] + 445
11  QuickClip                     	0x00016cf7 -[HelpMenu purchase] (HelpMenu.m:122)
12  CoreFoundation                	0x3704e435 -[NSObject performSelector:withObject:withObject:] + 53
13  UIKit                         	0x31ce79eb -[UIApplication sendAction:to:from:forEvent:] + 63
14  UIKit                         	0x31dad3cf -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 119
15  CoreFoundation                	0x3704e435 -[NSObject performSelector:withObject:withObject:] + 53
16  UIKit                         	0x31ce79eb -[UIApplication sendAction:to:from:forEvent:] + 63
17  UIKit                         	0x31ce79a7 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 31
18  UIKit                         	0x31ce7985 -[UIControl sendAction:to:forEvent:] + 45
19  UIKit                         	0x31ce76f5 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 493
20  UIKit                         	0x31ce802d -[UIControl touchesEnded:withEvent:] + 477
21  UIKit                         	0x31ce650f -[UIWindow _sendTouchesForEvent:] + 319
22  UIKit                         	0x31ce5f01 -[UIWindow sendEvent:] + 381
23  UIKit                         	0x31ccc4ed -[UIApplication sendEvent:] + 357
24  UIKit                         	0x31ccbd2d _UIApplicationHandleEvent + 5809
25  GraphicsServices              	0x32d26e13 PurpleEventCallback + 883
26  CoreFoundation                	0x370c8553 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 39
27  CoreFoundation                	0x370c84f5 __CFRunLoopDoSource1 + 141
28  CoreFoundation                	0x370c7343 __CFRunLoopRun + 1371
29  CoreFoundation                	0x3704a4dd CFRunLoopRunSpecific + 301
30  CoreFoundation                	0x3704a3a5 CFRunLoopRunInMode + 105
31  GraphicsServices              	0x32d25fed GSEventRunModal + 157
32  UIKit                         	0x31cfa743 UIApplicationMain + 1091
33  QuickClip                     	0x0000246f main (main.m:14)
34  QuickClip                     	0x00002428 0x1000 + 5160


Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x30fcf32c __pthread_kill + 8
1   libsystem_c.dylib             	0x380d5f54 pthread_kill + 48
2   libsystem_c.dylib             	0x380cefe4 abort + 88
3   libc++abi.dylib               	0x37159f64 abort_message + 40
4   libc++abi.dylib               	0x37157346 _ZL17default_terminatev + 18
5   libobjc.A.dylib               	0x324642dc _objc_terminate + 140
6   libc++abi.dylib               	0x371573be _ZL19safe_handler_callerPFvvE + 70
7   libc++abi.dylib               	0x3715744a std::terminate() + 14
8   libc++abi.dylib               	0x3715881e __cxa_rethrow + 82
9   libobjc.A.dylib               	0x3246422e objc_exception_rethrow + 6
10  CoreFoundation                	0x3704a53e CFRunLoopRunSpecific + 398
11  CoreFoundation                	0x3704a39e CFRunLoopRunInMode + 98
12  GraphicsServices              	0x32d25fe6 GSEventRunModal + 150
13  UIKit                         	0x31cfa73c UIApplicationMain + 1084
14  QuickClip                     	0x00002468 main (main.m:14)
15  QuickClip                     	0x00002420 0x1000 + 5152
 
Last edited:
Thanks for sharing

I was actually looking for help when I posted each thing. It was at the end when I'd finally solved everything myself I decided to retitle the topic. Figured it can help someone (most likely me in the future) from going through the pain of figuring it all out from scratch.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.