Closed FPST-08 closed 3 months ago
Hi @FPST-08,
If you use the UserDefaultsWhatsNewVersionStore
, the information about presented versions is stored in the UserDefaults and a property list file on disk. Resetting the simulator contents will remove this file and all other contents, resulting in the loss of information about which version has been presented. Consequently, the sheet will be presented "again" because there is no available information that the version has already been presented.
If you wish to further customize the behavior, consider writing your own implementation of a WhatsNewVersionStore
or WhatsNewEnvironment
.
Hi @SvenTiigi,
that makes sense. Why are you saving this information both in UserDefaults and a plist file?
I played a bit around with your package and I think this might be the best way. I am sorry for not making this a pull request.
This is a part from the file View+WhatsNewSheet.
`
public extension View {
/// Presents a WhatsNewView using the given WhatsNew object as a data source for the sheet’s content.
/// - Parameters:
/// - whatsNew: A Binding to an optional WhatsNew object
/// - versionStore: The optional WhatsNewVersionStore. Default value `nil`
/// - layout: The WhatsNew Layout. Default value `.default`
/// - onDismiss: The closure to execute when dismissing the sheet. Default value `nil`
func sheet(
whatsNew: Binding<WhatsNew?>,
versionStore: WhatsNewVersionStore? = nil,
layout: WhatsNew.Layout = .default,
onDismiss: (() -> Void)? = nil,
hideOnInitialInstall: Bool = false
) -> some View {
self.modifier(
ManualWhatsNewSheetViewModifier(
whatsNew: whatsNew,
versionStore: versionStore,
layout: layout,
onDismiss: onDismiss,
hideOnInitialInstall: hideOnInitialInstall
)
)
}
}
// MARK: - ManualWhatsNewSheetViewModifier
/// A Manual WhatsNew Sheet ViewModifier private struct ManualWhatsNewSheetViewModifier: ViewModifier {
// MARK: Properties
/// A Binding to an optional WhatsNew object
let whatsNew: Binding<WhatsNew?>
/// The optional WhatsNewVersionStore
let versionStore: WhatsNewVersionStore?
/// The WhatsNew Layout
let layout: WhatsNew.Layout
/// The closure to execute when dismissing the sheet
let onDismiss: (() -> Void)?
// Whether or not the sheet should be presented on initial launch
let hideOnInitialInstall: Bool
// MARK: ViewModifier
/// Gets the current body of the caller.
/// - Parameter content: The Content
func body(
content: Content
) -> some View {
// Check if a WhatsNew object is available
if let whatsNew = self.whatsNew.wrappedValue {
// Check if the WhatsNew Version has already been presented
if self.versionStore?.hasPresented(whatsNew.version) == true {
// Show content
content
} else if hideOnInitialInstall && ((self.versionStore?.presentedVersions.isEmpty) != nil) {
content
.onAppear {
versionStore?.save(presentedVersion: whatsNew.version)
}
} else {
// Show WhatsNew Sheet
content.sheet(
item: self.whatsNew,
onDismiss: self.onDismiss
) { whatsNew in
WhatsNewView(
whatsNew: whatsNew,
versionStore: self.versionStore,
layout: self.layout
)
}
}
} else {
// Otherwise show content
content
}
}
} ` I'll later try to use the intended GitHub tools for this but currently this is the best I can do. Is this something you would consider to implement?
Why are you saving this information both in UserDefaults and a plist file?
The UserDefaults API saves all key-value pairs in a property list by definition.
Happy to hear that this solution works for you đź‘Ť
As this implementation relies on if-statements within the body of a ViewModifier, I'm not considering to include it in this package which used by many other developers. This approach can lead to various issues, as described here.
I recommend using the automatic presentation mode and overriding the WhatsNewEnvironment
to implement a custom logic that determines which WhatsNew
object should be presented, as described here.
Is your feature request related to a problem?
First off big thanks for this package. I am not sure whether this is actually a bug or a missing feature. Every time I run an app (whether mine or your example) with a freshly reseted simulator the sheet is presented. This is a big problem for my app since I need to display a different sheet on initial install. Currently I cannot test if this behavior persists on a real device. Some more details: I use automatic presentation. The environment is set in the app struct and the sheet modifier is applied to the TabView in ContentView. I use the UserDefaults Store.
What solution would you like?
I would love if there was an option to not show the sheet when the app is opened for the first time.
What alternatives have you considered?
I tried applying the modifier in different locations but that obviously had no effect.
Any additional context?
No response