Port Pulse
Overview
Port Pulse is a macOS menu bar app built with SwiftUI that monitors the status of a specified network port.
This project gave me a chance to practice Swift and XCode developing.
Project Highlights
- Real-time Monitoring: Constantly checks the status of the specified port.
- User Interaction: Easily check and manage the port status through the macOS menu bar or the application window.
- Customizable: Adjust the target port and monitoring interval to suit your needs.
Project Details
Technologies Used
- SwiftUI
- Network Framework
- Swift programming language
GitHub Repository
Port Pulse GitHub Repository (opens in a new tab)
Screenshots
Caption: Port Pulse in the macOS menu bar. (version 0)
Caption: Port Pulse application window. (version 0)
My Role
I conceptualized, designed, and implemented Port Pulse from the ground up. This project allowed me to deepen my understanding of Swift development, networking in macOS applications, and creating an intuitive user interface.
Learning Points
- SwiftUI: Explored and applied SwiftUI for building the user interface.
- Network Framework: Learned how to use the Network framework for monitoring port status.
- User Interaction: Implemented features for user-friendly interaction in both the menu bar and application window.
Challenges and Solutions
Challenge: Toggle not reflecting real state of boolean
Whenever the toggle is being clicked, the value of monitor.showPortNumber
changes,
but whenever the window is being re-opened, the toggle always shows the same value as it initially was, not the current value of the variable.
caption: werid toggle behavior
@main
struct port_pulseApp: App {
// Create a state object for PortMonitor
@StateObject private var monitor = PortMonitor()
var body: some Scene {
// content view...
MenuBarExtra() {
VStack {
Form {
// other parts of window...
Section {
Toggle("", isOn: $monitor.showPortNumber)
//...
caption: source code of problematic toggle
Solution: Still working on it... 😥
Challenge: Icon not changing according to variable
In the project description, one would notice that I planned on showing the port status real-time on the Mac menu bar. Naturally, my code would look something like this:
MenuBarExtra() {
// menu bar on click window
} label: {
let colors: [String: NSColor] = ["UNKNOWN":.red, "IDLE":.gray, "RUNNING":.green]
let configuration = NSImage.SymbolConfiguration(pointSize: 12, weight: .light)
//! notice I called monitor.portStatusCode directly
.applying(.init(paletteColors: [monitor.portStatusCode]))
let image = NSImage(systemSymbolName: "circle.fill", accessibilityDescription: nil)
let updateImage = image?.withSymbolConfiguration(configuration)
Image(nsImage: updateImage!)
if monitor.showPortNumber {
Text("\(String(monitor.portNum))").font(.system(size: 3))
}
}
but with this approach, the icon color wouldn't change accordingly even if variable monitor.portStatusCode
value has updated
Solution: Object Property Re-assigning
TBH, I'm still having a hard time wrapping my head around why this solution would work, for now, I'm categorizing this as the subtlety of Swift, perhaps someday I'll see why.
MenuBarExtra() {
// menu bar on click window
} label: {
let colors: [String: NSColor] = ["UNKNOWN":.red, "IDLE":.gray, "RUNNING":.green]
// by re-assigning object property to a variable in scope, the icon became dynamic
let colorCode = monitor.portStatusCode
let iconColor = colors[colorCode] ?? .red
let configuration = NSImage.SymbolConfiguration(pointSize: 12, weight: .light)
.applying(.init(paletteColors: [iconColor]))ription: nil)
let updateImage = image?.withSymbolConfiguration(configuration)
Image(nsImage: updateImage!)
if monitor.showPortNumber {
Text("\(String(monitor.portNum))").font(.system(size: 3))
}
}
Challenge: Handling Network Connections
Implementing real-time monitoring required a deep dive into handling network connections. Swift's Network framework provided a solid foundation, but handling various states required careful consideration.
Solution: Stateful Design
I implemented a stateful design that allowed seamless updates to the UI based on the connection state. This approach enhanced user experience and provided clear feedback on the port status.
Roadmap / Future Enhancements
All planning related details & bugs already found is being documented by this notion page (opens in a new tab)