Ändringar i StoreKit i iOS 6

iOS 6 introducerade två ändringar i Store Kit API: möjligheten att visa iTunes-produkter (och App Store/iBookstore) inifrån din app och ett nytt köpalternativ i appen där Apple kommer att vara värd för dina nedladdningsbara filer. Det här dokumentet förklarar hur du implementerar dessa funktioner med Xamarin.iOS.

De viktigaste ändringarna i Store Kit i iOS6 är följande två nya funktioner:

  • In-App Content Display & Purchasing – användare kan köpa och ladda ned appar, musik, böcker och annat iTunes-innehåll utan att lämna din app. Du kan också länka till dina egna appar för att marknadsföra inköp eller bara uppmuntra recensioner och omdömen.
  • In-App Köp värdbaserat innehåll – Apple lagrar och levererar innehållet som är associerat med dina köpprodukter i appen, vilket tar bort behovet av en separat server för att vara värd för dina filer, stöder automatiskt bakgrundsnedladdning och låter dig skriva mindre kod.

Mer information om StoreKit-API:er finns i guiderna In-App Köp.

Krav

Funktionerna i Store Kit som beskrivs i det här dokumentet kräver iOS 6 och Xcode 4.5, tillsammans med Xamarin.iOS 6.0.

In-App innehållsvisning & inköp

Med den nya köpfunktionen i appen i iOS kan användarna visa produktinformation och köpa eller ladda ned produkten från din app. Tidigare skulle program behöva utlösa iTunes, App Store eller iBookstore, vilket skulle leda till att användaren lämnar det ursprungliga programmet. Den här nya funktionen returnerar automatiskt användaren till din app när de är klara.

återgår automatiskt till en app efter köp

Exempel på hur detta kan användas är:

  • Uppmuntra användare att betygsätta din app – Du kan öppna App Store-sidan så att användaren kan betygsätta och granska din app utan att lämna den.
  • Korsmarknadsföring av appar – Ge användaren möjlighet att se andra appar som du publicerar, med möjlighet att köpa/ladda ner direkt.
  • Hjälpa användare att hitta och ladda ned innehåll – Hjälp användare att köpa innehåll som appen hittar, hanterar eller aggregerar (t.ex. en musikrelaterad app kan tillhandahålla en spellista med låtar och tillåta att varje låt köps inifrån appen).

När SKStoreProductViewController har visats kan användaren interagera med produktinformationen som om de vore i iTunes, App Store eller iBookstore. Användaren kan:

  • Visa skärmbilder (för appar)
  • Exempellåtar eller video (för musik, TV-program och filmer),
  • Läsa (och skriva) recensioner,
  • Köp & nedladdningen, vilket sker helt inom vyhanteraren och Store Kit.

Vissa alternativ i SKStoreProductViewController tvingar fortfarande användaren att lämna appen och öppna relevant store-app, till exempel att klicka på Relaterade produkter eller en apps länk Support.

SKStoreProductViewController

API:et för att visa en produkt i en app är enkelt: det kräver bara att du skapar och visar en SKStoreProductViewController. Följ dessa steg för att skapa och visa en produkt:

  1. Skapa ett StoreProductParameters objekt för att skicka parametrar till vystyrenheten, inklusive productId i konstruktorn.
  2. Instansiera SKProductViewController. Tilldela det till ett fält på klassnivå.
  3. Tilldela en hanterare till vykontrollantens Finished händelse, vilket bör stänga visningskontrollanten. Den här händelsen anropas när användaren trycker på Avbryt. eller på annat sätt slutför en transaktion i vykontrollanten.
  4. Anropa LoadProduct-metoden som skickar in StoreProductParameters och en slutförandehanterare. Slutförandehanteraren bör kontrollera att produktbegäran har slutförts och i så fall presentera SKProductViewController modally. Lämplig felhantering bör läggas till om produkten inte kan hämtas.

Exempel

ProductView-projektet i StoreKit-exempelkoden för den här artikeln implementerar en Buy-metod som accepterar alla produkters Apple-ID och visar SKStoreProductViewController. Följande kod visar produktinformationen för ett visst Apple-ID:

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);
        }
    });
}

