From e16680232dd007e90584b13632fd9d371af51ec2 Mon Sep 17 00:00:00 2001 From: NachoSoto Date: Wed, 17 Aug 2022 14:42:30 -0700 Subject: [PATCH 1/2] `watchOS`: fixed crash on single-target apps Fixes [CSDK-416]. Starting on `watchOS 9.0` (Xcode 14.0), `watchOS` apps can be configured as a single target. Apps that run in this single-target crash when calling `WKExtension.shared`. To prevent this, we can use `WKApplication` if it's available. --- Sources/Misc/SystemInfo.swift | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Sources/Misc/SystemInfo.swift b/Sources/Misc/SystemInfo.swift index 10741a248f..0bed64b0a4 100644 --- a/Sources/Misc/SystemInfo.swift +++ b/Sources/Misc/SystemInfo.swift @@ -197,11 +197,12 @@ private extension SystemInfo { #elseif os(macOS) return false #elseif os(watchOS) - return WKExtension.shared().applicationState == WKApplicationState.background + return self.isApplicationBackgroundedWatchOS #endif } #if os(iOS) || os(tvOS) + // iOS/tvOS App extensions can't access UIApplication.sharedApplication, and will fail to compile if any calls to // it are made. There are no pre-processor macros available to check if the code is running in an app extension, // so we check if we're running in an app extension at runtime, and if not, we use KVC to call sharedApplication. @@ -211,7 +212,25 @@ private extension SystemInfo { } guard let sharedUIApplication = self.sharedUIApplication else { return false } - return sharedUIApplication.applicationState == UIApplication.State.background + return sharedUIApplication.applicationState == .background + } + + #elseif os(watchOS) + + var isApplicationBackgroundedWatchOS: Bool { + // In Xcode 13 and earlier the system divides a watchOS app into two sections: + // - WatchKit app + // - WatchKit extension + // In Xcode 14 and later, you can produce watchOS apps with a single watchOS app target. + // These single-target watchOS apps can run on watchOS 7 and later. + // Calling `WKExtension.shared` on these single-target apps crashes. + // + // `WKApplication` provides a more accurate value if it's available, and it avoids that crash. + if #available(watchOS 7.0, *) { + return WKApplication.shared().applicationState == .background + } else { + return WKExtension.shared().applicationState == .background + } } #endif From 686fb09069369ef7ed3b712786bf864c22891b7f Mon Sep 17 00:00:00 2001 From: NachoSoto Date: Thu, 18 Aug 2022 19:57:42 -0700 Subject: [PATCH 2/2] Fixed Xcode 13 compilation --- Sources/Misc/SystemInfo.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/Misc/SystemInfo.swift b/Sources/Misc/SystemInfo.swift index 0bed64b0a4..af19ac6185 100644 --- a/Sources/Misc/SystemInfo.swift +++ b/Sources/Misc/SystemInfo.swift @@ -226,11 +226,16 @@ private extension SystemInfo { // Calling `WKExtension.shared` on these single-target apps crashes. // // `WKApplication` provides a more accurate value if it's available, and it avoids that crash. + #if swift(>=5.7) if #available(watchOS 7.0, *) { return WKApplication.shared().applicationState == .background } else { return WKExtension.shared().applicationState == .background } + #else + // Before Xcode 14, single-target extensions aren't supported (and WKApplication isn't available) + return WKExtension.shared().applicationState == .background + #endif } #endif