Skip to content

Commit

Permalink
Merge pull request #59 from strvcom/feat/downloads-uploads-simplifica…
Browse files Browse the repository at this point in the history
…tion

[feat] Downloads/Uploads manager usage simplification and sample unification
  • Loading branch information
matejmolnar authored Jan 23, 2024
2 parents e01bf1e + ec70c53 commit 337da1f
Show file tree
Hide file tree
Showing 28 changed files with 544 additions and 657 deletions.
54 changes: 19 additions & 35 deletions NetworkingSampleApp/NetworkingSampleApp.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import Foundation
enum SampleAPIConstants {
static let userHost = "https://reqres.in/api"
static let authHost = "https://nonexistentmockauth.com/api"
// swiftlint:disable:next force_https
static let uploadHost = "https://httpbin.org"
// swiftlint:disable:next force_unwrapping force_https
static let uploadURL = URL(string: "https://httpbin.org/post")!
static let validEmail = "[email protected]"
static let validPassword = "cityslicka"
static let videoUrl = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// URLSessionTask.State+Convenience.swift
// NetworkingSampleApp
//
// Created by Matej Molnár on 21.12.2023.
//

import Foundation

extension URLSessionTask.State {
var title: String {
switch self {
case .canceling: "cancelling"
case .completed: "completed"
case .running: "running"
case .suspended: "suspended"
@unknown default: ""
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// UploadAPIManager+SharedInstance.swift
// NetworkingSampleApp
//
// Created by Matej Molnár on 21.12.2023.
//

import Networking

extension UploadAPIManager {
static var shared: UploadAPIManaging = {
var responseProcessors: [ResponseProcessing] = [
LoggingInterceptor.shared,
StatusCodeProcessor.shared
]
var errorProcessors: [ErrorProcessing] = [LoggingInterceptor.shared]

#if DEBUG
responseProcessors.append(EndpointRequestStorageProcessor.shared)
errorProcessors.append(EndpointRequestStorageProcessor.shared)
#endif

return UploadAPIManager(
urlSessionConfiguration: .default,
requestAdapters: [
LoggingInterceptor.shared
],
responseProcessors: responseProcessors,
errorProcessors: errorProcessors
)
}()
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,41 @@ import Foundation
import Networking

@MainActor
final class DownloadProgressViewModel: ObservableObject {
final class DownloadProgressViewModel: TaskProgressViewModel {
private let task: URLSessionTask

@Published var state: DownloadProgressState = .init()

let isRetryable = false
private(set) var title: String = ""
private(set) var status: String = ""
private(set) var downloadedBytes: String = ""
private(set) var state: URLSessionTask.State = .running
private(set) var percentCompleted: Double = 0

init(task: URLSessionTask) {
self.task = task
}

func startObservingDownloadProgress() async {
func onAppear() async {
let stream = DownloadAPIManager.shared.progressStream(for: task)

for try await downloadState in stream {
var newState = DownloadProgressState()
newState.percentCompleted = downloadState.fractionCompleted * 100
newState.downloadedBytes = ByteCountFormatter.megaBytesFormatter.string(fromByteCount: downloadState.downloadedBytes)
newState.status = downloadState.taskState
newState.statusTitle = downloadState.taskState.title
newState.errorTitle = downloadState.error?.localizedDescription
newState.fileURL = downloadState.downloadedFileURL?.absoluteString
newState.title = task.currentRequest?.url?.absoluteString ?? "-"
state = newState
title = task.currentRequest?.url?.absoluteString ?? "-"
percentCompleted = downloadState.fractionCompleted * 100
downloadedBytes = ByteCountFormatter.megaBytesFormatter.string(fromByteCount: downloadState.downloadedBytes)
state = downloadState.taskState
status = {
if let error = downloadState.error {
return "Error: \(error.localizedDescription)"
}

if let downloadedFileURL = downloadState.downloadedFileURL {
return "Downloaded at: \(downloadedFileURL.absoluteString)"
}

return downloadState.taskState.title
}()

objectWillChange.send()
}
}

Expand All @@ -45,28 +58,6 @@ final class DownloadProgressViewModel: ObservableObject {
func cancel() {
task.cancel()
}
}

// MARK: Download state
struct DownloadProgressState {
var title: String = ""
var status: URLSessionTask.State = .running
var statusTitle: String = ""
var percentCompleted: Double = 0
var downloadedBytes: String = ""
var errorTitle: String?
var fileURL: String?
}

// MARK: URLSessionTask states
private extension URLSessionTask.State {
var title: String {
switch self {
case .canceling: "cancelling"
case .completed: "completed"
case .running: "running"
case .suspended: "suspended"
@unknown default: ""
}
}
func retry() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct DownloadsView: View {
Section("Active downloads") {
List {
ForEach(viewModel.tasks, id: \.taskIdentifier) { task in
DownloadProgressView(viewModel: .init(task: task))
TaskProgressView(viewModel: DownloadProgressViewModel(task: task))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private extension DownloadsViewModel {

do {
let (task, _) = try await downloadAPIManager.downloadRequest(
SampleDownloadRouter.download(url: url),
url,
resumableData: nil,
retryConfiguration: RetryConfiguration.default
)
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 337da1f

Please sign in to comment.