Appen ser ut som skärmbilden nedan när den körs – nedladdning eller inköp sker helt inom SKStoreProductViewController.

Appen ser ut så här när körs

Stöd för äldre operativsystem

Exempelprogrammet innehåller kod som visar hur du öppnar App Store, iTunes eller iBookstore i tidigare versioner av iOS. Använd metoden OpenUrl för att öppna en korrekt utformad itunes.com URL.

Du kan implementera en versionskontroll för att avgöra vilken kod som ska köras, enligt följande:

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);
}

Fel

Följande fel uppstår om det Apple-ID som du använder inte är giltigt, vilket kan vara förvirrande eftersom det innebär ett nätverk eller autentiseringsproblem av något slag.

Error Domain=SKErrorDomain Code=5 "Cannot connect to iTunes Store"

Läsa dokumentation om Objective-C

Utvecklare som läser om Store Kit på Apples utvecklarportal kommer att se ett protokoll – SKStoreProductViewControllerDelegate – som beskrivs i förhållande till den här nya funktionen. Delegatprotokollet har bara en metod – productViewControllerDidFinish – som har exponerats som Finished-händelsen på SKStoreProductViewController i Xamarin.iOS.

Fastställa Apple-ID:t

Det Apple-ID som krävs av SKStoreProductViewController är ett nummer (ska inte förväxlas med paket-ID:n som "com.xamarin.mwc2012"). Det finns några olika sätt att ta reda på Apple-ID:t för produkter som du vill visa nedan:

iTunesConnect

För program som du publicerar är det enkelt att hitta Apple ID i iTunes Connect:

Hitta Apple ID i iTunes Connect

Sök-API

Apple tillhandahåller ett API för dynamisk sökning för att fråga alla produkter i App Store, iTunes och iBookstore. Information om hur du kommer åt sök-API:et finns i Apples Affiliate-resurser, även om API:et exponeras för vem som helst (inte bara registrerade affiliates). Den resulterande JSON:en kan parsas för att identifiera trackId som är det Apple-ID som ska användas med SKStoreProductViewController.

Resultatet innehåller även andra metadata, inklusive visningsinformation och tecknings-URL:er som kan användas för att återge produkten i din app.

Här följer några exempel:

Företagspartnerfeed

Apple ger godkända partner en fullständig datadump av alla sina produkter, i form av nedladdningsbara databasklara flata filer. Om du är berättigad till åtkomst till Enterprise-partnerfeeden kan Apple-ID:t för alla produkter hittas i den datamängden.

Många användare av Enterprise Partner Feed är medlemmar i Affiliate Program som gör att provisioner kan tjänas på produktförsäljning. SKStoreProductViewController stöder inte affiliate-ID:t (i skrivande stund).

Apple-ID:t för en produkt kan härledas från url-länken för förhandsversionen av iTunes. I alla iTunes-produktlänkar (för appar, musik eller böcker) hittar du den del av URL:en som börjar med id och använder talet som följer.

Direktlänken till iBooks är till exempel

http://itunes.apple.com/us/app/ibooks/id364709193?mt=8

och Apple-ID:t är 364709193. På samma sätt för appen MWC2012 är direktlänken:

http://itunes.apple.com/us/app/mwc-2012-unofficial/id496963922?mt=8

och Apple-ID:t är 496963922.

In-App köpa värdbaserat innehåll

Om dina köp i appen består av nedladdningsbart innehåll (till exempel böcker eller andra medier, konst och konfiguration på spelnivå eller andra stora filer) brukade dessa filer finnas på webbservern och appar var tvungna att införliva kod för att ladda ned dem på ett säkert sätt efter köpet. Från och med iOS 6 kommer Apple att vara värd för dina filer på sina servrar, vilket tar bort behovet av en separat server. Funktionen är endast tillgänglig för icke-förbrukningsbara produkter (inte förbrukningsbara eller prenumerationer). Fördelarna med att använda Apples värdtjänst är:

  • Spara kostnader för värdtjänst och bandbredd &.
  • Förmodligen mer skalbar än den servervärd som du använder för närvarande.
  • Mindre kod att skriva eftersom du inte behöver skapa någon bearbetning på serversidan.
  • Bakgrundsnedladdning är implementerad för dig.

