As the title suggests, I have a class marked with @Observable. Within the class I have multiple var's. When one of my var's changes (formation), I want to run an updateOrCreateContent(). I had thought I could just do this with a bit of combine, but I'm struggling to get it working...
The code below has a compile error at $formation
When I mark formation @Published, it generates a different compile error: "Invalid redeclaration of synthesized property '_formation'"
any help appreciated
thanks
class LayoutModel {
var players: [Player] = []
var formation: Formation = .f433
var cancellables = Set<AnyCancellable>()
init(players: [Player], formation: Formation) {
self.players = players
self.formation = formation
updateOrCreateContent()
$formation.sink(receiveValue: { _ in
self.updateOrCreateContent()
})
.store(in: &cancellables)
}
Observation
RSS for tagMake responsive apps that update the presentation when underlying data changes.
Posts under Observation tag
30 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello 👋
I ran into a SwiftUI lifecycle gotcha while debugging a List with .refreshable
I share the code used to reproduce the issue
@Observable
final class CounterModel: Identifiable {
let id: String
var title: String
var value: Int
init(id: String, title: String, value: Int = 0) {
self.id = id
self.title = title
self.value = value
}
deinit {
print("deinit", title)
}
}
@Observable
final class ObservableCountersStore {
var counters: [CounterModel] = [
.init(id: "1", title: "A"),
.init(id: "2", title: "B"),
.init(id: "3", title: "C")
]
func refresh() async {
try? await Task.sleep(nanoseconds: 300_000_000)
counters = [.init(id: "4", title: "D")]
}
}
struct ObservableCountersListView: View {
@State private var store = ObservableCountersStore()
var body: some View {
List {
ForEach(store.counters) { counter in
ObservableCounterRow(counter: counter)
}
}
.refreshable {
await store.refresh()
}
}
}
struct ObservableCounterRow: View {
let counter: CounterModel
var body: some View {
Text(counter.title)
}
}
Observation:
After calling refresh(), only some of the previous CounterModel
only one CounterModel is deallocated immediately.
Others are retained
This doesn’t look like a leak, but it made me realize that passing observable
reference types directly into List rows leads to non-deterministic object
lifetimes, especially with .refreshable.
Posting this as a gotcha — curious if this matches intended behavior
or if others have run into the same thing.
Hi all,
I’m running into a “double update” effect in SwiftUI when using the @Observable with @State. I’m trying to understand whether this is expected behavior, a misuse on my side, or a potential bug.
Setup
I have an observable store using the Observation macro:
@Observable
class AlbumStore {
var albums: [Album] = [
Album(id: "1", title: "Album 1", author: "user1"),
Album(id: "2", title: "Album 2", author: "user1"),
Album(id: "3", title: "Album 3", author: "user1"),
Album(id: "4", title: "Album 4", author: "user1"),
Album(id: "5", title: "Album 5", author: "user1"),
Album(id: "6", title: "Album 6", author: "user1")
]
func addAlbum(_ album: Album) {
albums.insert(album, at: 0)
}
func removeAlbum(_ album: Album) {
albums.removeAll(where: { $0 == album })
}
}
In my view, I inject it via @Environment and also keep some local state:
@Environment(AlbumStore.self) var albumStore
@State private var albumToAdd: Album?
I derive a computed array that depends on both the environment store and local state:
private var filteredAlbums: [Album] {
let albums = albumStore.albums.filter { album in
if let albumToAdd {
return album.id != albumToAdd.id
} else {
return true
}
}
return albums
}
View usage
Inside a horizontal ScrollView / LazyHStack, I observe changes to filteredAlbums:
@ViewBuilder
private func carousel() -> some View {
GeometryReader { proxy in
let itemWidth: CGFloat = proxy.size.width / 3
let sideMargin = (proxy.size.width - itemWidth) / 2
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 20) {
ForEach(filteredAlbums, id: \.id) { album in
albumItem(album: album)
.frame(width: itemWidth)
.scrollTransition(.interactive, axis: .horizontal) { content, phase in
content
.scaleEffect(phase.isIdentity ? 1.0 : 0.8)
}
}
}
.scrollTargetLayout()
}
.scrollTargetBehavior(.viewAligned(limitBehavior: .always))
.scrollPosition(id: $carouselScrollID, anchor: .center)
.contentMargins(.horizontal, sideMargin, for: .scrollContent)
.onChange(of: filteredAlbums) { old, new in
print("filteredAlbums id: \(new.map { $0.id })")
}
}
}
Triggering the update
When I add a new album, I do:
albumToAdd = newAlbum
albumStore.addAlbum(newAlbum)
Expected behavior
Since filteredAlbums explicitly filters out albumToAdd, I expect the result to remain unchanged.
Actual behavior
I consistently get two onChange callbacks, in this order:
filteredAlbums id: ["E852E42A-AAEC-4360-A6A6-A95752805E2E", "1", "2", "3", "4", "5", "6"]
filteredAlbums id: ["1", "2", "3", "4", "5", "6"]
This suggests:
The AlbumStore update (albums.insert) is observed first.
The @State update (albumToAdd) is applied later.
As a result, filteredAlbums is recomputed twice with different dependency snapshots.
On a real iPad device, this also causes a visible scroll position jump.
In the simulator, the jump is not visually observable; however, the onChange(of: filteredAlbums) callback still fires twice with the same sequence of values, indicating that the underlying state update behavior is identical.
Strange observations
This does not happen with ObservableObject
If I replace @Observable with a classic ObservableObject + @Published:
class OBAlbumStore: ObservableObject {
@Published var albums: [Album] = [
Album(id: "1", title: "Album 1", author: "user1"),
Album(id: "2", title: "Album 2", author: "user1"),
Album(id: "3", title: "Album 3", author: "user1"),
Album(id: "4", title: "Album 4", author: "user1"),
Album(id: "5", title: "Album 5", author: "user1"),
Album(id: "6", title: "Album 6", author: "user1")
]
func addAlbum(_ album: Album) {
albums.insert(album, at: 0)
}
func removeAlbum(_ album: Album) {
albums.removeAll(where: { $0 == album })
}
}
…and inject it with @EnvironmentObject, the double update disappears.
Removing GeometryReader also avoids the issue
If I remove the surrounding GeometryReader and hardcode sizes:
@ViewBuilder
private func carousel() -> some View {
// GeometryReader { proxy in
let itemWidth: CGFloat = 400
let sideMargin: CGFloat = 410
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 20) {
ForEach(filteredAlbums, id: \.id) { album in
albumItem(album: album)
.frame(width: itemWidth)
.scrollTransition(.interactive, axis: .horizontal) { content, phase in
content
.scaleEffect(phase.isIdentity ? 1.0 : 0.8)
}
}
}
.scrollTargetLayout()
}
.scrollTargetBehavior(.viewAligned(limitBehavior: .always))
.scrollPosition(id: $carouselScrollID, anchor: .center)
.contentMargins(.horizontal, sideMargin, for: .scrollContent)
.onChange(of: filteredAlbums) { old, new in
print("filteredAlbums id: \(new.map { $0.id })")
}
// }
}
…the double onChange no longer occurs.
Questions
Is this update ordering expected when using @Observable and @State?
Does Observation intentionally propagate environment changes before local state updates?
Is GeometryReader forcing an additional evaluation pass that exposes this ordering?
Is this a known limitation / bug compared to ObservableObject?
I want to understand why this behaves differently under Observation.
Thanks in advance for any insights 🙏
Full Project Link
I'm trying to understand the behavior I'm seeing here. In the following example, I have a custom @Observable class that adopts RandomAccessCollection and am attempting to populate a List with it.
If I use an inner collection property of the instance (even computed as this shows), the top view identifies additions to the list.
However, if I just use the list as a collection in its own right, it detects when a change is made, but not that the change increased the length of the list. If you add text that has capital letters you'll see them get sorted correctly, but the lower list retains its prior count. The choice of a List initializer with the model versus an inner ForEach doesn't change the outcome, btw.
If I cast that type as an Array(), effectively copying its contents, it works fine which leads me to believe there is some additional Array protocol conformance that I'm missing, but that would be unfortunate since I'm not sure how I would have known that. Any ideas what's going on here? The new type can be used with for-in scenarios fine and compiles great with List/ForEach, but has this issue. I'd like the type to not require extra nonsense to be used like an array here.
import SwiftUI
fileprivate struct _VExpObservable6: View {
@Binding var model: ExpModel
@State private var text: String = ""
var body: some View {
NavigationStack {
VStack(spacing: 20) {
Spacer()
.frame(height: 40)
HStack {
TextField("Item", text: $text)
.textFieldStyle(.roundedBorder)
.textContentType(.none)
.textCase(.none)
Button("Add Item") {
guard !text.isEmpty else { return }
model.addItem(text)
text = ""
print("updated model #2 using \(Array(model.indices)):")
for s in model {
print("- \(s)")
}
}
}
InnerView(model: model)
OuterView(model: model)
}
.listStyle(.plain)
.padding()
}
}
}
// - displays the model data using an inner property expressed as
// a collection.
fileprivate struct InnerView: View {
let model: ExpModel
var body: some View {
VStack {
Text("Model Inner Collection:")
.font(.title3)
List {
ForEach(model.sorted, id: \.self) { item in
Text("- \(item)")
}
}
.border(.darkGray)
}
}
}
// - displays the model using the model _as the collection_
fileprivate struct OuterView: View {
let model: ExpModel
var body: some View {
VStack {
Text("Model as Collection:")
.font(.title3)
// - the List/ForEach collections do not appear to work
// by default using the @Observable model (RandomAccessCollection)
// itself, unless it is cast as an Array here.
List {
// ForEach(Array(model), id: \.self) { item in
ForEach(model, id: \.self) { item in
Text("- \(item)")
}
}
.border(.darkGray)
}
}
}
#Preview {
@Previewable @State var model = ExpModel()
_VExpObservable6(model: $model)
}
@Observable
fileprivate final class ExpModel: RandomAccessCollection {
typealias Element = String
var startIndex: Int { 0 }
var endIndex: Int { sorted.count }
init() {
_listData = ["apple", "yellow", "about"]
}
subscript(_ position: Int) -> String {
sortedData()[position]
}
var sorted: [String] {
sortedData()
}
func addItem(_ item: String) {
_listData.append(item)
_sorted = nil
}
private var _listData: [String]
private var _sorted: [String]?
private func sortedData() -> [String] {
if let ret = _sorted { return ret }
let ret = _listData.sorted()
_sorted = ret
return ret
}
}
I want to use the Observations AsyncSequence on some SwiftData @Model instances to determine if internal calculations need to be done.
When a simple property is linked to the Observations it fires CONTINUOUSLY even though no change is made to the model property.
Also, when I try to observe a property which is a list of another @Model type the Observations sequence does not fire when I add or remove items.
I am hoping to use the async-algorithm's merge function so all the associated sequences can be combined since if any of the associated events should fire the calculation event.
We can get informed on object changes through conforming to ObservableObject or having the @Observable macro attached to the type’s definition. How do you handle imported code that assumes the other observation technique?
In Getting started with In-App Purchase using StoreKit views and the corresponding sample project, Store simultaneously enumerates Transaction.unfinished and Transaction.updates.
Since, "if your app has unfinished transactions, the updates listener receives them once, immediately after the app launches," it appears that Transaction.unfinished would also receive the same unfinished transactions causing handle(updatedTransaction:) to be called for twice for each transaction, causing consumables to be double-counted.
Is this a bug in the sample? Is there more information on concurrent execution of unfinished and updates?
I’m facing an issue in our native iOS app that occurs specifically on iOS 26.1 (not observed on any lower versions). When I update a @State field value, the UI does not reflect the change as expected.
The @State variable updates internally, but the view does not re-render.
This behaviour started after upgrading to iOS 26.1.
Works fine on iOS 26.0 and earlier versions.
Has anyone else encountered this issue or found a workaround? Any insights or suggestions would be greatly appreciated.
I have two @Observable manager classes, which share a reference to a third class. I initialize this setup using a custom init in my App struct, like so:
@main
struct MyApp: App {
private let managerA: ManagerA
private let managerB: ManagerB
init() {
let managerC = ManagerC()
self.managerA = ManagerA(managerC: managerC)
self.managerB = ManagerB(managerC: managerC)
}
var body: some Scene {
WindowGroup {
ContentView()
.environment(managerA)
.environment(managerB)
}
}
}
I've been using this pattern for some time and it has been working fine. However, I just today discovered that @Observable objects are supposed to be initialized as @State vars, as shown in Apple's documentation here. This means I shoud be doing the following:
@main
struct MyApp: App {
@State private var managerA: ManagerA
@State private var managerB: ManagerB
init() {
let managerC = ManagerC()
self.managerA = ManagerA(managerC: managerC)
self.managerB = ManagerB(managerC: managerC)
}
var body: some Scene {
WindowGroup {
ContentView()
.environment(managerA)
.environment(managerB)
}
}
}
I've also seen some examples where the @State vars are initialized manually like this:
@main
struct MyApp: App {
@State private var managerA: ManagerA
@State private var managerB: ManagerB
init() {
let managerC = ManagerC()
let managerA = ManagerA(managerC: managerC)
let managerB = ManagerB(managerC: managerC)
self._managerA = State(initialValue: managerA)
self._managerB = State(initialValue: managerB)
}
var body: some Scene {
WindowGroup {
ContentView()
.environment(managerA)
.environment(managerB)
}
}
}
ChatGPT tells me the third approach is the correct one, but I don't understand why and ChatGPT can't produce a convincing explanation. The compiler doesn't produce any errors or warnings under each approach, and as far as I can tell, they all behave identically with no discernible difference in performance.
Does it matter which pattern I use? Is there a "correct" way?
Hello,
I’m building a health-related app for both watchOS and iOS, which needs to monitor certain health data (e.g., heart rate, active energy).
Before updating to watchOS 26, the queries worked reliably without any issues. However, after adapting to watchOS 26, some users have reported that health data updates stop being delivered.
What I’ve observed:
HKObserverQuery with enableBackgroundDelivery is set up normally.
On WatchOS 26, the query sometimes stops delivering updates entirely after a certain point, and once an update is missed, it may stop delivering further updates completely.
Restarting the Apple Watch temporarily restores delivery, but the problem reoccurs after some time.
This makes background health data monitoring unreliable for my app.
Here’s a simplified version of the code we are using:
guard let heartType = HKObjectType.quantityType(forIdentifier: .heartRate) else { return }
let query = HKObserverQuery(sampleType: heartType, predicate: nil) { query, completionHandler, error in
if let error = error {
logEvent("Observer error: \(error.localizedDescription)")
return
}
logEvent("Heart rate changed")
MyNotificationManager.shared.sendNotification() // Send a local notification
completionHandler()
}
healthStore.execute(query)
healthStore.enableBackgroundDelivery(for: heartType, frequency: .hourly) { success, error in
if success {
logEvent("Background heart rate delivery enabled")
} else {
logEvent("Failed to enable background heart rate delivery: \(error?.localizedDescription ?? "Unknown error")")
}
}
Could you please clarify:
Is this a known issue with HKObserverQuery and enableBackgroundDelivery on watchOS 26?
Are there any recommended workarounds or best practices to ensure continuous background delivery of health data?
Thank you in advance for your help.
Topic:
App & System Services
SubTopic:
Health & Fitness
Tags:
Health and Fitness
watchOS
HealthKit
Observation
Greetings,
With MacOS 15 Sequoia, Apple updated key-value-observations in such a way, that an unremoved observation by a now deallocated object will no longer cause an exception, when the observed object triggers said observation.
While this is fundamentally a positive change, the issue comes with the fact, that this change affects systems based on the version of their operating system and not the version of the operating system of the build system.
Many of our customers use old operating system versions and old hardware - meaning they can't easily update. Since we need to use up to date Xcode versions to develop for newer systems, our developers tend to have rather new OS versions.
This means, that we are increasingly facing bugs which only happen in customer systems but not in most developer (or QA) systems.
Currently, we still can use earlier OS versions with Xcode to fix these bugs, but once the used Xcode versions no longer support MacOS 14 or below this will become a major hurdle.
Are there known solutions to this issue?
We are currently attempting to swizzle observer adding and removal in order to fix the problem for old systems as well, but this has proven to be quite difficult and unstable. Since any weakly held property in the middle of an observation keypath can cause crashes, one would have to split up observations into multiple subobservations, which is less simple than it sounds, due to custom implementations of addObserver (such as there seems to be in array controller proxies) and collection operators.
Thanks for any suggestions!
Hi,
In the Apple Scrumdinger sample, the SpeechRecognizer class conforms to the Observable protocol:
public actor SpeechRecognizer: Observable {
public enum RecognizerError: Error {
case nilRecognizer
.
.
.
The developer help text suggests that the protocol conformance does not add observation functionality.
This class does not use the @Observable macro.
So, how does this work under the hood?
With the new @Observable macro, it looks like every time the struct of a view is reinitialized, any observable class marked as @State in the struct also gets reinitialized. Moreover, the result of the reinitialization immediately gets discarded.
This is in contrast to @StateObject and ObservableObject, where the class would only be initialized at the first creation of the view. The initialization method of the class would never be called again between view updates.
Is this a bug or an expected behavior? This redundant reinitialization causes performance issues when the init method of the observable class does anything slightly heavyweight.
Feedback ID: FB13697724
Although I can't see anything in Apple's documentation to this effect, I'm coming to believe that ReferenceFileDocument is incompatible with @Observable.
But hopefully I've just missed something!
I have an app in which the data model is @Observable, and views see it through
@Environment(dataModel.self) private var dataModel
Since there are a large number of views, only some of which may need to be redrawn at a given time, Apple's documentation leads me to believe that @Observable may be smarter about only redrawing views that actually need redrawing than @Published and @ObservedObject.
I originally wrote the app without document persistence, and injected the data model into the environment like this:
@main
struct MyApp: App {
@State private var dataModel = DataModel()
var body: some Scene {
WindowGroup {
myDocumentView()
.environment(dataModel)
}
}
}
I’ve been trying to make the app document based. Although I started using SwiftData, it has trouble with Codable (you need to explicitly code each element), and a long thread in the Developer forum suggests that SwiftData does not support the Undo manager - and in any event, simple JSON serialization is all that this app requires - not a whole embedded SQLLite database.
At first, it seems to be easy to switch to a DocumentGroup:
@main
struct MyApp: App {
var body: some Scene {
DocumentGroup(newDocument: {DataModel() } ) { file in
myDocumentView()
.environment(file.document) }
}
}
Since I've written everything using @Observable, I thought that I'd make my data model conform to ReferenceFileDocument like this:
import SwiftUI
import SwiftData
import UniformTypeIdentifiers
@Observable class DataModel: Identifiable, Codable, @unchecked Sendable, ReferenceFileDocument {
// Mark: ReferenceFileDocument protocol
static var readableContentTypes: [UTType] {
[.myuttype]
}
required init(configuration: ReadConfiguration) throws {
if let data = configuration.file.regularFileContents {
let decodedModel = try MyModel(json: data)
if decodedModel != nil {
self = decodedModel!
} else {
print("Unable to decode the document.")
}
} else {
throw CocoaError(.fileReadCorruptFile)
}
}
func snapshot(contentType: UTType) throws -> Data {
try self.json()
}
func fileWrapper(snapshot: Data,
configuration: WriteConfiguration) throws -> FileWrapper {
FileWrapper(regularFileWithContents: snapshot)
}
var nodes = [Node]() // this is the actual data model
init() {
newDocument()
}
... etc.
I've also tried a similar approach in which the ReferenceFileDocument is a separate module that serializes an instance of the data model.
The problem I'm currently experiencing is that I can't figure out how to:
a) inject the newly created, or newly deserialized data model into the environment so that views can take advantage of it's @Observable properties, or
b) how to cause changes in the @Observable data model to trigger serialization (actually I can observe them triggering serialization, but what's being serialized is an empty instance of the data model).
I make data model changes through a call to the Undo manager:
// MARK: - Undo
func undoablyPerform(_ actionName: String, with undoManager: UndoManager? = nil, doit: () -> Void) {
let oldNodes = self.nodes
doit()
undoManager?.registerUndo(withTarget: self) { myself in
self.undoablyPerform(actionName, with: undoManager) {
self.nodes = oldNodes
}
}
undoManager?.setActionName(actionName)
}
The views looks like this:
import SwiftUI
import CoreGraphics
struct myDocumentView: View {
@Environment(DataModel.self) private var dataModel
@Environment(\.undoManager) var undoManager
... etc.
Some things work - if I prepopulate the model, it serializes correctly, and gets written to a file.
Unfortunately, in the view hierarchy, myModel is always empty.
Have I done something wrong? Do I need to abandon @Observable?
I've tried conforming the model to ObservedObject, adding @Published, and injecting it as an @ObservedObject - and viewing as @EnvironmentObject var dataModel: DataModel
But it's still not injected correctly into the View hierarchy.
Edit - I may have identified the problem - will update this question when confirmed.
When I update a variable inside my model that is marked @Transient, my view does not update with this change. Is this normal? If I update a non-transient variable inside the model at the same time that I update the transient one, then both changes are propagated to my view.
Here is an example of the model:
@Model public class WaterData {
public var target: Double = 3000
@Transient public var samples: [HKQuantitySample] = []
}
Updating samples only does not propagate to my view.
The "What's new in UIKit" session introduces new observation tracking features and mentions that they are "on by default" in 26. Is it possible to disable this feature?
We have our own system built on ObservableObject that keeps our UIKit models/views in sync and triggers updates. We want to make sure there isn't contention between the new feature and our own.
@Observable seems not to work well with generic typed throw.
The following code using @Observable with non-generic typed throw builds good:
@Observable
class ThrowsLoadingViewModel<R, E: Error> {
private(set) var isLoading = true
private(set) var error: E? = nil
private(set) var data: R? = nil
private var task: () throws(Error) -> R
init(task: @escaping () throws(E) -> R) {
self.task = task
}
func load() {
do throws(Error) {
self.data = try task()
} catch {
// self.error = error
}
self.isLoading = false
}
}
But if I change Line 7 and 14 to generic, it'll breaks the build with a "Command SwiftCompile failed with a nonzero exit code" message :
@Observable
class ThrowsLoadingViewModel<R, E: Error> {
private(set) var isLoading = true
private(set) var error: E? = nil
private(set) var data: R? = nil
private var task: () throws(E) -> R
init(task: @escaping () throws(E) -> R) {
self.task = task
}
func load() {
do throws(E) {
self.data = try task()
} catch {
// self.error = error
}
self.isLoading = false
}
}
A the same time, if I remove @Observable, the generic typed throw works again:
class ThrowsLoadingViewModel<R, E: Error> {
private(set) var isLoading = true
private(set) var error: E? = nil
private(set) var data: R? = nil
private var task: () throws(E) -> R
init(task: @escaping () throws(E) -> R) {
self.task = task
}
func load() {
do throws(E) {
self.data = try task()
} catch {
// self.error = error
}
self.isLoading = false
}
}
Currently the possible solution seems to fall back to use ObservableObject...
According to docs, .focusedObject() usage should be moved to .focusedValue() when migrating to @Observable, but there is no .focusedSceneValue() overload that accepts Observable like with .focusedValue(). So how are we supposed migrate .focusedSceneObject() to @Observable?
Greetings i have an app that uses three different SwiftData models and i want to know what is the best way to use the them accross the app. I though a centralized behaviour and i want to know if it a correct approach.First let's suppose that the first view of the app will load the three models using the @Enviroment that work with @Observation. Then to other views that add data to the swiftModels again with the @Environment. Another View that will use the swiftData models with graph and datas for average and min and max.Is this a corrent way? or i should use @Query in every view that i want and ModelContext when i add the data.
@Observable
class CentralizedDataModels {
var firstDataModel: [FirstDataModel] = []
var secondDataModel: [SecondDataModel] = []
var thirdDataModel: [ThirdDataModel] = []
let context: ModelContext
init(context:ModelContext) {
self.context = context
}
}
I have an app in which the data model is @Observable, and views see it through @Environment(dataModel.self) private var dataModel.
Since there are a large number of views, only some of which may need to be redrawn at a given time, I believe that @Observable is more efficient at run time than @Published and @ObservedObject
I’ve been trying to make the app document based. Although I started using SwiftData, it has trouble with Codable, and a long thread in the Developer forum suggests that SwiftData does not support the Undo manager - and in any event, simple JSON serialization is all that this app requires.
Unfortunately, ReferenceFileDocument inherits from ObservableObject, which seems to not play nice with @Observable.
I’d like to keep using @Observable, but haven’t been able to figure out how. When I deserialize a JSON ReferenceFileDocument, I can’t seem to connect it to an @Observable class instance and to let the various views and view models know where to find and update it.
I’d appreciate advice on how to implement document persistence in this app.
Also, the default behaviour of DoumentGroup provides a nice menu to, another things, rename a new file to something other than Untitled xx, but it doesn’t appear to work (there is an extensive thread on the Developer website discussing this issue). Is there a solution to this problem?
Thanks for any help you can offer.