共用方式為


iOS 6 中對 StoreKit 所做的變更

iOS 6 引進了市集套件 API 的兩項變更:從您的應用程式內顯示 iTunes(和 App Store/iBookstore) 產品的能力,以及 Apple 將裝載可下載檔的新應用程式內購買選項。 本文件說明如何使用 Xamarin.iOS 實作這些功能。

iOS6 中 Store Kit 的主要變更是下列兩項新功能:

  • 應用程式內內容顯示與購買 – 使用者可以購買和下載應用程式、音樂、書籍和其他 iTunes 內容,而不需要離開您的應用程式。 您也可以連結到自己的應用程式,以促銷購買,或只是鼓勵評論和評分。
  • 應用程式內購買託管的內容 – Apple 會儲存並傳遞與應用程式內購買產品相關聯的內容,這可移除個別伺服器裝載檔案的需求,自動支援背景下載,並讓您撰寫較少的程序代碼。

如需 StoreKit API 的詳細涵蓋範圍,請參閱應用程式內購買 指南。

需求

本文件中討論的市集套件功能需要 iOS 6 和 Xcode 4.5,以及 Xamarin.iOS 6.0。

應用程式內內容顯示和購買

iOS 中的新應用程式內購買功能可讓用戶檢視產品資訊,並從您的應用程式內購買或下載產品。 先前的應用程式必須觸發 iTunes、App Store 或 iBookstore,這會導致使用者離開原始應用程式。 這項新功能會在使用者完成時自動將用戶傳回您的應用程式。

購買後自動返回應用程式

如何使用此範例包括:

  • 鼓勵使用者評分您的應用程式 – 您可以開啟 App Store 頁面,讓使用者不需離開 App 即可評分和檢閱您的應用程式。
  • 交叉推廣應用程式 – 允許使用者查看您發佈的其他應用程式,並能夠立即購買/下載。
  • 協助使用者尋找和下載內容 – 協助使用者購買應用程式尋找、管理或匯總的內容(例如音樂相關應用程式可以提供歌曲播放清單,並允許從應用程式內購買每個歌曲)。

SKStoreProductViewController顯示之後,使用者可以與產品信息互動,就像是在iTunes、App Store或iBookstore 一樣。 使用者可以:

  • 檢視螢幕快照(適用於應用程式),
  • 範例歌曲或視頻(適用於音樂、電視節目和電影),
  • 閱讀(和寫入)評論,
  • 購買和下載,這完全發生在檢視控制器和市集套件內。

中的 SKStoreProductViewController 某些選項仍會強制使用者離開您的應用程式並開啟相關的市集應用程式,例如按兩下 [相關產品 ] 或應用程式的 [支援] 連結。

SKStoreProductViewController

在任何應用程式中顯示產品的 API 很簡單:它只需要您建立並顯示 SKStoreProductViewController。 請遵循下列步驟來建立及顯示產品:

  1. 建立 StoreProductParameters 物件,將參數傳遞至檢視控制器,包括 productId 建構函式中的 。
  2. 具現化 SKProductViewController。 將它指派給類別層級欄位。
  3. 將處理程式指派給檢視控制器的事件 Finished ,這應該會關閉檢視控制器。 當使用者按下取消時,就會呼叫此事件;否則會完成檢視控制器內的交易。
  4. LoadProduct呼叫 傳入 StoreProductParameters 和完成處理程式的方法。 完成處理程式應該檢查產品要求是否成功,如果是的話,請 SKProductViewController 以強制回應方式呈現。 如果無法擷取產品,應該新增適當的錯誤處理。

範例

本文的 StoreKit 範例程式代碼中的 ProductView 專案會Buy實作接受任何產品的 Apple ID 並顯示 SKStoreProductViewController的方法。 下列程式代碼會顯示任何指定 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);
        }
    });
}

執行 時,應用程式看起來像下面的螢幕快照 – 下載或購買完全發生在 內 SKStoreProductViewController

執行時,應用程式看起來會像這樣

支援舊版作業系統

範例應用程式包含程式代碼,示範如何在舊版 iOS 中開啟 App Store、iTunes 或 iBookstore。 OpenUrl使用方法來開啟正確製作的 itunes.com URL。

