Skip to content

Commit

Permalink
Merge pull request #22 from joselinoneto/saveitems
Browse files Browse the repository at this point in the history
refactor saving
  • Loading branch information
joselinoneto authored May 30, 2023
2 parents 275370d + fb3dd9b commit 321fe18
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 124 deletions.
75 changes: 13 additions & 62 deletions Sources/manager/Controllers/ApodManagerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,40 +51,17 @@ public class ApodManagerController {
/// Will emit saved data.
/// - Parameter currentMonth: Month to search data
public func getMonthData(currentMonth: TimelineMonth) async throws {
Task.retrying { [weak self] in
let response = try await self?.apiController.getMonthsApods(startDate: currentMonth.startMonth, endDate: currentMonth.endMonth)
if currentMonth == TimelineMonth.currentMonth {
try await self?.saveItems(response?.items)
} else {
try await self?.saveItemsBatch(response?.items, currentMonth: currentMonth)
let items = try storageController.searchApods(startMonth: currentMonth.startMonth, endMonth: currentMonth.endMonth)
if let apodItems = items?.mapToEntity() {
DispatchQueue.main.async { [weak self] in
self?.items = apodItems
}
}
}

private func handleError(_ error: Error) async throws {

}

/// Get All Data
/// - Returns: Returns an array of Apods
public func getAll() throws -> [Apod]? {
try storageController.getAllItems()?.mapToEntity()
}

/// Search locally Apod using date
/// - Parameter currentMonth: TimelineMonth to search
/// - Returns: Returns a locally Apod array
public func searchLocalData(currentMonth: TimelineMonth) throws -> [Apod]? {
let items = try storageController.searchApods(startMonth: currentMonth.startMonth, endMonth: currentMonth.endMonth)
guard let items = items else { return nil }
return items.mapToEntity()
}

/// Search locally Apod using ID
/// - Parameter id: ID to search
/// - Returns: Returns a locally Apod
public func getApod(id: UUID) throws -> Apod? {
try storageController.getApod(id: id)?.mapToEntity()
Task.retrying { [weak self] in
let response = try await self?.apiController.getMonthsApods(startDate: currentMonth.startMonth, endDate: currentMonth.endMonth)
try await self?.saveItems(response?.items)
}
}

/// Download images and save in Documents Folder
Expand All @@ -110,51 +87,25 @@ public class ApodManagerController {
/// - Parameter items: Remote Items
private func saveItems(_ items: [NasaApodDto]?) async throws {
let itemsAdd: [ApodStorage] = items?.map { ApodStorage($0) } ?? []

let tempItems = itemsAdd.mapToEntity()
DispatchQueue.main.async { [weak self] in
self?.items = tempItems
}

for item in itemsAdd {
guard let id = item.id else { return }
if try storageController.getApod(id: id) == nil {
try storageController.saveItemsSql([item])
}
}
}

/// Save remote data locally
/// - Parameter items: Remote Items
private func saveItemsBatch(_ items: [NasaApodDto]?, currentMonth: TimelineMonth) async throws {
let itemsAdd: [ApodStorage] = items?.map { ApodStorage($0) } ?? []
try storageController.saveItemsSql(itemsAdd)
let returnItems = try searchLocalData(currentMonth: currentMonth)

DispatchQueue.main.async { [weak self] in
self?.items = returnItems
}
try await storageController.saveItemsSql(itemsAdd)
}
}

extension Task where Failure == Error {
@discardableResult
static func retrying(
priority: TaskPriority? = nil,
maxRetryCount: Int = 3,
operation: @Sendable @escaping () async throws -> Success
) -> Task {
static func retrying(priority: TaskPriority? = nil,
maxRetryCount: Int = 3,
operation: @Sendable @escaping () async throws -> Success) -> Task {
Task(priority: priority) {
for _ in 0..<maxRetryCount {
try Task<Never, Never>.checkCancellation()

do {
return try await operation()
} catch {
guard let apiError = error as? APIErrors else { throw error }
switch apiError {
case .authenticationError:
await LoginManagerController.shared.loginDevice()
await LoginManagerController.shared.loginDevice(deviceId: UUID().uuidString)
default:
throw error
}
Expand Down
7 changes: 2 additions & 5 deletions Sources/manager/Controllers/LoginManagerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,16 @@
//

import Foundation
import UIKit
import apiclient
import tools

public class LoginManagerController {
public static let shared: LoginManagerController = LoginManagerController()
private let loginController: LoginManagerAPI = LoginManagerAPI()

public func loginDevice() async {
guard let deviceId: String = await UIDevice.current.identifierForVendor?.uuidString else { return }
public func loginDevice(deviceId: String) async {
let login = try? await loginController.deviceLogin(deviceId: deviceId)
guard let token = login?.token else { return }
let key: String = ConfigLoader.shared.appConfig.token
try? KeychainStorage.shared.set(newValue: token, forKey: key)
KeychainStorage.shared.accessToken = token
}
}
57 changes: 0 additions & 57 deletions Tests/managerTests/managerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,63 +13,6 @@ final class managerTests: XCTestCase {
cancellables = []
}

func testRemoteData() async throws {
let controller = ApodManagerController(currentMonth: TimelineMonth.currentMonth)
try await controller.getMonthData(currentMonth: TimelineMonth.currentMonth)
let items = try controller.getAll()
XCTAssertNotNil(items)
}

func testDownloadContent() async throws {
let controller = ApodManagerController(currentMonth: TimelineMonth.currentMonth)
let items = Apod.mockItems

try await controller.downloadContent(items: items)
}

func testLoginController() async throws {
let controller = LoginManagerController.shared
await controller.loginDevice()
XCTAssertTrue(true)
}

func testSearch() throws {
guard let month = TimelineYear.years.first?.months[1] else { return }
let controller = ApodManagerController(currentMonth: TimelineMonth.currentMonth)

let allItems = try controller.getAll()
XCTAssertNotNil(allItems)

let items = try controller.searchLocalData(currentMonth: month)
XCTAssertNotNil(items)
XCTAssertNotEqual(items?.count, 0)
}

func testBatch() async throws {
guard let month = TimelineYear.years.first?.months[2] else {
XCTFail()
return
}
let controller = ApodManagerController(currentMonth: month)

try await controller.getMonthData(currentMonth: month)
let allItems = try controller.searchLocalData(currentMonth: month)
XCTAssertNotNil(allItems)
}

func testGetId() async throws {
let controller = ApodManagerController(currentMonth: TimelineMonth.currentMonth)

try await controller.getMonthData(currentMonth: TimelineMonth.currentMonth)
let allItems = try controller.getAll()
guard let id = allItems?.first?.id else {
XCTFail()
return
}
let item = try controller.getApod(id: id)
XCTAssertEqual(allItems?.first?.id, item?.id)
}

func testTimelineController() throws {
let startMonthDate: Date = TimelineMonth.currentMonth.startMonthDate
XCTAssertEqual(Date().beginning(of: .month), startMonthDate)
Expand Down

0 comments on commit 321fe18

Please sign in to comment.