Alterações ao StoreKit no iOS 6
O iOS 6 introduziu duas alterações à API do Kit da Loja: a capacidade de apresentar os produtos iTunes (e App Store/iBookstore) a partir da sua aplicação e uma nova opção de compra na aplicação onde a Apple irá alojar os seus ficheiros transferíveis. Este documento explica como implementar esses recursos com o Xamarin.iOS.
As principais alterações ao Store Kit no iOS6 são estas duas novas funcionalidades:
- In-App Visualização de conteúdo & Compra de – os utilizadores podem comprar e descarregar apps, música, livros e outros conteúdos do iTunes sem sair da aplicação. Você também pode criar links para seus próprios aplicativos para promover compras ou apenas incentivar avaliações e classificações.
- In-App Comprar conteúdo hospedado – A Apple armazenará e entregará o conteúdo associado aos seus produtos de compra no aplicativo, o que elimina a necessidade de um servidor separado para hospedar seus arquivos, suporta automaticamente o download em segundo plano e permite que você escreva menos código.
Consulte os guias de compra In-App para obter uma cobertura detalhada das APIs do StoreKit.
Requerimentos
Os recursos do Kit da Loja discutidos neste documento exigem o iOS 6 e o Xcode 4.5, juntamente com o Xamarin.iOS 6.0.
In-App Exibição de Conteúdo & Aquisição
O novo recurso de compra no aplicativo no iOS permite que os usuários visualizem informações do produto e comprem ou baixem o produto de dentro do seu aplicativo. Anteriormente, os aplicativos teriam que acionar o iTunes, a App Store ou a iBookstore, o que resultaria na saída do usuário do aplicativo original. Esse novo recurso retorna automaticamente o usuário ao seu aplicativo quando ele terminar.
Exemplos de como isso poderia ser usado incluem:
- Incentivar os utilizadores a classificarem a sua aplicação – Pode abrir a página da App Store para que o utilizador possa avaliar e rever a sua aplicação sem a abandonar.
- Aplicativos de promoção cruzada – Permite que o usuário veja outros aplicativos que você publica, com a capacidade de comprar/baixar imediatamente.
- Ajudar os utilizadores a encontrar e transferir conteúdo – Ajude os utilizadores a comprar conteúdo que a sua aplicação encontra, gere ou agrega (por exemplo, uma aplicação relacionada com música pode fornecer uma lista de reprodução de músicas e permitir que cada música seja comprada a partir da aplicação).
Uma vez que o SKStoreProductViewController
tenha sido exibido, o usuário pode interagir com as informações do produto como se estivessem no iTunes, na App Store ou na iBookstore. O utilizador pode:
- Ver capturas de ecrã (para aplicações),
- Exemplos de músicas ou vídeos (para música, programas de TV e filmes),
- Leia (e escreva) comentários,
- Compre & e faça o download, algo que acontece inteiramente dentro do view controller e do Store Kit.
Algumas opções dentro do SKStoreProductViewController
ainda forçarão o utilizador a sair da sua aplicação e abrir o app da loja relevante, como clicar em Produtos Relacionados ou no link de Suporte de uma aplicação.
SKStoreProductViewController
A API para mostrar um produto dentro de qualquer aplicativo é simples: requer apenas que você crie e exiba um SKStoreProductViewController
. Siga estas etapas para criar e mostrar um produto:
- Crie um objeto
StoreProductParameters
para passar parâmetros para o controlador de exibição, incluindo oproductId
no construtor. - Para instanciar o
SKProductViewController
. Atribua-o a um campo de nível de classe. - Atribua um manipulador ao evento
Finished
do controlador de exibição, que deve descartar o controlador de exibição. Este evento é chamado quando o usuário pressiona cancelar; ou, de outra forma, finaliza uma transação dentro do controlador de exibição. - Chame o método
LoadProduct
passando oStoreProductParameters
e um manipulador de conclusão. O manipulador de conclusão deve verificar se a solicitação do produto foi bem-sucedida e, em caso afirmativo, apresentar oSKProductViewController
de forma modal. Deve ser adicionado o tratamento adequado de erros caso o produto não possa ser recuperado.
Exemplo
O projeto ProductView no código de exemplo do StoreKit para este artigo implementa um método Buy
que aceita o ID Apple de qualquer produto e exibe o SKStoreProductViewController
. O código a seguir exibe as informações do produto para qualquer ID Apple:
void Buy (int productId)
{
var spp = new StoreProductParameters(productId);
var productViewController = new SKStoreProductViewController ();
// must set the Finished handler before displaying the view controller
productViewController.Finished += (sender, err) => {
// Apple's docs says to use this method to close the view controller
this.DismissModalViewControllerAnimated (true);
};
productViewController.LoadProduct (spp, (ok, err) => { // ASYNC !!!
if (ok) {
PresentModalViewController (productViewController, true);
} else {
Console.WriteLine (" failed ");
if (err != null)
Console.WriteLine (" with error " + err);
}
});
}
O aplicativo se parece com a captura de tela abaixo quando em execução - download ou compra ocorre inteiramente dentro do SKStoreProductViewController
:
Suporte a sistemas operacionais mais antigos
O aplicativo de exemplo inclui código que mostra como abrir a App Store, o iTunes ou a iBookstore em versões anteriores do iOS. Utilize o método OpenUrl
para abrir uma URL itunes.com bem construída.
Você pode implementar uma verificação de versão para determinar qual código executar, conforme mostrado aqui:
if (UIDevice.CurrentDevice.CheckSystemVersion (6,0)) {
// do iOS6+ stuff, using SKStoreProductViewController as shown above
} else {
// don't do stuff requiring iOS 6.0, use the old syntax
// (which will take the user out of your app)
var nsurl = new NSUrl("http://itunes.apple.com/us/app/angry-birds/id343200656?mt=8");
UIApplication.SharedApplication.OpenUrl (nsurl);
}
Erros
O seguinte erro ocorrerá se o ID Apple que você usa não for válido, o que pode ser confuso, pois implica um problema de rede ou autenticação de algum tipo.
Error Domain=SKErrorDomain Code=5 "Cannot connect to iTunes Store"
Leitura da documentação Objective-C
Os desenvolvedores que lerem sobre o Store Kit no Portal do Desenvolvedor da Apple verão um protocolo – SKStoreProductViewControllerDelegate – discutido em relação a esse novo recurso. O protocolo delegado tem apenas um método – productViewControllerDidFinish – que foi exposto como o evento Finished
no SKStoreProductViewController
no Xamarin.iOS.
Determinar o ID Apple
O ID Apple exigido pelo SKStoreProductViewController
é um número (não confundir com IDs de pacote como "com.xamarin.mwc2012"). Existem algumas formas diferentes de descobrir o ID Apple para os produtos que pretende apresentar, listadas abaixo:
iTunesConnect
Para as aplicações que publica, é fácil encontrar o ID Apple no iTunes Connect:
API de pesquisa
A Apple fornece uma API de pesquisa dinâmica para consultar todos os produtos na App Store, iTunes e iBookstore. Informações sobre como acessar a API de pesquisa podem ser encontradas nos Recursos de Afiliados da Apple, embora a API esteja exposta a qualquer pessoa (não apenas afiliados registrados). O JSON resultante pode ser analisado para descobrir o trackId
que é o ID Apple a ser usado com SKStoreProductViewController
.
Os resultados também incluirão outros metadados, incluindo informações de exibição e URLs de ilustrações que podem ser usadas para renderizar o produto em seu aplicativo.
Eis alguns exemplos:
- aplicação iBooks – https://itunes.apple.com/search?term=ibooks& entity=software&country=us
- Dot e o Kangaroo iBook – https://itunes.apple.com/search?term=dot+and+the+kangaroo& entidade=ebook&country=eua
Feed de parceiros de empresas
A Apple fornece aos parceiros aprovados um dump de dados completo de todos os seus produtos, em ficheiros planos prontos para serem utilizados em bases de dados. Se se qualificar para aceder ao Feed de Parceiros Empresariais, o ID Apple de qualquer produto pode ser encontrado nesse conjunto de dados.
Muitos utilizadores do Feed de Parceiros Empresariais são membros do Programa de Afiliados que permite que comissões sejam ganhas sobre vendas de produtos.
SKStoreProductViewController
não suporta IDs de Afiliado (no momento da redação deste artigo).
Links diretos de produtos
O ID Apple de um produto pode ser inferido a partir da ligação URL de pré-visualização do iTunes.
Em qualquer link de produto do iTunes (para aplicativos, músicas ou livros), localize a parte do URL que começa com id
e use o número a seguir.
Por exemplo, o link direto para o iBooks é
http://itunes.apple.com/us/app/ibooks/id364709193?mt=8
e o ID Apple é 364709193. Da mesma forma, para o aplicativo MWC2012, o link direto é
http://itunes.apple.com/us/app/mwc-2012-unofficial/id496963922?mt=8
e o ID Apple é 496963922.
In-App Comprar conteúdo hospedado
Se suas compras no aplicativo consistirem em conteúdo para download (como livros ou outras mídias, arte e configuração no nível do jogo ou outros arquivos grandes), esses arquivos costumavam ser hospedados em seu servidor da Web e os aplicativos tinham que incorporar código para baixá-los com segurança após a compra. A partir do iOS 6, a Apple hospedará seus arquivos em seus servidores, eliminando a necessidade de um servidor separado. Esta funcionalidade está apenas disponível para produtos Não Consumíveis (não para Consumíveis ou Subscrições). As vantagens de usar o serviço de hospedagem da Apple incluem:
- Poupe em custos de largura de banda de hospedagem &.
- Provavelmente mais escalável do que qualquer host de servidor que você esteja usando no momento.
- Menos código para escrever, já que você não precisa criar nenhum processamento do lado do servidor.
- O download em segundo plano foi implementado para sua conveniência.
Nota: o teste de conteúdo de compra hospedado no aplicativo no iOS Simulator não é suportado, portanto, você deve testar com um dispositivo real.
Noções básicas de conteúdo hospedado
Antes do iOS 6, havia duas maneiras de fornecer um produto (descritas com mais detalhes na documentação de compra do In-App Xamarin):
- Built-In Produtos – Recursos que são "desbloqueados" pela compra, mas que são incorporados ao aplicativo (como código ou recursos incorporados). Exemplos de produtos integrados incluem filtros de fotos desbloqueados ou power-ups no jogo.
- Server-Delivered Produtos – Após a compra, a aplicação deve baixar o conteúdo de um servidor que você opera. Esse conteúdo é baixado durante a compra, armazenado no dispositivo e, em seguida, renderizado como parte do fornecimento do produto. Os exemplos incluem livros, edições de revistas ou níveis de jogo que consistem em arte de fundo e arquivos de configuração.
No iOS 6, a Apple oferece uma variação de produtos entregues pelo servidor: eles hospedarão seus arquivos de conteúdo em seus servidores. Isso torna muito mais simples criar produtos entregues pelo servidor, porque você não é obrigado a operar um servidor separado, e o Store Kit fornece a funcionalidade de download em segundo plano que você mesmo tinha que escrever anteriormente. Para aproveitar a hospedagem da Apple, habilite a hospedagem de conteúdo para novos produtos de compra no aplicativo e modifique o código do seu Kit da Loja para aproveitá-lo. Os arquivos de conteúdo do produto são então criados usando o Xcode e enviados para os servidores da Apple para revisão e lançamento.
Utilizar a App Store para fornecer compras no aplicativo com conteúdo hospedado requer a seguinte configuração e configuração:
- iTunes Connect – Você deve ter fornecido suas informações bancárias e fiscais à Apple para que eles possam remeter fundos coletados em seu nome. Em seguida, você pode configurar produtos para vender e configurar contas de usuário de área restrita para testar a compra. Você também deve configurar o Conteúdo Hospedado para os produtos não consumíveis que deseja hospedar com o Apple.
- Portal de Provisionamento do iOS – Criando um Identificador de Pacote e habilitando o acesso à App Store para seu aplicativo, como faria para qualquer aplicativo que suporte compras no aplicativo.
- Store Kit – Adicionar código ao seu aplicativo para exibir produtos, comprar produtos e restaurar transações. No iOS 6 Store Kit também gerenciará o download do conteúdo do seu produto, em segundo plano, com atualizações de progresso.
-
Código personalizado – Para rastrear as compras feitas pelos clientes e fornecer os produtos ou serviços que eles compraram. Utilize novas classes do iOS 6 Store Kit, como
SKDownload
para recuperar o conteúdo hospedado pela Apple.
As seções a seguir explicam como implementar o conteúdo hospedado, desde a criação e o carregamento do pacote até o gerenciamento do processo de compra e download, usando o código de exemplo deste artigo.
Código de exemplo
O projeto de exemplo HostedNonConsumables (em StoreKitiOS6.zip) usa conteúdo hospedado. O aplicativo oferece dois "capítulos de livros" para venda, cujo conteúdo está hospedado nos servidores da Apple. O conteúdo consiste em um arquivo de texto e uma imagem, embora um conteúdo muito mais complexo possa ser usado em um aplicativo real.
O aplicativo tem esta aparência antes, durante e depois de uma compra:
O ficheiro de texto e a imagem são descarregados e copiados para o diretório Documentos da aplicação. Para obter mais informações sobre os diferentes diretórios disponíveis para armazenamento de aplicativos, consulte a documentação do sistema de arquivos .
Ligação ao iTunes
Ao criar novos produtos que usarão a hospedagem de conteúdo da Apple, certifique-se de selecionar o tipo de produto Não Consumível . Outros tipos de produtos não suportam hospedagem de conteúdo. Além disso, você não deve habilitar a hospedagem de conteúdo para produtos existentes que você vende; Ative apenas a hospedagem de conteúdo para novos produtos.
Introduza um ID de Produto . Esta ID será necessária mais tarde quando criar o conteúdo para este produto.
A hospedagem de conteúdo é definida na seção Detalhes. Antes de a compra no aplicativo ser ativada, desmarque a caixa de seleção Host Content with Apple se desejar cancelar (mesmo que tenha carregado algum conteúdo de teste). No entanto, a hospedagem de conteúdo não pode ser removida após a compra no aplicativo ter sido ativada.
Depois de ativar a disponibilização de conteúdo, o produto entrará no estado Aguardando Upload e mostrará esta mensagem:
O pacote de conteúdo deve ser criado com o Xcode e carregado usando a ferramenta Arquivar. As instruções para criar pacotes de conteúdo são dadas na próxima seção Criando . Arquivos PKG.
Criação de ficheiros .PKG
Os ficheiros de conteúdo que carrega para a Apple têm de cumprir as seguintes restrições:
- Não pode exceder 2 GB de tamanho.
- Não pode conter código executável (ou links simbólicos que apontam para fora do conteúdo).
- Deve estar formatado corretamente (incluindo um arquivo de .plist) e ter uma extensão de arquivo .pkg. Isso será feito automaticamente se você seguir estas instruções usando o Xcode.
Você pode adicionar muitos arquivos diferentes e tipos de arquivos, desde que eles atendam a essas restrições. O conteúdo é compactado antes da entrega ao seu aplicativo e descompactado pelo Store Kit antes que seu código o acesse.
Depois de carregar um pacote de conteúdo, ele pode ser substituído por conteúdo mais recente. Os novos conteúdos devem ser carregados e submetidos para revisão/aprovação através do processo normal. Incremente o campo ContentVersion
em pacotes de conteúdo atualizados para indicar que ele é mais recente.
Projetos de Conteúdo para Compra do Xcode In-App
A criação de pacotes de conteúdo para produtos de compra no aplicativo atualmente requer o Xcode. Não é necessário qualquer tipo de codificação OBJECTIVE-C; o Xcode tem um novo tipo de projeto para esses pacotes, que contém apenas os seus ficheiros e um plist.
Nosso aplicativo de exemplo tem capítulos de livros à venda – cada pacote de conteúdo de capítulo conterá:
- um ficheiro de texto, e
- uma imagem para representar o capítulo.
Comece selecionando Arquivo > Novo Projeto no menu e escolhendo In-App Comprar Conteúdo:
Introduza o Nome do Produto e o Identificador da Empresa de modo a que o Identificador do Pacote corresponda ao ID do Produto que introduziu no iTunes Connect para este produto.
Agora você terá um projeto In-App em branco de Conteúdo de Compra. Pode clicar com o botão direito do rato e Adicionar Ficheiros... ou arrastá-los para o Project Navigator. Certifique-se de que a ContentVersion está correta (deve começar na versão 1.0, mas se mais tarde optar por atualizar o conteúdo, lembre-se de incrementá-lo).
Esta captura de ecrã mostra o Xcode com os ficheiros de conteúdo incluídos no projeto e as entradas plist visíveis na janela principal:
Depois de adicionar todos os seus arquivos de conteúdo, você pode salvar este projeto e editá-lo novamente mais tarde, ou começar o processo de upload.
Carregando arquivos .PKG
A maneira mais fácil de carregar pacotes de conteúdo é com o Xcode Archive Tool. Escolha Produto > Arquivo no menu para começar:
O pacote de conteúdo aparecerá no arquivo como mostrado abaixo. O tipo de arquivo e o ícone mostram que esta linha é um In-App Arquivo de Conteúdo de Compra. Clique Validar... para verificar se há erros no nosso pacote de conteúdo sem realmente realizar o upload.
Inicie sessão com as suas credenciais do iTunes Connect:
Escolha o aplicativo correto e a compra no aplicativo para associar esse conteúdo com:
Você verá uma mensagem como esta captura de tela:
Agora, passe por um processo semelhante, mas ao clicar em Distribuir..., o conteúdo será realmente carregado.
Selecione a primeira opção, para carregar o conteúdo:
Inicie sessão novamente:
Escolha o aplicativo correto e o registro de compra no aplicativo para carregar o conteúdo para:
Aguarde enquanto os seus ficheiros são carregados:
Quando o carregamento estiver concluído, aparecerá uma mensagem a informá-lo de que o conteúdo foi enviado para a App Store.
Feito isso, quando você retornar à página do produto no iTunes Connect, ele mostrará os detalhes do pacote e estará em status Pronto para enviar. Quando o produto estiver nesse status, você poderá começar a testar no ambiente de área restrita. NÃO é necessário "enviar" o produto para teste na sandbox.
Pode levar algum tempo (por exemplo, alguns minutos) entre o upload do arquivo e o status do iTunes Connect sendo atualizado. Você pode enviar o produto para revisão separadamente ou enviá-lo em conjunto com um binário de aplicativo. Somente depois que a Apple aprovar oficialmente o conteúdo ele estará disponível na App Store de produção para compra em seu aplicativo.
Formato de arquivo PKG
Usar o Xcode e a Ferramenta de Arquivo para criar e carregar um pacote de conteúdo hospedado significa que você nunca vê o conteúdo do pacote em si. Os ficheiros e diretórios nos pacotes criados para a aplicação de exemplo assemelham-se à captura de ecrã abaixo, com o ficheiro plist na raiz e os ficheiros do produto num subdiretório Contents.
Observe a estrutura de diretórios do pacote (especialmente o local dos arquivos no subdiretório Contents
) porque você precisará entender essas informações para extrair os arquivos do pacote no dispositivo.
Atualizando o conteúdo do pacote
O procedimento para atualizar o conteúdo após a sua aprovação:
- Edite o projeto In-App Purchase Content no Xcode.
- Aumente o número da versão.
- Carregue novamente para o iTunes Connect. Os compradores subsequentes receberão automaticamente a versão mais recente, MAS os usuários que já têm a versão antiga não receberão nenhuma notificação.
- Seu aplicativo é responsável por notificar os usuários e incentivá-los a recuperar uma versão mais recente do conteúdo. O aplicativo também deve criar uma função que baixa a nova versão, usando o recurso Restaurar do Store Kit.
- Para determinar se existe uma versão mais recente, você pode criar um recurso em seu aplicativo para buscar SKProducts (por exemplo, o mesmo processo usado para recuperar preços de produtos) e comparar a propriedade ContentVersion.
Visão Geral de Compras
Antes de ler esta seção, revise a documentação existente da compra In-App.
A sequência de eventos que ocorre quando um produto com conteúdo hospedado é comprado e baixado é ilustrada neste diagrama:
- Novos produtos podem ser criados no iTunes Connect com o Conteúdo Hospedado ativado. O conteúdo real é construído separadamente no Xcode (tão simplesmente como arrastar arquivos para uma pasta) e, em seguida, arquivado e enviado para o iTunes (nenhuma codificação é necessária). Cada produto é então submetido à aprovação, depois do qual fica disponível para compra. No código de exemplo, esses IDs de produto são codificados, mas hospedar conteúdo com a Apple é mais flexível se você armazenar a lista de produtos disponível em um servidor remoto para que ela possa ser atualizada quando você enviar novos produtos e conteúdo para o iTunes Connect.
- Quando o usuário compra um produto, uma transação é colocada na fila de pagamento para processamento.
- O Store Kit encaminha a solicitação de compra para os servidores do iTunes para processamento.
- A transação é concluída nos servidores iTunes (por exemplo, o cliente é cobrado) e um recibo é devolvido ao aplicativo, com informações do produto anexadas, incluindo se ele pode ser baixado (e, em caso afirmativo, o tamanho do arquivo e outros metadados).
- Seu código deve verificar se o produto pode ser baixado e, em caso afirmativo, fazer uma solicitação de download de conteúdo que também é colocada na fila de pagamento. O Store Kit envia este pedido para os servidores do iTunes.
- O servidor devolve o ficheiro de conteúdo ao Store Kit, que fornece uma chamada de retorno para informar sobre o progresso do download e as estimativas do tempo restante para o seu código.
- Depois de concluído, será notificado e será-lhe indicado um local de ficheiro na pasta Cache.
- O teu código deve copiar os arquivos e verificá-los, e salvar qualquer estado que precises para recordar-te de que o produto foi comprado. Aproveite esta oportunidade para definir o sinalizador de backup corretamente nos novos arquivos (dica: se eles vêm de um servidor e nunca são editados pelo usuário, você provavelmente deve pular o backup, já que o usuário sempre pode recuperá-los dos servidores da Apple no futuro).
- Invoque FinishTransaction. Esta etapa é IMPORTANTE, pois remove a transação da Fila de Pagamento. Também é importante que você NÃO chame FinishTransaction até DEPOIS de ter copiado o conteúdo do diretório Cache. Depois de chamar FinishTransaction, é provável que os arquivos armazenados em cache sejam rapidamente limpos.
Implementando a compra de conteúdo hospedado
As seguintes informações devem ser lidas em conjunto com a documentação completa de Compras In-App. As informações neste documento se concentram nas diferenças entre o conteúdo hospedado e a implementação anterior.
Aulas
As seguintes classes foram adicionadas ou alteradas para suportar conteúdo hospedado no iOS 6:
- SKDownload – Nova classe que representa um download em andamento. A API permite mais de um por produto, no entanto, inicialmente, apenas um foi implementado.
-
SKProduct – Novas propriedades adicionadas:
Downloadable
,ContentVersion
, matrizContentLengths
. -
SKPaymentTransaction – Nova propriedade adicionada:
Downloads
, que contém uma coleção de objetosSKDownload
se este produto tiver hospedado conteúdo disponível para download. -
SKPaymentQueue – Novo método adicionado:
StartDownloads
. Chame este método com objetosSKDownload
para obter o conteúdo hospedado. O download pode ocorrer em segundo plano. -
SKPaymentTransactionObserver – Novo método:
UpdateDownloads
. O Store Kit chama esse método com informações de progresso sobre as operações de download atuais.
Detalhes da nova classe SKDownload
:
- Progresso – Um valor entre 0-1 que se pode usar para exibir um indicador de percentagem de conclusão ao utilizador. NÃO use Progresso == 1 para detetar se o download está concluído, verifique o Estado == Concluído.
- TimeRemaining – Estimativa do tempo de download restante, em segundos. -1 significa que ainda está a calcular a estimativa.
- Estado – Ativo, Aguardando, Concluído, Falhado, Pausado, Cancelado.
-
ContentURL – Local do arquivo onde o conteúdo foi colocado no disco, no diretório
Cache
. APENAS preenchido quando o download tiver terminado. - Erro – Verifique esta propriedade se o Estado estiver falhando.
As interações entre as classes no código de exemplo são mostradas neste diagrama (o código específico para compras de conteúdo hospedado é mostrado em verde):
O código de exemplo onde essas classes foram usadas é mostrado no restante desta seção:
CustomPaymentObserver (SKPaymentTransactionObserver)
Altere a substituição de UpdatedTransactions
existente para verificar se há conteúdo para download e ligue para StartDownloads
se necessário:
public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions)
{
foreach (SKPaymentTransaction transaction in transactions) {
switch (transaction.TransactionState) {
case SKPaymentTransactionState.Purchased:
// UPDATED FOR iOS 6
if (transaction.Downloads != null && transaction.Downloads.Length > 0) {
// Purchase complete, and it has downloads... so download them!
SKPaymentQueue.DefaultQueue.StartDownloads (transaction.Downloads);
// CompleteTransaction() call has moved after downloads complete
} else {
// complete the transaction now
theManager.CompleteTransaction(transaction);
}
break;
case SKPaymentTransactionState.Failed:
theManager.FailedTransaction(transaction);
break;
case SKPaymentTransactionState.Restored:
// TODO: you must decide how to handle restored transactions.
// Triggering all the downloads at once is not advisable.
theManager.RestoreTransaction(transaction);
break;
default:
break;
}
}
}
O novo método substituído UpdatedDownloads
é mostrado abaixo. O Store Kit chama esse método depois que StartDownloads
é acionado no UpdatedTransactions
. Este método é chamado várias vezes em intervalos indeterminados para fornecer o progresso do download e, em seguida, novamente quando o download tiver terminado. Observe que o método aceita uma matriz de objetos SKDownload
, portanto, cada chamada de método pode fornecer o status de vários downloads na fila. Como mostrado na implementação abaixo, os status de download são verificados toda vez e as ações apropriadas são tomadas.
// ENTIRELY NEW METHOD IN iOS6
public override void PaymentQueueUpdatedDownloads (SKPaymentQueue queue, SKDownload[] downloads)
{
Console.WriteLine (" -- PaymentQueueUpdatedDownloads");
foreach (SKDownload download in downloads) {
switch (download.DownloadState) {
case SKDownloadState.Active:
// TODO: implement a notification to the UI (progress bar or something?)
Console.WriteLine ("Download progress:" + download.Progress);
Console.WriteLine ("Time remaining: " + download.TimeRemaining); // -1 means 'still calculating'
break;
case SKDownloadState.Finished:
Console.WriteLine ("Finished!!!!");
Console.WriteLine ("Content URL:" + download.ContentUrl);
// UNPACK HERE! Calls FinishTransaction when it's done
theManager.SaveDownload (download);
break;
case SKDownloadState.Failed:
Console.WriteLine ("Failed"); // TODO: UI?
break;
case SKDownloadState.Cancelled:
Console.WriteLine ("Canceled"); // TODO: UI?
break;
case SKDownloadState.Paused:
case SKDownloadState.Waiting:
break;
default:
break;
}
}
}
InAppPurchaseManager (SKProductsRequestDelegate)
Essa classe contém um novo método SaveDownload
que é chamado depois que cada download é concluído com êxito.
O conteúdo hospedado foi baixado com êxito e descompactado no diretório Cache
. A estrutura do . O arquivo PKG requer que todos os arquivos sejam salvos em um subdiretório Contents
, portanto, o código abaixo extrai arquivos de dentro do subdiretório Contents
.
O código itera através de todos os arquivos no pacote de conteúdo e os copia para o diretório Documents
, em uma subpasta nomeada para o ProductIdentifier
. Por fim, chama CompleteTransaction
, que, por sua vez, chama FinishTransaction
para remover a transação da fila de pagamentos.
// ENTIRELY NEW METHOD IN iOS 6
public void SaveDownload (SKDownload download)
{
var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); // Documents folder
var targetfolder = System.IO.Path.Combine (documentsPath, download.Transaction.Payment.ProductIdentifier);
// targetfolder will be "/Documents/com.xamarin.storekitdoc.montouchimages/" or something like that
if (!System.IO.Directory.Exists (targetfolder))
System.IO.Directory.CreateDirectory (targetfolder);
foreach (var file in System.IO.Directory.EnumerateFiles
(System.IO.Path.Combine(download.ContentUrl.Path, "Contents"))) { // Contents directory is the default in .PKG files
var fileName = file.Substring (file.LastIndexOf ("/") + 1);
var newFilePath = System.IO.Path.Combine(targetfolder, fileName);
if (!System.IO.File.Exists(newFilePath)) // HACK: this won't support new versions...
System.IO.File.Copy (file, newFilePath);
else
Console.WriteLine ("already exists " + newFilePath);
}
CompleteTransaction (download.Transaction); // so it gets 'finished'
}
Quando FinishTransaction
é chamado, os arquivos baixados não têm mais garantia de estar no diretório Cache
. Todos os arquivos devem ser copiados antes de chamar FinishTransaction
.
Outras considerações
O código de exemplo acima demonstra uma implementação bastante simples de compra de conteúdo hospedado. Existem alguns pontos adicionais que você deve considerar:
Detetando conteúdo atualizado
Embora seja possível atualizar seus pacotes de conteúdo hospedado, o Store Kit não fornece nenhum mecanismo para enviar essas atualizações para usuários que já baixaram e compraram o produto. Para implementar esta funcionalidade, o seu código pode verificar regularmente a nova propriedade SKProduct.ContentVersion
(se o SKProduct
for Downloadable
) e detetar se o valor é incrementado. Como alternativa, você pode criar um sistema de notificação por push.
Instalando versões de conteúdo atualizadas
O código de exemplo acima ignora a cópia do arquivo se o arquivo já existir. Isso NÃO é uma boa ideia se você deseja suportar versões mais recentes do conteúdo que está sendo baixado.
Uma alternativa pode ser copiar o conteúdo para uma pasta com o nome da versão e controlar qual é a versão atual (por exemplo, no NSUserDefaults
ou onde quer que você armazene registros de compra concluídos).
Restaurando transações
Quando SKPaymentQueue.DefaultQueue.RestoreCompletedTransactions
é chamado, o Store Kit retorna todas as transações anteriores para o usuário. Se eles compraram um grande número de itens, ou se cada compra tem grandes pacotes de conteúdo, então a restauração pode resultar em muito tráfego de rede, pois tudo fica na fila para download de uma só vez.
Considere acompanhar se um produto foi comprado separadamente do download real do pacote de conteúdo associado.
Pausar, reiniciar e cancelar downloads
Embora o código de exemplo não demonstre esse recurso, é possível pausar e reiniciar downloads de conteúdo hospedado. O SKPaymentQueue.DefaultQueue
tem métodos para PauseDownloads
, ResumeDownloads
e CancelDownloads
.
Se o código chamar FinishTransaction
na fila de pagamento antes de o download ser Finished
, então esse download será cancelado automaticamente.
Definindo o sinalizador de SKIP-Backup no conteúdo baixado
As Diretrizes de Backup do iCloud da Apple sugerem que o conteúdo de não-usuário que é facilmente restaurado a partir de um servidor não deve ser copiado (porque usaria desnecessariamente o armazenamento do iCloud). Para mais informações sobre como definir o atributo de backup, consulte a documentação do sistema de arquivos .
Resumo
Este artigo introduziu dois novos recursos do Store Kit no iOS6: comprar o iTunes e outros conteúdos de dentro do seu aplicativo e utilizar o servidor da Apple para hospedar suas próprias compras no aplicativo. Esta introdução deve ser lida em conjunto com o de documentação de compra deIn-App existente para obter uma cobertura completa da implementação da funcionalidade do Kit de Loja.