Подтвердить что ты не робот

Обновление содержимого при использовании контента, размещенного в Apple, для покупки в приложении

Я внедряю In-App Purchase с использованием контента, размещенного на Apple. Раньше я использовал Urban Airship для размещения моего контента и использования своего SDK для обеспечения пользовательского интерфейса и покупки в приложении.

Поскольку Urban Airship прекращают поддержку IAP в июле этого года, мне нужно его заменить.

В SDK Urban Airship была поддержка обновления приобретенного контента. Я вижу, что StoreKit предоставляет эту функциональность (по крайней мере, до некоторой степени), но я не уверен, как правильно реализовать само обновление контента.

SKProduct имеет downloadContentVersion, который указывает версию содержимого, доступную для загрузки из Apple. Я отслеживаю, какая версия в настоящее время загружается в приложение, поэтому я знаю, когда доступно обновление.

Часть, с которой я застрял, - это как загрузить загруженный контент?

Моя первая мысль заключалась в том, чтобы сделать восстановление для этой конкретной покупки, но, похоже, нет способа восстановить отдельные продукты (только для всех продуктов). Вторая мысль заключалась в том, чтобы просто повторно приобрести продукт, но это представляет предупреждение пользователю, указывающее, что они будут списаны снова - они не будут списаны, однако, поскольку после повторного приобретения отображается другое предупреждение, информирующее пользователя о том, что контент уже куплен и будет повторно загружен бесплатно, но для меня это похоже на плохой пользовательский опыт, они могут не знать, что они не будут списаны снова, пока не согласится на покупку.

В документации говорится, что я не создавал экземпляры SKDownload, поэтому я не могу просто создать его и добавить в очередь загрузки.

Как я могу реализовать обновления контента для In-App Purchase при использовании контента, размещенного в Apple?

4b9b3361

Ответ 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, который хранит идентификатор и версию для всех загруженных нами песен, и они хранятся в массиве 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];
    }
}

Ответ 2

Я поговорил с инженерами Store Kit в WWDC и задал им этот вопрос.

Их ответ был не таким позитивным, как я надеялся.

Они подтвердили отсутствие API для восстановления одного продукта в качестве ошибки и предложили мне записать две ошибки (один для запроса расширения для этого API в наборе для хранения, а другой - для слишком скудной документации по этой области обновление продуктов).

Что касается непосредственной проблемы, их предложение заключалось в том, чтобы либо реализовать функцию "обновить все", в которой все продукты были восстановлены, чтобы получить свои транзакции и их объекты загрузки (вариант, который я в конечном счете выбрал), или аналогичным образом восстановить все продукты, но игнорируйте все продукты, кроме тех, которые вы пытаетесь обновить (бессмысленно, в конечном счете, поскольку вы восстанавливаете все несколько раз, если будете следовать этому подходу для каждого продукта).

Я обновляю этот ответ с номерами Radar для файлов ошибок, которые я когда-либо делаю, чтобы другие могли дублировать их, если это необходимо (помните, обманывают ошибки bump!)

Изменить

Я сообщил об ошибке, и ее номер rdar://14174034 - не стесняйтесь дублировать.