iosswiftxcodeswiftuifreeze

Why does my app run in Simulator, but freezes on device?


My app runs fine in general with all features. But one new button/feature I added freezes the app on device, but works flawlessly in the simulator. I checked similar questions on here and found one general solution to restart the device and Xcode. It didn't help, as I expected.

I expected this behaviour as this is the second time exactly this happens. The button working in Simulator and freezing on device. And last time I commented out all code until I found one line causing the problem. It was the initialisation of the timer. Moving it into the body solved the problem.

import SwiftUI
import AVFoundation
import SwiftData
import CoreHaptics  /// For making vibrations once the timer is run out


struct TimerTapasFullView: View {
    @Environment(\.dismiss) var dismiss         /// To be able to dismiss the view
    
    @State var countdownTimer = 5 * 60          /// The actual seconds of the timer, being counted down/up
    @State var timerRunning = true              /// Var to set and see if timer is running
    @State var gongSound: AVAudioPlayer?        /// The Sound of the timer
    
    @State private var hours: Int = 0           /// Vars for the picker wheel
    @State private var minutes: Int = 0
    @State private var seconds: Int = 0
    
    @State private var brightnessLow = false    /// Var for saving if the brightness button was used
    
    @State private var engine: CHHapticEngine?  /// The object creating the vibrations later on
    @Environment(\.scenePhase) var scenePhase   /// Var to keep track of state of app, to restart HapticEngine
    
    /// Environment Objects
    @EnvironmentObject var userStat: StatisticsObject       /// Var to keep track of seconds using the Timer
    @EnvironmentObject var envObject: EnvObject             /// For getting FullDarkness, vibrateTimer
    
    /// Variables from the Tapas for setting the timer
    @State var asanas: [TapasAsana]
    @State var asana: TapasAsana
    @State var nextAsana = TapasAsana()

    let path = Bundle.main.path(forResource: "bell_basu.mp3", ofType:nil)!
    
    var body: some View {
        /// Initiate the timer
        let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
        
        /// For calculating hours, minutes, seconds
        let style = Duration.TimeFormatStyle(pattern: .minuteSecond)
        //let formTimer = Duration.seconds(countdownTimer).formatted()
        let formTimerShort = Duration.seconds(countdownTimer).formatted(style)
        let url = URL(fileURLWithPath: path)
        
        VStack {
        ... more code follows...

This was the line that caused this behaviour the first time:

let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

Now I added new features, including this line: @State var nextAsana = TapasAsana()

I have so many questions about this. Does anyone have any idea why it runs flawlessly in the Simulator and not at all on device? This way I always check in the Simulator and when I check after a coding session on device, I have no idea which of many changes I made causes this freeze.

The Debugger in Xcode shows nothing when this happens. Is there any way to make it show more detailed what is happening on device?

Do you have any idea why this happens? Is any of my code faulty or am I using bad practices that result in this freeze?

I would be very grateful to understand this big problem, thank you for any help.


Solution

  • Thank you everyone for your input. In the end it was a mix of answers that was correct.

    I moved the timer into .onReceive so it also gets killed when not in use anymore. And I just give the Array now and access each element as a number, so it is not necessary anymore to give elements to the views.

    Thank you so much for helping me even with this beginner question. My understanding of SwiftUI is growing with each problem.