From a purely "how do I get something I can link to" perspective, you can still build a cdylib and a header for it, Xcode will let you include the header in your Objective-C code or in the Swift bridging header, and then you can link to the cdylib and copy it into the "Frameworks" subdirectory in the bundle at build time. I've been doing that in an OS X app for several months and it works out very well.
> calling the main thread from Rust wasn't easy.
If you want to schedule code to run in the main queue/thread/runloop, that's an Apple-specific thing Rust wouldn't be aware of by default, but I did find a wrapper for libdispatch/GCD, and it seems to support calling things on the main queue which should do what you want.
https://crates.io/crates/dispatch
You can also have your app provide a C callback to the Rust code (even a Swift closure with captured variables, with some clever workarounds since you can't do that by default), and then in the callback you can schedule code to run on the main queue/thread if you want.