Obs! Testning av värdbaserat köpinnehåll i appen i iOS-simulatorn stöds inte, så du måste testa med en riktig enhet.

Grunderna för värdbaserat innehåll

Före iOS 6 fanns det två sätt att tillhandahålla en produkt (beskrivs mer detaljerat i dokumentationen Xamarins In-App Purchase):

  • Built-In Products – Funktioner som låses upp genom inköp, men som är inbyggda i applikationen (antingen som kod eller inbäddade resurser). Exempel på inbyggda produkter är upplåsta fotofilter eller förstärkningar i spelet.
  • Server-Delivered Produkter – Efter köpet måste programmet ladda ned innehåll från en server som du använder. Det här innehållet laddas ned under köpet, lagras på enheten och återges sedan som en del av tillhandahållandet av produkten. Exempel är böcker, tidskriftsutgåvor eller spelnivåer som består av bakgrundsgrafik och konfigurationsfiler.

I iOS 6 erbjuder Apple en variant av serverlevererad produkt: de kommer att vara värd för dina innehållsfiler på sina servrar. Detta gör det mycket enklare att skapa serverlevererad produkt eftersom du inte behöver använda en separat server, och Store Kit tillhandahåller funktioner för bakgrundsnedladdning som du tidigare var tvungen att skriva själv. Om du vill dra nytta av Apples värdtjänster, aktiverar du innehållsvärdtjänster för nya köp i appen och ändrar din kod för Store Kit för att utnyttja den. Produktinnehållsfiler skapas sedan med Xcode och laddas upp till Apples servrar för granskning och lansering.

Bygg- och leveransprocessen

Användning av App Store för att tillhandahålla köp i appen med värdbaserat innehåll kräver följande konfiguration:

  • iTunes Connect – Du måste har lämnat din bank- och skatteinformation till Apple så att de kan överföra pengar som samlats in för din räkning. Du kan sedan konfigurera produkter att sälja och konfigurera sandbox-användarkonton för att testa inköp. Du måste också konfigurera värdbaserat innehåll för de icke-förbrukningsbara produkter som du vill vara värd för hos Apple.
  • iOS-etableringsportalen – Skapa en paketidentifierare och aktivera App Store-åtkomst för din app, precis som för alla program som stöder köp i appen.
  • Store Kit – Lägga till kod i din app för att visa produkter, köpa produkter och återställa transaktioner. I iOS 6 Store Kit hanteras även nedladdningen av ditt produktinnehåll i bakgrunden med förloppsuppdateringar.
  • Anpassad kod – Spåra köp som görs av kunder och tillhandahålla de produkter eller tjänster som de har köpt. Använd nya iOS 6 Store Kit-klasser som SKDownload för att hämta innehållet som hanteras av Apple.

I följande avsnitt beskrivs hur du implementerar värdbaserat innehåll, från att skapa och ladda upp paketet till att hantera köp- och nedladdningsprocessen med hjälp av exempelkoden för den här artikeln.

Exempelkod

Exempelprojektet HostedNonConsumables (i StoreKitiOS6.zip) använder värdbaserat innehåll. Appen erbjuder två "bokkapitel" till salu, vars innehåll finns på Apples servrar. Innehållet består av en textfil och en bild, även om mycket mer komplext innehåll kan användas i ett verkligt program.

Appen ser ut så här före, under och efter ett köp:

Appen ser ut så här före, under och efter ett köp

Textfilen och bilden laddas ned och kopieras till programmets dokumentkatalog. Mer information om de olika kataloger som är tillgängliga för programlagring finns i dokumentationen om filsystem.

iTunes Connect

När du skapar nya produkter ska du välja produkttypen icke-förbrukningsbar för att använda Apples innehållshantering. Andra produkttyper stöder inte innehållshantering. Du bör inte heller aktivera innehållshantering för befintliga produkter som du säljer; aktivera endast innehållshantering för nya produkter.

