1
This commit is contained in:
parent
2095581969
commit
9dd9e9ebde
@ -13,6 +13,7 @@ class APUploadIAPListVC: NSViewController {
|
||||
@IBOutlet weak var enterBtn: NSButton!
|
||||
@IBOutlet weak var preserveCurrentPriceBtn: NSButton!
|
||||
@IBOutlet weak var showApiRateLimitLogsBtn: NSButton!
|
||||
@IBOutlet weak var submitSubscriptionReviewBtn: NSButton!
|
||||
|
||||
public var currentApp: App? {
|
||||
didSet {
|
||||
@ -151,11 +152,17 @@ extension APUploadIAPListVC {
|
||||
// 3、获取所有的内购商品,如果存在的商品就直接修改,如果不存在就创建
|
||||
let oldIAPs = await ascAPI.fetchInAppPurchasesList(appId: appId)
|
||||
|
||||
let submitSubscriptionReview = self.submitSubscriptionReviewBtn.state == .on
|
||||
|
||||
// 4、遍历所有要上传的商品
|
||||
for product in iaps {
|
||||
// 订阅类型与非订单类型不一样的处理逻辑
|
||||
if product.inAppPurchaseType == .AUTO_RENEWABLE {
|
||||
await createRenewSubscription(appId: appId, product: product, ascAPI: ascAPI)
|
||||
await createRenewSubscription(
|
||||
appId: appId,
|
||||
product: product,
|
||||
ascAPI: ascAPI,
|
||||
submitForReview: submitSubscriptionReview)
|
||||
} else {
|
||||
await createInAppPurchase(
|
||||
appId: appId, product: product, oldIAPs: oldIAPs, ascAPI: ascAPI)
|
||||
@ -480,7 +487,12 @@ extension APUploadIAPListVC {
|
||||
// MARK: - 上传订阅商品
|
||||
|
||||
/// 订阅商品创建或更新
|
||||
func createRenewSubscription(appId: String, product: IAPProduct, ascAPI: APASCAPI) async {
|
||||
func createRenewSubscription(
|
||||
appId: String,
|
||||
product: IAPProduct,
|
||||
ascAPI: APASCAPI,
|
||||
submitForReview: Bool
|
||||
) async {
|
||||
let groupName = product.groupName
|
||||
var currentSubGroup: ASCSubscriptionGroup?
|
||||
// 1、是否有订阅组,没有时要先创建
|
||||
@ -580,6 +592,10 @@ extension APUploadIAPListVC {
|
||||
// Apple 后台偶发会在创建/更新后错误显示“元数据缺失”,补一次等价 PATCH 来触发状态刷新。
|
||||
await refreshSubscriptionMetadata(iapId: iap.id, product: product, ascAPI: ascAPI)
|
||||
|
||||
if submitForReview {
|
||||
await submitSubscriptionForReview(iapId: iap.id, product: product, ascAPI: ascAPI)
|
||||
}
|
||||
|
||||
} else {
|
||||
// 1. 创建新的商品
|
||||
guard let iapGroupId = currentSubGroup?.id,
|
||||
@ -611,11 +627,57 @@ extension APUploadIAPListVC {
|
||||
|
||||
// Apple 后台偶发会在创建/更新后错误显示“元数据缺失”,补一次等价 PATCH 来触发状态刷新。
|
||||
await refreshSubscriptionMetadata(iapId: iap.id, product: product, ascAPI: ascAPI)
|
||||
|
||||
if submitForReview {
|
||||
await submitSubscriptionForReview(iapId: iap.id, product: product, ascAPI: ascAPI)
|
||||
}
|
||||
}
|
||||
|
||||
ascAPI.addMessage("订阅商品:\(product.productId),\(product.name) ,上传完成!\n")
|
||||
}
|
||||
|
||||
/// 提交订阅商品至审核
|
||||
func submitSubscriptionForReview(iapId: String, product: IAPProduct, ascAPI: APASCAPI) async {
|
||||
ascAPI.addMessage("开始提交订阅商品审核:\(product.productId)")
|
||||
|
||||
let maxRetryCount = 12
|
||||
for retryIndex in 0..<maxRetryCount {
|
||||
if let subscription = await ascAPI.fetchSubscription(iapId: iapId),
|
||||
let state = subscription.attributes?.state {
|
||||
ascAPI.addMessage("订阅商品:\(product.productId) 当前状态:\(state.rawValue)")
|
||||
|
||||
if state == .waitingForReview || state == .inReview {
|
||||
ascAPI.addMessage("订阅商品:\(product.productId) 已处于审核流程,无需重复提交。✅ ")
|
||||
return
|
||||
}
|
||||
|
||||
if state == .readyToSubmit {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
ascAPI.addMessage("订阅商品:\(product.productId) 当前状态获取失败,继续尝试提交审核")
|
||||
break
|
||||
}
|
||||
|
||||
let waitSeconds: UInt64 = 10
|
||||
let remainingCount = maxRetryCount - retryIndex - 1
|
||||
if remainingCount > 0 {
|
||||
ascAPI.addMessage("订阅商品:\(product.productId) 尚未进入准备提交状态,\(waitSeconds) 秒后重试,剩余 \(remainingCount) 次")
|
||||
try? await Task.sleep(nanoseconds: waitSeconds * 1_000_000_000)
|
||||
}
|
||||
}
|
||||
|
||||
if let submission = await ascAPI.submitSubscriptionForReview(iapId: iapId) {
|
||||
ascAPI.addMessage("订阅商品:\(product.productId) ,提交审核成功!提交ID:\(submission.id) ✅ ")
|
||||
if let subscription = await ascAPI.fetchSubscription(iapId: iapId),
|
||||
let state = subscription.attributes?.state {
|
||||
ascAPI.addMessage("订阅商品:\(product.productId) 提交后状态:\(state.rawValue)")
|
||||
}
|
||||
} else {
|
||||
ascAPI.addMessage("订阅商品:\(product.productId) ,提交审核失败!请检查商品是否为准备提交状态,或是否需要随 App 版本提交。❌ ")
|
||||
}
|
||||
}
|
||||
|
||||
/// 更新订阅商品的价格档位
|
||||
func updateSubscriptionPricePoint(iapId: String, product: IAPProduct, ascAPI: APASCAPI) async {
|
||||
guard let schedule = product.priceSchedules else {
|
||||
|
||||
@ -454,11 +454,22 @@ DQ
|
||||
<constraint firstAttribute="height" constant="16" id="UTk-E1-F8x"/>
|
||||
</constraints>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SMg-H8-CbS">
|
||||
<rect key="frame" x="18" y="7" width="154" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="上传后提交订阅审核" bezelStyle="regularSquare" imagePosition="left" inset="2" id="G3M-3N-oSq">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="16" id="rUz-sG-vbg"/>
|
||||
</constraints>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="gwi-GP-uQf" secondAttribute="bottom" constant="8" id="446-fY-M9B"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Wiy-jc-2Pw" secondAttribute="bottom" constant="20" symbolic="YES" id="7js-1K-u7U"/>
|
||||
<constraint firstItem="O5k-L7-xuw" firstAttribute="top" secondItem="mWR-IS-Cxn" secondAttribute="bottom" constant="10" id="8dK-sn-ZXM"/>
|
||||
<constraint firstItem="SMg-H8-CbS" firstAttribute="top" secondItem="O5k-L7-xuw" secondAttribute="bottom" constant="7" id="7vd-Dp-m2h"/>
|
||||
<constraint firstItem="yl7-CE-urn" firstAttribute="centerY" secondItem="6rW-KE-ixB" secondAttribute="centerY" id="ITd-YX-Trm"/>
|
||||
<constraint firstAttribute="trailing" secondItem="sv7-52-2Cw" secondAttribute="trailing" constant="15" id="QUP-CD-c2a"/>
|
||||
<constraint firstItem="Wiy-jc-2Pw" firstAttribute="top" secondItem="sv7-52-2Cw" secondAttribute="bottom" constant="12" id="Rp0-lh-D4G"/>
|
||||
@ -466,6 +477,7 @@ DQ
|
||||
<constraint firstItem="yl7-CE-urn" firstAttribute="centerX" secondItem="6rW-KE-ixB" secondAttribute="centerX" id="efU-0I-QhV"/>
|
||||
<constraint firstItem="mWR-IS-Cxn" firstAttribute="leading" secondItem="6rW-KE-ixB" secondAttribute="leading" constant="20" symbolic="YES" id="hjT-ey-2ZV"/>
|
||||
<constraint firstItem="O5k-L7-xuw" firstAttribute="leading" secondItem="6rW-KE-ixB" secondAttribute="leading" constant="20" symbolic="YES" id="htV-cS-Gxk"/>
|
||||
<constraint firstItem="SMg-H8-CbS" firstAttribute="leading" secondItem="6rW-KE-ixB" secondAttribute="leading" constant="20" symbolic="YES" id="W7O-7K-uBI"/>
|
||||
<constraint firstItem="gwi-GP-uQf" firstAttribute="centerX" secondItem="6rW-KE-ixB" secondAttribute="centerX" id="o1O-9Y-VOc"/>
|
||||
<constraint firstItem="mWR-IS-Cxn" firstAttribute="top" secondItem="6rW-KE-ixB" secondAttribute="top" constant="25" id="yx3-wU-dQT"/>
|
||||
</constraints>
|
||||
@ -490,6 +502,7 @@ DQ
|
||||
<outlet property="enterBtn" destination="yl7-CE-urn" id="fxo-dC-Eo4"/>
|
||||
<outlet property="preserveCurrentPriceBtn" destination="mWR-IS-Cxn" id="kC5-n4-ddM"/>
|
||||
<outlet property="showApiRateLimitLogsBtn" destination="O5k-L7-xuw" id="NkA-Kq-jRr"/>
|
||||
<outlet property="submitSubscriptionReviewBtn" destination="SMg-H8-CbS" id="IUP-9g-WUu"/>
|
||||
<outlet property="tableView" destination="FfT-VW-kGY" id="eo0-Hf-anq"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
|
||||
@ -31,6 +31,7 @@ typealias ASCSubscriptionScreenshot = AppStoreConnect_Swift_SDK.SubscriptionAppS
|
||||
typealias ASCSubscriptionGroup = AppStoreConnect_Swift_SDK.SubscriptionGroup
|
||||
typealias ASCSubscriptionGroupLocale = AppStoreConnect_Swift_SDK.SubscriptionGroupLocalization
|
||||
typealias ASCSubscriptionAvailability = AppStoreConnect_Swift_SDK.SubscriptionAvailability
|
||||
typealias ASCSubscriptionSubmission = AppStoreConnect_Swift_SDK.SubscriptionSubmission
|
||||
|
||||
|
||||
class APASCAPI {
|
||||
@ -844,6 +845,27 @@ class APASCAPI {
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取订阅商品详情
|
||||
/// - Parameter iapId: 订阅商品 id
|
||||
/// - Returns: 订阅商品详情
|
||||
func fetchSubscription(iapId: String) async -> ASCSubscription? {
|
||||
let request = APIEndpoint.v1.subscriptions.id(iapId).get(parameters: .init(
|
||||
fieldsSubscriptions: [.name, .productID, .state]
|
||||
))
|
||||
|
||||
do {
|
||||
guard let provider = provider else {
|
||||
return nil
|
||||
}
|
||||
return try await provider.request(request).data
|
||||
} catch APIProvider.Error.requestFailure(let statusCode, let errorResponse, _) {
|
||||
handleRequestFailure(statusCode, errorResponse)
|
||||
} catch {
|
||||
handleError("获取订阅商品详情失败: \(error.localizedDescription)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
/// 创建订阅商品
|
||||
/// - Parameters:
|
||||
@ -1303,6 +1325,41 @@ class APASCAPI {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// 提交订阅商品至 App Review
|
||||
/// - Parameter iapId: 订阅商品 id
|
||||
/// - Returns: 成功时返回对应的提交信息
|
||||
func submitSubscriptionForReview(iapId: String) async -> ASCSubscriptionSubmission? {
|
||||
let body = [
|
||||
"data": [
|
||||
"type": "subscriptionSubmissions",
|
||||
"relationships": [
|
||||
"subscription": [
|
||||
"data": [
|
||||
"id": iapId,
|
||||
"type": "subscriptions"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
do {
|
||||
guard let provider = provider else {
|
||||
return nil
|
||||
}
|
||||
let json = try JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
|
||||
let model = try JSONDecoder().decode(SubscriptionSubmissionCreateRequest.self, from: json)
|
||||
let request = APIEndpoint.v1.subscriptionSubmissions.post(model)
|
||||
let data = try await provider.request(request).data
|
||||
return data
|
||||
} catch APIProvider.Error.requestFailure(let statusCode, let errorResponse, _) {
|
||||
handleRequestFailure(statusCode, errorResponse)
|
||||
} catch {
|
||||
handleError("提交订阅商品审核失败: \(error.localizedDescription)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user