Reputation: 305
I've been working with a user of my app that is experiencing crashes upon launching the app. We believe it has to do something with the in-app purchase process, but I haven't been able to diagnose the cause so I thought I would bring it here (for every other user I've talked to, things seem to be working just fine).
Back to the user with the problem, she says that ever since she purchase the IAP, the app crashes upon launch. And following the crash, the device frequently prompts the user to enter her user ID and password (as if it's trying to make the purchase again). We've tried reinstalling the app, updating to iOS 7, updating the app itself...no luck.
She was nice enough to send me some crash logs, which I've copied below. Any input would be appreciated!
I followed Ray Wenderlich's IAP in iOS 6 tutorial if that helps...again, no other reported issues besides this one, which makes me wonder if something went haywire during the purchase process.
Incident Identifier: 1E0C36A9-C7EC-48D7-9BB8-D56F6203D62E
CrashReporter Key: 2ac3185fb0d2c64d11247cccfa4a55af32fd5462
Hardware Model: iPhone4,1
Process: MetricMe [9322]
Path: /var/mobile/Applications/847DC898-FD57-40F5-98F2-6C361DC7DECC/MetricMe.app/MetricMe
Identifier: com.anthonydubis.metricme
Version: 3.0.5 (3.0.5)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2013-10-04 13:48:13.129 -0400
OS Version: iOS 7.0.2 (11A501)
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Triggered by Thread: 0
Last Exception Backtrace:
0 CoreFoundation 0x2ebf9f4e __exceptionPreprocess + 126
1 libobjc.A.dylib 0x38fd26aa objc_exception_throw + 34
2 CoreFoundation 0x2eb37c12 -[__NSSetM addObject:] + 558
3 MetricMe 0x00069fc4 -[IAPHelper provideContentForRestoredProductIdentifier:] (IAPHelper.m:172)
4 MetricMe 0x00069ce8 -[IAPHelper restoreTransaction:] (IAPHelper.m:146)
5 MetricMe 0x00069b14 -[IAPHelper paymentQueue:updatedTransactions:] (IAPHelper.m:124)
6 StoreKit 0x312fddc8 __NotifyObserverAboutChanges + 80
7 CoreFoundation 0x2eb2d714 CFArrayApplyFunction + 32
8 StoreKit 0x312fdd64 -[SKPaymentQueue _notifyObserversAboutChanges:sendUpdatedDownloads:] + 124
9 StoreKit 0x312fe646 -[SKPaymentQueue _processUpdates:trimUnmatched:sendUpdatedDownloads:] + 1022
10 StoreKit 0x312fed1c -[SKPaymentQueue _setTransactionsWithReply:] + 124
11 StoreKit 0x312fd906 __38-[SKPaymentQueue _establishConnection]_block_invoke_2 + 58
12 libdispatch.dylib 0x394b5d76 _dispatch_call_block_and_release + 6
13 libdispatch.dylib 0x394b5d62 _dispatch_client_callout + 18
14 libdispatch.dylib 0x394bc7bc _dispatch_main_queue_callback_4CF$VARIANT$mp + 264
15 CoreFoundation 0x2ebc481c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 4
16 CoreFoundation 0x2ebc30f0 __CFRunLoopRun + 1296
17 CoreFoundation 0x2eb2dce2 CFRunLoopRunSpecific + 518
18 CoreFoundation 0x2eb2dac6 CFRunLoopRunInMode + 102
19 GraphicsServices 0x3384e27e GSEventRunModal + 134
20 UIKit 0x313cfa3c UIApplicationMain + 1132
21 MetricMe 0x00043842 main (main.m:16)
22 libdyld.dylib 0x394daab2 tlv_initializer + 2
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x395911fc __pthread_kill + 8
1 libsystem_pthread.dylib 0x395faa2e pthread_kill + 54
2 libsystem_c.dylib 0x39541ff8 abort + 72
3 libc++abi.dylib 0x38870cd2 abort_message + 70
4 libc++abi.dylib 0x388896e0 default_terminate_handler() + 248
5 libobjc.A.dylib 0x38fd291e _objc_terminate() + 190
6 libc++abi.dylib 0x388871c4 std::__terminate(void (*)()) + 76
7 libc++abi.dylib 0x38886a18 __cxa_throw + 112
8 libobjc.A.dylib 0x38fd277e objc_exception_throw + 246
9 CoreFoundation 0x2eb37c12 -[__NSSetM addObject:] + 558
10 MetricMe 0x00069fc4 -[IAPHelper provideContentForRestoredProductIdentifier:] (IAPHelper.m:172)
11 MetricMe 0x00069ce8 -[IAPHelper restoreTransaction:] (IAPHelper.m:146)
12 MetricMe 0x00069b14 -[IAPHelper paymentQueue:updatedTransactions:] (IAPHelper.m:124)
13 StoreKit 0x312fddc8 __NotifyObserverAboutChanges + 80
14 CoreFoundation 0x2eb2d716 CFArrayApplyFunction + 34
15 StoreKit 0x312fdd64 -[SKPaymentQueue _notifyObserversAboutChanges:sendUpdatedDownloads:] + 124
16 StoreKit 0x312fe646 -[SKPaymentQueue _processUpdates:trimUnmatched:sendUpdatedDownloads:] + 1022
17 StoreKit 0x312fed1c -[SKPaymentQueue _setTransactionsWithReply:] + 124
18 StoreKit 0x312fd906 __38-[SKPaymentQueue _establishConnection]_block_invoke_2 + 58
19 libdispatch.dylib 0x394b5d78 _dispatch_call_block_and_release + 8
20 libdispatch.dylib 0x394b5d64 _dispatch_client_callout + 20
21 libdispatch.dylib 0x394bc7bc _dispatch_main_queue_callback_4CF$VARIANT$mp + 264
22 CoreFoundation 0x2ebc481c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 4
23 CoreFoundation 0x2ebc30f0 __CFRunLoopRun + 1296
24 CoreFoundation 0x2eb2dce2 CFRunLoopRunSpecific + 518
25 CoreFoundation 0x2eb2dac6 CFRunLoopRunInMode + 102
26 GraphicsServices 0x3384e27e GSEventRunModal + 134
27 UIKit 0x313cfa3c UIApplicationMain + 1132
28 MetricMe 0x00043842 main (main.m:16)
29 libdyld.dylib 0x394daab4 start + 0
Edited to add line 172 of IAPHelper:
It's called during a product restore and passes in the productIdentifier of the IAP. What's interesting is that this is occurring right at the launch of the app, which makes me wonder if this is a scenario where internet connection was lost during the IAP purchase process, and now it's trying to restore it upon launch.
IAPHelper contains a lot of the methods to purchase and restore a product (also the observer for the purchasing notifications). The sharedInstance is called in applicationDidFinishLaunching so that it is ready to receive receipts from Apple. Line 172 is where the product identifier is being added to _purchasedProductIdentifiers, which is an NSMutableSet instance variable. Would the error imply that something is wrong with _purchasedProductIdentifiers (NSMutable set should be initialized before it gets here) or the productIdentifier passed in? In practice, we should never get to this point unless the sharedInstance of IAPHelper is created, which is where _purchasedProductIdentifiers is created.
- (void)provideContentForRestoredProductIdentifier:(NSString *)productIdentifier
{
[_purchasedProductIdentifiers addObject:productIdentifier];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductRestoredNotification object:productIdentifier userInfo:nil];
}
Upvotes: 19
Views: 8394
Reputation: 1275
I had similar symptoms(app crashed on every start) and the problem was that StoreObserver was not retained by the queue:
StoreObserver *observer = [[StoreObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
Solution was to make the observer an instance variable.
Thread dealing with this problem: App crash on [[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
Upvotes: 0
Reputation: 161
I ran into this problem this morning with my iPhone 5S and an app. The problem seemed to be caused by me needing to validate the security code on a recently added credit card upon trying to perform the in app purchase. This pulled me out of the app, into the App Store.
After verifying my security code, I was prompted to purchased the in-app purchase again. I did so, but since I was not in the app at the time, the app wasn't notified that I made the purchase. I switched back to the app and used the app's restore purchases option and the moment I entered my App store password, the app then crashed and continued to crash on start up even after being uninstalled, the phone rebooted and the app re-installed. I even tried resetting all settings and signing out of my App Store iTunes account. Nothing prevented the crashes.
I looked at the crash stack and it was very similar to the one pasted above, with a bunch of StoreKit entries in the stack. Unfortunately I didn't save the stack before taking the nuclear option (see below). This was under iOS 7.0.3. It appears the purchase went through as I installed the app on another device and did a restore purchases and that worked.
Unfortunately the only way to fix this that I found was to wipe the phone and restore from a backup made before the purchase was attempted. Fortunately for me I had just backed up to iCloud about 30 minutes prior to this happening so I did a "Erase All Settings and Data", followed by a "Restore from iCloud Backup". That ended up taking several hours, but after that I could do the purchase again and was told I already purchased and it worked.
That doesn't help anyone who doesn't have a recent backup or has run into this problem and continued using the device since then. Basically there's something stored on the device at that point that isn't cleared by removing the App or by doing a "Reset All Settings". Only wiping the device fixes it.
I'm assuming whatever is being stored is part of "In app-purchased" which gets backed up, so any backups made after this happens will likely be "corrupted", unless there's a way to fix them manually using a third party program.
I'd suggest reporting this to bugreport.apple.com. You can give them my details in addition to the track trace if you want.
Upvotes: 9
Reputation: 166
We recently started getting similar crash reports from some of our users, the issue is that the productId being passed here is 'nil', which will cause a crash b/c it will be used as a key and a hash will need to be computed down the line.
However, its still not clear to us why it is sometimes 'nil'. But at least the crash can be avoided by guarding against the possibility that the productId can be nil at times.
Upvotes: 15