题 在App Purchase(IAP)过程中,我的一个用户似乎在启动时崩溃了应用程序


我一直在与我的应用程序的用户一起工作,该用户在启动应用程序时遇到崩溃。我们认为它必须在应用程序内购买过程中做一些事情,但我无法诊断原因所以我认为我会把它带到这里(对于我所谈过的每个其他用户,事情似乎都在起作用正好)。

回到有问题的用户,她说,自从她购买IAP以来,应用程序在发布时崩溃了。在崩溃之后,设备经常提示用户输入她的用户ID和密码(好像它正在尝试再次购买)。我们已经尝试重新安装应用程序,更新到iOS 7,更新应用程序本身......没有运气。

她很高兴能给我发一些崩溃日志,我在下面复制过。任何输入将不胜感激!

我在iOS 6教程中关注了Ray Wenderlich的IAP,如果这有帮助的话......除此之外没有其他报道的问题,这让我想知道在购买过程中是否有什么事情发生了变化。

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

编辑添加IAPHelper的第172行:

它在产品恢复期间调用,并传入IAP的productIdentifier。有趣的是,这是在应用程序启动时发生的,这让我想知道这是否是在IAP购买过程中丢失了互联网连接的情况,现在它正试图在启动时恢复它。

IAPHelper包含许多购买和恢复产品的方法(也是购买通知的观察者)。在applicationDidFinishLaunching中调用sharedInstance,以便它可以从Apple接收收据。第172行是将产品标识符添加到_purchasedProductIdentifiers的位置,这是一个NSMutableSet实例变量。错误是否意味着_purchasedProductIdentifiers出现问题(NSMutable集应该在它到达之前初始化)或者传入productIdentifier?实际上,除非创建了IAPHelper的sharedInstance,否则我们永远不应该达到这一点,这是创建_purchasedProductIdentifiers的地方。

- (void)provideContentForRestoredProductIdentifier:(NSString *)productIdentifier
{
    [_purchasedProductIdentifiers addObject:productIdentifier]; 
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier];
    [[NSUserDefaults standardUserDefaults] synchronize];
    [[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductRestoredNotification object:productIdentifier userInfo:nil];

}

19
2017-10-05 23:55


起源


IAPHelper.m的172行是什么样的?环境越多越好。 - Jason Whitehorn
刚补充一些细节。 - tonyd
@tonyd你的问题到底是什么?我遇到了同样的问题,看起来它在同一个地方。我真的很感激您的反馈! - SAHM
@JPK请参阅下面的选定答案。希望有所帮助,但如果没有,请随时联系! - tonyd
可能重复 在应用程序购买之后,应用程序在启动时崩溃。产品识别=无? - tenpn


答案:


我们最近开始从我们的一些用户那里获得类似的崩溃报告,问题是这里传递的productId是'nil',这将导致崩溃b / c它将被用作密钥并且需要计算哈希值下线。

然而,它仍然不清楚为什么它有时是'零'。但至少可以通过防止productId有时可能为零的可能性来避免崩溃。


15
2017-11-11 22:46



这是该问题的正确答案。 productID以nil形式出现,这导致应用程序在添加到NSSet时崩溃。由于应用程序崩溃,finishTransaction:从未被调用,因此当我添加事务观察器时,它会在启动时始终崩溃,这会促使事务再次通过(仍然使用nil productID)。 - tonyd
该修复程序是为nil productID准备的。对于我有一个IAP的应用,我只需使用应用内购买初始化productID即可。另一个拥有多个productID的开发人员说他只是调用了FinishTransaction:没有做任何事情。然后,用户可以恢复事务,并且productID将通过。 - tonyd
我们如何为已经拥有零产品标识符的用户解决此问题?每次发布更新时,我都会有一位特别的用户给我一个星级评论,因为他的应用程序崩溃了(可以理解) - Eric


今天早上我用我的iPhone 5S和一个应用程序遇到了这个问题。问题似乎是由于我在尝试执行应用内购买时需要在最近添加的信用卡上验证安全代码。这让我退出应用程序,进入App Store。

验证我的安全代码后,系统提示我再次购买应用内购买。我这样做了,但由于我当时不在应用程序中,因此我没有通知应用程序我已购买。我切换回应用程序并使用应用程序的恢复购买选项,当我输入我的App Store密码时,应用程序随后崩溃并在启动时继续崩溃,即使在卸载后,手机重新启动并重新安装应用程序。我甚至尝试重置所有设置并退出我的App Store iTunes帐户。什么都没有阻止崩溃。

我查看了崩溃堆栈,它与上面粘贴的非常相似,堆栈中有一堆StoreKit条目。不幸的是,在采用核选项之前我没有保存堆栈(见下文)。这是在iOS 7.0.3下。当我在另一台设备上安装应用程序并进行恢复购买时,看起来购买已经完成。

不幸的是,解决这个问题的唯一方法就是擦除手机并从尝试购买前的备份中恢复。幸运的是,在发生这种情况之前大约30分钟我刚刚备份到iCloud,所以我做了“擦除所有设置和数据”,然后是“从iCloud备份恢复”。这最终需要花费几个小时,但之后我可以再次购买并被告知我已经购买并且有效。

这对于没有最近备份或遇到此问题并且从那时起继续使用该设备的任何人都没有帮助。基本上,此时设备上存储的内容无法通过删除应用程序或执行“重置所有设置”来清除。只擦拭设备就可以修复它。

我假设存储的内容是“在应用程序中购买”的一部分,它会被备份,因此在此之后进行的任何备份都可能会“损坏”,除非有办法使用第三方程序手动修复它们。

我建议将此报告给bugreport.apple.com。如果需要,您可以在轨道跟踪之外向他们提供我的详细信息。


9
2017-11-13 19:18



这是一个非常好的信息,确实有助于描述问题背后的原因。谢谢莫拉克。 - tonyd


我有类似的症状(应用程序在每次启动时崩溃),问题是队列没有保留StoreObserver:

StoreObserver *observer = [[StoreObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];

解决方案是使观察者成为实例变量。

线程处理这个问题: 应用程序崩溃[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];


0
2017-12-23 11:52