Skip to content

Add -ObjC linker flag to UIKitNavigation target#337

Open
connor-krazy7 wants to merge 2 commits intopointfreeco:mainfrom
connor-krazy7:fix/objc-linker-flag
Open

Add -ObjC linker flag to UIKitNavigation target#337
connor-krazy7 wants to merge 2 commits intopointfreeco:mainfrom
connor-krazy7:fix/objc-linker-flag

Conversation

@connor-krazy7
Copy link
Copy Markdown

Summary

When UIKitNavigation is built as a dynamic framework (e.g. in a modularized project with multiple dynamic targets), the linker dead-strips ObjC symbols from UIKitNavigationShim because no Swift code references them directly. This causes an "unrecognized selector" crash at runtime:

-[MyViewController set_UIKitNavigation_onDismiss:]: unrecognized selector sent to instance

The UIKitNavigationShim target contains ObjC code that:

  • Swizzles viewDidAppear:/viewDidDisappear: via +load
  • Adds categories on UIViewController (set_UIKitNavigation_onDismiss:, set_UIKitNavigation_hasViewAppeared:, etc.)

Adding -ObjC to UIKitNavigation's linker settings forces the linker to include all ObjC categories from the statically linked UIKitNavigationShim target, fixing the crash.

Reproduction

  1. Create a project with multiple dynamic framework targets
  2. Have one target depend on UIKitNavigation (e.g. via ComposableArchitecture)
  3. Use present(item:content:) to present a view controller
  4. Crash on set_UIKitNavigation_onDismiss: unrecognized selector

UIKitNavigationShim is an ObjC target that swizzles UIViewController (viewDidAppear/viewDidDisappear) via +load and adds categories like set_UIKitNavigation_onDismiss:. When UIKitNavigation is built as a dynamic framework, the linker dead-strips these ObjC symbols because no Swift code references them directly. Adding -ObjC forces the linker to include all ObjC categories, fixing "unrecognized selector" crashes at runtime.
@mbrandonw
Copy link
Copy Markdown
Member

Hi @connor-krazy7, packages are allowed to use unsafe flags only in Swift 6.2 and up (see this discussion), and so at the very least this would necessitate moving this Package.swift to Package‌@swift-6.0.swift and creating a new Package.swift for 6.2.

Package.swift (6.2+) includes -ObjC on UIKitNavigation to prevent dead-stripping of UIKitNavigationShim's ObjC categories when built as a dynamic framework. Package@swift-6.0.swift preserves the original manifest for pre-6.2 consumers where unsafeFlags are not allowed in versioned dependencies.
@connor-krazy7
Copy link
Copy Markdown
Author

Hi @connor-krazy7, packages are allowed to use unsafe flags only in Swift 6.2 and up (see this discussion), and so at the very least this would necessitate moving this Package.swift to Package‌@swift-6.0.swift and creating a new Package.swift for 6.2.

Thanks for the comment,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants