SDKS-4916 Fix swift build failures — platform bump and if canImport guards#157
SDKS-4916 Fix swift build failures — platform bump and if canImport guards#157rodrigoareis wants to merge 1 commit into
Conversation
| return window | ||
| } | ||
| #endif | ||
| fatalError("Window not set. This should never occur.") |
There was a problem hiding this comment.
Since the SDK only declares macOS as a build target for 3rd-party library compatibility, consumers on macOS should never reach this code path. However the fatalError message is now misleading — on macOS the UIKit fallback block is compiled out entirely, so there is genuinely no recovery path. Consider either adding a comment that clarifies why this is safe (// macOS: build target only — this path is unreachable in practice), or adding a macOS-specific fallback via NSApplication.shared.keyWindow to make the crash truly unreachable:
#if canImport(UIKit)
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first {
return window
}
#else
if let window = NSApplication.shared.keyWindow {
return window
}
#endif
fatalError("Window not set. This should never occur.")| @unknown default: | ||
|
|
||
| default: |
There was a problem hiding this comment.
The original code used @unknown default, which makes the compiler emit a warning if Apple adds a new CLAuthorizationStatus case in a future OS. This refactor replaces it with a plain default, silently swallowing any future enum cases (mapping them to authorizationDenied with no logging). The split into #if canImport(UIKit) for authorizedWhenInUse above is correct, but the switch itself should restore exhaustiveness protection:
@unknown default:
throw LocationError.authorizationDenied| "orientation": isPortrait ? 1 : 0 | ||
| ] | ||
| #else | ||
| return [:] |
There was a problem hiding this comment.
The macOS #else path returns [:] (empty dictionary) for display info. Since macOS is a build-only target for 3rd-party library compatibility and this code won't run in production, the empty return is fine — but a comment would help future readers distinguish intent from omission:
#else
// macOS: build target only for 3rd-party library compatibility — not a supported runtime platform
return [:]
#endif| let cameraCount = discoverySession.devices.count | ||
| return ["numberOfCameras": cameraCount] | ||
| #else | ||
| return [:] |
There was a problem hiding this comment.
Same as the display info fallback above — macOS is a build-only target so the empty return is intentional. Worth adding the same comment here for consistency:
#else
// macOS: build target only for 3rd-party library compatibility — not a supported runtime platform
return [:]
#endif| self.networkCountryIso = DeviceProfileConstants.unknown | ||
| } | ||
| #else | ||
| self.carrierName = DeviceProfileConstants.unknown |
There was a problem hiding this comment.
Since macOS is a build-only target and this code won't run in production, returning DeviceProfileConstants.unknown is acceptable. A brief comment would clarify that this is intentional (not a missing implementation), and flag that nil would be more semantically accurate if macOS ever gets promoted to a real target — telephony doesn't exist on Mac at all, whereas "Unknown" implies data was collected but unreadable:
#else
// macOS: build target only — telephony not available on this platform
self.carrierName = DeviceProfileConstants.unknown
self.networkCountryIso = DeviceProfileConstants.unknown
#endif| self.deviceName = await UIDevice.current.name | ||
| #else | ||
| self.platform = "macOS" | ||
| self.version = ProcessInfo.processInfo.operatingSystemVersionString |
There was a problem hiding this comment.
ProcessInfo.processInfo.operatingSystemVersionString returns a verbose string like "Version 13.0 (Build 22A380)", while the iOS path returns "16.0" via UIDevice.current.systemVersion. Since macOS is a build-only target this won't affect production, but if macOS is ever promoted or this data is sent to a server, the structural difference will break any version string parsing. Worth aligning the format now:
let v = ProcessInfo.processInfo.operatingSystemVersion
self.version = "\(v.majorVersion).\(v.minorVersion).\(v.patchVersion)"| return .failure(.idpCanceledException(message: error.localizedDescription)) | ||
| } | ||
| #else | ||
| return .failure(.illegalStateException(message: "Browser authentication is not supported on this platform")) |
There was a problem hiding this comment.
Since macOS is a build-only target and browser-based IdP is iOS-only, returning a failure here is correct and intentional. Worth adding a comment so it's obvious this isn't a gap to fill:
#else
// macOS: build target only — browser-based IdP authentication requires UIKit and is not a supported use case
return .failure(.illegalStateException(message: "Browser authentication is not supported on this platform"))
#endif|
Package.swift —
.product(name: "GoogleSignIn", package: "GoogleSignIn-iOS", condition: .when(platforms: [.iOS])) |
JIRA Ticket
SDKS-4916 Fix swift build failures — platform bump and if canImport guards
Summary
macOS(.v10_15)→macOS(.v13)inPackage.swift— resolvesLocale.language.languageCodeavailability and satisfies GoogleSignIn's macOS minimum requirement (cannot remove macOS entirely due toSPM platform compatibility validation)
CACHING_GUIDE.mdtoPingStorageexclude:inPackage.swift— eliminates the SPM "unhandled file" warningcondition: .when(platforms: [.iOS])toRecaptchaEnterprise,PingOneSignals, andFacebookLoginproduct dependencies — prevents SPM from resolving iOS-only XCFrameworks during native macOS builds#if canImport(X)— allows the macOS build path to compile cleanly without affecting iOS/xcodebuild buildsRoot Cause
Package.swiftdeclaresmacOS(.v13), soswift buildon a macOS host compiles all targets for native macOS. Three external XCFramework dependencies (RecaptchaEnterpriseSDK,PingOneSignals,FBSDKLoginKit) only ship iOS slices — causing "no such module" errors. UIKit-dependent source code in TamperDetector, Browser, ExternalIdP, and ExternalIdPGoogle also needed guards.Test Plan
rm -rf .build && swift build— completes with zero errorsswift build --target PingReCaptchaEnterprise,PingProtect,PingExternalIdPFacebook,PingPush,PingDavinci,PingOidc,PingBrowser— all pass