130 Widgets

Building tools. Learning to build tools. Learning to build learning tools.

9. Future Directions and License Considerations

FredCam works. The stream is live, latency is low, PiP keeps you informed while you cook dinner. But “works for me” and “ready to distribute” are different standards. This section looks at what would need to change before broader distribution, and what the longer-term architecture options are.

GPL v3 and the App Store: The Real Situation

Section 3 established that KSPlayer is GPL v3. The practical consequence for App Store distribution is stark: you cannot distribute a closed-source app that incorporates GPL v3 code without violating the license. Apple’s review process does not audit license compliance — that enforcement happens between you and the library authors, not Apple — but that doesn’t make a violation acceptable.

The VLC for iOS situation is instructive here. VLC was removed from the App Store in 2010 after the FSF complained that the App Store’s DRM and terms conflicted with the GPL. The FSF’s position was that Apple’s restrictions on sideloading and modification were incompatible with GPL’s requirement that users be free to replace the software. VLC returned in 2013 only because the iOS port was relicensed under a dual MIT/MPL license — effectively removing the GPL from the distributed iOS binary entirely.

For FredCam, the options for any kind of distribution are:

  1. Open-source FredCam under GPL v3. The source is already on GitHub at bojordan/FredCam. Adding a LICENSE file with the GPL v3 text and distributing under those terms is the path of least resistance if you don’t need the code to be proprietary.
  2. Purchase a commercial license from the KSPlayer maintainer. The maintainer offers LGPL and commercial licenses for projects that need to ship proprietary code. Contact kingslay@icloud.com. This is the paid path if you want to distribute a closed-source app without publishing your source.
  3. Replace KSPlayer with a direct FFmpeg integration. FFmpeg itself is LGPL, which is far more permissive. Bypassing the GPL v3 KSPlayer wrapper and talking directly to FFmpeg’s C API from Swift is non-trivial but scoped work. See the native implementation discussion below.
For Personal Use Only: No Issue

GPL v3 only triggers upon distribution. If you build FredCam in Xcode and install it on your own device via cable, you are not distributing it. The license imposes no obligations on private, personal use. FredCam as a personal printer-monitoring tool is completely fine as-is.

Access Code Security

Storing the printer’s access code in UserDefaults is pragmatic for a personal-use app but inappropriate for distribution. UserDefaults is stored unencrypted on disk and is included in unencrypted iTunes/Finder backups. If the device is compromised or a backup is stolen, the access code is exposed.

For a distributed app, the access code should move to the Keychain — iOS’s secure, hardware-backed credential storage that is excluded from plaintext backups and is encrypted at rest. The migration is straightforward:

import Security

// Write
let query: [CFString: Any] = [
    kSecClass: kSecClassGenericPassword,
    kSecAttrAccount: "accessCode",
    kSecValueData: accessCode.data(using: .utf8)!
]
SecItemAdd(query as CFDictionary, nil)

// Read
var result: AnyObject?
let readQuery: [CFString: Any] = [
    kSecClass: kSecClassGenericPassword,
    kSecAttrAccount: "accessCode",
    kSecReturnData: true
]
SecItemCopyMatching(readQuery as CFDictionary, &result)
let code = String(data: result as! Data, encoding: .utf8)

The KeychainSwift library wraps this API in a friendlier interface, though it introduces another dependency. For an app that only stores two values, the raw Security framework API is manageable and adds no licensing complexity (Security.framework is Apple first-party).

A Native RTSPS Implementation

The cleanest way to eliminate the GPL v3 dependency entirely is to implement RTSPS directly using Apple frameworks — no third-party code at all. The building blocks exist:

Task Apple Framework
TCP connection with custom TLS (self-signed cert bypass) Network.framework (NWConnection + NWProtocolTLS.Options)
RTSP protocol state machine (DESCRIBE, SETUP, PLAY) Custom implementation; RTSP is a simple text protocol similar to HTTP
RTP packet parsing and reordering Custom implementation; RTP headers are well-documented
H.264 NAL unit parsing from RTP Custom implementation; H.264 RTP packetization is RFC 6184
H.264 hardware decode VideoToolbox (VTDecompressionSession)
Video display Metal / AVSampleBufferDisplayLayer

The TLSProxy.swift file in the project already demonstrates how to bypass self-signed certificate validation using NWProtocolTLS.Options:

let tlsOptions = NWProtocolTLS.Options()
sec_protocol_options_set_verify_block(
    tlsOptions.securityProtocolOptions,
    { _, _, completion in completion(true) },  // Accept any certificate
    .main
)

The honest assessment: implementing a reliable RTSP client and H.264 RTP demuxer from scratch is 2–4 weeks of focused work for an experienced developer. It handles edge cases (packet loss, reordering, SDP negotiation) that FFmpeg has refined over 20 years. For a personal-use app, the engineering investment doesn’t justify the license simplification. For a commercial product with strict open-source policy requirements, it might.

Feature Improvements

Beyond license concerns, there are several obvious product improvements:

TestFlight and App Store Distribution

Distributing the app beyond your own device requires an Apple Developer Program membership ($99/year). With that:

Tip

The Privacy Manifest requirement catches many teams off-guard. Apple’s documentation lists which APIs require declaration. UserDefaults is on the list (as NSPrivacyAccessedAPICategoryUserDefaults). Failing to declare it results in a rejection email from App Review. Generate the manifest early and include it in your Xcode target.

Where FredCam Stands

FredCam is a focused, working tool that solves a specific problem well. Its 650 lines demonstrate a complete slice of iOS development: choosing the right dependency for an unusual networking constraint, bridging UIKit into SwiftUI, modeling app state as a typed enum, and wiring up platform features like Picture-in-Picture and adaptive layout.

The GPL v3 exposure from KSPlayer is the most important thing to address before any distribution. For personal use it doesn’t matter; for anything shared, the three options are clear: open-source the app, buy a commercial license, or replace KSPlayer. The access code storage in UserDefaults is the next most pressing issue before distributing to others.

The architecture — data model, state machine, UIViewRepresentable bridge — would scale to multi-printer support without fundamental rethinking. The bones are good.

Final Summary

For personal use (no distribution): FredCam is complete as-is. For any distribution: you must either open-source the app under GPL v3, purchase a commercial license from the KSPlayer maintainer, or replace KSPlayer with a direct FFmpeg integration (LGPL) or a fully native implementation. For App Store submission: additionally move the access code to Keychain, tighten the ATS exception, and add a Privacy Manifest.