Reputation: 956
I am trying to update my app to utilize SwiftUI architecture. It is a stand alone WatchKit app. I used to pass a few key classes between views utilizing the delegate approach. Since I am trying to utilize environmentObject, I would like to initialize the initial classes (which depend on each other) via the delegate.
Given I am using SwiftUI method, I have recreated AppDelegate in the @main.
import SwiftUI
class AppDelegate: NSObject, WKExtensionDelegate {
var class1: Class1?
var class2: Class2! = Class2()
var class3: Class3!
func application(_ application: WKExtension) -> Bool {
return true
}
}
@main
struct WatchApp: App {
@WKExtensionDelegateAdaptor(AppDelegate.self) var delegate
init() {
delegate.class1 = Class1()
delegate.class2 = Class2()
delegate.class3 = Class3()
}
@SceneBuilder var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
.environmentObject(delegate.class3)
.environmentObject(delegate.class2)
.environmentObject(delegate.class1)
}
}
WKNotificationScene(controller: NotificationController.self, category: "myCategory")
}
}
When Class 3 get's called I get a nil value in the access of the AppDelegate and a crash.
#if os(macOS)
let delegate = NSApplication.shared.delegate as! AppDelegate
#elseif !os(watchOS)
let delegate = UIApplication.shared.delegate as! AppDelegate
#else
let delegate = WKExtension.shared().delegate as! AppDelegate //<HERE's The Crash - Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
#endif
}
And in the info.plist
<key>WKExtensionDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).AppDelegate</string>
Is there an obvious thing I am overlooking?
Upvotes: 0
Views: 329
Reputation: 810
WKExtension.shared() is always defined, but delegate
property may be nil. Using as!
is what crashes your app
You will have to provide a delegate to handle lifecycle events in your extension, see Apple Doc
To assign an AppDelegate for the extension, follow this steps:
YOUR_CLASS_ExtensionDelegate
that implements the protocol WKExtensionDelegate
.WKExtensionDelegateClassName
in Info.plist in WatchKit Extension is $(PRODUCT_MODULE_NAME).YOUR_CLASS_ExtensionDelegate
In your case, you already did 1, but you should check for 2
Upvotes: 1