Skip to content

Commit

Permalink
Add builds screens
Browse files Browse the repository at this point in the history
  • Loading branch information
aromanov91 committed Nov 30, 2024
1 parent ce9c79e commit 702d80c
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 17 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ name: CI
on:
push:
branches:
- main
- develop
- '**'
tags:
- "*.*.*"
workflow_dispatch:

concurrency:
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ let commonDependencies: [PackageDescription.Package.Dependency] = [
.package(url: "https://github.com/aaronsky/asc-swift.git", .upToNextMajor(from: "1.0.1")),
.package(url: "https://github.com/hmlongco/Factory.git", .upToNextMajor(from: "2.1.3")),
.package(url: "https://github.com/1024jp/GzipSwift", .upToNextMajor(from: "6.1.0")),
.package(url: "https://github.com/dehesa/CodableCSV.git", .upToNextMajor(from: "0.6.7"))
.package(url: "https://github.com/dehesa/CodableCSV.git", .upToNextMajor(from: "0.6.7")),
]

let remoteDependencies: [PackageDescription.Package.Dependency] = commonDependencies + [
Expand Down Expand Up @@ -54,7 +54,7 @@ let package = Package(
.product(name: "OversizeModels", package: "OversizeModels"),
.product(name: "OversizeServices", package: "OversizeServices"),
.product(name: "Gzip", package: "GzipSwift"),
.product(name: "CodableCSV", package: "CodableCSV")
.product(name: "CodableCSV", package: "CodableCSV"),
]
),
.testTarget(
Expand Down
11 changes: 7 additions & 4 deletions Sources/OversizeAppStoreServices/Cache/СacheService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ public final class СacheService {
cacheDirectory.appendingPathComponent(key)
}

func save(_ data: some Encodable, for key: String = #function) {
let fileURL = cacheFilePath(for: key)
func save(_ data: some Encodable, key: String = #function) {
let trimmedKey = key.hasSuffix("()") ? String(key.dropLast(2)) : key
let fileURL = cacheFilePath(for: trimmedKey)
do {
let jsonData = try JSONEncoder().encode(data)
try jsonData.write(to: fileURL, options: .atomic)
Expand All @@ -31,8 +32,9 @@ public final class СacheService {
}
}

func load<T: Decodable>(for key: String = #function, as _: T.Type) -> T? {
let fileURL = cacheFilePath(for: key)
func load<T: Decodable>(key: String = #function, as _: T.Type) -> T? {
let trimmedKey = key.hasSuffix("()") ? String(key.dropLast(2)) : key
let fileURL = cacheFilePath(for: trimmedKey)

guard FileManager.default.fileExists(atPath: fileURL.path),
isCacheValid(for: fileURL)
Expand All @@ -51,6 +53,7 @@ public final class СacheService {
}

func remove(for key: String = #function) {
let trimmedKey = key.hasSuffix("()") ? String(key.dropLast(2)) : key
let fileURL = cacheFilePath(for: key)
try? FileManager.default.removeItem(at: fileURL)
}
Expand Down
9 changes: 9 additions & 0 deletions Sources/OversizeAppStoreServices/Models/Build.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public struct Build: Sendable, Identifiable, Equatable {
public let processingState: ProcessingState?
public let buildAudienceType: BuildAudienceType?

public let relationships: Relationships

public init?(schema: AppStoreAPI.Build) {
guard let version = schema.attributes?.version,
let uploadedDate = schema.attributes?.uploadedDate,
Expand Down Expand Up @@ -52,6 +54,13 @@ public struct Build: Sendable, Identifiable, Equatable {
format: "png"
)
)
relationships = .init(
buildBundlesIds: schema.relationships?.buildBundles?.data?.compactMap { $0.id }
)
}

public struct Relationships: Sendable, Equatable {
public let buildBundlesIds: [String]?
}
}

Expand Down
30 changes: 30 additions & 0 deletions Sources/OversizeAppStoreServices/Models/BuildBundleFileSize.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Generated by Create API
// https://github.com/CreateAPI/CreateAPI
//
// swift-format-ignore-file

import AppStoreAPI
import AppStoreConnect
import Foundation

public struct BuildBundleFileSize: Sendable, Identifiable {
public let id: String
public let deviceModel: String
public let osVersion: String
public let downloadBytes: Int
public let installBytes: Int

init?(schema: AppStoreAPI.BuildBundleFileSize) {
guard let attributes = schema.attributes,
let deviceModel = attributes.deviceModel,
let osVersion = attributes.osVersion,
let downloadBytes = attributes.downloadBytes,
let installBytes = attributes.installBytes
else { return nil }
id = schema.id
self.deviceModel = deviceModel
self.osVersion = osVersion
self.downloadBytes = downloadBytes
self.installBytes = installBytes
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// Copyright © 2024 Alexander Romanov
// InstallReport.swift, created on 28.11.2024
//
//

import Foundation

Expand Down
13 changes: 13 additions & 0 deletions Sources/OversizeAppStoreServices/Models/Typs/ProcessingState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,17 @@ public enum ProcessingState: String, CaseIterable, Codable, Sendable {
case failed = "FAILED"
case invalid = "INVALID"
case valid = "VALID"

public var displayName: String {
switch self {
case .processing:
"Processing"
case .failed:
"Failed"
case .invalid:
"Invalid"
case .valid:
"Valid"
}
}
}
14 changes: 6 additions & 8 deletions Sources/OversizeAppStoreServices/Services/AppsService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public actor AppsService {
client = nil
}
}

public func fetchApp(id: String) async -> Result<App, AppError> {
guard let client else { return .failure(.network(type: .unauthorized)) }
let request = Resources.v1.apps.id(id).get()
Expand All @@ -47,7 +47,7 @@ public actor AppsService {
return .failure(.network(type: .noResponse))
}
}

public func fetchAppsIncludeAppStoreVersionsAndPreReleaseVersions() async -> Result<[App], AppError> {
guard let client else {
return .failure(.network(type: .unauthorized))
Expand Down Expand Up @@ -83,9 +83,7 @@ public actor AppsService {
if let cachedData: AppsResponse = cacheService.load(as: AppsResponse.self) {
return .success(processAppsResponse(cachedData))
}
guard let client else {
return .failure(.network(type: .unauthorized))
}
guard let client else { return .failure(.network(type: .unauthorized)) }
let request = Resources.v1.apps.get(
include: [
.builds,
Expand All @@ -94,9 +92,9 @@ public actor AppsService {
]
)
do {
let result = try await client.send(request)
cacheService.save(result)
return .success(processAppsResponse(result))
let response = try await client.send(request)
cacheService.save(response)
return .success(processAppsResponse(response))
} catch {
return .failure(.network(type: .noResponse))
}
Expand Down
39 changes: 39 additions & 0 deletions Sources/OversizeAppStoreServices/Services/BuildsService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@

import AppStoreAPI
import AppStoreConnect
import Factory
import Foundation
import OversizeCore
import OversizeModels

public actor BuildsService {
@Injected(\.cacheService) private var cacheService: СacheService
private let client: AppStoreConnectClient?

public init() {
Expand All @@ -20,6 +22,43 @@ public actor BuildsService {
}
}

public func fetchBuild(buildId: String) async -> Result<Build, AppError> {
let pathKey = "fetchBuild\(buildId)"
if let cachedData: BuildResponse = cacheService.load(key: pathKey, as: BuildResponse.self),
let build: Build = .init(schema: cachedData.data)
{
return .success(build)
}
guard let client else { return .failure(.network(type: .unauthorized)) }
let request = Resources.v1.builds.id(buildId).get()
do {
let response = try await client.send(request)
guard let build: Build = .init(schema: response.data) else {
return .failure(.network(type: .decode))
}
cacheService.save(response, key: pathKey)
return .success(build)
} catch {
return .failure(.network(type: .noResponse))
}
}

public func fetchBuildBundlesId(buildBundlesId: String) async -> Result<[BuildBundleFileSize], AppError> {
let pathKey = "buildBundlesId\(buildBundlesId)"
if let cachedResponse = cacheService.load(key: pathKey, as: BuildBundleFileSizesResponse.self) {
return .success(cachedResponse.data.compactMap { .init(schema: $0) })
}
guard let client else { return .failure(.network(type: .unauthorized)) }
let request = Resources.v1.buildBundles.id(buildBundlesId).buildBundleFileSizes.get()
do {
let response = try await client.send(request)
cacheService.save(response, key: pathKey)
return .success(response.data.compactMap { .init(schema: $0) })
} catch {
return .failure(.network(type: .noResponse))
}
}

public func fetchAppBuilds(appId: String) async -> Result<[Build], AppError> {
guard let client else { return .failure(.network(type: .unauthorized)) }
let request = Resources.v1.builds.get(filterApp: [appId])
Expand Down

0 comments on commit 702d80c

Please sign in to comment.