This iOS application integrates a WKWebView to load a web-based flight simulator from "https://fly.pieter.com" and uses device motion data (CoreMotion) to control the simulation. It includes haptic feedback for missile firing events and a debug interface for calibration.
- Web Integration: Loads a flight simulator in a WKWebView.
- Motion Control: Uses CoreMotion to translate device roll and pitch into joystick controls.
- Haptic Feedback: Provides tactile feedback when missiles are fired using UIImpactFeedbackGenerator.
- Debug Interface: Displays motion data and calibration controls (visible when
debug = true).
- iOS device with motion sensors
- Xcode with Swift support
- Internet connection to load "https://fly.pieter.com"
Inherits from UIViewController and conforms to WKScriptMessageHandler.
webView: WKWebView for displaying the flight simulatormotionManager: CMMotionManager for device motion trackinghapticFeedback: UIImpactFeedbackGenerator for missile firing feedback (style:.heavy)- Calibration variables:
baseAmplification: Roll amplification factor (default: 4.9)decayFactor: Roll decay factor (default: 2.7)pitchBaseAmplification: Pitch amplification factor (default: 4.9)pitchDecayFactor: Pitch decay factor (default: 2.7)
debug: Boolean to toggle debug UI (default:true)
overlayLabel: Displays debug informationresetButton: Resets motion baseline- Calibration buttons: Adjust amplification and decay factors for roll and pitch
viewDidLoad(): Initializes UI, web view, and motion trackingsetupWebView(): Configures WKWebView with JavaScript injectionloadWebContent(): Loads the simulator URLsetupOverlayLabel(): Sets up debug overlaysetupResetButton(): Configures reset buttonsetupCalibrationButtons(): Creates buttons for adjusting motion parameters
calibrateMotion(): Establishes initial roll baselinesetupMotionTracking(): Continuously updates joystick data based on device motionresetRollBaseline(): Recalibrates motion baseline
userContentController(_:didReceive:): Handles "missileFired" messages from JavaScript- Triggers haptic feedback with
hapticFeedback.impactOccurred() - Prepares next feedback with
hapticFeedback.prepare()
- Triggers haptic feedback with
- Increase/decrease methods for
baseAmplification,decayFactor,pitchBaseAmplification, andpitchDecayFactor
- Injects a script to override
window.shootMissileand send "missileFired" messages - Updates
leftJoystickDatawith clamped roll and pitch values
- Launch the app on an iOS device.
- Tilt the device to control the simulator (roll for left/right, pitch for up/down).
- Fire missiles in the simulator to feel haptic feedback.
- Use debug controls (if enabled) to:
- Reset motion baseline
- Adjust amplification and decay factors
- Haptic feedback requires a compatible device.
- Motion tracking requires device motion availability.
- Debug UI is hidden when
debug = false. - Cleanup occurs in
deinitto stop motion updates and remove message handlers.
- Add cooldown for haptic feedback to prevent channel overload
- Implement error handling for web loading failures
- Add configuration options for haptic intensity
- Persist calibration settings
This application has only been tested on an iPhone 15 Pro. Compatibility with other devices is not guaranteed and may require adjustments to motion calibration or UI constraints.