您可以實作版本檢查來判斷要執行的程式代碼,如下所示:

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

錯誤

如果您使用的Apple ID無效,就會發生下列錯誤,這可能會造成混淆,因為它表示某種類型的網路或驗證問題。

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

閱讀 Objective-C 檔

閱讀 Apple 開發人員入口網站上 Store Kit 的開發人員會看到通訊協定 – SKStoreProductViewControllerDelegate - 與這項新功能相關的討論。 委派通訊協定只有一個方法 – productViewControllerDidFinish – 已公開為 Finished Xamarin.iOS 中的 SKStoreProductViewController 事件。

判斷 Apple 識別碼

所需的 SKStoreProductViewController Apple 識別符是一個 數位 (不要與套件組合標識符混淆,例如 “com.xamarin.mwc2012” )。 有幾種不同的方式可以找出您想要顯示之產品的 Apple ID,如下所示:

iTunes 連線

針對您發佈的應用程式,很容易就能在 iTunes 連線 中找到 Apple ID

在 iTunes 連線 中尋找 Apple ID

搜尋 API

Apple 提供動態搜尋 API 來查詢 App Store、iTunes 和 iBookstore 中的所有產品。 如需如何存取搜尋 API 的資訊,請參閱 Apple 的分支機構資源,雖然 API 會向任何人公開(不只是已註冊的聯盟)。 產生的 JSON 可以剖析,以探索 trackId 要搭配 SKStoreProductViewController使用的 Apple ID。

結果也會包含其他元數據,包括顯示資訊和圖稿 URL,可用來在應用程式中轉譯產品。

以下列出一些範例:

企業合作夥伴摘要

Apple 會以可下載的資料庫就緒一般檔案的形式,為已核准的合作夥伴提供其所有產品的完整數據傾印。 如果您有資格存取 Enterprise Partner Feed,則可以在該數據集中找到任何產品的 Apple ID。

企業合作夥伴摘要的許多使用者都是聯盟計劃的成員,可讓產品銷售獲得傭金。 SKStoreProductViewController 不支援分支機構標識碼(在撰寫時)。

產品的 Apple ID 可以從其 iTunes 預覽 URL 連結推斷。 在任何 iTunes 產品連結中(適用於應用程式、音樂或書籍)中,尋找 URL id 的一部分開頭,並使用後面的數位。

例如,iBooks 的直接連結是

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

且 Apple ID 為 364709193。 同樣地,針對MWC2012應用程式,直接連結為

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

且 Apple ID 為 496963922

應用程式內購買託管的內容

如果您的應用程式內購買包含可下載的內容(例如書籍或其他媒體、遊戲層級藝術和設定,或其他大型檔案),則這些檔案會用來裝載在網頁伺服器上,而應用程式必須納入程序代碼,才能在購買后安全地下載這些檔案。 從 iOS 6 開始,Apple 會在其伺服器上裝載您的檔案,以移除個別伺服器的需求。 此功能僅適用於非消費性產品(非消費性或訂閱)。 使用 Apple 裝載服務的優點包括:

  • 節省裝載和頻寬成本。
  • 可能比您目前使用的任何伺服器主機更具擴充性。
  • 撰寫的程式代碼較少,因為您不需要建置任何伺服器端處理。
  • 背景下載會為您實作。

注意:不支援在iOS模擬器中裝載的應用程式內購買內容進行測試,因此您必須使用實際裝置進行測試。

裝載的內容基本概念

在iOS 6之前,有兩種方式可提供產品(在 Xamarin 的 App 內購買檔中更詳細地說明):

  • 內建產品 – 購買而「解除鎖定」的功能,但內建於應用程式(程式代碼或內嵌資源)。 內建產品的範例包括解除鎖定的相片篩選或遊戲內電源。
  • 伺服器交付的產品 – 購買之後,應用程式必須從您操作的伺服器下載內容。 購買期間會下載此內容、儲存在裝置上,然後轉譯為提供產品的一部分。 範例包括由背景藝術和組態檔組成的書籍、雜誌問題或遊戲層級。

