FirewallApp Graphical User Interface (GUI) was designed by using Apple technologies introduced at WWDC2019 – such as SwiftUI and Combine.
SwiftUI was chosen due to the fact that a finished application can be easily ported to a mobile platform. Furthermore, it provides a comprehensive set of features in terms of speed and ease of development.
Combine (that was also used in SwiftUI) was utilized to simplify asynchronous interactions.
The main difficulties while using SwiftUI included: the development via the beta version of macOS 10.16 and Xcode 11 as well as the lack of comprehensive documentation. As a result, when an unwanted behavior occurred, it was not clear whether it was due to a SwiftUI error or incorrect usage of this tool.
To solve such issues — various versions of the code were deployed and in case of failures, a test application was written and these issues were put on hold until the next macOS beta version. In general, most problems were resolved in the release version of macOS, but some of them required using NSViewRepresentable:
- To display the list of applications in the main window, the options to use the SwiftUI List or ForEach structures inside ScrollView were applied. However, even with a small number of records (15-20) and with an active application list reordering, visual glitches occurred. To work around this problem, FastList (FastList.swift) was deployed. It helps implement such SwiftUI lists using NSTableView. It also provides a noteworthy method to update elements (var elements: [Element]) and FastListTableView that has an overloaded function validateProposedFirstResponder (_ responder: NSResponder, for event: NSEvent?). Thus, events reach the NSTextField class inside the table.
- NSAttributedString is used to display RTF (a text with images or another complex formatting) in AppKit. SwiftUI does not provide these features. Therefore, a NSViewRepresentable child – AttributedText was added. This structure displays NSAttributedString via NSTextView.
- SwiftUI does not include a table in the classic form – with rows and columns. Therefore, ApplicationStatisticsView was added to display application statistics. It uses NSTableView to present classic tables.
- IconView was added to display application icons. The standard SwiftUI image element rendered low-quality icons on non-retina displays.
- SelectableLabes was added to display labels with selectable content. The standard SwiftUI label does not provide this feature.
The model implementation in the NetFilterMode class represents a filter model with the ability to control the core part. MonitoredAppModel represents a single monitored application data model.
There is a code to activate or deactivate Network Extension in ExtensionLoader.swift.
The following function should be applied for activation:
activate(extensionInfo: SystemExtensionInfo, mode: FilterResult, rules: [Rule], logger: @escaping (String) -> Void, approval: @escaping SystemExtensionRequestApproval) -> AnyPublisher<NetworkFilterManager, Error>
disableNetworkExtension(extensionIdentifier: String) -> Future<Void, Error>
It is worth noting that the activation code uses Combine. This enables you to effectively handle asynchronous calls.
All work with OSSystemExtensionManager was done in the SystemExtensions.swift file.