Swift Error Description :
There are several types of handling errors within Swift.
When an error is thrown, the error will be of a particular error type which can be used to identify the specific nature of the error and to decide on the most appropriate course of action to be taken. The error type value can be any value that conforms to the ErrorType protocol.
enum of Errors Swift Function Throwing an Error Swift Throw Exception Errors Swift Exception Handling Methods Using try Keyword Exception handling in swift Using do-catch Statement Accessing the Error Object Disabling Error Catching Using the defer Statement
In addition to implementing methods in an app to throw errors when necessary, it is important to be aware that a number of API methods in the iOS SDK (particularly those relating to file handling) will throw errors which will need to be handled within the code of the iOS app.
Swift Error Types
Enum of Errors :
As an exception handling in swift example, consider a method that is required to transfer a file to a remote server. Such a method might fail to transfer the file for a variety of reasons such as there being no network connection, the connection being too slow or the failure to find the file to be transferred. All these possible errors could be represented within an enumeration that conforms to the Error protocol as follows.
enum FileTransferError: Error { case noConnection case lowBandwidth case fileNotFound }
Once an error type has been declared, it can be used within a method when throwing errors.
Swift Function Throwing an Error :
A swift handle errors method declares that it can throw an error using the throws keyword. For swift example.
func transferFile() throws { }
In the event that the function or method returns a result, the throws keyword is placed before the return type as follows.
func transferFile() throws -> Bool {
}
Swift Throw Exception Errors :
Once a method has been declared as being able to Swift throw errors, code can then be added to throw the errors when they are encountered. This is achieved using the throw statement in conjunction with the guard statement.
The following code declares some constants to serve as status values and then implements the guard and throw behavior for the method:
let connectionOK = true let connectionSpeed = 30.00 let fileFound = false enum FileTransferError: Error { case noConnection case lowBandwidth case fileNotFound } func fileTransfer() throws { guard connectionOK else { throw FileTransferError.noConnection } guard connectionSpeed > 30 else { throw FileTransferError.lowBandwidth } guard fileFound else { throw FileTransferError.fileNotFound } }
Within the body of the method, each guard statement checks a condition for a true or false result.
In the event of a false result, the code contained within the else body is executed. In the case of a false result, the throw statement is used to throw one of the error values contained in the FileTransferError enumeration.
Swift Exception Handling Methods Using try Keyword
Once a method or function is declared as throwing errors, it can no longer be called in the usual manner. Calls to such methods must now be prefixed by the try statement as follows.
try fileTransfer()
Exception handling in swift Using do-catch Statement
In addition to using the try statement, the call must also be made from within a do-catch statement to catch and handle any errors that may be thrown. Consider.
For exception handling in swift example, that the fileTransfer method needs to be called from within a method named sendFile. The code within this method might be implemented as follows.
func sendFile() -> String { do {try fileTransfer() } catch FileTransferError.noConnection { return("No Network Connection") } catch FileTransferError.lowBandwidth { return("File Transfer Speed too Low") } catch FileTransferError.fileNotFound { return("File not Found") } catch { return("Unknown error") } return("Successful transfer") }
The method calls the fileTransfer method from within a do-catch statement which, in turn, includes catch conditions for each of the three possible error conditions.
In each case, the method simply returns a string value containing a description of the error. In the event that no error was thrown, a string value is returned indicating a successful file transfer. Note that a fourth catch condition is included with no pattern matching. This is a "catch all" statement that ensures that any errors not matched by the preceding catch statements are also handled.
Swift also allows multiple matches to be declared within a single catch statement, with the list of matches separated by commas. For example, a single catch declaration could be used to handle both the noConnection and lowBandwidth errors as follows.
func sendFile() -> String { do {try fileTransfer() } catch FileTransferError.noConnection, FileTransferError.lowBandwidth { return("Connection problem") } catch FileTransferError.fileNotFound { return("File not Found") } catch { return("Unknown error") } return("Successful transfer") }
Accessing the Error Object :
When a method call fails, it will invariably return an Error object identifying the nature of the failure. A common requirement within the catch statement is to gain access to this object so that appropriate corrective action can be taken within the app code. The following code demonstrates how such an error object is accessed from within a catch statement when attempting to create a new file system directory.
do {try filemgr.createDirectory(atPath: newDir, withIntermediateDirectories: true, } catch let error { attributes: nil) print("Error: \(error.localizedDescription)") }
Disabling Error Catching :
A throwing method may be forced to run without the need to enclose the call within a do-catch statement by using the try! statement as follows.
try! fileTransfer
In using this approach we are informing the compiler that we know with absolute certainty that the method call will not result in an error being thrown. In the event that an error is thrown when using this technique, the code will fail with a runtime error.
Using The Defer Statement :
The previously implemented sendFile method demonstrated a common scenario when handling errors. Each of the catch clauses in the do-catch statement contained a return statement that returned control to the calling method.
In such a situation, however, it might be useful to be able to perform some other task before control is returned and regardless of the type of error that was encountered. The sendFile method might, for example, need to remove temporary files before returning. This behavior can be achieved using the defer statement.
The defer statement allows a sequence of code statements to be declared as needing to be run as soon as the method returns. In the following code, the sendFile method has been modified to include a defer statement:
func sendFile() -> String { defer { removeTmpFiles() closeConnection() } do {try fileTransfer() } catch FileTransferError.NoConnection { return("No Network Connection") } catch FileTransferError.LowBandwidth { return("File Transfer Speed too Low") } catch FileTransferError.FileNotFound { return("File not Found") } catch { return("Unknown error") } return("Successful transfer") }
With the defer statement now added, the calls to the removeTmpFiles and closeConnection methods will always be made before the method returns, regardless of which return call gets triggered.
- Swift Tutorial : Don't forget the heart of Swift Structures and Enumerations With Examples
- How to create Certificate Signing Request (CSR) in macOS (iOS) Keychain Access
- Implement Your Own Side Menu (Hamburger Menu) Swift
- Memory Management with ARC and Avoiding retain cycles with Weak and Unowned in Swift iOS
- How to Create an App ID and Bundle Identifier for your iOS App in Xcode
- Creating the iOS Development & Distribution Certificate and .p12 File
- How to convert an APNS token to String from Data in swift
------------------------------------------------------
0 Comments