Välj produkttypen Ej förbrukningsbar

Ange ett produkt-ID. Det här ID:t krävs senare när du skapar innehållet för den här produkten.

Ange ett produkt-ID

Innehållshantering anges i avsnittet Detaljer. Innan köpet i appen går live avmarkerar du kryssrutan Värdinnehåll med Apple om du vill avbryta (även om du har laddat upp testinnehåll). Det går dock inte att ta bort innehåll efter att köpet i appen har gått live.

Värd för innehåll med Apple

När du har aktiverat värdinnehåll anger produkten statusen Väntar på uppladdning och visar följande meddelande:

Produkten kommer att gå in i statusen Väntar på uppladdning och visa det här meddelandet

Innehållspaketet ska skapas med Xcode och laddas upp med hjälp av arkivverktyget. Instruktioner för att skapa innehållspaket finns i nästa avsnitt Skapa . PKG Files.

Skapande av .PKG-filer

Innehållsfilerna som du laddar upp till Apple måste uppfylla följande begränsningar:

  • Får inte överstiga 2 GB i storlek.
  • Det går inte att innehålla körbar kod (eller symlänkar som pekar utanför innehållet).
  • Måste vara korrekt formaterad (inklusive en .plist- fil) och ha ett .pkg filnamnstillägg. Detta görs automatiskt om du följer dessa instruktioner med Xcode.

Du kan lägga till många olika filer och typer av filer så länge de uppfyller dessa begränsningar. Innehållet zipas innan det levereras till din applikation och packas upp av Store Kit innan din kod kan komma åt det.

När du har laddat upp ett innehållspaket kan det ersättas med nyare innehåll. Nytt innehåll måste laddas upp och skickas för granskning/godkännande via den normala processen. Öka fältet ContentVersion i uppdaterade innehållspaket för att indikera att det är nyare.

Xcode-In-App Köp innehållsprojekt

För att skapa paket med innehåll för köpprodukter i appen krävs för närvarande Xcode. Det krävs ingen OBJECTIVE-C KODning. Xcode har en ny projekttyp för dessa paket som bara innehåller dina filer och en plist.

Vårt exempelprogram har bokkapitel till salu – varje kapitelinnehållspaket innehåller:

  • en textfil och
  • en bild som representerar kapitlet.

Börja med att välja Arkiv > Nytt projekt på menyn och välj In-App Köp innehåll:

Välj In-App Köp Innehåll

Ange produktnamn och företagsidentifierare så att Bundle Identifier matchar produkt-ID du angav i iTunes Connect för den här produkten.

Ange namn och identifierare

Nu kommer du ha ett tomt projekt för In-App inköpsinnehåll. Du kan högerklicka och Lägg till filer... eller dra dem till Project Navigator. Kontrollera att ContentVersion- är korrekt (den bör börja kl. 1.0, men om du senare väljer att uppdatera ditt innehåll, kom ihåg att öka det).

Den här skärmbilden visar Xcode med innehållsfilerna som ingår i projektet och plist-posterna som är synliga i huvudfönstret.

Den här skärmdumpen visar Xcode med innehållsfilerna som ingår i projektet och plist-posterna som visas i huvudfönstret

När du har lagt till alla innehållsfiler kan du spara projektet och redigera det igen senare, eller påbörja uppladdningsprocessen.

Uppladdning av .PKG-filer

Det enklaste sättet att ladda upp innehållspaket är med Xcode Archive Tool. Välj Product > Archive från menyn för att börja:

Välj Arkiv

Innehållspaketet visas sedan i arkivet enligt nedan. Arkivtypen och ikonen visar att den här raden är ett In-App Inköpsinnehållsarkiv. Klicka på Verifiera... för att kontrollera om det finns fel i innehållspaketet utan att utföra uppladdningen.

Verifiera paketet

Logga in med dina iTunes Connect-autentiseringsuppgifter:

Logga in med dina iTunes Connect-autentiseringsuppgifter