在iOS 6 Apple中,提供伺服器交付產品的變化:它們會在其伺服器上裝載您的內容檔案。 這可讓您更輕鬆地建置伺服器交付的產品,因為您不需要操作個別伺服器,而 Store Kit 提供您先前必須自行撰寫的背景下載功能。 若要利用 Apple 的裝載功能,請啟用應用程式內購買產品的內容裝載,並修改您的 Store Kit 程式代碼以利用它。 接著會使用 Xcode 建置產品內容檔案,並上傳至 Apple 的伺服器以供檢閱和發行。

建置和傳遞程式

使用 App Store 透過託管內容提供應用程式內購買,需要下列設定和設定:

  • iTunes 連線 – 您必須已將銀行和稅務資訊提供給 Apple,以便他們代表您匯回的資金。 然後,您可以設定要銷售的產品,並設定沙箱用戶帳戶以測試購買。 您也必須為您想要與 Apple 一起裝載的非消費性產品設定託管內容。
  • iOS 布建入口網站 – 建立套件組合標識符,併為您的應用程式啟用 App Store 存取權,就像支援應用程式內購買的任何應用程式一樣。
  • 市集套件 – 將程式代碼新增至您的應用程式,以顯示產品、購買產品及還原交易。 在 iOS 6 市集套件中,也會在背景中管理產品內容的下載,並包含進度更新。
  • 自定義程式代碼 – 追蹤客戶所做的購買,並提供他們購買的產品或服務。 利用新的 iOS 6 Store Kit 類別,例如 SKDownload 擷取 Apple 所裝載的內容。

下列各節說明如何使用本文的範例程式代碼,實作裝載的內容,從建立和上傳套件到管理購買和下載程式。

範例程式碼

範例專案 HostedNonConsumables (StoreKitiOS6.zip) 會使用託管的內容。 該應用程式提供兩個“書籍章節”出售,內容裝載在蘋果的伺服器上。 內容是由文本檔和影像所組成,不過在實際應用程式中可以使用更複雜的內容。

在購買之前、期間和之後,應用程式看起來會像這樣:

應用程式在購買之前、期間和之後看起來像這樣

文字檔和影像會下載並複製到應用程式的 Documents 目錄。 如需應用程式記憶體可用之不同目錄的詳細資訊,請參閱 檔案系統檔

iTunes Connect

建立將使用Apple內容裝載的新產品時,請務必選取 非消費 性產品類型。 其他產品類型不支援內容裝載。 此外,您不應該針對 您銷售的現有 產品啟用內容裝載;只開啟新產品的內容裝載。

選取非消費性產品類型

輸入產品標識碼。 當您建立此產品的內容時,稍後會需要此標識符。

輸入產品標識碼

內容裝載是在 [詳細數據] 區段中設定。 在 App 內購買上線之前,如果您想要取消 ,請取消核取 [使用 Apple 裝載內容] 複選框(即使您已上傳一些測試內容)。 不過,在應用程式內購買已上線之後,無法移除內容裝載。

使用 Apple 裝載內容

開啟主控內容之後,產品會輸入 等候上傳 狀態,並顯示此訊息:

產品將輸入等候上傳狀態,並顯示此訊息

內容套件應該使用 Xcode 建立,並使用封存工具上傳。 下一節 會提供建立內容套件的指示。PKG 檔案

創建。PKG 檔案

您上傳至 Apple 的內容檔案必須符合下列限制:

  • 大小不能超過 2 GB。
  • 不能包含指向內容外的可執行程式碼(或符號連結)。
  • 必須正確格式化(包括 .plist 檔案),且擴展名 為 .pkg 。 如果您使用 Xcode 遵循這些指示,系統就會自動完成此動作。

只要這些檔案符合這些限制,您就可以新增許多不同的檔案和文件類型。 內容會在傳遞至您的應用程式之前先壓縮,再由 Store Kit 解壓縮,然後您的程式代碼才能進行存取。

上傳內容套件之後,即可將它取代為較新的內容。 必須上傳並提交新內容,才能透過一般程式進行檢閱/核准。 ContentVersion遞增更新內容套件中的欄位,以指出它較新。

