Porting NetworkQuality to iOS is feasible but requires significant rework due to macOS-only dependencies and iOS platform restrictions. The core SwiftUI views can largely be shared, but the networking/testing layer must be reimplemented. Key challenges include the absence of the networkQuality CLI on iOS, no CoreWLAN framework, and Apple's restrictive Wi-Fi APIs on iOS.
The app relies on several macOS-only components:
| Component | macOS Framework | iOS Availability |
|---|---|---|
| Speed test (Apple) | networkQuality CLI tool |
Not available |
| Wi-Fi info (SSID, RSSI, channel) | CoreWLAN | Not available — use NEHotspotNetwork (limited) |
| Network diagnostics (ping, traceroute) | Process-based CLI wrappers | Not available — must use Network framework |
| LAN speed testing | Bonjour/NWListener | Available (Network framework) |
| Multi-server tests (Cloudflare, M-Lab) | HTTP/WebSocket | Fully portable |
| UI layer | SwiftUI + AppKit bits | SwiftUI portable; replace AppKit with UIKit |
| PDF reports | AppKit-based rendering | Replace with UIKit/PDFKit |
- Models:
NetworkQualityResult,HistoryModels,NetworkInsights— mostly portable as-is - Multi-server testing:
MultiServerTestService(Cloudflare HTTP + M-Lab NDT7) — fully portable - History/export logic: UserDefaults storage, CSV/JSON export — fully portable
- SwiftUI views: Most views can be adapted with
#if os(iOS)/#if os(macOS)conditional compilation - View models: Business logic in
NetworkQualityViewModelis largely reusable
The networkQuality CLI does not exist on iOS. Options:
-
Implement the RPM protocol yourself: The "Responsiveness under Working Conditions" metric is an IETF draft (draft-cpaasch-ippm-responsiveness). Reference implementations exist:
- goresponsiveness — Go implementation
- network-quality/server — Server-side configs
- This would be the most accurate port but is complex (~weeks of work)
-
Use M-Lab NDT7 as primary test: The ndt7-client-ios Swift library already provides download/upload speed measurement on iOS. This is the easiest path but loses Apple's RPM metric.
-
HTTP-based throughput test: Like the existing Cloudflare test in
MultiServerTestService, run timed HTTP GET/POST transfers to measure speed. Simple but lacks responsiveness measurement. -
Hybrid approach (recommended): Use NDT7 + Cloudflare for throughput, and implement a simplified latency-under-load test for a responsiveness approximation.
iOS severely restricts Wi-Fi information access. The replacement:
-
NEHotspotNetwork.fetchCurrent()(iOS 14+): Provides SSID and BSSID only- Requires the
com.apple.developer.networking.wifi-infoentitlement - Requires one of: CoreLocation authorization, active VPN, NEHotspotConfiguration, or NEDNSSettingsManager
- Does NOT provide: signal strength (RSSI), noise, channel, band, link speed, security type
- Requires the
-
What's lost on iOS: Signal strength, noise level, channel, band (2.4/5/6 GHz), link speed, security type — none of these are accessible to third-party iOS apps
-
Note:
CNCopyCurrentNetworkInfois deprecated as of iOS 26 SDK. UseNEHotspotNetwork.fetchCurrent()instead.
The macOS app wraps ping and traceroute CLI tools via Process. On iOS:
- Ping: Use
NWConnectionwith UDP/ICMP or a library like SwiftyPing. Note: raw ICMP sockets require special entitlements on iOS. - Traceroute: Implement using UDP probes with incrementing TTL via
NWConnection. No built-in iOS equivalent. - DNS lookup: Use
nw_connection_twith DNS service discovery, orCFHost/getaddrinfo.
- Replace
NavigationSplitViewsidebar pattern with tab-based navigation (TabView) for iPhone - iPad can keep sidebar layout via
NavigationSplitView - Replace AppKit share sheets (
NSSharingServicePicker) withUIActivityViewController - Replace
NSImagerendering withUIImagefor share cards - Adapt
GeoTracerouteViewMapKit usage (largely compatible) - Replace
NSPasteboardwithUIPasteboard
Replace AppKit-based PDF rendering with:
UIGraphicsPDFRenderer(UIKit)- Or render SwiftUI views to PDF using
ImageRenderer(iOS 16+)
For users who just want to test responsiveness on an iPhone/iPad without building an app:
- Install the Wi-Fi Performance Diagnostics profile from your Apple Developer account
- Go to Settings > Wi-Fi > tap (i) next to your network > Diagnostics
- Tap Test next to Responsiveness
This provides Apple's official RPM test on iOS but requires a developer account and offers no history, export, or multi-server comparison features.
The recommended project setup:
NetworkQuality/
├── Shared/ # Cross-platform code
│ ├── Models/ # All models (reuse as-is)
│ ├── Services/
│ │ ├── Protocols/ # Abstract service protocols
│ │ ├── CloudflareTestService.swift # Shared
│ │ ├── MLab NDT7Service.swift # Shared
│ │ └── GeoIPService.swift # Shared
│ ├── ViewModels/ # Shared business logic
│ └── Views/ # Shared SwiftUI views
├── macOS/ # macOS-specific
│ ├── Services/
│ │ ├── AppleNetworkQualityRunner.swift # CLI wrapper
│ │ ├── CoreWLANMetadata.swift # Wi-Fi info
│ │ └── CLINetworkTools.swift # ping/traceroute
│ └── Views/ # macOS-specific UI
├── iOS/ # iOS-specific
│ ├── Services/
│ │ ├── iOSSpeedTestService.swift # NDT7/HTTP-based
│ │ ├── iOSWiFiMetadata.swift # NEHotspotNetwork
│ │ └── iOSNetworkTools.swift # NWConnection-based
│ └── Views/ # iOS-specific UI (TabView, etc.)
| Task | Effort |
|---|---|
| Project restructure (multiplatform) | 1-2 days |
| Speed test service for iOS (NDT7-based) | 3-5 days |
| RPM/responsiveness implementation (if desired) | 1-2 weeks |
| Wi-Fi metadata (NEHotspotNetwork) | 1 day |
| Network tools (ping/traceroute/DNS) | 3-5 days |
| UI adaptations (iPhone + iPad layouts) | 3-5 days |
| PDF report (UIKit renderer) | 1 day |
| Share card adaptations | 1-2 days |
| Testing and polish | 3-5 days |
| Total (without RPM) | ~2-4 weeks |
| Total (with full RPM) | ~4-6 weeks |
- No Wi-Fi signal strength (RSSI) — Apple does not expose this on iOS
- No Wi-Fi channel/band/security info — CoreWLAN is macOS-only
- No Apple networkQuality RPM — must implement independently or approximate
- SSID requires location permission — users must grant location access
- No LAN speed test discovery unless both devices run the app (Bonjour works on iOS)
- ICMP ping requires entitlement — may need
com.apple.developer.networking.multicastor use UDP-based alternatives
- ndt7-client-ios — M-Lab's iOS speed test framework (Apache 2.0)
- goresponsiveness — Reference RPM implementation in Go
- network-quality/server — Server configs for networkQuality tests
- OpenSpeedTest — HTML5 speed test (works in iOS Safari)
- SpeedChecker SDK — Commercial iOS speed test SDK
The most practical path is Approach 1 with the hybrid speed test (NDT7 + Cloudflare + simplified latency-under-load). This provides:
- Real download/upload speed measurements
- Multi-server comparison (already built)
- A reasonable responsiveness approximation
- Achievable in ~2-4 weeks
Full RPM protocol implementation would make the app unique in the App Store but adds significant complexity. Consider it as a v2 feature.