Välj rätt program och köp i appen för att associera det här innehållet med:

Välj rätt program och köp i appen för att associera innehållet med

Du bör se ett meddelande som liknar den här skärmbilden:

Ett exempel på meddelande om inga problem

Gå nu igenom en liknande process, men om du klickar på Distribuera... kommer faktiskt att ladda upp innehållet.

Distribuera appen

Välj det första alternativet för att ladda upp innehållet:

Ladda upp innehållet

Logga in igen:

logga in

Välj rätt program- och appinköpspost för att ladda upp innehållet till:

Välj applikation och in-app-köpsregistrering

Vänta medan filerna laddas upp:

Dialogrutan för innehållsuppladdning

När uppladdningen är klar visas ett meddelande om att innehållet har skickats till App Store.

Ett exempel på lyckat uppladdningsmeddelande

När det är klart, när du återvänder till produktsidan på iTunes Connect, kommer paketinformationen att visas och vara i statusen Redo att skicka in. När produkten har den här statusen kan du börja testa i sandbox-miljön. Du behöver INTE "skicka" produkten för testning i sandbox-miljön.

i iTunes Connect kommer paketinformationen att visas och ha statusen Redo att skickas

Det kan ta lite tid (t.ex. några minuter) mellan uppladdningen av arkivet och iTunes Connect-statusen som uppdateras. Du kan skicka produkten för granskning separat eller skicka den tillsammans med ett binärt program. Först när Apple officiellt har godkänt innehållet kommer det att vara tillgängligt i produktionsappbutiken för köp i din app.

PKG-filformat

Att använda Xcode och arkivverktyget för att skapa och ladda upp ett värdbaserat innehållspaket innebär att du aldrig ser innehållet i själva paketet. Filerna och katalogerna i paketen som skapats för exempelappen ser ut som skärmbilden nedan, med plist-filen i roten och produktfilerna i en Innehåll underkatalog:

Plist-filen i roten och produktfilerna i en underkatalog för innehåll

Observera paketets katalogstruktur (särskilt platsen för filerna i underkatalogen Contents) eftersom du måste förstå den här informationen för att extrahera filerna från paketet på enheten.

Uppdatera paketinnehåll

Proceduren för att uppdatera innehåll efter att det har godkänts:

  • Redigera projektet In-App Köpinnehåll i Xcode.
  • Höj versionsnumret.
  • Ladda upp till iTunes Connect igen. Efterföljande köpare får automatiskt den senaste versionen men användare som redan har den gamla versionen får inga meddelanden.
  • Din app ansvarar för att meddela användare och uppmuntra dem att hämta en nyare version av innehållet. Appen måste också skapa en funktion som laddar ned den nya versionen med hjälp av funktionen Återställ i Store Kit.
  • För att avgöra om det finns en nyare version kan du skapa en funktion i din app för att hämta SKProducts (t.ex. samma process som används för att hämta produktpriser) och jämföra egenskapen ContentVersion.

Inköpsöversikt

Innan du läser det här avsnittet läser du den befintliga In-App Inköpsdokumentationen.

Sekvensen av händelser som inträffar när en produkt med värdbaserat innehåll köps och laddas ned illustreras i det här diagrammet:

