WWDC22 - In App Purchase 更新总结
作者:iHTCboy
前言
WWDC21 是歷年來 In App Purchase(IAP,內購內購買)最大的變化,分別推出了 StoreKit 2、App Store Server API、App Store Server Notifications V2 三大特性,去年我們也編寫了 《蘋果iOS內購三步曲:App內退款、歷史訂單查詢、綁定用戶防掉單!— WWDC21》 文章,所以我們本文不會再深入提及去年的更新,大家如果不太熟悉,可以先溫習一下。本文將對今年 WWDC22 帶來的變化,從整體的視角一起回顧。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-c7fWy8Qe-1657516283945)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cd35fcd8bccc4fbb95b66c57febc9d65~tplv-k3u1fbpfcp-watermark.image?)]
以下是編者對 In App Purchase 這幾年重要的更新或調整的梳理:
| 2020 年 11 月 18 日 | App Store 小型企業計劃 | 日歷年收入在 100 萬美元以下的小型和獨立開發者將可以享受 15% 的傭金費率,僅為 App Store 標準傭金費率 30% 的一半,付費 app 和 App 內購買項目的收益抽成將降低 15%。 | 1、2 |
| 2020 年 11 月 23 日 | 針對在線多人活動的 app 內購買項目規定 | 3.1.3(d) 一對一服務:如果您的 App 允許購買兩個人之間的一對一實時服務 (例如,學生輔導、醫療咨詢、看房服務或健身訓練),您可以使用 App 內購買項目以外的其他購買方式來收取相應款項。一對幾和一對多的實時服務則必須使用 App 內購買項目。 | 1、2 |
| 2021 年 8 月 26 日 | Apple 與美國開發者就 App Store 達成和解 | 美國開發者提起的 App Store 集體訴訟與蘋果和解,Apple 設立一億美元的基金來幫助美國的小型業務開發者,符合條件的開發者獲得 250 美元至 3 萬美元的現金)。 | 1、2 |
| 2021 年 9 月 1 日 | 日本公平貿易委員會結束對 App Store 的調查 | 3.1.3(a) “閱讀器”類型的 App:此類 App 可以允許用戶訪問先前購買的內容或內容訂閱 (具體包括:雜志、報紙、圖書、音頻、音樂和視頻)。各種閱讀器 App 可以為使用免費版本的用戶提供帳戶創建功能,并為現有用戶提供帳戶管理功能。閱讀器 App 開發者可以申請 External Link Account 授權,以在其 App 中提供一個指向其擁有或負責維護的網站的信息鏈接,以便用戶創建或管理帳戶。了解有關 External Link Account 授權的更多信息。 | 1、2 |
| 2022 年 1 月 14 日 | 針對在荷蘭 App Store 上分發的約會 App 的更新 | 荷蘭消費者和市場管理局(ACM)允許荷蘭 App Store 上的約會 App 開發人員與用戶共享額外的付款處理選項。允許僅在荷蘭 App Store 中分發的約會 App 在 App 內提供其他支付處理選項。開發者可以使用 StoreKit 外部購買授權,蘋果降低 3% 的傭金,可與小型企業計劃或自動續期訂閱的 15 %傭金疊加,最低抽成 12 %。 | 1、2 |
| 2022 年 5 月 16 日 | 自動續期訂閱提價更新 | 目前,當自動續期訂閱提價時,訂閱者必須在 App 提價之前選擇接受。新調整:符合某些特定條件并在提前通知用戶的情況下,開發者在為自動續訂訂閱提價時,無需用戶額外采取行動,亦不會中斷服務。(前提條件:每年提價不超過一次,同時訂閱價格上調不超過 5 美元和 50%,或者年度訂閱價格上調不超過 50 美元和 50%,并且是在法律允許的范圍內。) | 1、2 |
| 2022 年 6 月 30 日 | 針對在韓國分發 App 的更新 | 允許僅在韓國 App Store 中分發的 App 在 App 內提供其他支付處理選項。開發者可以使用 StoreKit 外部購買授權,但蘋果收益抽成 26%。 | 1、2 |
說到內購,環繞著的新聞,總起到一些波瀾,從 2021 年蘋果推出 App Store 小型企業計劃,降低 15% 的傭金,大家的討論一直源源不斷,對于小型企業和開發者,確實是明顯感受到 15% 帶來的回報!本文不去討論合理性,App Store 從 2008 年推出就是一個創舉,它改變了世界對 App 的認識。我們本文更多的是討論如果利用這些變化,為用戶提供更好的服務或體驗!
本文主要從四方面進行探討:
StoreKit 2
StoreKit 2 和 Original StoreKit,應該怎么選擇?蘋果在選擇文檔在給出了答案:
- StoreKit 2: 一個基于 Swift 的 API,以 JSON Web Signature (JWS) 格式提供 Apple 簽名交易驗證,從 iOS 15、macOS 12、tvOS 15 和 watchOS 8 開始提供。
- Original API for In-App Purchase: 一個使用 App Store 收據提供交易信息的API,從 iOS 3、macOS 10.7、tvOS 9 和 watchOS 6.2 開始提供。
去年的文章,我們提到以下功能必須依賴 Original StoreKit API:
因此,今年的 StoreKit 2,蘋果提供新的字段 preorderDate 和 originalPurchaseDate 來獲取 App 預訂時間和購買時間,但是只支持 iOS 16+。
所以,目前 iOS 16 和 StoreKit 2 不能解決的問題:
2022年,如何選擇 Original StoreKit 還是 StoreKit 2
對于支持低于 iOS 15 以下 app 依然需要使用 Original StoreKit,直到只支持 iOS 15+,并且支持遷移到 StoreKit 2。對于目前開發者來說,使用 StoreKit 2 的成本主要是兼容的系統版本,還有一方面是服務端的兼容,最后是 app 如果有 IAP 服務,那一定是核心業務,不容許一點點的錯誤!這導致了大多數 app 還處于圍觀 StoreKit 2 的狀態。對于只支持 iOS 15+ 或者獨立開發者,建議可以嘗試使用 StoreKit 2,如果有異常時,降級到 Original StoreKit 就可以。總之,最后等時間給我們答案吧。
App Transaction(App 交易)
StoreKit 2 增加了 App Transaction 結構體,用于代替 Original StoreKit 的 receipt 內容,具體直接查看接口文檔:
/// Represents signed transaction information for an app purchase. @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *) public struct AppTransaction : Sendable {/// The JSON representation of the transaction.public var jsonRepresentation: Data { get }/// A number the App Store uses to uniquely identify the application.public let appID: UInt64?/// The application version the transaction is for.public let appVersion: String/// A number the App Store uses to uniquely identify the version of the application.public let appVersionID: UInt64?/// Identifies the application the transaction is for.public let bundleID: String/// The server environment this transaction was created in.public let environment: AppStore.Environment/// The version of the app originally purchased.public let originalAppVersion: String/// The date this original app purchase occurred on.public let originalPurchaseDate: Date/// The date this app was preordered.public let preorderDate: Date?/// A SHA-384 hash of `AppStore.deviceVerificationID` appended after/// `deviceVerificationNonce` (both lowercased UUID strings).public let deviceVerification: Data/// The nonce used when computing `deviceVerification`./// - SeeAlso: `AppStore.deviceVerificationID`public let deviceVerificationNonce: UUID/// The date this transaction was generated and signed.public let signedDate: Date/// Get the cached `AppTransaction` for this version of the app or make/// a request to get one from the App Store server if one has not been cached yet.public static var shared: VerificationResult<AppTransaction> { get async throws }/// Refreshes the shared `AppTransaction` from the App Store server./// Calling this function will force an authentication dialog to display to the user.public static func refresh() async throws -> VerificationResult<AppTransaction> }App Transaction 從以上接口可以獲取 App 預訂時間 preorderDate 和購買時間 originalPurchaseDate 等。另外,驗證用戶當前使用的 app 是否正品購買以防止欺詐的作用。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-f0GlZYcw-1657516283946)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7238c8194e124ca7b76202546135881f~tplv-k3u1fbpfcp-watermark.image?)]
- 購買您的 app 的簽名信息
- 使用 JWS 簽名
- 替換 Original StoreKit 的 receipt(票據)
- StoreKit 提供驗證方法
- 開發者可以執行自己的驗證(或處理)
驗證 App Transaction 的方法:
@available(iOS 16.0, *)func verificationAppTransaction() {Task {do {let verificationResult = try await StoreKit.AppTransaction.sharedswitch verificationResult {case .verified(let appTransaction):// StoreKit verified that the user purchased this app and// the properties in the AppTransaction instance.// Add your code here.case .unverified(let appTransaction, let verificationError):// The app transaction didn't pass StoreKit's verification.// Handle unverified app transaction information according// to your business model.// Add your code here.}} catch {// Handle errors.}}}最后說明一下,App Transaction 的內容,首次啟動時,StoreKit 會自動獲取更新并保持最新狀態。當您的 app 無法通過 shared 屬性獲得 App Transaction 時(包括返回 Verification.unverified(:😃 或拋出異常錯誤),可以使用 refresh() 刷新 App 交易內容,但是刷新時,系統會彈窗提示用戶可能需要重新授權認證 Apple ID 賬號,所以建議是提供用戶操作的按鈕,由用戶主動發起調用。
New properties(新特性)
StoreKit 2 帶來了新的四個字段:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-r3mlRmE0-1657516283947)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6283a486d8674c078b4de7bdd695266d~tplv-k3u1fbpfcp-watermark.image?)]
- 價格地區
- 交易的服務器環境
- 最近的訂閱開始日期
- 哨兵值(占位符值)
Price locale
extension Product {@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)public var priceFormatStyle: Decimal.FormatStyle.Currency { get }@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)public var subscriptionPeriodFormatStyle: Date.ComponentsFormatStyle { get } }新增 priceFormatStyle 和 subscriptionPeriodFormatStyle 字段。一般情況下,蘋果建議盡可能使用 displayPrice 字段表示格式。例如從 price 屬性獲取兩個品項的價格,例如 2 products for $(price * 2)。
Server environment
public struct Transaction : Identifiable {@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)public let environment: AppStore.Environment@available(iOS, introduced: 15.0, deprecated: 16.0, message: "Use the environment property instead")@available(macOS, introduced: 12.0, deprecated: 13.0, message: "Use the environment property instead")@available(tvOS, introduced: 15.0, deprecated: 16.0, message: "Use the environment property instead")@available(watchOS, introduced: 8.0, deprecated: 9.0, message: "Use the environment property instead")@available(macCatalyst, introduced: 15.0, deprecated: 16.0, message: "Use the environment property instead")public var environmentStringRepresentation: String { get } }在 iOS 16+ 使用 environment 結構體,在 iOS 15 使用 environmentStringRepresentation 字段。
獲取到的字段值:
| App Store | Production | App Store 商店包環境的交易 |
| App Store Sandbox 或 TestFlight | Sandbox | Develop 或 TestFlight 環境的交易 |
| Xcode StoreKit Testing | Xcode | 使用 Xcode 進行 StoreKit 測試的交易 |
Recent subscription start date
extension Product.SubscriptionInfo {public struct RenewalInfo {@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)public var recentSubscriptionStartDate: Date { get }} }recentSubscriptionStartDate 表示自動續期訂閱購買中訂閱的最早開始日期,忽略了超過 60 天的所有續費失敗的訂閱。
需要注意的是,不要使用 recentSubscriptionStart 字段日期來計算付費服務天數,以前,自動續期訂閱的凈收入結構和 App Store 上的其他商業模式不同,用戶訂閱累積滿一年后,開發者的 收入將增加到訂閱價格的 85%。所以,開發者不能依據這個字段來判斷用戶訂閱是否滿一年。另外,如果開發者當前注冊了 App Store Small Business Program,符合條件的情況下,無論訂閱是否已累積滿一年,其實在每個結算周期收到訂閱價格的 85%。
Sentinel values
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0Yf3wg2B-1657516283947)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1540c16b532544dd9c59e87e58d5c67c~tplv-k3u1fbpfcp-watermark.image?)]
另外,在不支持的系統和環境中,就會使用 Sentinel values 哨兵值(占位符值),例如 Price local 下使用 Locale(identifier: "xx\_XX"),而 Recent subscription start date 使用 Date.distantPast 等。這是為什么呢?
因為以上的字段,其它在 Xcode13 和 iOS 15 是不存在的!蘋果利用 Xcode 14 提供了對 iOS 15, iPadOS 15, macOS 12, Mac Catalyst 15, watchOS 9, tvOS 15 等的支持。原理是通過 Xcode 14 編譯 app 時,會帶上這些字段在 app 包體中,低系統的用戶更新包含這些字段的版本時,就能使用。(具體是怎么編譯和實現,有懂的朋友歡迎留言交流,小編暫時還沒有找到相關文檔。)
另外,JWS Transaction 的 Payload 內也新增 environment、recentSubscriptionStartDate 相關字段,下文會提到。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-KffajSt3-1657516283947)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0256a2a19591428fbb7a6747e429e315~tplv-k3u1fbpfcp-watermark.image?)]
SwiftUI API
針對 SwiftUI 增加了優惠代碼兌換接口和應用內評分接口。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JxlEFbLD-1657516283948)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d6af3fb607464085b971fbe9b8d2c47a~tplv-k3u1fbpfcp-watermark.image?)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3cOekFIV-1657516283948)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/588ae193e50f43a6993bce9147e8ea03~tplv-k3u1fbpfcp-watermark.image?)]
StoreKit messages
StoreKit Message API 只支持 iOS 16+,用于開發者在 app 中接收和顯示 App Store 消息處理。舉例來說,自動續期訂閱的費用漲價時,如果需要用戶確認同意漲價,就需要彈窗給用于確認:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-8w9672zh-1657516283948)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5a52e63aff1b4fffa7ffc11c027cabeb~tplv-k3u1fbpfcp-watermark.image?)]
具體的 StoreKit messages 交互流程圖:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ry1WAW7v-1657516283948)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c4471cc620754cc1bea1fe272eb9cea3~tplv-k3u1fbpfcp-watermark.image?)]
獲取 App Store messages 消息,使用 SwiftUI 實現的代碼示例:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-V5sSbdGE-1657516283949)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/61daa1d61e8748cfbee59e69d5159a37~tplv-k3u1fbpfcp-watermark.image?)]
然后顯示 App Store messages 消息,需要通過 SwiftUI 環境變量 displayStoreKitMessage 來解析和顯示,使用 SwiftUI 實現的代碼示例:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-AwQMqXhF-1657516283949)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3b9a59952a0c4db2adab5031dab7aa22~tplv-k3u1fbpfcp-watermark.image?)]
applicationUsername 和 appAccountToken
let payment = SKMutablePayment(product: product) payment.applicationUsername = uuidStringSKPaymentQueue.default().add(payment)applicationUsername 是 Original StoreKit 創建蘋果訂單時,由開發者賦值的一個字段,原本這個字段是傳入用戶 UID 的 Hash 值,作用是給蘋果驗證應用購買以防止欺詐,比如代充和黑產惡意充值等。
而 appAccountToken 是去年 WWDC21 推出 StoreKit 2 的一個字段,用于開發者將蘋果交易與自己服務上的用戶關聯的 UUID 格式的字段。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qFHrrj0B-1657516283949)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a554a90af1b64923aca09b677990d099~tplv-k3u1fbpfcp-watermark.image?)]
而現在,蘋果打通了 applicationUsername 和 appAccountToken,當用 Original StoreKit 創建訂單時,applicationUsername 字段賦值使用 UUID 格式內容時,則可以在服務端通知或者解析 receipt 票據時,可以獲取這個 UUID 值,也就是訂單可以關聯確認。
我們回顧一下,我們為什么需要使用 applicationUsername?我們是希望每個交易 transaction 可以關聯用戶訂單號,對于訂閱類型和非消耗類型品項,關聯用戶 UID 就能滿足需求,但是對于非消耗型品項,其實,需要關聯用戶 UID 還有訂單號 OrderID,因為非消耗型品項可以重復購買并且沒有 UID 的強關聯。舉例來說,游戲里的用戶賬號可能不止一個,或者一個賬號下的游戲角色,通常不止有一個角色,所以購買非消耗型品項時,開發者希望關聯的是當前用戶 UID 和此角色 RoleID 生成的開發者訂單號 OrderID,但此時,UUID 格式并不能滿足開發者自定義的需求!
所以,applicationUsername 和 appAccountToken 的透傳值,對開發者有一定的關聯作用,但其實還不完美。
External Purchase(外部購買,第三方支付)
符合條件的 app 可以包含一個鏈接,引導使用該 app 的用戶訪問網站進行外部購買。要包含該鏈接,請完成此授權的請求。有關符合條件的 app 和請求此授權的更多信息,請參閱:
- 在荷蘭分發約會 App
- 在韓國使用第三方支付提供商分發 App
具體的細節這里不說,就重點說說代碼。首先,需要更新 app 的 Info.plist 文件,添加權限:
- com.apple.developer.storekit.external-purchase :表示您的 app 是否可以提供外部購買。
- com.apple.developer.storekit.external-purchase-link :表示您的 app 是否可以包含一個鏈接,引導用戶訪問網站進行外部購買。
- SKExternalPurchase :表示您的 app 可以提供外部購買的國家或地區。
- SKExternalPurchaseLink :表示您的 app 可以提供外部購買的國家或地區和對應的用戶訪問網站進行外部購買的鏈接。
配置示例:
<key>com.apple.developer.storekit.external-purchase</key><true/><key>com.apple.developer.storekit.external-purchase-link</key><true/><key>SKExternalPurchase</key><array><string>nl</string></array><key>SKExternalPurchaseLink</key><dict><key>nl</key><string>https://www.iHTCboy.com</string></dict>然后就是接口調用,在 iOS 或 iPadOS 15.4 或更高版本,使用 StoreKit External Purchase API:
@available(iOS 15.4, *) @available(macOS, unavailable) @available(tvOS, unavailable) @available(watchOS, unavailable) public enum ExternalPurchase {/// The result of presenting the external purchase notice sheet.public enum NoticeResult : Sendable {/// The user chose to continue to view external purchases.case continued/// The user chose to cancel and **not** view external purchases.case cancelledpublic static func == (a: ExternalPurchase.NoticeResult, b: ExternalPurchase.NoticeResult) -> Boolpublic func hash(into hasher: inout Hasher)public var hashValue: Int { get }}/// Present a notice sheet to users before showing external purchases.////// Only call this method as a result of deliberate user interaction, such as tapping a button./// - Returns: Whether the user chose to continue to view the external purchases. Only show/// external purchases if the result is `NoticeResult.continued`./// - Throws: A `StoreKitError`public static func presentNoticeSheet() async throws -> ExternalPurchase.NoticeResult }[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2xWXrOM8-1657516283949)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/58f87e4e4cf74ebabefb231a3d9c31fc~tplv-k3u1fbpfcp-watermark.image?)]
如圖所示,按照蘋果的規范,使用外部購買必須要的步驟:
在 iOS 和 iPadOS 15.4 運行的代碼示例:
// 當前設備不能支付,則不能進行購買~ guard AppStore.canMakePayments else {return }do {// 打開外部購買流程let res = try await ExternalPurchase.presentNoticeSheet()// 打開結果switch res {case .continued:print("用戶選擇繼續查看外部購買")case .cancelled:print("用戶選擇取消,不查看外部購買")@unknown default:fatalError()} } catch {// 異常流程print(error.localizedDescription) }注意事項:
- 獲取蘋果許可權限后,您才可以在 app 中包含第三方支付系統
- 只有用戶點擊 I Understand(我明白)后,才能跳轉到第三方支付系統
- 不包含任何隱藏、休眠或蘋果未允許的支付功能或行為
- 只能在蘋果允許的國家或地區的 App Store 商店使用第三方支付系統
External Link Account(訪問外部網站的鏈接)
閱讀器 App 是指將提供以下一種或多種數字內容類型作為其主要功能的 App:雜志、報紙、圖書、音頻、音樂或視頻。
通過閱讀器 App,用戶可以登錄他們在 App 之外創建的帳戶,從而可以在用戶的 Apple 設備上閱覽和暢讀先前購買的媒體內容或內容訂閱。開發者可以提供指向 app 網站的鏈接,以便用戶在 app 網站上創建和管理帳戶。有關符合條件的 app 和請求此授權的更多信息,請參閱:
- 分發包含指向您網站的鏈接的“閱讀器” App
同理,首先,需要更新 app 的 Info.plist 文件,添加權限:
- com.apple.developer.storekit.external-link.account :表示您的 app 是否可以鏈接到外部網站進行帳戶創建或管理。
- SKExternalLinkAccount :表示您的 app 可以提供外部創建或管理帳戶的國家或地區,和對應的用戶訪問創建或管理帳戶網站的鏈接。
然后就是接口調用,在 iOS 或 iPadOS 16 或更高版本,使用 StoreKit External Link Account API:
@available(iOS 16.0, *) @available(macOS, unavailable) @available(tvOS, unavailable) @available(watchOS, unavailable) public enum ExternalLinkAccount : Sendable {/// Whether the app can open the external link account.////// Check this property before showing any UI controls that the user can use to open the external link/// account./// You may want to check the value of this property again when the App Store storefront changes./// - Important: If this property is `false`, do not show UI controls that call `open()` as the/// method will always fail.public static var canOpen: Bool { get async }/// Opens the external link account in the user's default browser.////// Only call this method as a result of deliberate user interaction, such as tapping a button. If/// `canOpen` is `false`, this method will always throw an error. Returning without throwing an error/// does not guarantee the user was redirected to the external link account./// - Throws: A `StoreKitError`public static func open() async throws }[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-E4NvYXw3-1657516283949)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7bdbbbf9a6494633a8c3dfe5c44a796c~tplv-k3u1fbpfcp-watermark.image?)]
如圖所示,按照蘋果的規范,使用外部購買必須要的步驟:
在 iOS 和 iPadOS 15.4 運行的代碼示例:
@available(iOS 16.0, *) func externalLinkAccount() {// 當前設備不能支付,則不能進行購買~guard AppStore.canMakePayments else {return}Task {// 判斷是否有打開外部鏈接帳戶的權限let canOpen = await ExternalLinkAccount.canOpenguard canOpen else {print("不能打開外部鏈接帳戶")return}do {// 打開外部鏈接帳戶try await ExternalLinkAccount.open()} catch {print(error.localizedDescription)}} }注意事項:
- 獲取蘋果許可權限后,您才可以在 app 中包含鏈接到外部網站進行帳戶創建或管理
- 只有用戶點擊 Continue(繼續)后,才能跳轉到外部網站進行帳戶創建或管理
- 跳轉到外部網站,不能有沒有任何重定向、中間鏈接或著陸頁面
- 不得在 URL 中傳遞附加參數,以便保護用戶 (例如用戶的隱私)
App Store Server API
App Store Server API 是蘋果去年 WWDC21 推出的 ,詳細可以參考我們之前的文章《WWDC21 - App Store Server API 實踐總結》。
今年 WWDC22 蘋果新增了三個新接口,并且對部分接口增加了過濾功能,這里我們列了一個表格:
| WWDC21 | Look Up Order ID | 查詢用戶訂單的收據,使用訂單ID從收據中獲取用戶的應用內購買項目收據信息。 | GET https://api.storekit.itunes.apple.com/inApps/v1/lookup/{orderId} |
| WWDC21 | Get Transaction History | 查詢用戶歷史收據,獲取用戶在您的 app 的應用內購買交易歷史記錄。 | GET https://api.storekit.itunes.apple.com/inApps/v1/history/{originalTransactionId} |
| WWDC21 | Get Refund History | 查詢用戶內購退款,獲取 app 中為用戶退款的所有應用內購買項目的列表。 | GET https://api.storekit.itunes.apple.com/inApps/v1/refund/lookup/{originalTransactionId} |
| WWDC21 | Get All Subscription Statuses | 查詢用戶訂閱項目狀態,獲取您 app 中用戶所有訂閱的狀態。 | GET https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{originalTransactionId} |
| WWDC21 | Send Consumption Information | 提交防欺詐信息,當用戶申請退款時,蘋果通知(CONSUMPTION_REQUEST)開發者服務器,開發者可在12小時內,提供用戶的信息(比如游戲金幣是否已消費、用戶充值過多少錢、退款過多少錢等),最后蘋果收到這些信息,協助“退款決策系統” 來決定是否允許用戶退款。 | PUT https://api.storekit.itunes.apple.com/inApps/v1/transactions/consumption/{originalTransactionId} |
| WWDC21 | Extend a Subscription Renewal Date | 延長用戶訂閱的時長,使用原始交易標識符延長用戶有效訂閱的續訂日期。(相當于免費給用戶增加訂閱時長) | PUT https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/extend/{originalTransactionId} |
| WWDC22 | Request a Test Notification | 測試 App Store 服務器通知,讓 App Store 服務器通知向開發者服務器發送測試通知。 | POST https://api.storekit.itunes.apple.com/inApps/v1/notifications/test |
| WWDC22 | Get Test Notification Status | 獲取 App Store 服務器通知的測試結果,獲取發送到開發者服務器的 App Store 服務器測試通知的檢查狀態。 | GET https://api.storekit.itunes.apple.com/inApps/v1/notifications/test/{testNotificationToken} |
| WWDC22 | Get Notification History | 獲取 App Store 服務器通知的歷史通知,獲取 App Store 服務器嘗試發送到開發者服務器的通知列表。 | POST https://api.storekit.itunes.apple.com/inApps/v1/notifications/history |
Filter and Sort(過濾和排序)
其中只有 Get Transaction History 接口提供了過濾和排序的功能:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-p6v179hq-1657516283950)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c8ce66e99439459e89cfcd4a999cb86a~tplv-k3u1fbpfcp-watermark.image?)]
目前支持的查詢參數列表:
| productType | 包含在交易歷史記錄中的產品類型。您的查詢可以指定多個productType。 | AUTO_RENEWABLE, NON_RENEWABLE, CONSUMABLE, NON_CONSUMABLE |
| productId | 包含在交易歷史記錄中的產品標識符。您的查詢可以指定多個productID。 | - |
| subscriptionGroupIdentifier | 包含在交易歷史記錄中的訂閱組標識符。您的查詢可能會指定多個subscriptionGroupIdentifier。 | - |
| startDate | 交易開始日期,以 UNIX 時間表示的時間跨度的開始日期,以毫秒為單位。 | - |
| endDate | 交易截止日期,以 UNIX 時間表示的時間跨度的截止日期,以毫秒為單位。 | - |
| inAppOwnershipType | 按應用程序內所有權類型限制交易歷史記錄。 | PURCHASED,FAMILY_SHARED。 |
| excludeRevoked | 交易歷史記錄是否排除退款和撤銷的交易。默認值為false。 | true, false |
| sort | 交易歷史記錄的可選排序順序。響應按最近修改的日期對交易記錄進行排序。默認值為 ASCENDING(升序),因此您首先會收到最舊的交易記錄。 | ASCENDING, DESCENDING |
| revision | 獲取下一組最多20筆交易的令牌。所有回復都包含一個revision令牌。注意:對于使用revision令牌的請求,請包含與初始請求相同的查詢參數。使用上一個History中的revision令牌。除初始請求外,所有請求都需要revision。 | - |
查詢示例:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZaBh5gPy-1657516283950)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/29e8fe1a7985486eba9424179bb5f25e~tplv-k3u1fbpfcp-watermark.image?)]
productId、productType 和 subscriptionGroupIdentifier 查詢參數可以同時指定多個值。例如,要按 NON_CONSUMABLE(非消耗型) 和 AUTO_RENEWABLE(自動續期產品類型)字符來篩選交易歷史記錄,請求中包含以下內容:
GET https://api.storekit.itunes.apple.com/inApps/v1/history/{originalTransactionId}?productType=NON_CONSUMABLE&productType=AUTO_RENEWABLE其實更優雅的方式可能是 App Store Connect API 的形式:&filter[appStoreVersions.appStoreState]=READY_FOR_SALE,PREORDER_READY_FOR_SALE,READY_FOR_REVIEW 。
最后,交易歷史記錄接口返回結果只支持以下情況:
- 自動續期訂閱
- 非續訂訂閱
- 非消耗型應用內購買項目
- 消耗型應用內購買項目:如果交易被退款、撤銷或 app 尚未完成交易處理等。
特別注意:消耗型應用內購買項目如果調用了 finishTransaction(_😃,則不會在出現在舞臺的交易歷史列表中,所以,消耗型應用內購買項目不能使用這個接口作為校驗接口!!!
New Notification API(新的通知接口)
測試 App Store 服務器通知
Request a Test Notification 讓 App Store 服務器通知向開發者服務器發送測試通知。
POST https://api.storekit.itunes.apple.com/inApps/v1/notifications/test[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-lt9ppEGh-1657516283950)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a61baf3d4a4c464eaabaeb1b682633d4~tplv-k3u1fbpfcp-watermark.image?)]
接口響應的 testNotificationToken 字段是 App Store 服務器通知發送到開發者服務器的通知測試的測試通知令牌,每次請求獲取的唯一標識 Token,這個 Token 用于下面的接口參數。
獲取 App Store 服務器通知的測試結果
Get Test Notification Status,獲取發送到開發者服務器的 App Store 服務器測試通知的檢查狀態。
GET https://api.storekit.itunes.apple.com/inApps/v1/notifications/test/{testNotificationToken}根據 Request a Test Notification 接口獲取到的 testNotificationToken 請求測試結果:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9M40VhOg-1657516283950)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3fc837961be34716be9f90e3e43cab48~tplv-k3u1fbpfcp-watermark.image?)]
返回的響應有兩個參數:
- firstSendAttemptResult:表示 App Store 服務器嘗試向開發者服務器發送 TEST 通知的結果,如果不是 SUCCESS,則如上圖會返回原因,如果 TIMED_OUT 表示超時,SSL_ISSUE 表示開發者服務器的 SSL 證書有問題。根據這個字段就能測試和檢查 App Store 服務器和開發者服務器之前的連通性。
- signedPayload:JWS 格式的簽名有效負載,包含 App Store 服務器發送到您的服務器的 TEST 通知。
具體的 signedPayload 解碼后的格式內容如下示例:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fcK2Ykgx-1657516283950)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e0d56077a46e4700a5905e0d439eaff6~tplv-k3u1fbpfcp-watermark.image?)]
獲取 App Store 服務器通知的歷史通知
Get Notification History,獲取 App Store 服務器嘗試發送到開發者服務器的通知列表。
POST https://api.storekit.itunes.apple.com/inApps/v1/notifications/history此接口的目的是,因為 App Store 服務器通知是蘋果推送的通知,開發者是被動接收,總會因為各種情況(服務器宕機,運營商鏈路或云服務提供商故障等)導致無法按時接收到 App Store 服務器通知。所以,可以通過這個接口查詢 App Store 服務器通知的歷史記錄:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WmOWDGuc-1657516283951)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b77c8af77552418f9e0800759714ded2~tplv-k3u1fbpfcp-watermark.image?)]
- 只支持 App Store 服務器通知 V2 版本的響應(即 JWS 格式)
- 最多可以查詢 6 個月以內的歷史列表(180天內)
- 可以過濾通知類型、通知子類型或用戶
- 開發者服務器宕機后可使用接口主動獲取通知記錄,直到開發者服務器可接收 App Store 服務器通知為止
查詢接口的示例:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ocKAxWaY-1657516283951)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1600b9b7fbdd4a49b1cbda9105f599c0~tplv-k3u1fbpfcp-watermark.image?)]
接口每次最多返回20條通知歷史記錄,所以響應會返回一個 paginationToken 字段,用來查詢更多分頁的通知結果。paginationToken 獲取下一組最多 20 條通知歷史記錄,所有有更多歷史記錄的響應都包含 paginationToken 字段。
New properties(新特性)
除了 StoreKit 2 增加了 environment、recentSubscriptionStartDate 字段,App Store Server API 的 JWS 格式的簽名交易也包含。
JWS transaction info Decoded Payload:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sFoZMFy9-1657516283951)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/43003701fe4d466f81c0d47b80313a33~tplv-k3u1fbpfcp-watermark.image?)]
JWS renewal info Decoded Payload:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-RqxNgjjA-1657516283951)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9bd1295ff9d64e8cb93badc92eeb187a~tplv-k3u1fbpfcp-watermark.image?)]
詳細說明可以查看官方文檔:environment 和 recentSubscriptionStartDate,這里不在復述。
App Store Server Notifications V2
同理 App Store Server Notifications 也有新增相應的 environment 和 recentSubscriptionStartDate 字段。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wPaxtAUv-1657516283951)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/31fb8b2740cd4c60be8c0cf9262121f5~tplv-k3u1fbpfcp-watermark.image?)]
從這個圖片可以看出,App Store Server API 是 App Store 服務器和開發者服務器之前,相互可以響應的流程。而 App Store Server Notifications V1 和 V2 通知,是 App Store 服務器主動通知開發者服務器,開發者服務器不能主動請求,所以導致了一些場景的缺陷。
App Store 服務器通知宕機
服務器宕機是很常見的問題,但是宕機后,開發者就無法接收 App Store 服務器的通知。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zmXcnk0B-1657516283951)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/82a7cfe8cb75441da5ca048334185523~tplv-k3u1fbpfcp-watermark.image?)]
所以,App Store Server Notifications V2 通知在首次嘗試通知后沒有收到來自開發者服務器的響應時會進行重試:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-AUmY6cWu-1657516283952)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/47afd20f61af4e8c99332ed59f2e8ff9~tplv-k3u1fbpfcp-watermark.image?)]
- App Store Server Notifications V1:重試三次;在上次嘗試后 6、24 和 48 小時。
- App Store Server Notifications V2:重試五次;在上次嘗試后 1、12、24、48 和 72 小時。
重試成功后,開發者服務器接收到的通知,可以并不再是順序顯示:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wNcSuOXs-1657516283952)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0634316419d64fa4b797fb29c6a89295~tplv-k3u1fbpfcp-watermark.image?)]
所以,開發者需要通過 signedDate 字段,確保通知的順序邏輯正確,也就是說通知的結果狀態以最新的 signedDate 時間來準,來更新用戶能享受的服務。而重試的通知可能會出現重復的通知響應,所以開發者可以通過 notificationUUID 字段去重通知。
留住訂閱者
用戶需要不斷從訂閱中獲得價值,才會持續地訂閱您的 App。定期更新您的 App,提供新內容和增強功能,以鼓勵訂閱者繼續訂閱。
App Store Server Notifications V2 提供了更多的通知類型,達到 28 個,未來還會增加更多。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QVSEKJAu-1657516283952)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/303688c732e04b0a9d79e0e4a2919860~tplv-k3u1fbpfcp-watermark.image?)]
這里一個用戶訂閱過程的可能會發生的通知:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5mtIE2IO-1657516283952)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c022d743394d4587ab4e8d1c19588e08~tplv-k3u1fbpfcp-watermark.image?)]
從這個圖中,開發者可以思考到什么?
Subscription loyalty(訂閱忠誠度)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cxzHusis-1657516283952)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/610aae2cd90d44ec9eb70d9174a7239b~tplv-k3u1fbpfcp-watermark.image?)]
從蘋果的 自動續期訂閱 文檔可以獲取這樣的思考:
通過使用 獲取所有訂閱狀態 接口和 獲取交易歷史記錄 接口,可確定用戶的訂閱狀態并查看交易歷史記錄,幫助您識別并執行以下操作:
- 自愿流失。使用 獲取所有訂閱狀態 接口確定訂閱者是不是已關閉特定訂閱的自動續訂。您還可以使用 App Store 服務器通知來獲取有關用戶狀態變化的實時更新以及與其 App 內購買項目相關的關鍵事件,例如退款通知。使用這一信息來采取相應的行動,例如,您可以提供促銷優惠以鼓勵他們繼續訂閱,建議更符合他們需求的備用等級,或者在訂閱到期后鎖定相關訂閱內容的訪問權限。請務必向用戶告知您所做的任何更改,以及他們是否需要完成任何操作,還有重新訂閱的方式。
- 非自愿流失。當訂閱者遇到賬單問題 (如信用卡過期問題) 時,就會發生非自愿流失。選擇接收服務器通知以了解何時由于賬單問題而導致訂閱續訂失敗,或使用 獲取所有訂閱狀態 接口確定訂閱是不是由于賬單問題而處于計費重試狀態。根據上述信息采取相應措施,例如,您可以在 App 中顯示信息或發送電子郵件,提醒訂閱者更新他們之前登記的付款方式,并提供其 App Store 帳戶中“付款信息”區域的鏈接。一旦問題得到解決,您就可以恢復服務。Apple 將在 60 天內嘗試收取付款。如果訂閱在 60 天內續訂,則付費服務的天數從續訂日期開始繼續累積。
為避免由于賬單問題而導致服務中斷,請在 App Store Connect 中啟用賬單寬限期。Apple 將嘗試解決賬單問題,并在訂閱者保留訂閱訪問權限的同時恢復訂閱。如果訂閱在這個期限內恢復,則付費服務天數的計數和您的收入都不會中斷。如果用戶在 60 天后重新訂閱,則付費服務的天數將重置,您將收到一年的標準訂閱費用,直到付費服務滿一年為止。
- 價格上調同意狀態。當您提高訂閱價格時,Apple 會詢問受影響的訂閱者是否同意這個新價格,您可以在價格變動生效之前跟蹤用戶的同意狀態。在向受影響的用戶顯示價格上調單之前,您可以顯示一條 App 內信息,說明訂閱的好處和價值,以及價格上調將如何改善服務。如果用戶沒有對上調做出反應,他們的訂閱將在當前結算周期結束時到期。
簡單來說,通過訂閱通知,分析用戶的忠誠度,根據用戶不同的行為習慣和選擇決定(通知),然后分析用戶行為的背后原因,從而優化開發者的服務,從而提升訂閱的忠誠度!
App Store Connect
App Store 相關的調整不多,都是細節優化。
Sandbox & Test
開發人員將能夠更輕松地創建沙盒用戶,并測試沙盒購買。相比以前少了 安全提示問題、安全提示問題答案、出生日期 三個選項。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-M76o2fa3-1657516283953)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0aac2b9d12b14e7fa38ae7c80a01ae78~tplv-k3u1fbpfcp-watermark.image?)]
增加了 Allow Purchase & Renewals 開關,用于測試訂閱到期自動扣費和失敗重試。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-7mV7I54B-1657516283953)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/164eef01660c40bca30ba25f58285629~tplv-k3u1fbpfcp-watermark.image?)]
Xcode StoreKit 測試中添加了更多測試用例,例如退款請求、優惠代碼兌換、訂閱漲價、賬單扣款重試等。這是一個不錯的改進,但目前測試內購功能的開發者還不多,詳細參考 What’s new in StoreKit testing - WWDC22。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4VpuviWK-1657516283953)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e64af411d1904595a7d6eb71c9e43455~tplv-k3u1fbpfcp-watermark.image?)]
App Store Connect API
App Store Connect API 增加了查詢沙盒賬號、清除沙盒內購歷史記錄、設置中斷內購狀態等,也增加內購、用戶商店評論內容和回復、App 掛起診斷數據等接口。
最重要是,增加了內購項目的創建!
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-pSLb8Xk4-1657516283953)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/242edb260b7d4ea6b1968bb49bc10b11~tplv-k3u1fbpfcp-watermark.image?)]
內購品項和訂閱品項的相關 API:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TTfMTi6D-1657516283954)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ed13327496fa48359cbbe7aa94990342~tplv-k3u1fbpfcp-watermark.image?)]
- 新建訂閱品項
- 創建、編輯和刪除品項
- 管理定價
- 提交審核
- 創建優惠和促銷代碼
目前截止本文發表,蘋果 App Store Connect API 文檔,依然還沒有看到這些接口的描述!
最后,是蘋果棄用 XML 流文檔的形式與 App Store Connect 的交互,未來開發者,都需要遷移到 App Store Connect API!
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-8XfvdJg9-1657516283954)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/476fd46d3cfa499d9ec8e58159481bff~tplv-k3u1fbpfcp-watermark.image?)]
這個怎么理解?參考我們之前開源的一款蘋果 macOS 工具:《AppleParty(蘋果派)》,它使用到了蘋果 Transporter 命令工具,批量上傳內購商品列表和上傳 IAP 包文件等。預測 Reporter 和 altool 等命令也會被棄用。
蘋果表示,今年秋天開始停用 XML 提交,強制推薦使用 App Store Connect API 接口。但目前還沒有看到官網相關的說明文檔!
App Store
今年 App Store 相關更新,可能最引人關注的功能,就是這個 Benchmarks in App Analytics(App 分析中的基準)功能,,基準通過將與獲客率、使用和盈利情況相關的績效指標置于具體情境中,在整個客戶旅程期間提供有價值的見解,這樣您就可以很容易地看到您與同行相比的表現,并做出相應決策以實現業務目標。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EeSXRDXg-1657516283954)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c991c6e05a1c4cdd950b2eabc91333fb~tplv-k3u1fbpfcp-watermark.image?)]
查看自己 app 與同行相比的表現,并做出實現業務目標的決策。使用差異隱私技術,以確保機密信息的安全和私密性。蘋果表示這個功能明年 2023 年初才上線,目前官方文檔也沒有找到詳細的介紹。差異隱私技術介紹可以參考我們之前的文章《WWDC22 - Apple 隱私技術探索》。
關于 app 數據,Xcode 提供了功率、性能指標和診斷等新接口。
- 分析和解決 App 掛起(hangs:延時、慢、卡頓)
- 查看診斷簽名
- 下載詳細日志
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-nX5vxN6o-1657516283954)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7c7de43718b24d3d9cf38d20f1b09878~tplv-k3u1fbpfcp-watermark.image?)]
詳細功能可以參考:Identify trends with the Power and Performance API - WWDC20 和 Track down hangs with Xcode and on-device detection - WWDC22。
在 App Store Connect app 中可以送審內購、新版本、In-App Event、產品面優化、自定義產品而等。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sIzc4ciU-1657516283955)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/014eb8dc3421407cbdb3f7ec3986d091~tplv-k3u1fbpfcp-watermark.image?)]
目前蘋果支持送審的內容:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FMgofoxv-1657516283955)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bf7b60cd61b64e9497f9029810887b74~tplv-k3u1fbpfcp-watermark.image?)]
可以看到 iOS 除了新版本 app 送審,現在支持 In-App Event、自定義產品、產品面優化測試等。而 tvOS 和 macOS 目前還沒有,可能明年 WWDC23 應該就支持一波了吧!
另外,需要提示一下,送審新版本 app 、In-App Event、自定義產品、產品面優化測試等,蘋果是建議開發者可以合并提交一起送審,因為這樣蘋果會以當前送審的內容一起審核,提高蘋果的審核效率?總之,提審這些項目后,如果有項目審核不通過,可以單獨發布審核通過的內容。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rg5DTete-1657516283955)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fe74f79f62ac4a98b5f0e3a7c44c7036~tplv-k3u1fbpfcp-watermark.image?)]
關于 App Store 的優化,2022 年 1 月 20 日 推出適用于訂閱的自定優惠代碼,開發者可以自定義,如 VIP888 的優惠代碼,用于推廣活動,自定代碼可通過直接 URL 或在您的 app 中兌換。2022 年 4 月 29 日 闡明 App Store 改善流程的標準和新的限期延長,蘋果明確了 App 長期不更新被下架的細則,當一款 App 在過去三年內從未更新且未達到最低下載量 (即該 App 在連續 12 個月內完全沒有或只有極低的下載量) 時,其開發者將會收到電子郵件,告知該 App 已被識別并可能從 App Store 中被移除,開發者收到通知起,有 90 天的時間來更新他們的 App。
總結
關于 In App Purchase 和 App Store,隨著這幾年蘋果的開放,已經很大程度上解決了開發者大多數的問題,從退款查詢到所有訂單查詢,從被動通知到主動獲取通知,從內購稅率降低到提高 App 曝光量,蘋果已經提供了非常多的接口、案例展示和建議。比如,自動續期訂閱類型,目前已經復雜到不能再復雜,訂閱群組、免費試用期限、推介促銷優惠、促銷優惠、優惠代碼、計費重試、重新激活、續期等。
最后,大家覺得 In App Purchase 和 App Store 還有什么疑惑或痛點嗎?
歡迎大家評論區一起討論交流~
歡迎關注我們,了解更多 iOS 和 Apple 的動態~
參考引用
- 蘋果iOS內購三步曲:App內退款、歷史訂單查詢、綁定用戶防掉單!— WWDC21 - 掘金
- App?Store Small Business Program 公布 - Apple Developer
- 注冊新的 App?Store Small Business Program - Apple Developer
- 全新的 App Store 小型企業計劃讓開發者看到無盡可能 - Apple (中國大陸)
- App Store Small Business Program - Apple Developer
- 要求在線團體活動需使用 App 內購買方式的截止日期已延長 - Apple Developer
- 針對在線團體活動服務的 app?內購買項目規定更新 - Apple Developer
- 針對在線多人活動的 app 內購買項目規定提醒 - Apple Developer
- App Store 審核指南 - Apple Developer
- Apple 與美國開發者就 App Store 更新達成一致 - Apple (中國大陸)
- 小型業務開發者協助申請提交將于 5 月 20 日截止 - Apple Developer
- Cameron et al. v. Apple Inc.
- 日本公平貿易委員會結束對 App Store 的調查 - Apple (中國大陸)
- “閱讀器”app 分發的更新 - Apple Developer
- Update on dating apps distributed on the App Store in the Netherlands - Apple Developer
- Distributing dating apps in the Netherlands - Apple Developer
- Additional details available for dating apps in the Netherlands - Apple Developer
- Update on StoreKit External Entitlement for dating apps - Apple Developer
- Further updates on StoreKit External Entitlement for dating apps in the Netherlands storefront - Latest News - Apple Developer
- 訂閱通知更新 - 最新動態 - Apple Developer
- 管理自動續期訂閱的定價 - App Store Connect 幫助
- 針對在韓國分發 App 的更新 - Apple Developer
- Distributing apps using a third-party payment provider in South Korea - Apple Developer
- AppTransaction | Apple Developer Documentation
- Message | Apple Developer Documentation
- applicationUsername | Apple Developer Documentation
- appAccountToken | Apple Developer Documentation
- External Purchase | Apple Developer Documentation
- External Link Account | Apple Developer Documentation
- App Store Server API | Apple Developer Documentation
- App Store Server Notifications | Apple Developer Documentation
- App Store Connect API | Apple Developer Documentation
- WWDC21 - App Store Server API 實踐總結 - 掘金
- 開源一款蘋果 macOS 工具 - AppleParty(蘋果派) - 掘金
- WWDC22 - Apple 隱私技術探索 - 掘金
- Transporter 用戶指南
- altool 指南
- Reporter 用戶指南
- 充分利用 App Store - Apple Developer
- 自動續期訂閱 - App Store - Apple Developer
- 闡明 App Store 改善流程的標準和新的限期延長 - Apple Developer
- 現已推出適用于訂閱的自定優惠代碼 - Apple Developer
總結
以上是生活随笔為你收集整理的WWDC22 - In App Purchase 更新总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用boston房价数据进行线性回归分析
- 下一篇: 别瞎找了,你要的C语言经典示例都在这~