diff --git a/AppleParty.xcodeproj/project.pbxproj b/AppleParty.xcodeproj/project.pbxproj index 0fd090d..8e2bb9b 100644 --- a/AppleParty.xcodeproj/project.pbxproj +++ b/AppleParty.xcodeproj/project.pbxproj @@ -1077,7 +1077,7 @@ CODE_SIGN_ENTITLEMENTS = AppleParty/AppleParty.entitlements; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 2022.04.10; + CURRENT_PROJECT_VERSION = 2022.07.13; DEVELOPMENT_TEAM = ""; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = AppleParty/Info.plist; @@ -1090,7 +1090,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 2.0.4; + MARKETING_VERSION = 2.0.5; PRODUCT_BUNDLE_IDENTIFIER = cn.com.37iOS.AppleParty; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1111,7 +1111,7 @@ CODE_SIGN_ENTITLEMENTS = AppleParty/AppleParty.entitlements; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 2022.04.10; + CURRENT_PROJECT_VERSION = 2022.07.13; DEVELOPMENT_TEAM = ""; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = AppleParty/Info.plist; @@ -1124,7 +1124,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 2.0.4; + MARKETING_VERSION = 2.0.5; PRODUCT_BUNDLE_IDENTIFIER = cn.com.37iOS.AppleParty; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/AppleParty/AppListView/APAppListCell.swift b/AppleParty/AppListView/APAppListCell.swift index b83d7e5..22ebddc 100644 --- a/AppleParty/AppListView/APAppListCell.swift +++ b/AppleParty/AppListView/APAppListCell.swift @@ -37,7 +37,7 @@ class APAppListCell: NSCollectionViewItem { func configure(app: App) { self.app = app nameView.stringValue = app.appName - imgView?.showWebImage(app.largeIconUrl) + imgView?.showWebImage(app.iconUrl) } diff --git a/AppleParty/AppListView/APAppListModel.swift b/AppleParty/AppListView/APAppListModel.swift index 23c1ebd..a140dfa 100644 --- a/AppleParty/AppListView/APAppListModel.swift +++ b/AppleParty/AppListView/APAppListModel.swift @@ -10,35 +10,54 @@ import Foundation // MARK: - 游戏列表 struct AppList { - var games: [App] - - init(body: [String: Any]) { - games = [App]() - let data = dictionary(body["data"]) - let softwares = dictionaryArray(data["softwares"]) - for software in softwares { - var game = App() - game.adamId = string(from: software["adamId"]) - game.appName = string(from: software["appName"]) - game.platforms = string(from: software["platforms"]) - game.largeIconUrl = string(from: software["largeIconUrl"]) - game.largeIconType = string(from: software["largeIconType"]) - game.iconPlatform = string(from: software["iconPlatform"]) - games.append(game) - } - games = games.sorted(by: { (g1, g2) -> Bool in - g1.appName < g2.appName - }) - } + var games: [App] + + init(body: [String: Any]) { + games = [App]() + let included = dictionaryArray(body["included"]) + let apps = dictionaryArray(body["data"]) + for software in apps { + var game = App() + let attributes = dictionary(software["attributes"]) + game.appId = string(from: software["id"]) + game.appName = string(from: attributes["name"]) + game.platforms = string(from: attributes["distributionType"]) + game.bundleId = string(from: attributes["bundleId"]) + game.sku = string(from: attributes["sku"]) + game.primaryLocale = string(from: attributes["primaryLocale"]) + // icon 处理 + let appVersion = dictionaryArray( dictionary( dictionary(software["relationships"])["appStoreVersions"])["data"]).first + if let version = appVersion { + let vid = string(from: version["id"]) + for info in included { + let iid = string(from: info["id"]) + if vid == iid, vid.count > 0 { + let info_att = dictionary(info["attributes"]) + let storeIcon = dictionary(info_att["storeIcon"]) + let templateUrl = string(from: storeIcon["templateUrl"]) + if templateUrl.count > 0 { + game.iconUrl = templateUrl.replacingOccurrences(of: "{w}x{h}bb.{f}", with: "500x500bb.png") + } + break + } + } + } + games.append(game) + } + games = games.sorted(by: { (g1, g2) -> Bool in + g1.appName < g2.appName + }) + } } struct App { - var adamId: String = "" + var appId: String = "" var appName: String = "" var platforms: String = "" - var largeIconUrl: String = "" - var largeIconType: String = "" - var iconPlatform: String = "" + var iconUrl: String = "" + var bundleId: String = "" + var sku: String = "" + var primaryLocale: String = "" } struct AppInfo { diff --git a/AppleParty/AppListView/APAppListVC.swift b/AppleParty/AppListView/APAppListVC.swift index 0b177cf..41ef4c0 100644 --- a/AppleParty/AppListView/APAppListVC.swift +++ b/AppleParty/AppListView/APAppListVC.swift @@ -46,7 +46,7 @@ class APAppListVC: NSViewController { extension APAppListVC { func fetchAppList() { - APClient.apps.request(showLoading: true, inView: self.view) { [weak self] result, response, error in + APClient.appList(status: .filter(nil)).request(showLoading: true, inView: self.view) { [weak self] result, response, error in guard let err = error else { let gamelist = AppList(body: result) self?.adapter?.set(items: gamelist.games) diff --git a/AppleParty/AppListView/InAppPurchseView/APInAppPurchseVC.swift b/AppleParty/AppListView/InAppPurchseView/APInAppPurchseVC.swift index aaba0f8..37a6063 100644 --- a/AppleParty/AppListView/InAppPurchseView/APInAppPurchseVC.swift +++ b/AppleParty/AppListView/InAppPurchseView/APInAppPurchseVC.swift @@ -106,7 +106,7 @@ extension APInAppPurchseVC { // 请求商品列表 func fetchIAPs() { - APClient.iaps(appid: currentApp!.adamId).request(showLoading: true, inView: self.view) { [weak self] result, response, error in + APClient.iaps(appid: currentApp!.appId).request(showLoading: true, inView: self.view) { [weak self] result, response, error in guard let err = error else { guard let app = self?.currentApp else { return } //请求过程关闭页面可能导致为空 let iapL = IAPList(body:result, app: app) @@ -128,7 +128,7 @@ extension APInAppPurchseVC { let group = DispatchGroup() for i in 0.. Void) = { [weak self] pwd in DispatchQueue.global(qos: .userInitiated).async { - let result = XMLManager.uploadITMS(account: UserCenter.shared.loginedUser.appleid, pwd: pwd, filePath: XMLManager.getITMSPath(self?.currentApp!.adamId ?? "null")) + let result = XMLManager.uploadITMS(account: UserCenter.shared.loginedUser.appleid, pwd: pwd, filePath: XMLManager.getITMSPath(self?.currentApp!.appId ?? "null")) DispatchQueue.main.async { APHUD.hide() self?.enterBtn.isEnabled = true @@ -180,7 +180,7 @@ class InputExcelListVC: NSViewController { extension InputExcelListVC { func fetchAppInfo(_ replay: Int = 3) { - guard let appid = currentApp?.adamId else { + guard let appid = currentApp?.appId else { APHUD.hide(message: "当前 App 的 appleid 为空!", delayTime: 1) return } diff --git a/AppleParty/AppListView/ScreenShotsView/ScreenShotUploadVC.swift b/AppleParty/AppListView/ScreenShotsView/ScreenShotUploadVC.swift index b6e4456..b05bfd8 100644 --- a/AppleParty/AppListView/ScreenShotsView/ScreenShotUploadVC.swift +++ b/AppleParty/AppListView/ScreenShotsView/ScreenShotUploadVC.swift @@ -152,7 +152,7 @@ extension ScreenShotUploadVC { } func fetchAppInfo(_ replay: Int = 3) { - guard let appid = currentApp?.adamId else { + guard let appid = currentApp?.appId else { APHUD.hide(message: "当前 App 的 appleid 为空!", delayTime: 1) return } @@ -175,7 +175,7 @@ extension ScreenShotUploadVC { func fetchAppVersionData(_ replay: Int = 3) { - guard let appid = currentApp?.adamId else { + guard let appid = currentApp?.appId else { APHUD.hide(message: "当前 App 的 appleid 为空!", delayTime: 1) return } @@ -311,7 +311,7 @@ extension ScreenShotUploadVC { uploadModel.vendor_id = info.sku // 获取创建 itms 文件的路径 - let filePath = XMLManager.getShotsPath(currentApp!.adamId) + let filePath = XMLManager.getShotsPath(currentApp!.appId) // 先删除旧的文档 XMLManager.deleteITMS(filePath) @@ -393,7 +393,7 @@ extension ScreenShotUploadVC { if result.0 == 0 { NSAlert.show("上传成功!稍后可在苹果后台查看~") // 删除旧的文档,避免占用空间过大 - let filePath = XMLManager.getShotsPath(currentApp!.adamId) + let filePath = XMLManager.getShotsPath(currentApp!.appId) XMLManager.deleteITMS(filePath) } else { let sb = NSStoryboard(name: "APDebugVC", bundle: Bundle(for: self.classForCoder)) diff --git a/AppleParty/Shared/Info/UserCenter.swift b/AppleParty/Shared/Info/UserCenter.swift index 858f4a3..01ff91c 100644 --- a/AppleParty/Shared/Info/UserCenter.swift +++ b/AppleParty/Shared/Info/UserCenter.swift @@ -32,8 +32,6 @@ struct UserCenter { var accountEmail = "" /// 账号所有子账号信息 var accountProviders: [String: Any] = [:] - /// 账号所有 app - var accountApps: [String: Any] = [:] /// 账号登陆态是否有效 var isAuthorized = false diff --git a/AppleParty/Shared/Network/APClient.swift b/AppleParty/Shared/Network/APClient.swift index a735601..3782c71 100644 --- a/AppleParty/Shared/Network/APClient.swift +++ b/AppleParty/Shared/Network/APClient.swift @@ -48,6 +48,11 @@ struct APClientSession { } } +enum AppListStatus { + case all + case available + case filter(_ query: String?) +} enum APClient { // 初始化登录请求 @@ -67,8 +72,7 @@ enum APClient { // 账号合同消息 case providerContractMessage // 应用列表 - case apps - case appsDetail + case appList(status: AppListStatus) // 应用版本 case appVersion(appid: String) // 内购列表-新 @@ -132,7 +136,7 @@ extension APClient { switch self { case .signIn, .submitSecurityCode, .appAnalytics, .appSalestrends, .initCSRF, .switchProvider: return .post - case .signInSession, .apps, .appsDetail, .inAppPurchase, .iaps, .iapDetail, .ascProvider, .ascProviders, .appInfo, .trusDevice, .providerNews, .providerContractMessage, .validateSession, .sapVendorNumbers, .summaryFinancialReport, .paymentConsolidation, .generateFinancialReport, .generateFinancialReportStatus, .detailFinancialReport, .appVersion, .bankList, .bankAccountNumber, .userDetail: + case .signInSession, .inAppPurchase, .iaps, .iapDetail, .ascProvider, .ascProviders, .appInfo, .trusDevice, .providerNews, .providerContractMessage, .validateSession, .sapVendorNumbers, .summaryFinancialReport, .paymentConsolidation, .generateFinancialReport, .generateFinancialReportStatus, .detailFinancialReport, .appVersion, .bankList, .bankAccountNumber, .userDetail, .appList: return .get case .verifySecurityPhone: return .put @@ -172,10 +176,16 @@ extension APClient { return "https://idmsa.apple.com/appleauth/auth/verify/phone" case let .submitSecurityCode(code): return "https://idmsa.apple.com/appleauth/auth/verify/\(code.urlPathComponent)/securitycode" - case .apps: - return "https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/index" - case .appsDetail: - return "https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/manageyourapps/summary/v2" + case let .appList(status): + switch status { + case .all: + return "https://appstoreconnect.apple.com/iris/v1/apps?limit=999" + case .available: + return "https://appstoreconnect.apple.com/iris/v1/apps?include=reviewSubmissions&limit=999&filter[removed]=false&filter[appStoreVersions.appStoreState]=READY_FOR_SALE" + case .filter(query: let query): + let filter = query ?? "limit=999&include=appStoreVersions&limit[appStoreVersions]=1" + return "https://appstoreconnect.apple.com/iris/v1/apps?\(filter)" + } case let .appVersion(appid): return "https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/"+appid+"/overview" case let .inAppPurchase(appid, type): @@ -428,8 +438,10 @@ extension APClient { UserCenter.shared.developerId = string(from: dictionary(json["provider"])["providerId"]) UserCenter.shared.developerName = string(from: dictionary(json["provider"])["name"]) } - case .apps: - UserCenter.shared.accountApps = json + case .appList: + if response?.statusCode != 200 { + return true + } case .ascProvider: let includeds = dictionaryArray(json["included"]) for included in includeds { diff --git a/AppleParty/SparkleUpdate/AppleParty-release.html b/AppleParty/SparkleUpdate/AppleParty-release.html index 2479750..0b4808b 100644 --- a/AppleParty/SparkleUpdate/AppleParty-release.html +++ b/AppleParty/SparkleUpdate/AppleParty-release.html @@ -15,6 +15,12 @@ --> +
+

v2.0.52022-07-13

+ +

v2.0.42022-04-10