Skip to content

Commit

Permalink
First part #13
Browse files Browse the repository at this point in the history
  • Loading branch information
Javier Galera committed Mar 23, 2022
1 parent cc212ca commit d7e594e
Show file tree
Hide file tree
Showing 16 changed files with 181 additions and 56 deletions.
42 changes: 25 additions & 17 deletions petWalk/petWalk.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,22 @@
uuid = "4E7C9AB4-8BA9-4F56-B4D4-14ED8DCB03B3"
type = "0"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "598FDC7A-3FBB-44A1-9C45-4F1AD6ABD797"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "petWalkWatchKitExtension/Design/View/PetDataView.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "62"
endingLineNumber = "62"
landmarkName = "body"
landmarkType = "24">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class UserDefaultsRepositoryTest: XCTestCase {
func testThatDailyStepsAreSavedOnMemory_When_SaveDailyStepsIsCalled() throws {
let stepsMocked = 10

sut.saveDailySteps(stepsMocked)
sut.saveAccumulatedDailySteps(stepsMocked)

XCTAssertEqual(1, dataSource.setCallsCount)
XCTAssertEqual(10, dataSource.setParamValueReceived as! Int)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import XCTest
@testable import petWalkWatchKitExtension

class ContentViewModelTest: XCTestCase {
private var sut: ContentViewModel!
private var sut: PetViewModel!
private var requestDailyStepsPermissionUseCaseMock: RequestDailyStepsPermissionUseCaseMock!
private var saveDailyStepsUseCaseMock: SaveDailyStepsUseCaseMock!
private var saveDailyStepsUseCaseMock: SaveAccumulatedDailyStepsUseCaseMock!
private var saveTotalDailyStepsUseCaseMock : SaveTotalStepsUseCaseMock!
private var getDailyStepsUseCaseMock: GetDailyStepsUseCaseMock!
private var getAccumulatedDailyStepsUseCase: GetAccumulatedDailyStepsUseCaseMock!
Expand All @@ -20,13 +20,13 @@ class ContentViewModelTest: XCTestCase {
try super.setUpWithError()

requestDailyStepsPermissionUseCaseMock = RequestDailyStepsPermissionUseCaseMock()
saveDailyStepsUseCaseMock = SaveDailyStepsUseCaseMock()
saveDailyStepsUseCaseMock = SaveAccumulatedDailyStepsUseCaseMock()
saveTotalDailyStepsUseCaseMock = SaveTotalStepsUseCaseMock()
getDailyStepsUseCaseMock = GetDailyStepsUseCaseMock()
getAccumulatedDailyStepsUseCase = GetAccumulatedDailyStepsUseCaseMock()

sut = ContentViewModel(requestDailyStepsPermissionUseCase: requestDailyStepsPermissionUseCaseMock,
saveDailyStepsUseCase: saveDailyStepsUseCaseMock,
sut = PetViewModel(requestDailyStepsPermissionUseCase: requestDailyStepsPermissionUseCaseMock,
saveAccumulatedDailyStepsUseCase: saveDailyStepsUseCaseMock,
saveTotalDailyStepsUseCase: saveTotalDailyStepsUseCaseMock,
getDailyStepsUseCase: getDailyStepsUseCaseMock,
getAccumulatedDailyStepsUseCase: getAccumulatedDailyStepsUseCase)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import XCTest
@testable import petWalkWatchKitExtension

class SaveDailyStepsUseCaseTest: XCTestCase {
private var sut: SaveDailyStepsUseCase!
private var sut: SaveAccumulatedDailyStepsUseCase!
private var repository: UserDefaultsRepositoryMock!

override func setUpWithError() throws {
try super.setUpWithError()
repository = UserDefaultsRepositoryMock()

sut = SaveDailyStepsUseCaseImplementation(repository: repository)
sut = SaveAccumulatedDailyStepsUseCaseImplementation(repository: repository)
}

func testThatDailyStepsAndDateAreSavedOnMemory_When_ExecuteIsCalled() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,15 @@ class HealthStoreDataSourceImplementation: HealthStoreDataSource {
try await withCheckedThrowingContinuation { continuation in
let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!

guard let healthStore = healthStore else { return continuation.resume(returning: false) }
guard let healthStore = healthStore else {
continuation.resume(returning: false)
return
}

healthStore.requestAuthorization(toShare: [], read: [stepType]) { success, error in
if let error = error {
continuation.resume(throwing: error)
}
continuation.resume(returning: success)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

protocol UserDefaultsRepository: AutoMockable {
func saveDailySteps(_ steps: Int)
func saveAccumulatedDailySteps(_ steps: Int)
func saveTotalSteps(_ steps: Int)
func saveDateDailySteps(_ date: Date)
func getAccumulatedDailySteps() -> Int
Expand All @@ -16,7 +16,7 @@ class UserDefaultsRepositoryImplementation: UserDefaultsRepository {
self.userDefaultDataSource = userDefaultDataSource
}

func saveDailySteps(_ steps: Int) {
func saveAccumulatedDailySteps(_ steps: Int) {
userDefaultDataSource.set(value: steps, forKey: .accumulatedDailySteps)
}

Expand Down
60 changes: 57 additions & 3 deletions petWalk/petWalkWatchKitExtension/Design/View/PetDataView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,71 @@
import SwiftUI

struct PetDataView: View {
private let petDataViewConfigurator = PetDataViewConfigurator()

@State var dailySteps: Int
@State var newExp: Int
@State var expNextLevel: Int = 100


@ObservedObject var petDataViewModel: PetDataViewModel

init() {
petDataViewModel = petDataViewConfigurator.configure()
newExp = petDataViewModel.animationDailySteps
}

var body: some View {
HStack {
Text("Exp: \(dailySteps)")
ZStack {
VStack {
Text("Exp: \(dailySteps)")
Text("Next Lvl: \(expNextLevel - dailySteps)")
}
Animation(newExp: $newExp, expNextLevel: $expNextLevel)
}
.onAppear {
petDataViewModel.calculateAnimationDailySteps(dailySteps)
}
}
}

struct Animation: View {
private let endCircleShape = 0.8

@State var previousExp = 0.0
@State var progressUntilNextLevel = 0.0

@Binding var newExp: Int
@Binding var expNextLevel: Int

var body: some View {
ZStack {
Circle()
.fill(Color.clear)
.overlay(
Circle()
.trim(from: self.previousExp, to: self.progressUntilNextLevel)
.rotation(Angle(degrees: 125))
.stroke(style: StrokeStyle(lineWidth: 12, lineCap: .round, lineJoin: .round))
.fill(Color.red)
)
}
.animation(.spring(response: 2.0, dampingFraction: 1.0, blendDuration: 1.0), value: self.progressUntilNextLevel)
.onAppear {
self.progressUntilNextLevel = (Double(newExp) * endCircleShape) / Double(expNextLevel)

// Save progressUntilNextLevel as newPreviousExp
}
}

private func calculateNewPath() {


}
}

struct PetDataView_Previews: PreviewProvider {
static var previews: some View {
PetDataView(dailySteps: 10)
PetDataView()
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
//
// ContentView.swift
// PetView.swift
// petWalk WatchKit Extension
//
// Created by Galera, Javier on 3/1/22.
//

import SwiftUI

struct ContentView: View {
struct PetView: View {
private let petMock = Swordman(name: "Beldrick")
private let contentViewConfigurator = ContentViewConfigurator()
private let contentViewConfigurator = PetViewConfigurator()

private let deviceSize = WKInterfaceDevice.current().screenBounds

@ObservedObject var contentViewModel: ContentViewModel
@ObservedObject var contentViewModel: PetViewModel

init() {
self.contentViewModel = contentViewConfigurator.configure()
Expand Down Expand Up @@ -59,11 +59,11 @@ struct ItemBarMenu: View {
var imageName: String
var valueText: String

@EnvironmentObject var contentViewModel: ContentViewModel
@EnvironmentObject var contentViewModel: PetViewModel

var body: some View {
HStack {
NavigationLink(destination: PetDataView(dailySteps: contentViewModel.currentSteps)) {
NavigationLink(destination: PetDataView()) {
Image(imageName)
.resizable()
.frame(width: 25,
Expand All @@ -78,9 +78,7 @@ struct ItemBarMenu: View {
}

struct ContentView_Previews: PreviewProvider {
let contentViewModel = ContentViewConfigurator().configure()

static var previews: some View {
ContentView()
PetView()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// PetDataViewConfigurator.swift
// petWalkWatchKitExtension
//
// Created by Galera, Javier on 17/3/22.
//

import Foundation

class PetDataViewConfigurator {
func configure() -> PetDataViewModel {
let userDefaultDataSource = UserDefaultsDataSourceImplementation()
let userDefaultRepository = UserDefaultsRepositoryImplementation(userDefaultDataSource: userDefaultDataSource)
let getAccumulatedDailyStepsUseCase = GetAccumulatedDailyStepsUseCaseImplementation(repository: userDefaultRepository)

return PetDataViewModel(getAccumulatedDailyStepsUseCase: getAccumulatedDailyStepsUseCase)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// PetDataViewModel.swift
// petWalkWatchKitExtension
//
// Created by Galera, Javier on 17/3/22.
//

import Foundation

class PetDataViewModel: ObservableObject {
@Published var animationDailySteps: Int = 0

private var getAccumulatedDailyStepsUseCase: GetAccumulatedDailyStepsUseCase

init(getAccumulatedDailyStepsUseCase: GetAccumulatedDailyStepsUseCase) {
self.getAccumulatedDailyStepsUseCase = getAccumulatedDailyStepsUseCase
}

func calculateAnimationDailySteps(_ steps: Int) {
let accumulatedDailySteps = self.getAccumulatedDailyStepsUseCase.execute()
self.animationDailySteps = steps - accumulatedDailySteps
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import Foundation

class ContentViewConfigurator {
@MainActor func configure() -> ContentViewModel {
class PetViewConfigurator {
@MainActor func configure() -> PetViewModel {
let healthStoreDataSource = HealthStoreDataSourceImplementation()
let healthStoreRepository = HealthStoreRepositoryImplementation(dataSource: healthStoreDataSource)

Expand All @@ -18,15 +18,15 @@ class ContentViewConfigurator {
let userDefaultDataSource = UserDefaultsDataSourceImplementation()
let userDefaultRepository = UserDefaultsRepositoryImplementation(userDefaultDataSource: userDefaultDataSource)

let saveDailyStepsUseCase = SaveDailyStepsUseCaseImplementation(repository: userDefaultRepository)
let saveAccumulatedDailyStepsUseCase = SaveAccumulatedDailyStepsUseCaseImplementation(repository: userDefaultRepository)
let saveTotalStepsUseCase = SaveTotalStepsUseCaseImplementation(repository: userDefaultRepository)
let getAccumulatedDailyStepsUseCase = GetAccumulatedDailyStepsUseCaseImplementation(repository: userDefaultRepository)




return ContentViewModel(requestDailyStepsPermissionUseCase: requestDailyStepsPermissionUseCase,
saveDailyStepsUseCase: saveDailyStepsUseCase,
return PetViewModel(requestDailyStepsPermissionUseCase: requestDailyStepsPermissionUseCase,
saveAccumulatedDailyStepsUseCase: saveAccumulatedDailyStepsUseCase,
saveTotalDailyStepsUseCase: saveTotalStepsUseCase,
getDailyStepsUseCase: getDailyStepsUseCase,
getAccumulatedDailyStepsUseCase: getAccumulatedDailyStepsUseCase)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@
import Foundation

@MainActor
class ContentViewModel: ObservableObject {
class PetViewModel: ObservableObject {
@Published var currentSteps: Int = 0
var animationDailySteps: Int = 0

private var requestDailyStepsPermissionUseCase: RequestDailyStepsPermissionUseCase
private var saveDailyStepsUseCase: SaveDailyStepsUseCase
private var saveAccumulatedDailyStepsUseCase: SaveAccumulatedDailyStepsUseCase
private var saveTotalDailyStepsUseCase: SaveTotalStepsUseCase
private var getDailyStepsUseCase: GetDailyStepsUseCase
private var getAccumulatedDailyStepsUseCase: GetAccumulatedDailyStepsUseCase

init(requestDailyStepsPermissionUseCase: RequestDailyStepsPermissionUseCase, saveDailyStepsUseCase: SaveDailyStepsUseCase, saveTotalDailyStepsUseCase: SaveTotalStepsUseCase, getDailyStepsUseCase: GetDailyStepsUseCase, getAccumulatedDailyStepsUseCase: GetAccumulatedDailyStepsUseCase) {
init(requestDailyStepsPermissionUseCase: RequestDailyStepsPermissionUseCase, saveAccumulatedDailyStepsUseCase: SaveAccumulatedDailyStepsUseCase, saveTotalDailyStepsUseCase: SaveTotalStepsUseCase, getDailyStepsUseCase: GetDailyStepsUseCase, getAccumulatedDailyStepsUseCase: GetAccumulatedDailyStepsUseCase) {
self.requestDailyStepsPermissionUseCase = requestDailyStepsPermissionUseCase
self.saveDailyStepsUseCase = saveDailyStepsUseCase
self.saveAccumulatedDailyStepsUseCase = saveAccumulatedDailyStepsUseCase
self.saveTotalDailyStepsUseCase = saveTotalDailyStepsUseCase
self.getDailyStepsUseCase = getDailyStepsUseCase
self.getAccumulatedDailyStepsUseCase = getAccumulatedDailyStepsUseCase
Expand All @@ -32,15 +32,16 @@ class ContentViewModel: ObservableObject {
if permission {
try await getDailySteps()
}
// TODO: Manage no permission
} catch {
print (error)
}
}

func getDailySteps() async throws {
func getDailySteps() async throws { // TODO: Probably this should be on PetDataViewModel
let steps = try await getDailyStepsUseCase.execute()
calculateAnimationDailySteps(steps)
saveDailyStepsUseCase.execute(steps)
saveAccumulatedDailyStepsUseCase.execute(steps)
saveTotalDailyStepsUseCase.execute(steps)
currentSteps = steps
}
Expand Down
3 changes: 1 addition & 2 deletions petWalk/petWalkWatchKitExtension/Design/petWalkApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import SwiftUI
@main
struct petWalkApp: App {


var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
PetView()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import Foundation

protocol SaveDailyStepsUseCase: AutoMockable {
protocol SaveAccumulatedDailyStepsUseCase: AutoMockable {
func execute(_ steps: Int)
}

class SaveDailyStepsUseCaseImplementation: SaveDailyStepsUseCase {
class SaveAccumulatedDailyStepsUseCaseImplementation: SaveAccumulatedDailyStepsUseCase {
private var repository: UserDefaultsRepository

public init(repository: UserDefaultsRepository) {
self.repository = repository
}

func execute(_ steps: Int) {
repository.saveDailySteps(steps)
repository.saveAccumulatedDailySteps(steps)
repository.saveDateDailySteps(Date())
}
}

0 comments on commit d7e594e

Please sign in to comment.