Files
Gas-Tank-AR-App/GasTankAR/Model/Project.swift
2026-09-02 20:54:36 +02:00

82 lines
2.5 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Project.swift
// GasTankAR
//
// Created by Dennis Nemec on 25.08.26.
//
import Foundation
import SwiftData
import ARKit
@Model
final class Project {
/// Identifier given by the user for the project. In DOCUframe terms
/// it is the LeadID.
var leadID: String
/// Customer name to link the project to.
var customerName: String
var creationDate: Date
/// Der für das Projekt ausgewählte Tank. Jedes Projekt hat genau einen Tank.
/// `Tank` ist `Codable`, daher persistiert SwiftData das direkt als Attribut.
var tank: Tank
/// Archivierte `ARWorldMap` (via `NSKeyedArchiver`). Wegen der Größe extern gespeichert.
@Attribute(.externalStorage) var worldMapData: Data?
/// Welt-Transform des platzierten Tanks (Position, Rotation, Skalierung) als
/// 16 Floats (spaltenweise). Zusammen mit der WorldMap wird der Tank so wiederhergestellt.
var tankTransform: [Float]?
/// Im AR-Modus aufgenommene Fotos. Werden beim Löschen des Projekts mitentfernt.
@Relationship(deleteRule: .cascade, inverse: \ProjectPhoto.project)
var photos: [ProjectPhoto] = []
init(
leadID: String,
customerName: String,
creationDate: Date,
tank: Tank = Tank(),
worldMapData: Data? = nil,
tankTransform: [Float]? = nil
) {
self.leadID = leadID
self.customerName = customerName
self.creationDate = creationDate
self.tank = tank
self.worldMapData = worldMapData
self.tankTransform = tankTransform
}
/// Human-readable title combining the lead identifier and customer name.
var title: String {
"\(leadID) – \(customerName)"
}
/// Up to two uppercased initials derived from the customer name, for use as an avatar.
var initials: String {
let letters = customerName
.split(whereSeparator: { $0 == " " || $0 == "&" })
.prefix(2)
.compactMap { $0.first }
return String(letters).uppercased()
}
/// Gespeicherte Session der getrackten Welt. (De-)serialisiert `worldMapData`.
/// Berechnete Property – wird von SwiftData nicht persistiert.
var worldMap: ARWorldMap? {
get {
guard let worldMapData else { return nil }
return try? NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: worldMapData)
}
set {
worldMapData = newValue.flatMap {
try? NSKeyedArchiver.archivedData(withRootObject: $0, requiringSecureCoding: true)
}
}
}
}