Xcode 應用程式內購買內容專案

建立應用程式內購買產品的內容套件目前需要 Xcode。 不需要 OBJECTIVE-C 編碼;Xcode 有一個新的專案類型,這些套件只包含您的檔案和 plist。

我們的範例應用程式有書籍章節可供銷售 – 每個章節內容套件將包含:

  • 文字檔, 和
  • 表示章節的影像。

從功能表中選取 [檔案 > 新專案 ],然後選擇 [ 應用程式內購買內容] 開始:

選擇應用程式內購買內容

輸入產品名稱公司標識碼,讓套件組合標識元符合您在iTunes 中輸入的產品識別碼,連線 此產品。

輸入名稱和識別碼

現在您將有空白 的應用程式內購買內容 專案。 您可以用滑鼠右鍵按兩下 [ 新增檔案...] ,或將它們拖曳到 [項目導覽器]。 請確定 ContentVersion 正確(應該從 1.0 開始,但如果您稍後選擇更新內容,請記得遞增內容)。

此螢幕快照顯示 Xcode,其中包含專案的內容檔案,以及主視窗中可見的 plist 專案:

此螢幕快照顯示 Xcode,其中包含專案的內容檔案,以及主視窗中可見的 plist 專案

新增所有內容檔案之後,您可以儲存此專案,稍後再編輯它,或開始上傳程式。

上傳。PKG 檔案

上傳內容套件最簡單的方式是使用 Xcode 封存工具。 從選單中選擇 [產品 > 封存 ] 以開始:

選擇 [封存]

內容套件接著會出現在封存中,如下所示。 封存類型和圖示顯示這一行是應用程式 內購買內容封存。 按兩下 [ 驗證... ],檢查內容套件是否有錯誤,而不會實際執行上傳。

驗證套件

使用 iTunes 連線 認證登入:

使用 iTunes 連線 認證登入

選擇正確的應用程式和應用程式內購買,將此內容與下列內容產生關聯:

選擇正確的應用程式和應用程式內購買,以將此內容與建立關聯

您應該會看到類似下列螢幕快照的訊息:

範例沒有問題訊息

現在進行類似的程式,但按兩下 [發佈...] 實際上會上傳內容。

散發應用程式

選取第一個選項,以上傳內容:

上傳內容

再次登入:

登入

選擇正確的應用程式和應用程式內購買記錄,以上傳內容至:

選擇應用程式和應用程式內購買記錄

上傳檔案時請稍候:

內容上傳對話框

上傳完成時,會出現一則訊息,告知您內容已提交至 App Store。

成功上傳訊息的範例

完成後,當您返回 iTunes 上的產品頁面時,連線 它會顯示套件詳細數據,並處於 [準備提交] 狀態。 當產品處於此狀態時,您可以在沙盒環境中開始測試。 您不需要「提交」產品,才能在沙箱中進行測試。

iTunes 連線 會顯示套件詳細數據,並處於 [準備提交] 狀態

上傳封存和iTunes 連線 狀態更新之間可能需要一些時間(例如幾分鐘)。 您可以個別提交產品以供檢閱,或與應用程式二進位檔一起提交。 只有在 Apple 正式核准內容之後,才能在生產 App Store 中提供內容,才能在您的應用程式中購買。

PKG 檔案格式

使用 Xcode 和封存工具來建立和上傳託管的內容套件,表示您永遠不會看到套件本身的內容。 為範例應用程式建立的套件中的檔案和目錄看起來就像下面的螢幕快照,其中包含根目錄中的 plist 檔案,以及 Contents 子目錄中的產品檔案

根目錄中的 plist 檔案和 Contents 子目錄中的產品檔案

請注意套件的目錄結構(特別是子目錄中的檔案 Contents 位置),因為您必須瞭解這項資訊,才能從裝置上的套件擷取檔案。

更新套件內容

