From 6906db124937d991b2893420b371ca63897e8dee Mon Sep 17 00:00:00 2001 From: Alexandr Romanov Date: Mon, 4 Nov 2024 01:21:42 +0300 Subject: [PATCH] Add patch methods --- .../Models/AgeRatingDeclaration.swift | 217 ++++++++++++++++++ .../Models/AppInfo.swift | 3 +- .../Models/Typs/AppStoreAgeRating.swift | 18 ++ .../ServiceRegistering.swift | 2 +- .../Services/AppCategoryService.swift | 50 +++- .../Services/AppInfoService.swift | 96 ++++++++ .../Services/AppStoreReviewService.swift | 46 ++++ .../Services/VersionsService.swift | 3 +- 8 files changed, 430 insertions(+), 5 deletions(-) create mode 100644 Sources/OversizeAppStoreServices/Models/AgeRatingDeclaration.swift diff --git a/Sources/OversizeAppStoreServices/Models/AgeRatingDeclaration.swift b/Sources/OversizeAppStoreServices/Models/AgeRatingDeclaration.swift new file mode 100644 index 0000000..6198e51 --- /dev/null +++ b/Sources/OversizeAppStoreServices/Models/AgeRatingDeclaration.swift @@ -0,0 +1,217 @@ +// +// Copyright © 2024 Alexander Romanov +// AgeRatingDeclaration.swift, created on 04.11.2024 +// + +import AppStoreAPI +import AppStoreConnect +import OversizeCore + +public struct AgeRatingDeclaration: Sendable { + public let id: String + + public var alcoholTobaccoOrDrugUseOrReferences: AppStoreAgeRatingDeclaration? + public var contests: AppStoreAgeRatingDeclaration? + public var isGamblingAndContests: Bool? + public var isGambling: Bool? + public var gamblingSimulated: AppStoreAgeRatingDeclaration? + public var kidsAgeBand: KidsAgeBand? + public var isLootBox: Bool? + public var medicalOrTreatmentInformation: AppStoreAgeRatingDeclaration? + public var profanityOrCrudeHumor: AppStoreAgeRatingDeclaration? + public var sexualContentGraphicAndNudity: AppStoreAgeRatingDeclaration? + public var sexualContentOrNudity: AppStoreAgeRatingDeclaration? + public var horrorOrFearThemes: AppStoreAgeRatingDeclaration? + public var matureOrSuggestiveThemes: AppStoreAgeRatingDeclaration? + public var isUnrestrictedWebAccess: Bool? + public var violenceCartoonOrFantasy: AppStoreAgeRatingDeclaration? + public var violenceRealisticProlongedGraphicOrSadistic: AppStoreAgeRatingDeclaration? + public var violenceRealistic: AppStoreAgeRatingDeclaration? + public var ageRatingOverride: AgeRatingOverride? + public var koreaAgeRatingOverride: KoreaAgeRatingOverride? + public var isSeventeenPlus: Bool? + + public init?(schema: AppStoreAPI.AgeRatingDeclaration) { + guard let attributes = schema.attributes else { return nil } + id = schema.id + + } + +} + +/* +import AppStoreAPI +import AppStoreConnect +import Foundation + +public struct AgeRatingDeclaration: Codable, Equatable, Identifiable, Sendable { + public var type: `Type` + public var id: String + public var attributes: Attributes? + public var links: ResourceLinks? + + public enum `Type`: String, CaseIterable, Codable, Sendable { + case ageRatingDeclarations + } + + public struct Attributes: Codable, Equatable, Sendable { + public var alcoholTobaccoOrDrugUseOrReferences: AlcoholTobaccoOrDrugUseOrReferences? + public var contests: Contests? + public var isGamblingAndContests: Bool? + public var isGambling: Bool? + public var gamblingSimulated: GamblingSimulated? + public var kidsAgeBand: KidsAgeBand? + public var isLootBox: Bool? + public var medicalOrTreatmentInformation: MedicalOrTreatmentInformation? + public var profanityOrCrudeHumor: ProfanityOrCrudeHumor? + public var sexualContentGraphicAndNudity: SexualContentGraphicAndNudity? + public var sexualContentOrNudity: SexualContentOrNudity? + public var horrorOrFearThemes: HorrorOrFearThemes? + public var matureOrSuggestiveThemes: MatureOrSuggestiveThemes? + public var isUnrestrictedWebAccess: Bool? + public var violenceCartoonOrFantasy: ViolenceCartoonOrFantasy? + public var violenceRealisticProlongedGraphicOrSadistic: ViolenceRealisticProlongedGraphicOrSadistic? + public var violenceRealistic: ViolenceRealistic? + public var ageRatingOverride: AgeRatingOverride? + public var koreaAgeRatingOverride: KoreaAgeRatingOverride? + public var isSeventeenPlus: Bool? + + public enum AlcoholTobaccoOrDrugUseOrReferences: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum Contests: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum GamblingSimulated: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum MedicalOrTreatmentInformation: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum ProfanityOrCrudeHumor: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum SexualContentGraphicAndNudity: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum SexualContentOrNudity: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum HorrorOrFearThemes: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum MatureOrSuggestiveThemes: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum ViolenceCartoonOrFantasy: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum ViolenceRealisticProlongedGraphicOrSadistic: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum ViolenceRealistic: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" + } + + public enum AgeRatingOverride: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case seventeenPlus = "SEVENTEEN_PLUS" + case unrated = "UNRATED" + } + + public enum KoreaAgeRatingOverride: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case fifteenPlus = "FIFTEEN_PLUS" + case nineteenPlus = "NINETEEN_PLUS" + } + + public init(alcoholTobaccoOrDrugUseOrReferences: AlcoholTobaccoOrDrugUseOrReferences? = nil, contests: Contests? = nil, isGamblingAndContests: Bool? = nil, isGambling: Bool? = nil, gamblingSimulated: GamblingSimulated? = nil, kidsAgeBand: KidsAgeBand? = nil, isLootBox: Bool? = nil, medicalOrTreatmentInformation: MedicalOrTreatmentInformation? = nil, profanityOrCrudeHumor: ProfanityOrCrudeHumor? = nil, sexualContentGraphicAndNudity: SexualContentGraphicAndNudity? = nil, sexualContentOrNudity: SexualContentOrNudity? = nil, horrorOrFearThemes: HorrorOrFearThemes? = nil, matureOrSuggestiveThemes: MatureOrSuggestiveThemes? = nil, isUnrestrictedWebAccess: Bool? = nil, violenceCartoonOrFantasy: ViolenceCartoonOrFantasy? = nil, violenceRealisticProlongedGraphicOrSadistic: ViolenceRealisticProlongedGraphicOrSadistic? = nil, violenceRealistic: ViolenceRealistic? = nil, ageRatingOverride: AgeRatingOverride? = nil, koreaAgeRatingOverride: KoreaAgeRatingOverride? = nil, isSeventeenPlus: Bool? = nil) { + self.alcoholTobaccoOrDrugUseOrReferences = alcoholTobaccoOrDrugUseOrReferences + self.contests = contests + self.isGamblingAndContests = isGamblingAndContests + self.isGambling = isGambling + self.gamblingSimulated = gamblingSimulated + self.kidsAgeBand = kidsAgeBand + self.isLootBox = isLootBox + self.medicalOrTreatmentInformation = medicalOrTreatmentInformation + self.profanityOrCrudeHumor = profanityOrCrudeHumor + self.sexualContentGraphicAndNudity = sexualContentGraphicAndNudity + self.sexualContentOrNudity = sexualContentOrNudity + self.horrorOrFearThemes = horrorOrFearThemes + self.matureOrSuggestiveThemes = matureOrSuggestiveThemes + self.isUnrestrictedWebAccess = isUnrestrictedWebAccess + self.violenceCartoonOrFantasy = violenceCartoonOrFantasy + self.violenceRealisticProlongedGraphicOrSadistic = violenceRealisticProlongedGraphicOrSadistic + self.violenceRealistic = violenceRealistic + self.ageRatingOverride = ageRatingOverride + self.koreaAgeRatingOverride = koreaAgeRatingOverride + self.isSeventeenPlus = isSeventeenPlus + } + + private enum CodingKeys: String, CodingKey { + case alcoholTobaccoOrDrugUseOrReferences + case contests + case isGamblingAndContests = "gamblingAndContests" + case isGambling = "gambling" + case gamblingSimulated + case kidsAgeBand + case isLootBox = "lootBox" + case medicalOrTreatmentInformation + case profanityOrCrudeHumor + case sexualContentGraphicAndNudity + case sexualContentOrNudity + case horrorOrFearThemes + case matureOrSuggestiveThemes + case isUnrestrictedWebAccess = "unrestrictedWebAccess" + case violenceCartoonOrFantasy + case violenceRealisticProlongedGraphicOrSadistic + case violenceRealistic + case ageRatingOverride + case koreaAgeRatingOverride + case isSeventeenPlus = "seventeenPlus" + } + } + + public init(type: `Type` = .ageRatingDeclarations, id: String, attributes: Attributes? = nil, links: ResourceLinks? = nil) { + self.type = type + self.id = id + self.attributes = attributes + self.links = links + } +} +*/ diff --git a/Sources/OversizeAppStoreServices/Models/AppInfo.swift b/Sources/OversizeAppStoreServices/Models/AppInfo.swift index cbc5f6b..1fa4f8f 100644 --- a/Sources/OversizeAppStoreServices/Models/AppInfo.swift +++ b/Sources/OversizeAppStoreServices/Models/AppInfo.swift @@ -8,7 +8,7 @@ import AppStoreConnect import OversizeCore public struct AppInfo: Sendable { - public let id: String? + public let id: String public var appStoreState: AppStoreVersionState? public let appStoreAgeRating: AppStoreAgeRating? @@ -79,5 +79,6 @@ public struct AppInfo: Sendable { public struct Included: Sendable { public let primaryCategory: AppCategory? public let secondaryCategory: AppCategory? + //public let ageRatingDeclaration: AgeRatingDeclaration? } } diff --git a/Sources/OversizeAppStoreServices/Models/Typs/AppStoreAgeRating.swift b/Sources/OversizeAppStoreServices/Models/Typs/AppStoreAgeRating.swift index 0a5a5bf..be27590 100644 --- a/Sources/OversizeAppStoreServices/Models/Typs/AppStoreAgeRating.swift +++ b/Sources/OversizeAppStoreServices/Models/Typs/AppStoreAgeRating.swift @@ -46,3 +46,21 @@ public enum KoreaAgeRating: String, CaseIterable, Codable, Sendable { case nineteen = "NINETEEN" case notApplicable = "NOT_APPLICABLE" } + +public enum AppStoreAgeRatingDeclaration: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case infrequentOrMild = "INFREQUENT_OR_MILD" + case frequentOrIntense = "FREQUENT_OR_INTENSE" +} + +public enum AgeRatingOverride: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case seventeenPlus = "SEVENTEEN_PLUS" + case unrated = "UNRATED" +} + +public enum KoreaAgeRatingOverride: String, CaseIterable, Codable, Sendable { + case `none` = "NONE" + case fifteenPlus = "FIFTEEN_PLUS" + case nineteenPlus = "NINETEEN_PLUS" +} diff --git a/Sources/OversizeAppStoreServices/ServiceRegistering.swift b/Sources/OversizeAppStoreServices/ServiceRegistering.swift index aad27bc..30dae8f 100644 --- a/Sources/OversizeAppStoreServices/ServiceRegistering.swift +++ b/Sources/OversizeAppStoreServices/ServiceRegistering.swift @@ -45,7 +45,7 @@ public extension Container { var appStoreReviewService: Factory { self { AppStoreReviewService() } } - + var appCategoryService: Factory { self { AppCategoryService() } } diff --git a/Sources/OversizeAppStoreServices/Services/AppCategoryService.swift b/Sources/OversizeAppStoreServices/Services/AppCategoryService.swift index 5617e3c..df6e33d 100644 --- a/Sources/OversizeAppStoreServices/Services/AppCategoryService.swift +++ b/Sources/OversizeAppStoreServices/Services/AppCategoryService.swift @@ -1,7 +1,7 @@ // // Copyright © 2024 Alexander Romanov // AppCategoryService.swift, created on 03.11.2024 -// +// import AppStoreAPI import AppStoreConnect @@ -60,4 +60,52 @@ public actor AppCategoryService { return .failure(.network(type: .noResponse)) } } + + public func patchAppCategories( + appInfoId: String, + primaryCategoryId: String? = nil, + primarySubcategoryOneId: String? = nil, + primarySubcategoryTwoId: String? = nil, + secondaryCategoryId: String? = nil, + secondarySubcategoryOneId: String? = nil, + secondarySubcategoryTwoId: String? = nil + ) async -> Result { + guard let client = client else { return .failure(.network(type: .unauthorized)) } + + let primaryCategory: AppInfoUpdateRequest.Data.Relationships.PrimaryCategory? = primaryCategoryId != nil ? .init(data: .init(id: primaryCategoryId!)) : nil + let primarySubcategoryOne: AppInfoUpdateRequest.Data.Relationships.PrimarySubcategoryOne? = primarySubcategoryOneId != nil ? .init(data: .init(id: primarySubcategoryOneId!)) : nil + let primarySubcategoryTwo: AppInfoUpdateRequest.Data.Relationships.PrimarySubcategoryTwo? = primarySubcategoryTwoId != nil ? .init(data: .init(id: primarySubcategoryTwoId!)) : nil + let secondaryCategory: AppInfoUpdateRequest.Data.Relationships.SecondaryCategory? = secondaryCategoryId != nil ? .init(data: .init(id: secondaryCategoryId!)) : nil + let secondarySubcategoryOne: AppInfoUpdateRequest.Data.Relationships.SecondarySubcategoryOne? = secondarySubcategoryOneId != nil ? .init(data: .init(id: secondarySubcategoryOneId!)) : nil + let secondarySubcategoryTwo: AppInfoUpdateRequest.Data.Relationships.SecondarySubcategoryTwo? = secondarySubcategoryTwoId != nil ? .init(data: .init(id: secondarySubcategoryTwoId!)) : nil + + let requestRelationships: AppInfoUpdateRequest.Data.Relationships = .init( + primaryCategory: primaryCategory, + primarySubcategoryOne: primarySubcategoryOne, + primarySubcategoryTwo: primarySubcategoryTwo, + secondaryCategory: secondaryCategory, + secondarySubcategoryOne: secondarySubcategoryOne, + secondarySubcategoryTwo: secondarySubcategoryTwo + ) + + let requestData: AppInfoUpdateRequest.Data = .init( + type: .appInfos, + id: appInfoId, + relationships: requestRelationships + ) + + let request = Resources.v1.appInfos.id(appInfoId).patch( + .init(data: requestData) + ) + + do { + let data = try await client.send(request).data + guard let appStoreReviewDetail: AppInfo = .init(schema: data) else { + return .failure(.network(type: .decode)) + } + return .success(appStoreReviewDetail) + } catch { + return .failure(.network(type: .noResponse)) + } + } } diff --git a/Sources/OversizeAppStoreServices/Services/AppInfoService.swift b/Sources/OversizeAppStoreServices/Services/AppInfoService.swift index 7d249aa..aefc2f9 100644 --- a/Sources/OversizeAppStoreServices/Services/AppInfoService.swift +++ b/Sources/OversizeAppStoreServices/Services/AppInfoService.swift @@ -45,4 +45,100 @@ public actor AppInfoService { return .failure(.network(type: .noResponse)) } } + + public func fetchAppInfoLocalizations(appInfoId: String) async -> Result<[AppInfoLocalization], AppError> { + guard let client = client else { return .failure(.network(type: .unauthorized)) } + let request = Resources.v1.appInfos.id(appInfoId).appInfoLocalizations.get() + do { + let data = try await client.send(request).data + return .success(data.compactMap { .init(schema: $0) }) + } catch { + return .failure(.network(type: .noResponse)) + } + } + + public func fetchAppInfoLocalization(appInfoId: String, locale: String) async -> Result { + guard let client = client else { return .failure(.network(type: .unauthorized)) } + let request = Resources.v1.appInfos.id(appInfoId).appInfoLocalizations.get( + filterLocale: [locale] + ) + do { + let data = try await client.send(request).data + guard let firstDataItem = data.first, let appInfoLocalization: AppInfoLocalization = .init(schema: firstDataItem) else { + return .failure(.network(type: .decode)) + } + return .success(appInfoLocalization) + } catch { + return .failure(.network(type: .noResponse)) + } + } + + public func patchAgeRatingDeclarations( + ageRatingDeclarationId: String, + alcoholTobaccoOrDrugUseOrReferences: AgeRatingDeclarationUpdateRequest.Data.Attributes.AlcoholTobaccoOrDrugUseOrReferences?, + contests: AgeRatingDeclarationUpdateRequest.Data.Attributes.Contests?, + isGamblingAndContests: Bool?, + isGambling: Bool?, + gamblingSimulated: AgeRatingDeclarationUpdateRequest.Data.Attributes.GamblingSimulated?, + kidsAgeBand: AppStoreAPI.KidsAgeBand?, + isLootBox: Bool?, + medicalOrTreatmentInformation: AgeRatingDeclarationUpdateRequest.Data.Attributes.MedicalOrTreatmentInformation?, + profanityOrCrudeHumor: AgeRatingDeclarationUpdateRequest.Data.Attributes.ProfanityOrCrudeHumor?, + sexualContentGraphicAndNudity: AgeRatingDeclarationUpdateRequest.Data.Attributes.SexualContentGraphicAndNudity?, + sexualContentOrNudity: AgeRatingDeclarationUpdateRequest.Data.Attributes.SexualContentOrNudity?, + horrorOrFearThemes: AgeRatingDeclarationUpdateRequest.Data.Attributes.HorrorOrFearThemes?, + matureOrSuggestiveThemes: AgeRatingDeclarationUpdateRequest.Data.Attributes.MatureOrSuggestiveThemes?, + isUnrestrictedWebAccess: Bool?, + violenceCartoonOrFantasy: AgeRatingDeclarationUpdateRequest.Data.Attributes.ViolenceCartoonOrFantasy?, + violenceRealisticProlongedGraphicOrSadistic: AgeRatingDeclarationUpdateRequest.Data.Attributes.ViolenceRealisticProlongedGraphicOrSadistic?, + violenceRealistic: AgeRatingDeclarationUpdateRequest.Data.Attributes.ViolenceRealistic?, + ageRatingOverride: AgeRatingDeclarationUpdateRequest.Data.Attributes.AgeRatingOverride?, + koreaAgeRatingOverride: AgeRatingDeclarationUpdateRequest.Data.Attributes.KoreaAgeRatingOverride?, + isSeventeenPlus: Bool? + ) async -> Result { + guard let client = client else { return .failure(.network(type: .unauthorized)) } + + let requestAttributes: AgeRatingDeclarationUpdateRequest.Data.Attributes = .init( + alcoholTobaccoOrDrugUseOrReferences: alcoholTobaccoOrDrugUseOrReferences, + contests: contests, + isGamblingAndContests: isGamblingAndContests, + isGambling: isGambling, + gamblingSimulated: gamblingSimulated, + kidsAgeBand: kidsAgeBand, + isLootBox: isLootBox, + medicalOrTreatmentInformation: medicalOrTreatmentInformation, + profanityOrCrudeHumor: profanityOrCrudeHumor, + sexualContentGraphicAndNudity: sexualContentGraphicAndNudity, + sexualContentOrNudity: sexualContentOrNudity, + horrorOrFearThemes: horrorOrFearThemes, + matureOrSuggestiveThemes: matureOrSuggestiveThemes, + isUnrestrictedWebAccess: isUnrestrictedWebAccess, + violenceCartoonOrFantasy: violenceCartoonOrFantasy, + violenceRealisticProlongedGraphicOrSadistic: violenceRealisticProlongedGraphicOrSadistic, + violenceRealistic: violenceRealistic, + ageRatingOverride: ageRatingOverride, + koreaAgeRatingOverride: koreaAgeRatingOverride, + isSeventeenPlus: isSeventeenPlus + ) + + let requestData: AgeRatingDeclarationUpdateRequest.Data = .init( + type: .ageRatingDeclarations, + id: ageRatingDeclarationId, + attributes: requestAttributes + ) + + let request = Resources.v1.ageRatingDeclarations.id(ageRatingDeclarationId).patch( + .init(data: .init(type: .ageRatingDeclarations, id: ageRatingDeclarationId, attributes: requestAttributes)) + ) + + do { + let data = try await client.send(request).data + guard let ageRatingDeclaration: AgeRatingDeclaration = .init(schema: data) else { + return .failure(.network(type: .decode)) + } + return .success(ageRatingDeclaration) + } catch { + return .failure(.network(type: .noResponse)) + } + } } diff --git a/Sources/OversizeAppStoreServices/Services/AppStoreReviewService.swift b/Sources/OversizeAppStoreServices/Services/AppStoreReviewService.swift index 335b7a0..bbaaebf 100644 --- a/Sources/OversizeAppStoreServices/Services/AppStoreReviewService.swift +++ b/Sources/OversizeAppStoreServices/Services/AppStoreReviewService.swift @@ -51,6 +51,51 @@ public actor AppStoreReviewService { } public func patchAppStoreReviewDetail( + appStoreReviewDetailId: String, + contactFirstName: String?, + contactLastName: String?, + contactPhone: String?, + contactEmail: String?, + demoAccountName: String?, + demoAccountPassword: String?, + isDemoAccountRequired: Bool?, + notes: String? + ) async -> Result { + guard let client = client else { return .failure(.network(type: .unauthorized)) } + + let requestAttributes: AppStoreReviewDetailUpdateRequest.Data.Attributes = .init( + contactFirstName: contactFirstName?.isEmpty == true ? nil : contactFirstName, + contactLastName: contactLastName?.isEmpty == true ? nil : contactLastName, + contactPhone: contactPhone?.isEmpty == true ? nil : contactPhone, + contactEmail: contactEmail?.isEmpty == true ? nil : contactEmail, + demoAccountName: demoAccountName?.isEmpty == true ? nil : demoAccountName, + demoAccountPassword: demoAccountPassword?.isEmpty == true ? nil : demoAccountPassword, + isDemoAccountRequired: isDemoAccountRequired, + notes: notes?.isEmpty == true ? nil : notes + ) + + let requestData: AppStoreReviewDetailUpdateRequest.Data = .init( + type: .appStoreReviewDetails, + id: appStoreReviewDetailId, + attributes: requestAttributes + ) + + let request = Resources.v1.appStoreReviewDetails.id(appStoreReviewDetailId).patch( + .init(data: requestData) + ) + + do { + let data = try await client.send(request).data + guard let appStoreReviewDetail: AppStoreReviewDetail = .init(schema: data) else { + return .failure(.network(type: .decode)) + } + return .success(appStoreReviewDetail) + } catch { + return .failure(.network(type: .noResponse)) + } + } + + public func postAppStoreReviewDetail( versionId: String, contactFirstName: String?, contactLastName: String?, @@ -96,6 +141,7 @@ public actor AppStoreReviewService { } return .success(appStoreReviewDetail) } catch { + print(error) return .failure(.network(type: .noResponse)) } } diff --git a/Sources/OversizeAppStoreServices/Services/VersionsService.swift b/Sources/OversizeAppStoreServices/Services/VersionsService.swift index fc1ccb2..af951ec 100644 --- a/Sources/OversizeAppStoreServices/Services/VersionsService.swift +++ b/Sources/OversizeAppStoreServices/Services/VersionsService.swift @@ -18,7 +18,7 @@ public actor VersionsService { client = nil } } - + public func fetchAppVersions(appId: String) async -> Result<[AppStoreVersion], AppError> { guard let client = client else { return .failure(.network(type: .unauthorized)) } let request = Resources.v1.apps.id(appId).appStoreVersions.get() @@ -41,7 +41,6 @@ public actor VersionsService { } } - public func fetchAllVersionLocalizations(forVersion versionId: String) async throws -> Result<[(String, AppStoreLanguage)], AppError> { guard let client = client else { return .failure(.network(type: .unauthorized)) } let request = Resources.v1.appStoreVersions.id(versionId).appStoreVersionLocalizations.get()