【问题标题】:Updating content when using Apple-hosted content for In-App Purchase使用 Apple 托管的内容进行应用内购买时更新内容
【发布时间】:2013-06-05 06:40:54
【问题描述】:

我正在使用 Apple 托管的内容实施应用内购买。以前我使用 Urban Airship 来托管我的内容,并使用他们的 SDK 来提供应用内商店 UI 和购买功能。

由于 Urban Airship 将于今年 7 月停止其 IAP 支持,我需要更换它。

Urban Airship SDK 支持更新购买的内容。我看到 StoreKit 提供了这个功能(至少在一定程度上),但不确定如何正确实现内容更新本身。

SKProduct 有一个downloadContentVersion,它指定了可从 Apple 下载的内容的版本。我会跟踪应用程序中当前下载的版本 - 所以我知道什么时候有可用的更新。

我坚持的部分是如何实际下载更新的内容?

我的第一个想法是为该特定购买进行恢复,但似乎无法恢复个别产品(仅限所有产品)。第二个想法是重新购买产品,但这会向用户显示一个提醒,表明他们将再次被收费 - 但是他们不会被收费,因为在重新购买后会显示另一个提醒,通知用户内容已购买,将免费重新下载 - 但对我来说,这感觉像是一种糟糕的用户体验,他们可能不一定知道在同意购买之前不会再次收费。

文档说不要自己创建 SKDownload 实例,所以我不能只创建一个并将其添加到下载队列中。

在使用 Apple 托管的内容时,我应该如何为应用内购买实施内容更新?

【问题讨论】:

  • 你有没有发现更多关于这个的信息?我有完全相同的问题。
  • @montreux 在下面看到我的回答

标签: ios in-app-purchase


【解决方案1】:

感谢 Jasarien 就此事与 Apple 联系。以下是一些示例代码,供任何发现此主题并试图了解如何更新应用内内容的人使用。

首先,当您收到来自 SKProductsRequest 的响应时,请检查 downloadContentVersion 与您之前下载的内容的版本。您可以使用如下代码获取现有内容的内容版本:

NSString *pathToYourContent = @""; // Put your path here
NSString *contentInfoPath = [pathToYourContent stringByAppendingPathComponent:@"ContentInfo.plist"];
NSDictionary *contentInfo = [NSDictionary dictionaryWithContentsOfFile:contentInfoPath];

NSString *contentVersion = [contentInfo objectForKey:@"ContentVersion"];
NSString *iapProductIdentifier = [contentInfo objectForKey:@"IAPProductIdentifier"];

然后,如果您发现该版本已更改,则可以提示用户进行更新。如果他们同意,则开始恢复。

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

然后,当交易开始进入时,您需要决定接受哪些交易,忽略哪些交易。在这个下载歌曲内容的应用程序示例中,我有一个 YHSongVersion 类,它存储我们下载的所有歌曲的 ID 和版本,这些存储在数组 self.ownedSongVersions 中。此示例将接受版本号不同或我们没有获得内容的任何恢复。

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            case SKPaymentTransactionStateFailed:
                break;

            case SKPaymentTransactionStatePurchased:
                [self provideContentForTransaction:transaction];
                break;

            case SKPaymentTransactionStatePurchasing:
                break;

            case SKPaymentTransactionStateRestored:
                [self restorePurchaseIfRequired:transaction];
                break;
        }
    }

}

/// On a restore download the content if either we don't have the content or the version number has changed.
- (void)restorePurchaseIfRequired:(SKPaymentTransaction *)transaction {
    BOOL haveSong = NO;
    SKDownload *download = [transaction.downloads objectAtIndex:0];
    for (YHSongVersion *ownedSongVersion in self.ownedSongVersions) {
        BOOL isSongForThisDownload = [ownedSongVersion.iapProductIdentifier isEqualToString:download.contentIdentifier];
        if (isSongForThisDownload) {
            haveSong = YES;
            BOOL hasDifferentVersionNumber = ![ownedSongVersion.contentVersion isEqualToString:download.contentVersion];
            if (hasDifferentVersionNumber) {
                [self provideContentForTransaction:transaction];
            }
            else {
                // Do nothing
                [self completeTransaction:transaction];
                NSLog(@"Ignoring restore for %@", ownedSongVersion.iapProductIdentifier);
            }
        }
    }

    if (!haveSong) {
        [self provideContentForTransaction:transaction];
    }
}

【讨论】:

  • 这似乎是一个有希望的答案。 +1
  • 这里的“问题”是用户需要输入密码,因为恢复总是需要密码。看到整个应用都可以在没有密码的情况下更新,这很不方便。
【解决方案2】:

我与 WWDC 的一些 Store Kit 工程师交谈,并问了他们这个问题。

他们的反应并不像我希望的那样积极。

他们确认没有用于将单个产品恢复为错误的 API,并鼓励我提交两个错误(一个是针对商店套件中该 API 的增强请求,另一个是关于该领域的文档过于稀疏)升级产品)。

至于眼前的问题,他们的建议是要么实现“全部更新”功能,其中恢复所有产品以获取它们的交易和下载对象(我最终选择的选项),或者类似地恢复所有产品,但忽略除您尝试更新的产品之外的所有产品(最终毫无意义,因为如果您对每个产品都采用这种方法,您将多次恢复所有产品)。

一旦我这样做,我将使用我提交的错误的雷达编号更新此答案,以便其他人可以在必要时复制它们(请记住,欺骗碰撞错误!)

编辑

我已经报告了这个错误,它的编号是 rdar://14174034 - 请随意复制。

【讨论】:

  • 我自己选择了您的第二个选项。当我看到内容版本增加时,我会提示用户查看他们是否要更新,如果他们愿意,我会开始恢复,但忽略我们已经拥有最新版本的任何产品。我将在另一个答案中添加一些代码,供我们之后的人使用。
猜你喜欢
  • 2015-03-03
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多