在应用内购买之后,启动时 SKPaymentQueue addTransactionObserver 要求输入App Store 的密码。

56

我的应用使用应用内购买,大多数用户可以顺利购买而没有任何问题。对于这些用户,我的应用会在购买成功后下载内容,他们也很满意。

然而,越来越多的用户,在完成一次成功的应用内购买后,每次启动应用程序时都被要求输入他们的App Store密码。我认为这是发生在调用以下函数时:

[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];

根据苹果的应用内购买指南中的第6步,我在启动时调用了以下函数:

我猜测是因为某种原因,苹果应用内购买服务器没有成功注册交易完成的事实 - 即使我调用了该方法。

[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

当交易完成并且我的内容已经成功下载时。

2个问题:

  1. 还有其他人看到这个问题吗?

  2. 有人有建议的修复方法吗?

悬赏编辑:

这是一个使用不同的Apple-ID进行的交易。因此,除非您在对话框中输入正确的凭据,否则无法完成交易。问题应该是:

  1. 如何防止这种死亡交易(交易未完成,用户没有网络,同时更改了App-ID)?
  2. 如何修剪 SkPaymentQueue

我也遇到了这个问题。 - Aloha Silver
1
它必须依赖于某些已被另一个AppStore帐户中断的交易:http://stackoverflow.com/questions/6971740/in-app-purchase-sign-in-to-itunes-store-after-skpaymentqueue-defaultqueue-a。用户必须尝试他曾经使用过的所有AppStore帐户,如果找到正确的帐户,则不会再出现该消息。但这不能是解决方案。必须确保不会弹出与旧/以前的AppStore帐户相关的任何交易。也许这是苹果的“漏洞”? - Rene Berlin
你在哪里添加了你的事务观察器? - βhargavḯ
@montuno 你最终是如何解决这个问题的? - SAHM
有时测试服务器上的iTunes表现得有点奇怪。在我的应用程序中,当我调用[[SKPaymentQueue defaultQueue] addTransactionObserver:paymentProcessorDelegate];后,它会不停地要求验证。这种情况是偶尔发生的,并且仅在今天出现,因此我期望问题会在以后某个时候“自行解决”。 - bobobobo
苹果公司提供了一些最佳实践:https://developer.apple.com/library/content/technotes/tn2387/_index.html - Cœur
14个回答

32

我曾经也遇到过相同的问题。请确保你调用了

[[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 

对于交易的三种状态:SKPaymentTransactionStatePurchased、SKPaymentTransactionStateRestored和SKPaymentTransactionStateFailed。


3
是的,但我连任何交易都没有。 我甚至为每个5个SKPaymentTransactionObserver代理方法插入了代理。现在每次启动我的应用程序时iTunes商店都会要求我登录.. - bobobobo
为了解决同样的问题,这对我帮助很大! - pipipi
情况:您已经注册了一些testuser1@t.com并测试了IAP,但没有完成某些交易。然后您注册了testuser2@t.com。因此,如果您打开应用程序(想要使用testuser2@t.com进行测试),您将看到一个对话框,要求输入testuser1@t.com的凭据!即使您从ITC中删除了testuser1@t.com用户-这个对话框仍然会出现,直到您为旧用户(testuser1@t.com)输入正确的凭据。之后,这个对话框就不会再出现了!这对我很有效。 - iVader

8

我曾经遇到了同样的问题,即在调用时弹出登录提示:

[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];

有时,即使我不使用我的应用程序(在主屏幕或其他应用程序中),它也会不时地弹出,这真的很烦人。看了一下,似乎有很多关于这个问题的建议答案,但最终我从我收集的资料中找到了一个解决方案。
注意:在第1步之前,我已经从iTunes Connect中删除了测试沙盒帐户。我不确定这是否会影响解决方案。
为了解决这个问题,我做了以下几点:
  1. 从Xcode运行您的应用程序。
  2. 等待提示框弹出。输入所需的帐户密码并点击“确定”。
  3. 按设备上的Home按钮。
  4. 从Xcode终止应用程序。
  5. 从设备中删除应用程序。
  6. 在“设置”应用程序中退出iTunes和App Store。
  7. 关闭设备,然后重新启动它。
  8. 从应用商店购买某些东西。当它提示您时,请使用生产Apple ID帐户登录。(我假设您应该能够在“设置”应用程序下只使用生产帐户登录iTunes和App Store,但这是我做法的方式)。
  9. 回到Xcode并再次运行您的应用程序。(这应该是一个新安装,因为您之前删除了应用程序。)
  10. 等待登录提示框弹出。
  11. 点击取消。会出现"需要登录。点击继续并登录以检查下载内容。[环境:沙盒]"的对话框。这是与之前不同的关键点。当它要求我输入密码时,我按取消从未看到过这个对话框。
  12. 点击“继续”。
  13. 输入帐户密码。
就这样。从那以后,每当我运行我的应用程序时,登录提示框都不会再弹出,在随机时间也不会再弹出。
希望这有所帮助!

1
对我有用。第11到13步是解决问题的关键步骤。我不确定步骤1到10中需要触发它的步骤数量。记录一下,我没有删除测试沙盒帐户(步骤0),也没有从应用商店购买任何东西(步骤8)。不过,我确实使用了生产帐户在设置中登录(如步骤8所建议的)。 - Mark A. Durham
1
我刚刚做了1到10,然后在第11步上点击了取消,就这样。它真的起作用了 :) - Infaz
#11 是关键! - Michael Ozeryansky
addTransationObserver: 的文档说明中提到:“这可能需要用户进行身份验证。”- 因此,如果您调用该方法,则这似乎是正确/预期的行为。 - pkamb

8

不要删除此答案。正是这个特定的Stackoverflow问题让我误导了,让我困扰了好几天。

我把它放在这里是因为有很多非常糟糕的答案提供了错误的解决问题的信息。

不要:

  • 删除沙盒测试用户。这会使问题无法解决,您将不得不联系苹果开发者支持手动解决。
  • 如果您删除了沙盒测试用户,则在随后反复提示您登录该用户并完成交易时,您将无法这样做,因此出现了无限循环问题。您也无法再次添加已删除的测试用户;开发人员门户网站表示用户ID已被使用。
  • 删除应用程序或重新安装iOS或任何其他类似的荒谬行为。这没有任何效果,也不能解决问题,浪费了很多时间。

要:

  • 对于所有交易,请调用Finish方法。
  • 如果由于某种原因中断了其中一个交易,请在随后的应用程序运行中简单地完成它。应用程序将反复收到付款队列通知,直到您在其中调用finish方法:

[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

就是这样,完成所有交易!否则,每次在该设备上启动您的应用程序时,您都将被发送到无限循环的登录请求地狱。


1
不太确定为什么人们要对此进行投票?显然,进行投票的人要么无知于事实,要么就是出于报复心理。作为一名长期从事iOS开发的人,最近曾因此处某个答案而遭受严重影响,我向你保证,千万不要这样做。 - Cliff Ribaudo
我猜人们会点踩是因为你没有清楚地表明你建议在测试/调试期间完成所有交易作为临时解决方案。其他一些人可能会使用你的建议,他们的应用程序将立即清除.deferred或.purchasing状态并进入生产环境(这对于生产环境中的应用程序不利)。 - Vitalii
你在说什么?!我不建议完成交易是一种临时解决方案。无论是在测试还是生产环境中,都必须始终完成交易...所以如果你投了反对票,也许你应该重新考虑一下或者向我展示确切的地方表明它是临时的。 - Cliff Ribaudo
1
Cliff,我没有给你的回答点踩。我点了赞,因为你的回答帮助了我。答案很明显,这就是为什么我猜测你问“为什么人们会点踩?”...你绝对是正确的,应用程序应该被设计(并经过充分测试)以确保所有交易最终都能完成,否则事情会变得糟糕。我猜想有些人可能会字面理解你的建议——他们可能会尝试在paymentQueue(_:updatedTransactions:)中立即完成所有事情,并感到失望,因为他们正在处理“购买”和“延迟”状态下的交易。 - Vitalii
好的,我现在明白了 ;) 一些人因为某些原因对此进行了负面评价。不确定为什么,因为这实际上是最正确的答案。许多开发人员遇到问题时的第一反应是删除沙盒用户,这将会带来麻烦。 - Cliff Ribaudo
我知道这是一个旧答案,但它很有帮助 - 特别是“不要”部分。@CliffRibaudo,我认为误解在于人们将您说的“所有交易”与所有状态混淆了。交易必须在队列上“完成”,才能达到“已购买”,“已恢复”和“失败”的状态。在任何其他状态下尝试完成都会引发异常。 - siburb

4

有一个问题叫作“无限循环”。在自动续订的早期阶段,这是一个很大的问题,因为服务器在约一个星期内没有将续订次数限制为5次。如果设备收到一笔交易但不调用finishTransaction函数,则该交易会每周发送一次到该设备,直到特定测试用户登录并调用finishTransaction函数。如果您切换到飞行模式,可以“清除”这些交易一周 - 但它们会重新出现。


这听起来非常类似于我以前遇到的一个问题,那时候自动续订还不存在。不幸的是,这些弹出窗口与我的个人主帐户绑定,所以它们每周或更长时间就会出现一次,我必须按取消按钮30-50次才能放弃。经过多年的努力,我通过回到以前测试IAP实现的测试应用程序,创建具有相同捆绑标识符的应用程序,成功地解决了这个问题。我能够捕获一些非常旧的未完成交易,完成它们,然后我几年来遇到的问题就消失了。 - Jonny

3

我认为这是正确的行为。当您设置 SKPaymentQueue 的代理时,尝试检查是否有一些需要完成的交易。可能没有未完成的交易,但检查的事实需要登录到 iTunes。我认为您无法做任何事情。

这通常是有道理的,但对于设置每次交易请求密码的用户(例如某些儿童保护),这非常令人烦恼。所以与其这样,不如在请求 iTunes 时明确设置代理。例如,您可以添加一个类似“恢复我的购买”的按钮。虽然不太美观,但肯定不那么烦人。


我曾经在我协助开发的一个应用中也做过同样的事情。这可能是最简单的解决方案。 - F.X.

1
如果有人看到这个并且正在使用GoogleMobileAds.framework,那么您可能还需要调用。
[GADMobileAds disableAutomatedInAppPurchaseReporting];

在`-application:didFinishLaunchingWithOptions:`方法中。

1

当我测试IAP时,遇到了同样的问题。

我用了3个测试账户。应用程序一直要求输入密码,即使我没有点击任何购买/还原按钮或addTransactionObserver

我认为这是因为某些之前的交易没有正确完成,但是[[SKPaymentQueue defaultQueue] finishTransaction:transaction];毫无作用。

所以,以下是我解决这个问题的方法:

  1. 无论App Store要求多少次,都要为每个帐户输入密码--我为3个帐户输入了6次--直到它不再要求。
  2. 进入设置并注销Apple ID。
  3. 正常退出应用程序--不要在Xcode中终止它。然后在任务列表中杀死进程。
  4. 从设备中删除应用程序(简单地删除应用程序不起作用,它仍然会要求输入密码)
  5. 重新启动设备
  6. 从Xcode运行应用程序/在您的情况下从应用商店重新安装应用程序。

灵感来自 使用iTunes测试用户时的预期序列


1

以下是我如何持续重现和解决这个问题的步骤:

iOS 8.4,应用程序的开发构建版本。

  1. Use a test(sandbox) Apple Account.

  2. Restore purchased transactions.

    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]
    
  3. Immediately close the app.

  4. Log out of test account (through settings)

  5. Launch app

现在每次我启动应用程序时,都会弹出“登录”表单。无论我是否输入密码,无论我是否进行购买或恢复购买,无论我是否删除并重新安装应用程序,每次启动应用程序时,都会出现iTune登录页面。
修复:强制重启设备。
这是我不知道的事情。在生产环境(发布的应用程序和实际的苹果登录)中是否会发生这种情况?我希望不会。

0

删除并重新安装应用程序将删除与另一个iTunes帐户相关联的任何旧交易。如果您仍然看到发布到通知队列的交易,则可能在逻辑中有一些分支未调用finishTransaction。

您需要在paymentQueue:updatedTransactions:中发布的所有交易上调用finishTransaction,即使是SKPaymentTransactionStateFailed的交易也要调用。


不,它不会!这是错误的建议。不要这样做。 - Cliff Ribaudo

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接