Händelsesekvensen som inträffar när en produkt med värdbaserat innehåll köps och laddas ned

  1. Nya produkter kan skapas i iTunes Connect med värdbaserat innehåll aktiverat. Det faktiska innehållet konstrueras separat i Xcode (som att helt enkelt dra filer till en mapp) och sedan arkiveras och laddas upp till iTunes (ingen kodning krävs). Varje produkt skickas sedan för godkännande, varefter den blir tillgänglig för köp. I exempelkoden är dessa produkt-ID:n hårdkodade, men att vara värd för innehåll med Apple är mer flexibelt om du lagrar den tillgängliga produktlistan på en fjärrserver så att den kan uppdateras när du skickar nya produkter och innehåll till iTunes Connect.
  2. När användaren köper en produkt placeras en transaktion i betalningskön för bearbetning.
  3. Store Kit vidarebefordrar inköpsbegäran till iTunes-servrar för bearbetning.
  4. Transaktionen slutförs på iTunes-servrarna (t.ex. kunden debiteras) och ett kvitto returneras till appen, med produktinformation bifogad, inklusive om den är nedladdningsbar (och i så fall filstorleken och andra metadata).
  5. Koden bör kontrollera om produkten kan laddas ned och i så fall göra en begäran om nedladdning av innehåll som också placeras i betalningskön. Store Kit skickar denna begäran till iTunes-servrarna.
  6. Servern returnerar innehållsfilen till Store Kit, vilket ger ett återanrop för att returnera nedladdningsförloppet och återstående tidsuppskattningar till koden.
  7. När processen är klar får du ett meddelande och en filplats i cachemappen levereras till dig.
  8. Din kod bör kopiera ut filerna och verifiera dem, spara all den information du behöver för att minnas att produkten har köpts. Ta tillfället i akt att ange säkerhetskopieringsflaggan korrekt på de nya filerna (tips: om de kommer från en server och aldrig redigeras av användaren bör du förmodligen hoppa över att säkerhetskopiera dem, eftersom användaren alltid kan hämta dem från Apples servrar i framtiden).
  9. Anropa FinishTransaction. Det här steget är VIKTIGT eftersom det tar bort transaktionen från betalningskön. Det är också viktigt att du INTE anropar FinishTransaction förrän du har kopierat innehållet från cachekatalogen. När du anropar FinishTransaction rensas förmodligen cachelagrade filer snabbt.

Implementera köp av värdbaserat innehåll

Följande information bör läsas i samband med den fullständiga inköpsdokumentationen In-App. Informationen i det här dokumentet fokuserar på skillnaderna mellan värdbaserat innehåll och den tidigare implementeringen.

Klasserna

Följande klasser har lagts till eller ändrats för att stödja värdbaserat innehåll i iOS 6:

  • SKDownload – Ny klass som representerar en pågående nedladdning. API:et tillåter mer än en per produkt, men till en början har endast en implementerats.
  • SKProduct – Nya egenskaper har lagts till: Downloadable, ContentVersion, ContentLengths matris.
  • SKPaymentTransaction – Ny egenskap har lagts till: Downloads, som innehåller en samling SKDownload objekt om den här produkten har värdbaserat innehåll tillgängligt för nedladdning.
  • SKPaymentQueue – Ny metod har lagts till: StartDownloads. Anropa den här metoden med SKDownload objekt för att hämta deras värdbaserade innehåll. Nedladdning kan ske i bakgrunden.
  • SKPaymentTransactionObserver – Ny metod: UpdateDownloads. Store Kit anropar den här metoden med förloppsinformation om aktuella nedladdningsåtgärder.

Information om den nya klassen SKDownload:

  • Progress – Ett värde mellan 0 och 1 som du kan använda för att visa en procent färdig indikator för användaren. Använd INTE Progress == 1 för att kontrollera om nedladdningen är klar, kontrollera efter State == Finished.
  • TimeRemaining – Uppskattning av den återstående nedladdningstiden i sekunder. -1 innebär att den fortfarande beräknar uppskattningen.
  • Status – Aktiv, Väntar, Slutförd, Misslyckad, Pausad, Avbruten.
  • ContentURL – Filplats där innehållet placerades på disk, i katalogen Cache. Fylls bara i när nedladdningen har slutförts.
  • Fel – Kontrollera egenskapen om tillståndet är misslyckat.

Interaktionerna mellan klasserna i exempelkoden visas i det här diagrammet (koden som är specifik för värdbaserade innehållsköp visas i grönt):

Köp av värdbaserat innehåll visas i grönt i det här diagrammet

Exempelkoden där dessa klasser har använts visas i resten av det här avsnittet:

CustomPaymentObserver (SKPaymentTransactionObserver)

Ändra den befintliga UpdatedTransactions åsidosättning för att söka efter nedladdningsbart innehåll och anropa StartDownloads om det behövs:

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;
        }
    }
}

