parent
7a9ae3f7ff
commit
ef1bfb7352
@ -0,0 +1,52 @@ |
||||
<?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="AbstractSoundTimer" representedClassName="AbstractSoundTimer" isAbstract="YES" parentEntity="AbstractTimer" elementID="soundList" syncable="YES"> |
||||
<attribute name="confirmationSoundList" optional="YES" attributeType="String"/> |
||||
<attribute name="playableIds" optional="YES" attributeType="String" elementID="soundList"/> |
||||
<attribute name="repeatCount" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/> |
||||
</entity> |
||||
<entity name="AbstractTimer" representedClassName="AbstractTimer" isAbstract="YES" syncable="YES"> |
||||
<attribute name="image" optional="YES" attributeType="String"/> |
||||
<attribute name="order" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/> |
||||
<relationship name="activity" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Activity" inverseName="timers" inverseEntity="Activity"/> |
||||
</entity> |
||||
<entity name="Activity" representedClassName="Activity" syncable="YES"> |
||||
<attribute name="name" attributeType="String" defaultValueString=""/> |
||||
<relationship name="records" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="Record" inverseName="activity" inverseEntity="Record"/> |
||||
<relationship name="timers" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="AbstractTimer" inverseName="activity" inverseEntity="AbstractTimer"/> |
||||
</entity> |
||||
<entity name="Alarm" representedClassName="Alarm" parentEntity="AbstractSoundTimer" syncable="YES"> |
||||
<attribute name="fireDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/> |
||||
</entity> |
||||
<entity name="Countdown" representedClassName="Countdown" parentEntity="AbstractSoundTimer" syncable="YES"> |
||||
<attribute name="duration" attributeType="Double" defaultValueString="0" usesScalarValueType="YES"/> |
||||
<relationship name="group" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="IntervalGroup" inverseName="countdown" inverseEntity="IntervalGroup"/> |
||||
</entity> |
||||
<entity name="CustomSound" representedClassName="CustomSound" syncable="YES"> |
||||
<attribute name="file" optional="YES" attributeType="String"/> |
||||
<attribute name="text" optional="YES" attributeType="String"/> |
||||
</entity> |
||||
<entity name="Interval" representedClassName="Interval" syncable="YES"> |
||||
<attribute name="duration" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/> |
||||
<attribute name="soundList" optional="YES" attributeType="String"/> |
||||
<relationship name="group" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="IntervalGroup" inverseName="intervals" inverseEntity="IntervalGroup"/> |
||||
</entity> |
||||
<entity name="IntervalGroup" representedClassName="IntervalGroup" syncable="YES"> |
||||
<attribute name="repeatCount" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/> |
||||
<relationship name="countdown" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Countdown" inverseName="group" inverseEntity="Countdown"/> |
||||
<relationship name="intervals" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="Interval" inverseName="group" inverseEntity="Interval"/> |
||||
</entity> |
||||
<entity name="Record" representedClassName="Record" syncable="YES"> |
||||
<attribute name="duration" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/> |
||||
<attribute name="end" attributeType="Date" defaultDateTimeInterval="696425400" usesScalarValueType="NO"/> |
||||
<attribute name="month" optional="YES" attributeType="Integer 16" usesScalarValueType="YES"/> |
||||
<attribute name="start" attributeType="Date" defaultDateTimeInterval="696425400" usesScalarValueType="NO"/> |
||||
<attribute name="year" optional="YES" attributeType="Integer 16" usesScalarValueType="YES"/> |
||||
<relationship name="activity" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Activity" inverseName="records" inverseEntity="Activity"/> |
||||
</entity> |
||||
<entity name="Stopwatch" representedClassName="Stopwatch" parentEntity="AbstractSoundTimer" syncable="YES"> |
||||
<attribute name="end" optional="YES" attributeType="Date" usesScalarValueType="NO"/> |
||||
<attribute name="sound" optional="YES" attributeType="Integer 16" usesScalarValueType="YES"/> |
||||
<attribute name="start" optional="YES" attributeType="Date" usesScalarValueType="NO"/> |
||||
</entity> |
||||
</model> |
||||
@ -0,0 +1,45 @@ |
||||
// |
||||
// Extensions.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 28/03/2023. |
||||
// |
||||
|
||||
import Foundation |
||||
|
||||
// MARK: - Storage convenience |
||||
|
||||
let idSeparator = "|" |
||||
let numberFormatter: NumberFormatter = NumberFormatter() |
||||
|
||||
extension String { |
||||
|
||||
func enumItems<T : RawRepresentable<Int>>() -> [T] { |
||||
let ids: [String] = self.components(separatedBy: idSeparator) |
||||
let intIds: [Int] = ids.compactMap { numberFormatter.number(from: $0)?.intValue } |
||||
return intIds.compactMap { T(rawValue: $0) } |
||||
} |
||||
|
||||
} |
||||
|
||||
//extension Sequence where Element : RawRepresentable<Int> { |
||||
// var stringRepresentation: String { |
||||
// let ids = self.compactMap { formatter.string(from: NSNumber(value: $0.rawValue)) } |
||||
// return ids.joined(separator: separator) |
||||
// } |
||||
//} |
||||
|
||||
extension Sequence where Element : StringRepresentable { |
||||
var stringRepresentation: String { |
||||
let ids = self.compactMap { $0.stringValue } |
||||
return ids.joined(separator: idSeparator) |
||||
} |
||||
} |
||||
|
||||
protocol StringRepresentable { |
||||
var stringValue: String { get } |
||||
} |
||||
|
||||
extension String: StringRepresentable { |
||||
var stringValue: String { self } |
||||
} |
||||
Loading…
Reference in new issue