解决元数据丢失问题

This commit is contained in:
zeng 2026-04-01 11:38:50 +08:00
parent 1c33b5b991
commit 809679751b

View File

@ -43,9 +43,14 @@ class APUploadIAPListVC: NSViewController {
func showUploadView() {
// present
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
let mainStoryboard = NSStoryboard(name: "InAppPurchseView", bundle: Bundle(for: self.classForCoder))
let upVC = mainStoryboard.instantiateController(withIdentifier: "IAPUploadVCID") as? IAPUploadImageVC
let screenshot = self.iaps.filter({ $0.reviewScreenshot.count > 0 }).map({ $0.reviewScreenshot })
let mainStoryboard = NSStoryboard(
name: "InAppPurchseView", bundle: Bundle(for: self.classForCoder))
let upVC =
mainStoryboard.instantiateController(withIdentifier: "IAPUploadVCID")
as? IAPUploadImageVC
let screenshot = self.iaps.filter({ $0.reviewScreenshot.count > 0 }).map({
$0.reviewScreenshot
})
//
let uniquedshot = screenshot.enumerated().filter { (index, value) -> Bool in
return screenshot.firstIndex(of: value) == index
@ -75,7 +80,6 @@ class APUploadIAPListVC: NSViewController {
return
}
guard let appid = currentApp?.appId else {
APHUD.hide(message: "当前 App 的 appleid 为空!", delayTime: 1)
return
@ -109,7 +113,8 @@ extension APUploadIAPListVC {
func updateInAppPurchse(iaps: [IAPProduct], appId: String, ascKey: AppStoreConnectKey) {
let showApiRateLimit = showApiRateLimitLogsBtn.state.rawValue == 1
let ascAPI = APASCAPI.init(issuerID: ascKey.issuerID,
let ascAPI = APASCAPI.init(
issuerID: ascKey.issuerID,
privateKeyID: ascKey.privateKeyID,
privateKey: ascKey.privateKey,
showApiRateLimit: showApiRateLimit)
@ -152,7 +157,8 @@ extension APUploadIAPListVC {
if product.inAppPurchaseType == .AUTO_RENEWABLE {
await createRenewSubscription(appId: appId, product: product, ascAPI: ascAPI)
} else {
await createInAppPurchase(appId: appId, product: product, oldIAPs: oldIAPs, ascAPI: ascAPI)
await createInAppPurchase(
appId: appId, product: product, oldIAPs: oldIAPs, ascAPI: ascAPI)
}
}
@ -165,13 +171,15 @@ extension APUploadIAPListVC {
// MARK: -
///
func createInAppPurchase(appId: String, product: IAPProduct, oldIAPs: [ASCInAppPurchaseV2], ascAPI: APASCAPI) async {
func createInAppPurchase(
appId: String, product: IAPProduct, oldIAPs: [ASCInAppPurchaseV2], ascAPI: APASCAPI
) async {
ascAPI.addMessage("开始上传内购商品:\(product.productId)\(product.name) ")
//
let iaps = oldIAPs.filter({ $0.attributes?.productID == product.productId })
if let iap = iaps.first {
ascAPI.addMessage("订阅商品已经存在:\(product.productId) ,跳过更新信息...")
return;
return
ascAPI.addMessage("内购已经存在:\(product.productId) ,开始更新信息中...")
// 0. 使
@ -180,23 +188,27 @@ extension APUploadIAPListVC {
product.reviewNote = note
}
// 1.
guard let iap = await ascAPI.updateInAppPurchases(iapId: iap.id, product: product) else {
guard let iap = await ascAPI.updateInAppPurchases(iapId: iap.id, product: product)
else {
//
ascAPI.addMessage("内购已经存在:\(product.productId) ,更新信息失败!❌ ")
return
}
// 3.
ascAPI.addMessage("开始更新内购本地化版本:\(product.productId)")
let localizations = await ascAPI.fetchInAppPurchasesLocalizations(iapId: iap.id)
for localization in product.localizations {
//
if let locale = localizations.filter({ $0.attributes?.locale == localization.locale }).first {
if let locale = localizations.filter({
$0.attributes?.locale == localization.locale
}).first {
//
ascAPI.addMessage("内购已存在本地化版本:\(localization.locale),开始更新信息中...")
if (await ascAPI.updateInAppPurchasesLocalization(iapLocaleId: locale.id, localization: localization)) != nil {
if (await ascAPI.updateInAppPurchasesLocalization(
iapLocaleId: locale.id, localization: localization)) != nil
{
//
ascAPI.addMessage("内购本地化版本:\(localization.locale) ,更新语言成功!✅ ")
} else {
@ -205,7 +217,8 @@ extension APUploadIAPListVC {
}
} else {
//
await createIAPLocalization(iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
await createIAPLocalization(
iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
}
}
@ -226,10 +239,10 @@ extension APUploadIAPListVC {
return
}
// 3.
for localization in product.localizations {
await createIAPLocalization(iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
await createIAPLocalization(
iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
}
// 4.
@ -258,23 +271,37 @@ extension APUploadIAPListVC {
ascAPI.addMessage("开始更新价格计划表:\(product.productId)\(baseTerritory)\(baseCustomerPrice) \n")
let points = await ascAPI.fetchPricePoints(iapId: iapId, territory: [baseTerritory])
if let point = points.filter({ $0.attributes?.customerPrice!.normalizePrice() == baseCustomerPrice }).first {
if let point = points.filter({
$0.attributes?.customerPrice!.normalizePrice() == baseCustomerPrice
}).first {
var manualPrices: [Any] = []
var included: [Any] = []
ascAPI.addMessage("开始构建基准国家和自定价格:")
// base Territory
manualPrices.append(["id": "${\(baseTerritory)-\(included.count)}", "type": "inAppPurchasePrices"])
included.append(ascAPI.fetchInAppPurchasePriceSchedule(scheduleId: baseTerritory, pricePointId: point.id, iapId: iapId, index: included.count))
manualPrices.append([
"id": "${\(baseTerritory)-\(included.count)}", "type": "inAppPurchasePrices",
])
included.append(
ascAPI.fetchInAppPurchasePriceSchedule(
scheduleId: baseTerritory, pricePointId: point.id, iapId: iapId,
index: included.count))
// customerPrice
for pricePoint in schedule.manualPrices {
let territory = pricePoint.territory
let customerPrice = pricePoint.customerPrice.normalizePrice()
let points = await ascAPI.fetchPricePoints(iapId: iapId, territory: [territory])
if let point = points.filter({ $0.attributes?.customerPrice!.normalizePrice() == customerPrice }).first {
manualPrices.append(["id": "${\(territory)-\(included.count)}", "type": "inAppPurchasePrices"])
included.append(ascAPI.fetchInAppPurchasePriceSchedule(scheduleId: territory, pricePointId: point.id, iapId: iapId, index: included.count))
if let point = points.filter({
$0.attributes?.customerPrice!.normalizePrice() == customerPrice
}).first {
manualPrices.append([
"id": "${\(territory)-\(included.count)}", "type": "inAppPurchasePrices",
])
included.append(
ascAPI.fetchInAppPurchasePriceSchedule(
scheduleId: territory, pricePointId: point.id, iapId: iapId,
index: included.count))
} else {
ascAPI.addMessage("自定价格的内购价格点:\(territory)\(customerPrice) ,未找到此档位!❌ ")
}
@ -282,7 +309,10 @@ extension APUploadIAPListVC {
ascAPI.saveLogs(log: "内购的基准国家和自定价格:\(manualPrices)\(included)")
if (await ascAPI.updateInAppPurchasePricePoint(iapId: iapId, baseTerritoryId: baseTerritory, manualPrices: manualPrices, included: included)) != nil {
if (await ascAPI.updateInAppPurchasePricePoint(
iapId: iapId, baseTerritoryId: baseTerritory, manualPrices: manualPrices,
included: included)) != nil
{
//
ascAPI.addMessage("内购价格点:\(baseTerritory)\(baseCustomerPrice) ,更新价格成功!✅ ")
} else {
@ -295,11 +325,14 @@ extension APUploadIAPListVC {
}
}
///
func createIAPLocalization(iapId: String, localization: IAPLocalization, product: IAPProduct, ascAPI: APASCAPI) async {
func createIAPLocalization(
iapId: String, localization: IAPLocalization, product: IAPProduct, ascAPI: APASCAPI
) async {
ascAPI.addMessage("开始更新本地化版本:\(product.productId)\(localization.locale)")
if (await ascAPI.createInAppPurchasesLocalization(iapId: iapId, localization: localization)) != nil {
if (await ascAPI.createInAppPurchasesLocalization(iapId: iapId, localization: localization))
!= nil
{
//
ascAPI.addMessage("内购本地化版本:\(localization.locale) ,更新语言成功!✅ ")
} else {
@ -341,7 +374,10 @@ extension APUploadIAPListVC {
ascAPI.addMessage("内购商品截图文件错误:\(imgPath) ,文件大小为 0~")
return
}
guard let shot = await ascAPI.createInAppPurchasesScreenshot(iapId: iapId, fileName: uploadFileName, fileSize: imaSize) else {
guard
let shot = await ascAPI.createInAppPurchasesScreenshot(
iapId: iapId, fileName: uploadFileName, fileSize: imaSize)
else {
//
ascAPI.addMessage("内购商品:\(product.productId) ,创建送审截图失败!❌ ")
return
@ -351,7 +387,8 @@ extension APUploadIAPListVC {
guard let method = shot.attributes?.uploadOperations?.first?.method,
let url = shot.attributes?.uploadOperations?.first?.url,
let requestHeaders = shot.attributes?.uploadOperations?.first?.requestHeaders,
let baseURL = URL(string: url) else {
let baseURL = URL(string: url)
else {
ascAPI.addMessage("内购商品:\(product.productId) ,创建送审截图失败!苹果参数异常~ ❌ ")
return
}
@ -364,18 +401,23 @@ extension APUploadIAPListVC {
ascAPI.addMessage("上传新的送审截图:\(uploadFileName)")
//
guard let response = try? await URLSession.shared.upload(for: request, fromFile: imaUrl) else {
guard let response = try? await URLSession.shared.upload(for: request, fromFile: imaUrl)
else {
ascAPI.addMessage("内购商品:\(product.productId) ,创建送审截图失败!上传图片异常~ ❌ ")
return
}
guard let responseCode = (response.1 as? HTTPURLResponse)?.statusCode, responseCode == 200 else {
ascAPI.addMessage("内购商品:\(product.productId) ,创建送审截图失败!上传图片异常 \(response.1.description)~ ❌ ")
guard let responseCode = (response.1 as? HTTPURLResponse)?.statusCode, responseCode == 200
else {
ascAPI.addMessage(
"内购商品:\(product.productId) ,创建送审截图失败!上传图片异常 \(response.1.description)~ ❌ ")
return
}
ascAPI.addMessage("提交新的送审截图:\(uploadFileName)")
//
if ((await ascAPI.updateInAppPurchasesScreenshot(iapShotId: shot.id, fileMD5: fileMD5)) != nil) {
if (await ascAPI.updateInAppPurchasesScreenshot(iapShotId: shot.id, fileMD5: fileMD5))
!= nil
{
ascAPI.addMessage("内购商品:\(product.productId) ,送审截图上传成功!✅ ")
} else {
ascAPI.addMessage("内购商品:\(product.productId) ,送审截图可能上传失败! ")
@ -396,11 +438,14 @@ extension APUploadIAPListVC {
territories.forEach { territory in
allTerritories.append([
"type": "territories",
"id": territory.id
"id": territory.id,
])
}
//
if (await ascAPI.updateInAppPurchasesAvailabilityTerritories(iapId: iapId, availableTerritories: allTerritories, availableInNewTerritories: inNew)) != nil {
if (await ascAPI.updateInAppPurchasesAvailabilityTerritories(
iapId: iapId, availableTerritories: allTerritories,
availableInNewTerritories: inNew)) != nil
{
ascAPI.addMessage("选择:所有国家(地区)销售,\(newTerritory),更新成功!✅ ")
} else {
ascAPI.addMessage("选择:所有国家(地区)销售,\(newTerritory),更新失败!❌ ")
@ -416,19 +461,22 @@ extension APUploadIAPListVC {
product.territories.territories?.forEach({ territory in
territories.append([
"type": "territories",
"id": territory.id
"id": territory.id,
])
})
let customerTerritory = product.territories.territories?.map({ $0.id }).joined(separator: ",") ?? ""
if (await ascAPI.updateInAppPurchasesAvailabilityTerritories(iapId: iapId, availableTerritories: territories, availableInNewTerritories: inNew)) != nil {
let customerTerritory =
product.territories.territories?.map({ $0.id }).joined(separator: ",") ?? ""
if (await ascAPI.updateInAppPurchasesAvailabilityTerritories(
iapId: iapId, availableTerritories: territories, availableInNewTerritories: inNew))
!= nil
{
ascAPI.addMessage("内购商品的销售国家/地区:\(customerTerritory) ,更新成功!✅ ")
} else {
ascAPI.addMessage("内购商品的销售国家/地区:\(customerTerritory) ,更新失败!❌ ")
}
}
// MARK: -
///
@ -437,8 +485,8 @@ extension APUploadIAPListVC {
var currentSubGroup: ASCSubscriptionGroup?
// 1
var subGroups = await ascAPI.fetchSubscriptionGroups(appId: appId)
// if subGroups.isEmpty {
// }
// if subGroups.isEmpty {
// }
for subGroup in subGroups {
if subGroup.attributes?.referenceName == groupName {
@ -447,19 +495,25 @@ extension APUploadIAPListVC {
}
//
if currentSubGroup == nil, let group = await ascAPI.createSubscriptionGroups(appId: appId, groupName: groupName) {
if currentSubGroup == nil,
let group = await ascAPI.createSubscriptionGroups(appId: appId, groupName: groupName)
{
currentSubGroup = group
subGroups.append(group)
for localization in product.localizations {
let _ = await ascAPI.createSubscriptionGroupLocalizations(iapGroupId: group.id, name: localization.name, locale: localization.locale, customAppName: nil)
let _ = await ascAPI.createSubscriptionGroupLocalizations(
iapGroupId: group.id, name: localization.name, locale: localization.locale,
customAppName: nil)
}
}
//
if let group = currentSubGroup {
if let localization = product.groupLocalization {
let _ = await ascAPI.createSubscriptionGroupLocalizations(iapGroupId: group.id, name: localization.name, locale: localization.locale, customAppName: nil)
let _ = await ascAPI.createSubscriptionGroupLocalizations(
iapGroupId: group.id, name: localization.name, locale: localization.locale,
customAppName: nil)
}
}
@ -470,15 +524,9 @@ extension APUploadIAPListVC {
subscriptions.append(contentsOf: subs)
}
// 3
let subs = subscriptions.filter({ $0.attributes?.productID == product.productId })
if let sub = subs.first {
///
ascAPI.addMessage("订阅商品已经存在:\(product.productId) ,跳过更新信息...")
return;
ascAPI.addMessage("订阅商品已经存在:\(product.productId) ,开始更新信息中...")
// 0. 使
var product = product
@ -495,13 +543,17 @@ extension APUploadIAPListVC {
// 2.
ascAPI.addMessage("开始更新订阅商品本地化版本:\(product.productId)")
let localizations = await ascAPI.fetchSubscriptionLocalizations(iapId: iap.id)
// for localization in product.localizations {
// for localization in product.localizations {
if let localization = product.subscriptionLocalization {
//
if let locale = localizations.filter({ $0.attributes?.locale == localization.locale }).first {
if let locale = localizations.filter({
$0.attributes?.locale == localization.locale
}).first {
//
ascAPI.addMessage("订阅商品已存在本地化版本:\(localization.locale),开始更新信息中...")
if (await ascAPI.updateSubscriptionLocalization(iapLocaleId: locale.id, localization: localization)) != nil {
if (await ascAPI.updateSubscriptionLocalization(
iapLocaleId: locale.id, localization: localization)) != nil
{
//
ascAPI.addMessage("订阅商品本地化版本:\(localization.locale) ,更新语言成功!✅ ")
} else {
@ -510,7 +562,8 @@ extension APUploadIAPListVC {
}
} else {
//
await createSubscriptionLocalization(iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
await createSubscriptionLocalization(
iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
}
}
@ -518,14 +571,20 @@ extension APUploadIAPListVC {
await createSubscriptionScreenshot(iapId: iap.id, product: product, ascAPI: ascAPI)
// 5.
await updateSubscriptionAvailableTerritories(iapId: iap.id, product: product, ascAPI: ascAPI)
await updateSubscriptionAvailableTerritories(
iapId: iap.id, product: product, ascAPI: ascAPI)
// 3.
await updateSubscriptionPricePoint(iapId: iap.id, product: product, ascAPI: ascAPI)
// Apple / PATCH
await refreshSubscriptionMetadata(iapId: iap.id, product: product, ascAPI: ascAPI)
} else {
// 1.
guard let iapGroupId = currentSubGroup?.id, let iap = await ascAPI.createSubscription(iapGroupId: iapGroupId, product: product) else {
guard let iapGroupId = currentSubGroup?.id,
let iap = await ascAPI.createSubscription(iapGroupId: iapGroupId, product: product)
else {
//
ascAPI.addMessage("订阅商品:\(product.productId) ,创建失败!❌ ")
return
@ -533,28 +592,30 @@ extension APUploadIAPListVC {
// 2.
if let localization = product.subscriptionLocalization {
await createSubscriptionLocalization(iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
await createSubscriptionLocalization(
iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
}
// for localization in product.localizations {
// await createSubscriptionLocalization(iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
// }
// for localization in product.localizations {
// await createSubscriptionLocalization(iapId: iap.id, localization: localization, product: product, ascAPI: ascAPI)
// }
// 4.
await createSubscriptionScreenshot(iapId: iap.id, product: product, ascAPI: ascAPI)
// 5.
await updateSubscriptionAvailableTerritories(iapId: iap.id, product: product, ascAPI: ascAPI)
await updateSubscriptionAvailableTerritories(
iapId: iap.id, product: product, ascAPI: ascAPI)
// 3.
await updateSubscriptionPricePoint(iapId: iap.id, product: product, ascAPI: ascAPI)
// Apple / PATCH
await refreshSubscriptionMetadata(iapId: iap.id, product: product, ascAPI: ascAPI)
}
ascAPI.addMessage("订阅商品:\(product.productId)\(product.name) ,上传完成!\n")
}
///
func updateSubscriptionPricePoint(iapId: String, product: IAPProduct, ascAPI: APASCAPI) async {
guard let schedule = product.priceSchedules else {
@ -565,26 +626,37 @@ extension APUploadIAPListVC {
let baseTerritory = schedule.baseTerritory
let baseCustomerPrice = schedule.baseCustomerPrice.normalizePrice()
ascAPI.addMessage("开始更新订阅商品价格点,基准国家:\(product.productId)\(baseTerritory)\(baseCustomerPrice) \n")
ascAPI.addMessage(
"开始更新订阅商品价格点,基准国家:\(product.productId)\(baseTerritory)\(baseCustomerPrice) \n")
let isPreservePrice = preserveCurrentPriceBtn.state.rawValue == 1
ascAPI.addMessage("保留自动续期订阅者现有定价:\(isPreservePrice ? "" : "")")
let points = await ascAPI.fetchSubscriptionPricePoints(iapId: iapId, territory: [baseTerritory])
if let point = points.filter({ $0.attributes?.customerPrice!.normalizePrice() == baseCustomerPrice }).first {
let points = await ascAPI.fetchSubscriptionPricePoints(
iapId: iapId, territory: [baseTerritory])
if let point = points.filter({
$0.attributes?.customerPrice!.normalizePrice() == baseCustomerPrice
}).first {
ascAPI.addMessage("开始更新自定价格:")
// ,
var customerPriceSchedules = schedule.manualPrices
customerPriceSchedules.append(IAPPricePoint(territory: baseTerritory, customerPrice: baseCustomerPrice))
customerPriceSchedules.append(
IAPPricePoint(territory: baseTerritory, customerPrice: baseCustomerPrice))
let manualPricesTerritory: [String] = customerPriceSchedules.map({ $0.territory })
//
for pricePoint in customerPriceSchedules {
let territory = pricePoint.territory
let customerPrice = pricePoint.customerPrice.normalizePrice()
let points = await ascAPI.fetchSubscriptionPricePoints(iapId: iapId, territory: [territory])
if let point = points.filter({ $0.attributes?.customerPrice!.normalizePrice() == customerPrice }).first {
if (await ascAPI.updateSubscriptionPricePoint(iapId: iapId, pricePointId: point.id, preserveCurrentPrice: isPreservePrice)) != nil {
let points = await ascAPI.fetchSubscriptionPricePoints(
iapId: iapId, territory: [territory])
if let point = points.filter({
$0.attributes?.customerPrice!.normalizePrice() == customerPrice
}).first {
if (await ascAPI.updateSubscriptionPricePoint(
iapId: iapId, pricePointId: point.id, preserveCurrentPrice: isPreservePrice))
!= nil
{
ascAPI.addMessage("自定价格的订阅商品的价格点:\(territory)\(customerPrice) ,更新价格成功!✅ ")
} else {
ascAPI.addMessage("自定价格的订阅商品的价格点:\(territory)\(customerPrice) ,更新价格失败!❌ ")
@ -596,7 +668,8 @@ extension APUploadIAPListVC {
ascAPI.addMessage("开始更新全球均衡价格:")
// API
let allPoints = await ascAPI.fetchSubscriptionPricePointsEqualizations(pointId: point.id, territory: nil)
let allPoints = await ascAPI.fetchSubscriptionPricePointsEqualizations(
pointId: point.id, territory: nil)
for apoint in allPoints {
let territory = apoint.relationships?.territory?.data?.id ?? ""
//
@ -604,7 +677,10 @@ extension APUploadIAPListVC {
continue
}
let customerPrice = apoint.attributes?.customerPrice ?? ""
if (await ascAPI.updateSubscriptionPricePoint(iapId: iapId, pricePointId: apoint.id, preserveCurrentPrice: isPreservePrice)) != nil {
if (await ascAPI.updateSubscriptionPricePoint(
iapId: iapId, pricePointId: apoint.id, preserveCurrentPrice: isPreservePrice))
!= nil
{
//
ascAPI.addMessage("全球均衡价格的订阅商品的价格点:\(territory)\(customerPrice) ,更新价格成功!✅ ")
} else {
@ -618,11 +694,14 @@ extension APUploadIAPListVC {
}
}
///
func createSubscriptionLocalization(iapId: String, localization: IAPLocalization, product: IAPProduct, ascAPI: APASCAPI) async {
func createSubscriptionLocalization(
iapId: String, localization: IAPLocalization, product: IAPProduct, ascAPI: APASCAPI
) async {
ascAPI.addMessage("开始更新订阅商品本地化版本:\(product.productId)\(localization.locale)")
if (await ascAPI.createSubscriptionLocalization(iapId: iapId, localization: localization)) != nil {
if (await ascAPI.createSubscriptionLocalization(iapId: iapId, localization: localization))
!= nil
{
//
ascAPI.addMessage("订阅商品本地化版本:\(localization.locale) ,更新语言成功!✅ ")
} else {
@ -631,6 +710,38 @@ extension APUploadIAPListVC {
}
}
/// Apple
func refreshSubscriptionMetadata(iapId: String, product: IAPProduct, ascAPI: APASCAPI) async {
ascAPI.addMessage("开始刷新订阅商品元数据状态:\(product.productId)")
guard (await ascAPI.updateSubscription(iapId: iapId, product: product)) != nil else {
ascAPI.addMessage("订阅商品:\(product.productId) ,刷新基础元数据失败!❌ ")
return
}
guard let localization = product.subscriptionLocalization else {
ascAPI.addMessage("订阅商品:\(product.productId) 无本地化元数据,跳过刷新本地化状态")
return
}
let localizations = await ascAPI.fetchSubscriptionLocalizations(iapId: iapId)
guard
let locale = localizations.first(where: { $0.attributes?.locale == localization.locale }
)
else {
ascAPI.addMessage("订阅商品:\(product.productId) ,未找到本地化 \(localization.locale),跳过本地化刷新")
return
}
if (await ascAPI.updateSubscriptionLocalization(
iapLocaleId: locale.id, localization: localization)) != nil
{
ascAPI.addMessage("订阅商品:\(product.productId) ,元数据状态刷新成功!✅ ")
} else {
ascAPI.addMessage("订阅商品:\(product.productId) ,刷新本地化元数据失败!❌ ")
}
}
///
func createSubscriptionScreenshot(iapId: String, product: IAPProduct, ascAPI: APASCAPI) async {
ascAPI.addMessage("开始更新订阅商品的送审截图:\(product.productId)\(product.reviewScreenshot)")
@ -664,7 +775,10 @@ extension APUploadIAPListVC {
ascAPI.addMessage("订阅商品截图文件错误:\(imgPath) ,文件大小为 0~")
return
}
guard let shot = await ascAPI.createSubscriptionScreenshot(iapId: iapId, fileName: uploadFileName, fileSize: imaSize) else {
guard
let shot = await ascAPI.createSubscriptionScreenshot(
iapId: iapId, fileName: uploadFileName, fileSize: imaSize)
else {
//
ascAPI.addMessage("订阅商品:\(product.productId) ,创建送审截图失败!❌ ")
return
@ -674,7 +788,8 @@ extension APUploadIAPListVC {
guard let method = shot.attributes?.uploadOperations?.first?.method,
let url = shot.attributes?.uploadOperations?.first?.url,
let requestHeaders = shot.attributes?.uploadOperations?.first?.requestHeaders,
let baseURL = URL(string: url) else {
let baseURL = URL(string: url)
else {
ascAPI.addMessage("订阅商品:\(product.productId) ,创建送审截图失败!苹果参数异常~ ❌ ")
return
}
@ -687,18 +802,22 @@ extension APUploadIAPListVC {
ascAPI.addMessage("上传新的送审截图:\(uploadFileName)")
//
guard let response = try? await URLSession.shared.upload(for: request, fromFile: imaUrl) else {
guard let response = try? await URLSession.shared.upload(for: request, fromFile: imaUrl)
else {
ascAPI.addMessage("订阅商品:\(product.productId) ,创建送审截图失败!上传图片异常~ ❌ ")
return
}
guard let responseCode = (response.1 as? HTTPURLResponse)?.statusCode, responseCode == 200 else {
ascAPI.addMessage("订阅商品:\(product.productId) ,创建送审截图失败!上传图片异常 \(response.1.description)~ ❌ ")
guard let responseCode = (response.1 as? HTTPURLResponse)?.statusCode, responseCode == 200
else {
ascAPI.addMessage(
"订阅商品:\(product.productId) ,创建送审截图失败!上传图片异常 \(response.1.description)~ ❌ ")
return
}
ascAPI.addMessage("提交新的送审截图:\(uploadFileName)")
//
if ((await ascAPI.updateSubscriptionScreenshot(iapShotId: shot.id, fileMD5: fileMD5)) != nil) {
if (await ascAPI.updateSubscriptionScreenshot(iapShotId: shot.id, fileMD5: fileMD5)) != nil
{
ascAPI.addMessage("订阅商品:\(product.productId) ,送审截图上传成功!✅ ")
} else {
ascAPI.addMessage("订阅商品:\(product.productId) ,送审截图可能上传失败! ")
@ -706,7 +825,9 @@ extension APUploadIAPListVC {
}
///
func updateSubscriptionAvailableTerritories(iapId: String, product: IAPProduct, ascAPI: APASCAPI) async {
func updateSubscriptionAvailableTerritories(
iapId: String, product: IAPProduct, ascAPI: APASCAPI
) async {
let inAll = product.territories.availableInAllTerritories
let inNew = product.territories.availableInNewTerritories
let summary = territoryInfo(product: product)
@ -719,11 +840,14 @@ extension APUploadIAPListVC {
territories.forEach { territory in
allTerritories.append([
"type": "territories",
"id": territory.id
"id": territory.id,
])
}
//
if (await ascAPI.updateSubscriptionAvailabilityTerritories(iapId: iapId, availableTerritories: allTerritories, availableInNewTerritories: inNew)) != nil {
if (await ascAPI.updateSubscriptionAvailabilityTerritories(
iapId: iapId, availableTerritories: allTerritories,
availableInNewTerritories: inNew)) != nil
{
ascAPI.addMessage("选择:所有国家(地区)销售,\(newTerritory),更新成功!✅ ")
} else {
ascAPI.addMessage("选择:所有国家(地区)销售,\(newTerritory),更新失败!❌ ")
@ -739,12 +863,16 @@ extension APUploadIAPListVC {
product.territories.territories?.forEach({ territory in
territories.append([
"type": "territories",
"id": territory.id
"id": territory.id,
])
})
let customerTerritory = product.territories.territories?.map({ $0.id }).joined(separator: ",") ?? ""
if (await ascAPI.updateSubscriptionAvailabilityTerritories(iapId: iapId, availableTerritories: territories, availableInNewTerritories: inNew)) != nil {
let customerTerritory =
product.territories.territories?.map({ $0.id }).joined(separator: ",") ?? ""
if (await ascAPI.updateSubscriptionAvailabilityTerritories(
iapId: iapId, availableTerritories: territories, availableInNewTerritories: inNew))
!= nil
{
ascAPI.addMessage("订阅商品的销售国家/地区:\(customerTerritory) ,更新成功!✅ ")
} else {
ascAPI.addMessage("订阅商品的销售国家/地区:\(customerTerritory) ,更新失败!❌ ")
@ -758,65 +886,91 @@ extension APUploadIAPListVC {
func territoryInfo(product: IAPProduct) -> String {
let inAll = product.territories.availableInAllTerritories
let inNew = product.territories.availableInNewTerritories
let customerTerritory = product.territories.territories?.map({ $0.id }).joined(separator: ",") ?? ""
let customerTerritory =
product.territories.territories?.map({ $0.id }).joined(separator: ",") ?? ""
let off = !inAll && !inNew && (product.territories.territories?.isEmpty ?? true)
let territory = off ? "下架" : (customerTerritory.isEmpty ? (inAll ? "全部" : "当前下架") : customerTerritory)
let stringValue = "在所有国家/地区销售:'\(inAll ? "" : "")'\n将来新国家/地区自动提供:'\(inNew ? "" : "")'\n指定国家/地区销售:\(territory)"
let territory =
off ? "下架" : (customerTerritory.isEmpty ? (inAll ? "全部" : "当前下架") : customerTerritory)
let stringValue =
"在所有国家/地区销售:'\(inAll ? "" : "")'\n将来新国家/地区自动提供:'\(inNew ? "" : "")'\n指定国家/地区销售:\(territory)"
return stringValue
}
}
// MARK: - NSTableViewDelegate
extension APUploadIAPListVC: NSTableViewDelegate, NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return iaps.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int)
-> NSView?
{
let iap = iaps[row]
switch tableColumn?.identifier.enumValue() {
case ColumnIdetifier.id.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.id.cellValue, owner: self) as? NSTableCellView
cell?.textField?.stringValue = String(row+1)
let cell =
tableView.makeView(withIdentifier: ColumnIdetifier.id.cellValue, owner: self)
as? NSTableCellView
cell?.textField?.stringValue = String(row + 1)
return cell
case ColumnIdetifier.productID.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.productID.cellValue, owner: self) as? NSTableCellView
let cell =
tableView.makeView(withIdentifier: ColumnIdetifier.productID.cellValue, owner: self)
as? NSTableCellView
cell?.textField?.stringValue = iap.productId
return cell
case ColumnIdetifier.productName.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.productName.cellValue, owner: self) as? NSTableCellView
let cell =
tableView.makeView(
withIdentifier: ColumnIdetifier.productName.cellValue, owner: self)
as? NSTableCellView
cell?.textField?.stringValue = iap.name
return cell
case ColumnIdetifier.price.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.price.cellValue, owner: self) as? NSTableCellView
let cell =
tableView.makeView(withIdentifier: ColumnIdetifier.price.cellValue, owner: self)
as? NSTableCellView
cell?.textField?.stringValue = territoryInfo(product: iap)
return cell
case ColumnIdetifier.level.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.level.cellValue, owner: self) as? NSTableCellView
let cell =
tableView.makeView(withIdentifier: ColumnIdetifier.level.cellValue, owner: self)
as? NSTableCellView
let territory = iap.priceSchedules?.baseTerritory ?? "-"
let price = iap.priceSchedules?.baseCustomerPrice ?? "-"
let customerPrice = iap.priceSchedules?.manualPrices.map({ pp in
let customerPrice =
iap.priceSchedules?.manualPrices.map({ pp in
"{'国家:'\(pp.territory)', '自定价格':'\(pp.customerPrice)'}\n"
}).joined() ?? "-"
cell?.textField?.stringValue = "基准国家:'\(territory)'\n基准价格:'\(price)'\n\(customerPrice)"
return cell
case ColumnIdetifier.productPds.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.productPds.cellValue, owner: self) as? NSTableCellView
let cell =
tableView.makeView(
withIdentifier: ColumnIdetifier.productPds.cellValue, owner: self)
as? NSTableCellView
cell?.textField?.stringValue = iap.reviewNote
return cell
case ColumnIdetifier.state.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.state.cellValue, owner: self) as? NSTableCellView
let cell =
tableView.makeView(withIdentifier: ColumnIdetifier.state.cellValue, owner: self)
as? NSTableCellView
cell?.textField?.stringValue = iap.inAppPurchaseType.CNValue()
return cell
case ColumnIdetifier.screenshot.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.screenshot.cellValue, owner: self) as? ImageViewCell
let cell =
tableView.makeView(
withIdentifier: ColumnIdetifier.screenshot.cellValue, owner: self)
as? ImageViewCell
let file_name = iap.reviewScreenshot
let imgPath = screenshotPaths[file_name] ?? ""
cell?.imgSel.image = NSImage(contentsOfFile: imgPath)
return cell
case ColumnIdetifier.language.cellValue:
let cell = tableView.makeView(withIdentifier: ColumnIdetifier.language.cellValue, owner: self) as? NSTableCellView
let cell =
tableView.makeView(withIdentifier: ColumnIdetifier.language.cellValue, owner: self)
as? NSTableCellView
cell?.textField?.stringValue = iap.localizations.map({ lz in
"{'locale:'\(lz.locale)', 'title':'\(lz.name)', 'desc':'\(lz.description)'}\n"
}).joined()