Dynamic linking problem. (Swift, System Preferences)

Hi,


I am trying to creat a screen-saver with Swift4 on High Sierra. When I try to set it up in System Preferences I get this error:


Error loading /Users/ebak/Library/Screen Savers/AnalogVoyager.macOS.saver/Contents/MacOS/AnalogVoyager.macOS: dlopen(/Users/ebak/Library/Screen Savers/AnalogVoyager.macOS.saver/Contents/MacOS/AnalogVoyager.macOS, 265): can't resolve symbol _OBJC_CLASS_$_NSError in /Users/ebak/Library/Screen Savers/AnalogVoyager.macOS.saver/Contents/MacOS/../Frameworks/libswiftCore.dylib because dependent dylib #1 could not be loaded in /Users/ebak/Library/Screen Savers/AnalogVoyager.macOS.saver/Contents/MacOS/../Frameworks/libswiftCore.dylib


I have found a similar error description here: https://stackoverflow.com/questions/46460767/swift4-error-on-high-sierra-cant-resolve-symbol


Does anyone know some solution?

I am trying to creat a screen-saver with Swift 4 on High Sierra.

Don’t do this. The current screen saver architecture uses an NSBundle-style plug-in. It’s not safe to create such plug-ins in Swift unless you control all the plug-ins and the app loading those plug-ins, and that’s clearly not the case here. The problem is one of ABI compatibility. If the app loading the plug-ins loads two different plug-ins, each of which is linked to its own Swift runtime, you’ll have two Swift runtimes running in the same process and that will be Bad™.

Note that this does not apply to modern plug-ins, which are all app extensions. An app extension can be safely written in Swift because it runs in its own process.

If you’d like to write a screen saver in Swift, I encourage you to file an enhancement request for the system to add support for app extension-based screen savers. Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Bug number: 34940805

Hi Quinn, thank you for your input (& I valued your tips on CloudKit in the past)!


My situation is that I already wrote a screen saver in Swift and it is running without any problems for over a year now (https://EmojiSaver.eu, everyone that reads this can use coupon code "APPLERADAR" to get the full version for free).


I encountered the same issue as @e.bak , but I cannot backport my whole code to Objective-C. Do you know anything specific, why or what in the area of loading screen savers has changed?


Actually this error applies to preferences panes as well. I created a very minimal sample here: https://github.com/klaas/QlaasSwiftPreferencesPane and submitted a bug report as well: http://openradar.appspot.com/35648336 (rdar://35648336)


Do you think a TSI (/DTS) would be helpful?

"Don't do this" really isn't an acceptible response. Apple has pushed us all to Swift. Don't now tell us not to use Swift.


Things are so broken at this point that a bare-bones Swift project that simply stubs out a ScreenSaver will not load successfully with mysterious errors in the console. If you are saying that the screen saver/display preferences panel is loading some other Swift runtime, then that is *your* (Apple's) problem, not ours. It is completely reasonable for developers to expect to be able to use the provided "approved" interfaces from the language of our choice, especially when that language is the "official" language that Apple claims to support. If there is anything that needs to be disambiguated, that needs to happen on the OS and OS services end.


Additionally, the fact that writing the same code under Sierra worked just fine makes your response suspect.

"Don't do this" really isn't an acceptible response.

Please look at the context of my response. e.bak specifically stated that they’re starting out writing a new screen saver, in which case the points from my response are correct:

  • It’s not safe to write a screen saver in Swift right now.

  • If this is something you’d like to do in the future, you should file an enhancement request for better support.

If the original poster had reported that they’re existing product was broken by this change, my suggestion would have been to file a binary compatibility bug about that breakage.

Don't now tell us not to use Swift.

There are lots of places where it’s impossible to use Swift right now. For example:

  • Binary compatible frameworks

  • Old school plug-ins, which is the subject of this thread

  • Real time code (because there’s no way to guarantee that the runtime won’t allocate memory)

  • In the kernel

Note The last two are problematic for Objective-C as well.

As a big Swift fan I, like you, wish I could use Swift everywhere [1]. Alas that simply is not the case right now.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] In fact, I have an entirely new authorisation plug-in sample, written in Swift, that I can’t ship because, like screen savers, authorisation plug-ins are based on the old school plug-in architecture.

Just to let everybody know: Some code angel at Apple fixed the specific issue in one of the latest dot releases of macOS High Sierra! Yay!


I'm on the latest macOS 10.13.4 (17E199), Xcode 9.3 (9E145) and Swift 4.1 (swiftlang-902.0.48 clang-902.0.37.1). Both

https://github.com/JohnCoates/Aerial/pull/420 and https://emojisaver.eu work again!


The issues described by Quinn still exist in general, but at least with only one (used) Swift plugin/saver within the System Preferences it works again.

Please give my simple sample project https://github.com/klaas/QlaasSwiftScreenSaver a try. It works again! 🙂

There are lots of places where it’s impossible to use Swift right now.

Just a quick update. With the advent of ABI stability, the first two items on my list, binary compatible frameworks and old school plug-ins, are not now supported. Some notes:

  • If you’re creating a binary compatible framework, use the new XCFrameworks support we introduced in WWDC 2019 Session 416 Binary Frameworks in Swift.

  • Old school plug-ins must use the system’s Swift runtime, meaning they must have a deployment target of macOS 10.14.4 or later.

The second two items I referenced, real-time code and the kernel, are still not feasible.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Dynamic linking problem. (Swift, System Preferences)
 
 
Q