在內容核准之後更新內容的程式:

  • 在 Xcode 中編輯應用程式內購買內容專案。
  • 向上凸起版本號碼。
  • 再次上傳至 iTunes 連線。 後續購買者會自動取得最新版本但已有舊版的使用者將不會收到任何通知。
  • 您的應用程式會負責通知使用者,並鼓勵他們擷取較新版本的內容。 應用程式也必須使用 Store Kit 的還原功能,建置可下載新版本的函式。
  • 若要判斷是否有較新版本存在,您可以將功能建置至您的應用程式,以擷取 SKProducts(例如用來擷取產品價格的相同程式),並比較 ContentVersion 屬性。

購買概觀

閱讀本節之前,請先檢閱現有的 應用程式內購買檔

購買並下載具有託管內容的產品時所發生的事件順序如下圖所示:

購買並下載具有託管內容的產品時所發生的事件順序

  1. 您可以在已啟用託管內容的 iTunes 連線 中建立新產品。 實際內容是以 Xcode 個別建構的(就像將檔案拖曳到資料夾一樣),然後封存並上傳至 iTunes(不需要編碼)。 然後,每個產品都會提交核准,之後便可供購買。 在範例程式代碼中,這些產品標識符會硬式編碼,但如果您將可用的產品清單儲存在遠端伺服器上,則使用 Apple 裝載內容會更有彈性,以便在您將新產品和內容提交至 iTunes 連線 時更新。
  2. 當使用者購買產品時,交易會放在付款佇列中進行處理。
  3. Store Kit 會將購買要求轉送至 iTunes 伺服器進行處理。
  4. 交易會在 iTunes 伺服器上完成(例如,客戶付費),並將收據傳回給應用程式,並附加產品資訊,包括是否可下載(如果是的話,檔案大小和其他元數據)。
  5. 您的程式代碼應該檢查產品是否可下載,如果是的話,請提出同時放在付款佇列的內容下載要求。 市集套件會將此要求傳送至 iTunes 伺服器。
  6. 伺服器會將內容檔案傳回至 Store Kit,以提供回呼,以將下載進度和剩餘時間估計傳回您的程式代碼。
  7. 完成後,您會在快取資料夾中收到通知並傳遞檔案位置。
  8. 您的程式代碼應該複製檔案並加以驗證,並儲存任何您需要記住產品已購買的狀態。 請利用這個機會,在新的檔案上正確設定備份旗標(提示:如果他們來自伺服器,且從未由用戶編輯,您可能應該略過備份,因為用戶將來一律可以從 Apple 的伺服器擷取它們)。
  9. 呼叫 FinishTransaction。 此步驟很重要,因為它會從付款佇列中移除交易。 在將內容複製到快取目錄之後之前,您也必須不要呼叫 FinishTransaction。 呼叫 FinishTransaction 之後,快取的檔案可能會快速清除。

實作託管內容購買

下列資訊應與完整的 應用程式內購買檔一起閱讀。 本文件中的資訊著重於託管內容與先前實作之間的差異。

類別

已新增或變更下列類別,以支援 iOS 6 中的裝載內容:

  • SKDownload – 代表進行中下載的新類別。 API 允許每個產品有多個,但一開始只有一個已經實作。
  • SKProduct – 新增屬性:Downloadable、、ContentVersionContentLengths陣列。
  • SKPaymentTransaction – 新增屬性: Downloads,如果此產品已裝載可供下載的內容,則會包含 物件的集合 SKDownload
  • SKPaymentQueue – 新增方法: StartDownloads。 使用 SKDownload 物件呼叫這個方法,以擷取其裝載的內容。 下載可能會發生在背景中。
  • SKPaymentTransactionObserver – 新方法: UpdateDownloads。 Store Kit 會呼叫此方法,其中包含目前下載作業的進度資訊。

SKDownload 類別的詳細資料:

  • Progress – 介於 0-1 之間的值,可用來向用戶顯示完成百分比指標。 請勿使用 Progress == 1 來偵測下載是否完成,請檢查狀態 == 已完成。
  • TimeRemaining – 估計剩餘的下載時間,以秒為單位。 -1 表示它仍在計算估計值。
  • 狀態 – 作用中、等候中、已完成、失敗、暫停、已取消。
  • ContentURL – 目錄中內容放在磁碟上的 Cache 檔案位置。 只有在下載完成之後才會填入。
  • 錯誤 – 如果狀態為失敗,請檢查此屬性。

