Enhancing SwiftUI Alerts : A Reusable Approach with Unit and UI Testing

Why Do We Need a Reusable Alert View? When building an app, we often display alerts in different places like this: VStack { Button(action: { viewModel.showAlert1() }) { Text("Show Alert1") } .alert("Alert1", isPresented: $isShowingAlert1) { Button(role: .cancel, action: { print("do something") viewModel.isShowingAlert1 = false }) { Text("OK") } } message: { Text("Alert1 message") } Button(action: { viewModel.showAlert2() }) { Text("Show Alert2") } .alert("Alert2", isPresented: $isShowingAlert2) { Button(role: .cancel, action: { print("do something") viewModel.isShowingAlert2 = false }) { Text("Action1") } Button(action: { print("do something") viewModel.isShowingAlert2 = false }) { Text("Action2") } } message: { Text("Alert2 message") } Button(action: { viewModel.showAlert3() }) { Text("Show Alert3") } .alert("Alert3", isPresented: $isShowingAlert3) { Button(role: .cancel, action: { print("do something") viewModel.isShowingAlert3 = false }) { Text("Action1") } Button(action: { print("do something") viewModel.isShowingAlert3 = false }) { Text("Action2") } Button(action: { print("do something") viewModel.isShowingAlert3 = false }) { Text("Action3") } } message: { Text("Alert3 message") } } As you can see, each alert follows the same structure: a title, a message, and buttons. Instead of duplicating similar code, let’s create a reusable alert system to keep our code clean and maintainable. Please feel free to leave a comment. I'm happy to discuss my code to improve!

Feb 17, 2025 - 21:41
 0
Enhancing SwiftUI Alerts : A Reusable Approach with Unit and UI Testing

Why Do We Need a Reusable Alert View?

When building an app, we often display alerts in different places like this:

VStack {
    Button(action: {
        viewModel.showAlert1()
    }) {
        Text("Show Alert1")
    }
    .alert("Alert1", isPresented: $isShowingAlert1) {
        Button(role: .cancel, action: {
            print("do something")
            viewModel.isShowingAlert1 = false
        }) {
            Text("OK")
        }
    } message: {
        Text("Alert1 message")
    }

    Button(action: {
        viewModel.showAlert2()
    }) {
        Text("Show Alert2")
    }
    .alert("Alert2", isPresented: $isShowingAlert2) {
        Button(role: .cancel, action: {
            print("do something")
            viewModel.isShowingAlert2 = false
        }) {
            Text("Action1")
        }
        Button(action: {
            print("do something")
            viewModel.isShowingAlert2 = false
        }) {
            Text("Action2")
        }
    } message: {
        Text("Alert2 message")
    }

    Button(action: {
        viewModel.showAlert3()
    }) {
        Text("Show Alert3")
    }
    .alert("Alert3", isPresented: $isShowingAlert3) {
        Button(role: .cancel, action: {
            print("do something")
            viewModel.isShowingAlert3 = false
        }) {
            Text("Action1")
        }
        Button(action: {
            print("do something")
            viewModel.isShowingAlert3 = false
        }) {
            Text("Action2")
        }
        Button(action: {
            print("do something")
            viewModel.isShowingAlert3 = false
        }) {
            Text("Action3")
        }
    } message: {
        Text("Alert3 message")
    }
}

As you can see, each alert follows the same structure: a title, a message, and buttons. Instead of duplicating similar code, let’s create a reusable alert system to keep our code clean and maintainable.

Please feel free to leave a comment. I'm happy to discuss my code to improve!