Search code examples
iosswiftxcodedelegateswatchkit

ExtensionDelegate.swift not called


I would like to start by saying I know there is a question like this but I haven't found anything on those I've read that fixes my problem.

My end goal is to have a Watch complication like a countdown clock. I have an iOS app that reads information from a socketIO file and stores information from that file in a GlobalVarible.swift file.

In my iOS ContentView, I then read from that GlobalVarible and display it. I also read from the same GlobalVarible file and display this information on a WatchKit Extension -> ContentView.

This is working but when I try to get the information to my ComplicationController the socketIO information hasn't changed the variables yet so I need to scheduled new entries preferred each second but I can make a workaround if I can get it to work by updating each minute.

Someone showed me that I could use getTimelineEntries but if I do link in this link it will load 100 entries and update that 100 times but the information from my GlobalVaribel file stores the first second or the default info 100 times. This approach didn't work for me. How do I refresh WatchApp complications

That leads me to a CreatingAndUpdatingAComplicationsTimelinepost with an attached project I could look in to and try figure things out. In that document and on another post I could read that I should use `ExtensionDelegate``

The problem is now that this file and all whats in it never triggers and I don't know where to start my search on how to get it to trigger? I try to log all the different functions in this Delegate but NONE is triggering that's why I think the file is not loaded into the app.

/*
See LICENSE folder for this sample’s licensing information.

Abstract:
A delegate object for the WatchKit extension that implements the needed life cycle methods.
*/

import ClockKit
import WatchKit
import os

// The app's extension delegate.
class ExtensionDelegate: NSObject, WKExtensionDelegate {
    func applicationDidFinishLaunching(){
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
    }
    func applicationDidBecomeActive(){
        print("--------------------------------------------------")
        print("applicationDidBecomeActive")
        print("--------------------------------------------------")

        
    }
    func applicationWillResignActive(){
        print("--------------------------------------------------")
        print("applicationWillResignActive")
        print("--------------------------------------------------")
    }
    func applicationWillEnterForeground(){
        print("--------------------------------------------------")
        print("applicationWillEnterForeground")
        print("--------------------------------------------------")
    }
    func applicationDidEnterBackground(){
        print("--------------------------------------------------")
        print("applicationDidEnterBackground")
        print("--------------------------------------------------")
    }


    func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
        print("__________________________________________________")
        print("Handling a background task...")
        print("App State: \(WKExtension.shared().applicationState.rawValue)")
        print("__________________________________________________")

        
        for task in backgroundTasks {
            print("++++++++++++++++++++++++++++++++++++++++++++++++++")
            print("Task: \(task)")
            print("++++++++++++++++++++++++++++++++++++++++++++++++++")

            switch task {
            // Handle background refresh tasks.
            case let backgroundTask as WKApplicationRefreshBackgroundTask:
                scheduleBackgroundRefreshTasks()
                backgroundTask.setTaskCompletedWithSnapshot(true)
            case let snapshotTask as WKSnapshotRefreshBackgroundTask:
                snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)
            case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:
                connectivityTask.setTaskCompletedWithSnapshot(false)
            case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
                urlSessionTask.setTaskCompletedWithSnapshot(false)
            case let relevantShortcutTask as WKRelevantShortcutRefreshBackgroundTask:
                relevantShortcutTask.setTaskCompletedWithSnapshot(false)
            case let intentDidRunTask as WKIntentDidRunRefreshBackgroundTask:
                intentDidRunTask.setTaskCompletedWithSnapshot(false)
            default:
                task.setTaskCompletedWithSnapshot(false)
            }
        }
    }
}

func scheduleBackgroundRefreshTasks() {
    
    
    print("**************************************************")
    print("Scheduling a background task.")
    print("**************************************************")

    let watchExtension = WKExtension.shared()
    let targetDate = Date().addingTimeInterval(3*60)
    
    watchExtension.scheduleBackgroundRefresh(withPreferredDate: targetDate, userInfo: nil) { (error) in
        if let error = error {
            print("An error occurred while scheduling a background refresh task: \(error.localizedDescription)")
            return
        }
        
        print("Task scheduled!")
    }
}

The whole project is here

https://github.com/mattehalen/Scheduled-countdown-WatchKit/tree/iPhone%26WatchApp

Solution

  • It turns out that I was using SwiftUI 2.0 and the SwiftApp lifecycle.

    To fix this problem I needed to add the code below to my Scheduled_countdownApp.swift

        @WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate
        @Environment(\.scenePhase) var scenePhase
    

    With @EnvironmentI could use the code below but because I already had the ExtensionDelegate I just commented it out.

    //        .onChange(of: scenePhase) { phase in
    //            switch phase{
    //            case .active:
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //                print("Active")
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //            case .inactive:
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //                print("inactive")
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //            case .background:
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //                print("background")
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //            @unknown default:
    //                print("something new added by apple")
    //            }
    //        }
    

    The Whole Code

    //  Scheduled_countdownApp.swift
    //  WatchApp WatchKit Extension
    //
    //  Created by Mathias Halén on 2021-06-22.
    //  Copyright © 2021 Mathias Halén. All rights reserved.
    //
    
    import SwiftUI
    
    @main
    struct Scheduled_countdownApp: App {
        @WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate
        //@UIApplicationDelegateAdaptor(ExtensionDelegate.self) var appDelegate
        @Environment(\.scenePhase) var scenePhase
        
        @SceneBuilder var body: some Scene {
            WindowGroup {
                NavigationView {
                    ContentView()
                }
            }
    //        .onChange(of: scenePhase) { phase in
    //            switch phase{
    //            case .active:
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //                print("Active")
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //            case .inactive:
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //                print("inactive")
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //            case .background:
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //                print("background")
    //                print("->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->")
    //            @unknown default:
    //                print("something new added by apple")
    //            }
    //        }
            WKNotificationScene(controller: NotificationController.self, category: "myCategory")
        }
    }