此圖顯示範例程式代碼中類別之間的互動(託管內容購買的特定程式代碼會以綠色顯示):

此圖表中的託管內容購買會以綠色顯示

本節其餘部分會顯示使用這些類別的範例程序代碼:

CustomPaymentObserver (SKPaymentTransactionObserver)

變更現有的 UpdatedTransactions 覆寫以檢查可下載的內容,並視需要呼叫 StartDownloads

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

新的覆寫方法 UpdatedDownloads 如下所示。 Store Kit 會在 中UpdatedTransactions觸發 之後StartDownloads呼叫這個方法。 這個方法會以不確定的間隔多次呼叫,以提供下載進度,然後在下載完成時再次呼叫。 請注意, 方法會接受 物件的陣列 SKDownload ,因此每個方法呼叫都可以提供佇列中多個下載的狀態。 如實作所示,每次執行適當的動作時,都會檢查下載狀態下方的下載狀態。

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

這個類別包含一個新的方法 SaveDownload ,會在每次下載成功完成之後呼叫。

裝載的內容已成功下載並解壓縮到 Cache 目錄中。 的結構。PKG 檔案需要將所有檔案儲存在 Contents 子目錄中,因此下列程式代碼會從 Contents 子目錄中擷取檔案。

程序代碼會逐一查看內容套件中的所有檔案,並將其複製到 Documents 目錄,在名為的 ProductIdentifier子資料夾中。 最後,它會呼叫 CompleteTransactionFinishTransaction ,以從付款佇列中移除交易。

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

呼叫 時 FinishTransaction ,已下載的檔案將不再保證位於 Cache 目錄中。 呼叫 之前 FinishTransaction,應該先複製所有檔案。

其他考量

上述範例程式代碼示範裝載內容購買的相當簡單的實作。 您必須考慮其他幾點:

偵測更新的內容

雖然您可以更新裝載的內容套件,但 Store Kit 不提供任何機制,將這些更新推送給已下載並購買產品的使用者。 若要實作這項功能,您的程式代碼可能會定期檢查新的 SKProduct.ContentVersion 屬性(如果 SKProductDownloadable),並偵測值是否遞增。 或者,您可以建置推播通知系統。

安裝更新的內容版本

上述範例程式代碼會略過檔案複製,如果檔案已經存在。 如果您想要支持下載的較新版本內容,這不是個好主意。

替代方式可能是將內容複製到名為 版本的資料夾,並追蹤其為目前版本(例如,在您儲存完成的購買記錄中 NSUserDefaults 或何處)。

還原交易

呼叫 時 SKPaymentQueue.DefaultQueue.RestoreCompletedTransactions ,Store Kit 會傳回使用者的所有先前交易。 如果他們已購買大量專案,或每次購買都有大型內容套件,則還原可能會導致大量的網路流量,因為所有項目都會一次排入佇列以供下載。

請考慮追蹤產品是否已與相關聯內容套件的實際下載分開購買。

暫停、重新啟動和取消下載

雖然範例程式代碼並未示範這項功能,但可以暫停和重新啟動託管的內容下載。 SKPaymentQueue.DefaultQueue具有、 ResumeDownloadsCancelDownloads的方法PauseDownloads

如果在下載Finished之前,程式代碼會在付款佇列上呼叫 FinishTransaction ,則會自動取消該下載。

在下載的內容上設定 SKIP-Backup 旗標

Apple 的 iCloud 備份指導方針建議,從伺服器輕鬆還原的非用戶內容不應進行備份(因為它會不必要的使用 iCloud 記憶體)。 如需設定備份屬性的詳細資訊,請參閱 文件系統 檔。

摘要

本文介紹 iOS6 中 Store Kit 的兩項新功能:從您的應用程式內購買 iTunes 和其他內容,並使用 Apple 的伺服器裝載您自己的應用程式內購買。 本簡介應與現有的 應用程式內購買檔 一起閱讀,以完整涵蓋實作市集套件功能。