parent
7430a3842c
commit
5ea3c3f824
@ -0,0 +1,46 @@ |
||||
// |
||||
// CoreDataRequests.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 26/01/2023. |
||||
// |
||||
|
||||
import Foundation |
||||
|
||||
class CoreDataRequests { |
||||
|
||||
static func getOrCreateActivity(name: String) -> Activity { |
||||
|
||||
let context = PersistenceController.shared.container.viewContext |
||||
let request = Activity.fetchRequest() |
||||
request.predicate = NSPredicate(format: "name like %@", name) |
||||
|
||||
do { |
||||
let results = try context.fetch(request) |
||||
if let activity = results.first { |
||||
return activity |
||||
} |
||||
} catch { |
||||
print("error = \(error)") |
||||
} |
||||
let activity = Activity(context: context) |
||||
activity.name = name |
||||
return activity |
||||
} |
||||
|
||||
static func recordActivity(countdown: Countdown, dateInterval: DateInterval) throws { |
||||
|
||||
guard let activity = countdown.activity else { |
||||
return |
||||
} |
||||
|
||||
let context = PersistenceController.shared.container.viewContext |
||||
let record = Record(context: context) |
||||
record.start = dateInterval.start |
||||
record.end = dateInterval.end |
||||
record.activity = activity |
||||
|
||||
try context.save() |
||||
} |
||||
|
||||
} |
||||
@ -1,10 +1,20 @@ |
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21513" systemVersion="22A400" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="YES" userDefinedModelVersionIdentifier=""> |
||||
<entity name="Activity" representedClassName="Activity" syncable="YES" codeGenerationType="class"> |
||||
<attribute name="name" attributeType="String" defaultValueString=""/> |
||||
<relationship name="countdowns" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Countdown" inverseName="activity" inverseEntity="Countdown"/> |
||||
<relationship name="records" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Record" inverseName="activity" inverseEntity="Record"/> |
||||
</entity> |
||||
<entity name="Countdown" representedClassName="Countdown" syncable="YES" codeGenerationType="class"> |
||||
<attribute name="duration" attributeType="Double" defaultValueString="0" usesScalarValueType="YES"/> |
||||
<attribute name="image" optional="YES" attributeType="String"/> |
||||
<attribute name="name" optional="YES" attributeType="String"/> |
||||
<attribute name="order" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/> |
||||
<attribute name="sound" optional="YES" attributeType="Date" usesScalarValueType="NO"/> |
||||
<relationship name="activity" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Activity" inverseName="countdowns" inverseEntity="Activity"/> |
||||
</entity> |
||||
<entity name="Record" representedClassName="Record" syncable="YES" codeGenerationType="class"> |
||||
<attribute name="end" attributeType="Date" defaultDateTimeInterval="696425400" usesScalarValueType="NO"/> |
||||
<attribute name="start" attributeType="Date" defaultDateTimeInterval="696425400" usesScalarValueType="NO"/> |
||||
<relationship name="activity" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Activity" inverseName="records" inverseEntity="Activity"/> |
||||
</entity> |
||||
</model> |
||||
@ -0,0 +1,36 @@ |
||||
// |
||||
// PropertyWrappers.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 26/01/2023. |
||||
// |
||||
|
||||
import Foundation |
||||
|
||||
@propertyWrapper |
||||
struct UserDefault<T: Codable> { |
||||
let key: String |
||||
let defaultValue: T |
||||
|
||||
init(_ key: String, defaultValue: T) { |
||||
self.key = key |
||||
self.defaultValue = defaultValue |
||||
} |
||||
|
||||
var wrappedValue: T { |
||||
get { |
||||
|
||||
if let data = UserDefaults.standard.object(forKey: key) as? Data, |
||||
let user = try? JSONDecoder().decode(T.self, from: data) { |
||||
return user |
||||
|
||||
} |
||||
return defaultValue |
||||
} |
||||
set { |
||||
if let encoded = try? JSONEncoder().encode(newValue) { |
||||
UserDefaults.standard.set(encoded, forKey: key) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,40 @@ |
||||
// |
||||
// RecordsView.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 26/01/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct RecordsView: View { |
||||
|
||||
@FetchRequest( |
||||
sortDescriptors: [NSSortDescriptor(keyPath: \Record.start, ascending: false)], |
||||
animation: .default) |
||||
private var records: FetchedResults<Record> |
||||
|
||||
var body: some View { |
||||
|
||||
if records.isEmpty { |
||||
Text("You don't have any recorded activity yet") |
||||
} else { |
||||
List { |
||||
ForEach(records) { record in |
||||
HStack { |
||||
Text(record.activity?.name ?? "no activity") |
||||
Spacer() |
||||
Text(record.details) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
struct RecordsView_Previews: PreviewProvider { |
||||
static var previews: some View { |
||||
RecordsView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue