- Open
ACE_RFID_iOS.xcodeprojin Xcode - Right-click on
ACE_RFID_iOSfolder in Project Navigator - Select "Add Files to ACE_RFID_iOS..."
- Select these 4 files:
SettingsModel.swiftSettingsView.swiftTagDetailsModel.swiftTagDetailsView.swift
- Make sure "Copy items if needed" is checked
- Click "Add"
Add these at the top with other @State variables:
@StateObject private var settings = AppSettings.shared
@State private var showingSettings = false
@State private var showingTagDetails = false
@State private var currentTagDetails: TagDetails?Add Settings button to toolbar (after the Reset button):
ToolbarItem(placement: .navigationBarTrailing) {
Button {
showingSettings = true
} label: {
Image(systemName: "gearshape")
}
.accessibilityLabel("Settings")
}Add sheets after the existing ones:
.sheet(isPresented: $showingSettings) {
SettingsView(settings: settings)
}
.sheet(isPresented: $showingTagDetails) {
if let details = currentTagDetails {
TagDetailsView(details: details)
}
}Update resetToDefaults() to use settings:
private func resetToDefaults() {
withAnimation(.spring(response: 0.3)) {
selectedProfile = nil
selectedColor = .blue
selectedSpoolSize = settings.defaultSpoolSize // Use setting
nfcManager.tagUID = ""
nfcManager.tagType = ""
nfcManager.lastReadData = nil
nfcManager.lastReadBytes = nil
nfcManager.tagLockStatus = ""
nfcManager.statusMessage = ""
}
}When tag is read successfully, show details:
.onChange(of: nfcManager.lastReadBytes) { newBytes in
if let bytes = newBytes, let tagData = RFIDTagData.fromBytes(bytes, database: filamentDB) {
withAnimation(.spring(response: 0.3)) {
selectedProfile = tagData.profile
selectedColor = tagData.color
selectedSpoolSize = tagData.spoolSize
nfcManager.lastReadData = tagData
}
// Create and show tag details
if !nfcManager.tagUID.isEmpty {
currentTagDetails = TagDetails(
uid: nfcManager.tagUID,
tagType: nfcManager.tagType,
memoryUsed: bytes.count,
memoryTotal: 504, // Adjust based on tag type
readDate: Date(),
hasData: true,
dataType: tagData.profile.displayName
)
showingTagDetails = true
}
}
}Add .accessibilityLabel() to all interactive elements. Examples:
// For buttons in ActionButtonsCard
Button("Write to Tag") {
// ...
}
.accessibilityLabel("Write filament data to tag")
.accessibilityHint("Hold iPhone near NFC tag to write")
// For color picker button
Button {
showingColorPicker = true
} label: {
// ...
}
.accessibilityLabel("Select filament color")
.accessibilityValue("Currently \(colorDescription(selectedColor))")
// For spool size picker
Picker("Size", selection: $selectedSpoolSize) {
// ...
}
.accessibilityLabel("Spool size")
.accessibilityValue(selectedSpoolSize.displayName)Add at top of class:
@Published var tagDetails: TagDetails?In playSuccessHaptic(), playErrorHaptic(), playDetectionHaptic():
func playSuccessHaptic() {
guard AppSettings.shared.hapticFeedbackEnabled else { return }
// ... existing code
}In performWrite, check auto-verify setting:
if success {
DispatchQueue.main.async {
self.statusMessage = "✅ Write complete"
if AppSettings.shared.autoVerifyEnabled {
self.statusMessage += " - Starting verification..."
}
self.playSuccessHaptic()
}
if AppSettings.shared.autoVerifyEnabled {
// ... existing verify code
} else {
session.alertMessage = "✅ Write complete!"
session.invalidate()
}
}Create a helper function in FilamentModel.swift or ContentView:
func temperatureWarning(for profile: FilamentProfile) -> String? {
let extruderMid = (profile.temperatures.extruderMin + profile.temperatures.extruderMax) / 2
let bedMid = (profile.temperatures.bedMin + profile.temperatures.bedMax) / 2
switch profile.type {
case .pla, .plaPlus:
if extruderMid > 230 {
return "⚠️ High temperature for PLA"
}
case .abs:
if extruderMid < 220 || extruderMid > 260 {
return "⚠️ Unusual temperature for ABS"
}
case .petg:
if extruderMid < 220 || extruderMid > 260 {
return "⚠️ Unusual temperature for PETG"
}
default:
break
}
return nil
}Display warning in SpoolConfigCard:
if let profile = selectedProfile, let warning = temperatureWarning(for: profile) {
Label(warning, systemImage: "exclamationmark.triangle.fill")
.font(.caption)
.foregroundColor(.orange)
.padding(.top, 4)
}- Build the project (Cmd+B)
- Fix any compilation errors
- Run on device or simulator
- Test:
- Settings screen opens and saves preferences
- Tag details appear after reading
- Temperature warnings show for unusual temps
- VoiceOver reads all labels correctly
- Haptic feedback respects settings
Widgets require:
- New Widget Extension target in Xcode
- App Groups for shared data
- WidgetKit implementation
- Timeline provider
- Deep linking
This is a separate, larger task that should be done in a future update.
Files not building:
- Make sure they're added to target membership
- Check File Inspector → Target Membership → ACE_RFID_iOS
Settings not persisting:
- Check UserDefaults keys are unique
- Test on device (simulator can have issues)
VoiceOver not working:
- Enable VoiceOver: Settings → Accessibility → VoiceOver
- Test with triple-click home/side button shortcut
Haptics not working:
- Must test on physical device
- Simulator doesn't support haptics