I have a modal presented Sheet
which should display based on a UserDefault
bool.
I wrote a UI-Test which dismisses the sheet and I use launch arguments to control the defaults value.
However, when I tried using @AppStorage
initially it didn't seem to persist the value, or was secretly not writing it? My test failed as after 'dismissing' the modal pops back up as the value is unchanged.
To work around this I wrote a custom binding. But i'm not sure what the behaviour difference is between the two implementations? The test passes this way.
Does anyone know what i'm not understanding sorry?
Cheers!
Simple Example
1. AppStorage
struct ContentView: View {
@AppStorage("should.show.sheet") private var binding: Bool = true
var body: some View {
Text("Content View")
.sheet(isPresented: $binding) {
Text("Sheet")
}
}
}
2. Custom Binding:
struct ContentView: View {
var body: some View {
let binding = Binding<Bool> {
UserDefaults.standard.bool(forKey: "should.show.sheet")
} set: {
UserDefaults.standard.set($0, forKey: "should.show.sheet")
}
Text("Content View")
.sheet(isPresented: binding) {
Text("Sheet")
}
}
}
Test Case:
final class SheetUITests: XCTestCase {
override func setUpWithError() throws {
continueAfterFailure = false
}
func testDismiss() {
// Given 'true' userdefault value to show sheet on launch
let app = XCUIApplication()
app.launchArguments += ["-should.show.sheet", "<true/>"]
app.launch()
// When the user dismisses the modal view
app.swipeDown()
// Wait a second for animation (make sure it doesn't pop back)
sleep(1)
// Then the sheet should not be displayed
XCTAssertFalse(app.staticTexts["Sheet"].exists)
}
}