On iOS 13 I used to use optional @State properties to adapt views. In my case, the presented view would either create a new object (an assignment) if the state that is passed into it is nil, or edit the assignment if an assignment was passed in. This would be done in the action block of a Button and it worked beautifully.
On iOS 14 / Xcode 12 this no longer seems to work. Given the following code which creates a new assignment and passes it into the editor view when the user taps a "New Assignment" button, the value of assignment remains nil. Is anyone else experiencing similar behaviour?
struct ContentView: View {
		@Environment(\.managedObjectContext) var context
		@State var assignmentEditorIsPresented = false
		@State var assignment: Assignment? = nil
		var Body: some View {
				[...]
				Button("New Assignment", action: {
						self.assignment = Assignment(context: context)
						self.assignmentEditorIsPresented = true
				})
				.sheet(isPresented: assignmentEditorIsPresented) {
						[...]
				}
		}
}
What's even weirder is that I tried adding a random piece of state, an Int, to this view and modifying it right before the assignment state (between lines 9 and 10) and it didn't change either.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I wanted to be able to install both an App Store/Release version and a development version of my app on the same device and have them access different persistent stores, so I changed the bundle identifier of my app for the debug build configuration to "com.kevinolmats.Guru.debug", while the release configuration stayed as "com.kevinolmats.Guru". Since then, Xcode previews have completely stopped working. After a long build time, the canvas displays Cannot show preview: check whether the preview is compiled for the current scheme and OS of the device used for previewing.
The only things I have changed are:
the bundle identifier for the debug configuration
the product and bundle names (debug config is now Guru (debug))
added a new entitlements file for the debug configuration
Any ideas as to why my previews have stopped working? Enable previews is set to on, and the usual troubleshooting steps (restarting Xcode, my computer, deleting DerivedData) have not helped. The app runs perfectly fine otherwise--it's just previews that are broken.
I'm experiencing a new error in SwiftData since updating to Xcode 16/iOS 17 DB1. When passing in a model (Student) to a view and then displaying an array of Points using ForEach, I get the following fatal error:
SwiftData/ModelCoders.swift:2438: Fatal error: Failed to locate relationship for StringCodingKey(stringValue: "group", intValue: nil) on Entity - name: Point
superentity:
subentities:
storedProperties:
CompositeAttribute - name: type, options: [], valueType: PointType, defaultValue: nil
Properties:
Attribute - name: type, options: [], valueType: String, defaultValue: nil, hashModifier: nil
Relationship - name: outcome, options: [], valueType: Outcome, destination: Outcome, inverseName: nil, inverseKeypath: nil
CompositeAttribute - name: proficiency, options: [], valueType: Proficiency, defaultValue: nil
Properties:
Attribute - name: proficiency, options: [], valueType: String, defaultValue: nil, hashModifier: nil
Attribute - name: date, options: [], valueType: Date, defaultValue: nil, hashModifier: nil
Attribute - name: note, options: [], valueType: String, defaultValue: nil, hashModifier: nil
Relationship - name: student, options: [], valueType: Optional<Student>, destination: Student, inverseName: points, inverseKeypath: Optional(\Student.points)
Attribute - name: group, options: [], valueType: Array<PersistentIdentifier>, defaultValue: [], hashModifier: nil
inheritedProperties:
uniquenessConstraints:
indices:
Xcode flags this line of the macro-generated getter of the outcome property on Point:
@storageRestrictions(accesses: _$backingData, initializes: _outcome)
init(initialValue) {
_$backingData.setValue(forKey: \.outcome, to: initialValue)
_outcome = _SwiftDataNoType()
}
get {
_$observationRegistrar.access(self, keyPath: \.outcome)
return self.getValue(forKey: \.outcome) // Fatal error: Failed to locate relationship for StringCodingKey...
}
set {
_$observationRegistrar.withMutation(of: self, keyPath: \.outcome) {
self.setValue(forKey: \.outcome, to: newValue)
}
}
This worked just fine in iOS 17. Here's a snippet of the Student implementation:
@Model
class Student: Identifiable, Comparable {
var name: String
var number: Int
@Relationship(deleteRule: .cascade, inverse: \Point.student) var points: [Point]
@Relationship(deleteRule: .cascade, inverse: \Mark.student) var marks: [Mark]
@Relationship(deleteRule: .nullify, inverse: \StudentGroup.students) var groups: [StudentGroup] = []
var archived: Bool
}
and the implementation of Point:
@Model
class Point: Identifiable, Comparable {
var student: Student?
var type: PointType
var outcome: Outcome
var proficiency: Proficiency
var group: [Student.ID] = []
var date: Date
var note: String
}
and finally the implementation for Outcome:
@Model
class Outcome: Identifiable, Comparable {
var name: String
var index: Int
var rubric: Rubric?
var proficiencies: [Proficiency]
}
I've tried adding a relationship in Outcome as an inverse of the outcomes property on Points (although this does not make sense in my implementation, which is why I initially did not set a relationship here) and the problem persisted.
Any ideas what this error means and how I might go about fixing it?
I'm working on an app that uses HomeKit-enabled accessories such as wall plugs to control a photographic enlarger in a darkroom. This requires precise timing when toggling the power state of the plug. For example, the timer in my app might be set to 5 seconds, so I turn on the plug using writeValue() on the plugs power state characteristic, wait 5 seconds, then turn it off again.
I want to be able to measure if the plug actually responded to the command and if there was any delay in the plug actually turning on/off so I can display a warning to the user if network latency resulted in the plug being on for longer than the set time.
Does writeValue() (in my case, the async/await version) only return when the plug has been turned on, or does it return as soon as the command has been sent, regardless of if it has been received/acted on? Is there a way I can (a) quickly verify that the plug has been turned on/off, and (b) measure how long it took for the plug to act on the request, that is, the time elapsed between when writeValue() is called and when the plug actually updates to the corresponding value?
I’ve been trying to figure out a way to copy adjustments made in the native Photos app on macOS to a different photo using PhotoKit or Swift.
My DSLR sends lower quality versions of every photo it takes right to my phone as it takes them, but when I get around to importing the high res copies from the SD card, I’d like to be able to easily copy the favourited status and any edits I may have made to the high res versions.
Copying the isFavourite status and removing the duplicate files was easy, but I can’t figure out a way to copy edits over to the higher quality file. I figured since it’s an easy copy/paste in Photos that it shouldn’t be too difficult with code.
Has anyone managed to pull this off?