Den nya åsidosatta metoden UpdatedDownloads visas nedan. Store Kit anropar den här metoden när StartDownloads har utlösts i UpdatedTransactions. Den här metoden kallas flera gånger med obestämda intervall för att ge dig nedladdningsframsteg och återigen när nedladdningen har slutförts. Observera att metoden accepterar en matris med SKDownload objekt, så att varje metodanrop kan ge dig status för flera nedladdningar i kön. Som du ser i implementeringen nedan kontrolleras nedladdningsstatusen varje gång och lämpliga åtgärder vidtas.

// 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)

Den här klassen innehåller en ny metod SaveDownload som anropas när varje nedladdning har slutförts.

Det värdbaserade innehållet har laddats ned och packats upp i katalogen Cache. Strukturen för . PKG-filen kräver att alla filer sparas i en Contents underkatalog, så koden nedan extraherar filer från Contents underkatalog.

Koden itererar genom alla filer i innehållspaketet och kopierar dem till katalogen Documents i en undermapp med namnet för ProductIdentifier. Slutligen anropas CompleteTransaction, som anropar FinishTransaction för att ta bort transaktionen från betalningskön.

// 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'
}

När FinishTransaction anropas är det inte längre garanterat att de nedladdade filerna finns i katalogen Cache. Alla filer bör kopieras innan du anropar FinishTransaction.

Andra överväganden

Exempelkoden ovan visar en ganska enkel implementering av köp av värdbaserat innehåll. Det finns några ytterligare punkter som du måste tänka på:

Identifiera uppdaterat innehåll

Det är möjligt att uppdatera dina värdbaserade innehållspaket, men Store Kit tillhandahåller ingen mekanism för att skicka ut uppdateringarna till användare som redan har laddat ned och köpt produkten. Om du vill implementera den här funktionen kan koden kontrollera den nya egenskapen SKProduct.ContentVersion (om SKProduct är Downloadable) regelbundet och identifiera om värdet ökas. Du kan också skapa ett push-meddelandesystem.

Installera uppdaterade innehållsversioner

Exempelkoden ovan hoppar över filkopiering om filen redan finns. Detta är INTE en bra idé om du vill stödja nyare versioner av innehållet som laddas ned.

Ett alternativ kan vara att kopiera innehållet till en mapp med namnet för versionen och hålla reda på vilken version som är den aktuella versionen (t.ex. i NSUserDefaults eller var du än lagrar slutförda inköpsposter).

Återställa transaktioner

När SKPaymentQueue.DefaultQueue.RestoreCompletedTransactions anropas returnerar Store Kit alla tidigare transaktioner för användaren. Om de har köpt ett stort antal objekt, eller om varje köp har stora innehållspaket, kan återställningen resultera i mycket nätverkstrafik eftersom allt placeras i kö för nedladdning samtidigt.

Överväg att hålla reda på om en produkt har köpts separat från den faktiska nedladdningen av det associerade innehållspaketet.

Pausa, starta om och avbryta nedladdningar

Även om exempelkoden inte visar den här funktionen är det möjligt att pausa och starta om värdbaserade nedladdningar av innehåll. SKPaymentQueue.DefaultQueue har metoder för PauseDownloads, ResumeDownloads och CancelDownloads.

Om koden anropar FinishTransaction i betalningskön innan nedladdningen har blivit Finished, avbryts nedladdningen automatiskt.

Ange flaggan SKIP-Backup för nedladdat innehåll

Apples riktlinjer för säkerhetskopiering av iCloud tyder på att innehåll som inte är användarbaserat och enkelt återställs från en server inte bör säkerhetskopieras (eftersom det i onödan skulle använda iCloud-lagring). Mer information om hur du anger attributet för säkerhetskopiering finns i dokumentationen om filsystem.

Sammanfattning

Den här artikeln har introducerat två nya funktioner i Store Kit i iOS6: köpa iTunes och annat innehåll från din app och använda Apples server som värd för dina egna köp i appen. Den här introduktionen bör läsas tillsammans med den befintliga In-App köpdokumentationen för fullständig täckning av implementeringen av Store Kit-funktioner.