- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
对于具有非消耗性应用内购买的基本应用,有没有人想出使用 SKPaymentQueue 的 restoreCompletedTransactions
的最佳实践?
我知道建议始终注册事务观察器以接收返回应用程序的未决事务,但这是一个不同的问题。看起来 restoreCompletedTransactions
是应用程序必须主动决定何时调用以轮询客户已经进行的所有购买的事情。
据我所知,该方法旨在检索可能已丢失的购买。例如,客户可能会以这样一种方式将应用安装或移动到新设备,从而导致该应用以前付款的本地记录丢失或重置。
我不清楚的是如何以可靠的方式自动检测这种情况(即如何决定何时轮询丢失的购买)。我不想搞砸这件事并冒着拒绝客户访问他们已经付费的功能的风险。
与此同时,我不想每次应用程序启动时都调用 restoreCompletedTransactions
只是为了安全并且基本上取回我已经知道大约 99.9% 的交易。 (除了应用内购买,我的应用实际上不需要任何网络连接。)
Apple 文档阐明,客户无需为他们已经购买的任何非消耗品再次付费。如果他们尝试重新购买,付款交易仍会发送到该应用。
最坏的情况是,客户可以通过这种方式收 repo 买的商品,但我仍然希望避免让他们走上类似于重新购买他们已经支付过的东西的道路。
最佳答案
Apple 已经为这个主题命名,并用整个 WWDC session 来讨论它。
(如果链接最终失效,它指的是 WWDC 2022 的 session 110404。)
类(class)20分钟,内容丰富,值得推荐。有很多细节需要导航,但我将提供两个亮点。
restoreCompletedTransactions
不用于此。)您的应用唯一需要调用 restoreCompletedTransactions
的时间是用户点击“恢复购买”按钮时。 (从一开始,这几乎就是我们对这篇文章的建议。)
Apple 的 documentation on this topic 2018年更新的,比较全面。它的许多建议与我们最终在这里得出的结论一致。自此问题于 2009 年首次发布以来最大的发展是 iOS 7 中的 App Store 收据。
如果链接在将来的某个时候失效,我将在此处引用一些文档。
Restoring Purchased Products
Users restore transactions to maintain access to content they’ve already purchased. For example, when they upgrade to a new phone, they don’t lose all of the items they purchased on the old phone. Include some mechanism in your app to let the user restore their purchases, such as a Restore Purchases button. Restoring purchases prompts for the user’s App Store credentials, which interrupts the flow of your app: because of this, don’t automatically restore purchases, especially not every time your app is launched.
In most cases, all your app needs to do is refresh its receipt and deliver the products in its receipt. The refreshed receipt contains a record of the user’s purchases in this app, on this device or any other device. However, some apps need to take an alternate approach for one of the following reasons:
- If you use Apple-hosted content, restoring completed transactions gives your app the transaction objects it uses to download the content.
- If you need to support versions of iOS earlier than iOS 7, where the app receipt isn’t available, restore completed transactions instead.
- If your app uses non-renewing subscriptions, your app is responsible for the restoration process.
Refreshing the receipt asks the App Store for the latest copy of the receipt. Refreshing a receipt does not create any new transactions. Although you should avoid refreshing multiple times in a row, this action would have same result as refreshing it just once.
Restoring completed transactions creates a new transaction for every completed transaction the user made, essentially replaying history for your transaction queue observer. While transactions are being restored, your app maintains its own state to keep track of why it’s restoring completed transactions and how it needs to handle them. Restoring multiple times creates multiple restored transactions for each completed transaction.
在写下问题并思考之后,我想出了几个解决方案。
一个选项是在用户默认值中记录 restoreCompletedTransactions
是否已在应用程序中调用(并成功完成)。如果没有,应用程序会在启动时调用它一次。由于此标志可以存储在与非消耗性付款相同的位置,如果用户默认值稍后被删除,则恢复方法将在应用程序启动时再次调用。
这样,如果现有客户以某种方式重新安装应用程序,他们仍然会自动恢复购买。如果他们是以前从未启动过该应用程序的新客户,则恢复操作不会返回任何内容。
无论哪种情况,restoreCompletedTransactions
都只被调用一次,而不是在每次启动时调用。
另一种选择是在某处为客户提供“恢复购买”按钮,将其连接到 restoreCompletedTransactions
并让他们决定是否以及何时可能需要它。
(下面的评论说明了为什么手动恢复可能比尝试自动恢复更好。)
关于iphone - 何时使用 restoreCompletedTransactions 进行应用内购买?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1757467/
我正在通过 labrepl 工作,我看到了一些遵循此模式的代码: ;; Pattern (apply #(apply f %&) coll) ;; Concrete example user=> (a
我从未向应用商店提交过应用,但我会在不久的将来提交。 到目前为止,我对为 iPhone 而非 iPad 进行设计感到很自在。 我了解,通过将通用PAID 应用放到应用商店,客户只需支付一次就可以同时使
我有一个应用程序,它使用不同的 Facebook 应用程序(2 个不同的 AppID)在 Facebook 上发布并显示它是“通过 iPhone”/“通过 iPad”。 当 Facebook 应用程序
我有一个要求,我们必须通过将网站源文件保存在本地 iOS 应用程序中来在 iOS 应用程序 Webview 中运行网站。 Angular 需要服务器来运行应用程序,但由于我们将文件保存在本地,我们无法
所以我有一个单页客户端应用程序。 正常流程: 应用程序 -> OAuth2 服务器 -> 应用程序 我们有自己的 OAuth2 服务器,因此人们可以登录应用程序并获取与用户实体关联的 access_t
假设我有一个安装在用户设备上的 Android 应用程序 A,我的应用程序有一个 AppWidget,我们可以让其他 Android 开发人员在其中以每次安装成本为基础发布他们的应用程序推广广告。因此
Secrets of the JavaScript Ninja中有一个例子它提供了以下代码来绕过 JavaScript 的 Math.min() 函数,该函数需要一个可变长度列表。 Example:
当我分别将数组和对象传递给 function.apply() 时,我得到 NaN 的 o/p,但是当我传递对象和数组时,我得到一个数字。为什么会发生这种情况? 由于数组也被视为对象,为什么我无法使用它
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界. 这篇CFSDN的博客文章ASP转换格林威治时间函数DateDiff()应用由作者收集整理,如果你
我正在将列表传递给 map并且想要返回一个带有合并名称的 data.frame 对象。 例如: library(tidyverse) library(broom) mtcars %>% spl
我有一个非常基本的问题,但我不知道如何实现它:我有一个返回数据框,其中每个工具的返回值是按行排列的: tmp<-as.data.frame(t(data.frame(a=rnorm(250,0,1)
我正在使用我的 FB 应用创建群组并邀请用户加入我的应用群组,第一次一切正常。当我尝试创建另一个组时,出现以下错误: {"(OAuthException - #4009) (#4009) 在有更多用户
我们正在开发一款类似于“会说话的本”应用程序的 child 应用程序。它包含大量用于交互式动画的 JPEG 图像序列。 问题是动画在 iPad Air 上播放正常,但在 iPad 2 上播放缓慢或滞后
我关注 clojure 一段时间了,它的一些功能非常令人兴奋(持久数据结构、函数式方法、不可变状态)。然而,由于我仍在学习,我想了解如何在实际场景中应用,证明其好处,然后演化并应用于更复杂的问题。即,
我开发了一个仅使用挪威语的应用程序。该应用程序不使用本地化,因为它应该仅以一种语言(挪威语)显示。但是,我已在 Info.plist 文件中将“本地化 native 开发区域”设置为“no”。我还使用
读完 Anthony's response 后上a style-related parser question ,我试图说服自己编写单体解析器仍然可以相当紧凑。 所以而不是 reference ::
multicore 库中是否有类似 sapply 的东西?还是我必须 unlist(mclapply(..)) 才能实现这一点? 如果它不存在:推理是什么? 提前致谢,如果这是一个愚蠢的问题,我们深表
我喜欢在窗口中弹出结果,以便更容易查看和查找(例如,它们不会随着控制台继续滚动而丢失)。一种方法是使用 sink() 和 file.show()。例如: y <- rnorm(100); x <- r
我有一个如下所示的 spring mvc Controller @RequestMapping(value="/new", method=RequestMethod.POST) public Stri
我正在阅读 StructureMap关于依赖注入(inject),首先有两部分初始化映射,具体类类型的接口(interface),另一部分只是实例化(请求实例)。 第一部分需要配置和设置,这是在 Bo
我是一名优秀的程序员,十分优秀!