Swift - Assertions and Precondition



Swift provides two special mechanisms: assertions and preconditions which allow the developers to enforce some special conditions in their programs for debugging and ensuring the correctness of the program. Both methods create robust and reliable Swift applications by catching and addressing unexpected situations occurring during the different stages of application development.

Swift Assertions

Assertion is a powerful debugging tool to check and fix errors or bugs in the development process of an application. Or we can say that its main purpose is to catch and identify errors or bugs at the runtime. It is represented in a boolean condition, if the condition is evaluated to true, then the program will continue its execution. Whereas if the condition is evaluated as false, then the execution of the program will end. Assertion is non-recoverable, which means if the assertion fails we cannot recover it or catch it. We can achieve assertion using the assert() function.

The assert(_:_:file:line) function performs a runtime check during the development. Or we can say that it implements C-style assert.

Syntax

Following is the syntax for the assert() function −

func assert(_condition: @autoclosure()->Bool,
_message: @autoclosure() -> String = String(),
file: StaticString = #file,
line: UInt = #line)

Parameters

This function takes the following parameters −

  • condition − It represents the test condition.

  • message − It represents the message that will be displayed when the condition is set to false. By default, its value is empty.

  • file − It represents the file name where the assertion is present and will display along with the message if the assertion is failed. It is an optional parameter.

  • line − It represents the line number where the assertion is present and will display along with the message if the assertion is failed. It is an optional parameter.

Example

import Foundation

func validateMarks(_ marks: Int) {

   // Assert that the marks is non-negative
   // If the given condition fails, then the program will terminated 
   // And will display this message
   assert(marks >= 0, "Marks must be non-negative value")
    
   print("Marks are valid")
}
validateMarks(345)

Output

Marks are valid

Example

If we enter marks in the negative, then the given condition in the assert will fail and our program will end.

import Foundation

func validateMarks(_ marks: Int) {

   // Assert that the marks is non-negative
   // If the given condition fails, then the program will terminated 
   // And will display this message
   assert(marks >= 0, "Marks must be non-negative value")
    
   print("Marks are valid")
}
validateMarks(-39)

Output

main/main.swift:8: Assertion failed: Marks must be non-negative value
Current stack trace:
0    libswiftCore.so                    0x00007f8870bbcdc0 _swift_stdlib_reportFatalErrorInFile + 112
1    libswiftCore.so                    0x00007f887088691c <unavailable> + 1444124
2    libswiftCore.so                    0x00007f8870886738 <unavailable> + 1443640
3    libswiftCore.so                    0x00007f8870885220 _assertionFailure(_:_:file:line:flags:) + 419
6    swift-frontend                     0x0000557401fc6b3d <unavailable> + 26479421
7    swift-frontend                     0x00005574012fadb9 <unavailable> + 13061561
8    swift-frontend                     0x00005574010cb4c6 <unavailable> + 10769606
9    swift-frontend                     0x00005574010c79b6 <unavailable> + 10754486
.......................................................................
....................................................................
..................................................................

Swift Precondition

Precondition is used to catch and handle unexpected states and assumptions at the time of execution of the code. Or we can say that precondition helps the developer to find issues in the production state of the application.

It is also represented in a boolean condition, if the condition is evaluated to true, then the program will continue its execution. Whereas if the condition is evaluated as false, then the execution of the program will end. It is also non-recoverable. We can achieve precondition using the precondition() function.

The precondition(_:_:file:line) function is used to enforce a condition during the execution of the program

Syntax

Following is the syntax for the assert() function −

func precondition(_condition: @autoclosure()->Bool,
_message: @autoclosure() -> String = String(),
file: StaticString = #file,
line: UInt = #line)

Parameters

This function takes the following parameters −

  • condition − It represents the test condition.

  • message − It represents the message that will be displayed when the condition is set to false. By default, its value is empty.

  • file − It represents the file name where the precondition is present and will display along with the message if the precondition is failed. It is an optional parameter.

  • line − It represents the line number where the precondition is present and will display along with the message if the precondition is failed. It is an optional parameter.

Example

import Foundation

func modulus(_ num: Int, by deno: Int) -> Int {

   // Ensure that the denominator is not zero before performing the modulus
   precondition(deno != 0, "The value of denominator must be non-zero")

   return num % deno
}

let output = modulus(19, by: 3)
print("Result: \(output)")  

Output

Result: 1

Example

If we enter a zero denominator, then the given condition in the precondition will fail and our program will end.

import Foundation

func modulus(_ num: Int, by deno: Int) -> Int {

   // Ensure that the denominator is not zero before performing the modulus
   precondition(deno != 0, "The value of denominator must be non-zero")

   return num % deno
}

let output = modulus(19, by: 0)
print("Result: \(output)")  

Output

main/main.swift:6: Precondition failed: The value of denominator must be non-zero
Current stack trace:
0    libswiftCore.so                    0x00007fbee7245dc0 _swift_stdlib_reportFatalErrorInFile + 112
1    libswiftCore.so                    0x00007fbee6f0f91c <unavailable> + 1444124
2    libswiftCore.so                    0x00007fbee6f0f738 <unavailable> + 1443640
3    libswiftCore.so                    0x00007fbee6f0e220 _assertionFailure(_:_:file:line:flags:) + 419
6    swift-frontend                     0x0000558e85a69b3d <unavailable> + 26479421
7    swift-frontend                     0x0000558e84d9ddb9 <unavailable> + 13061561
8    swift-frontend                     0x0000558e84b6e4c6 <unavailable> + 10769606
9    swift-frontend                     0x0000558e84b6a9b6 <unavailable> + 10754486
.......................................................................
....................................................................
..................................................................
Advertisements