繁体   English   中英

将 RxSwift 链接到命令行工具的正确方法

[英]The right way to link RxSwift into a Command Line Tool

我正在尝试为命令行工具构建 RxSwift,但它比使用 iOS 应用程序要困难得多。

我创建了一个新的命令行项目并使用pod安装了 RxSwift

$ cat Podfile
# Podfile
use_frameworks!

target 'HelloRx' do
    pod 'RxSwift',    '~> 4.0'
end

$ pod --version
1.5.3

代码 10.1

打开工作区 (.xcworkspace) 并且不添加任何代码后,项目构建良好但在运行时崩溃:

dyld: Library not loaded: @rpath/RxAtomic.framework/Versions/A/RxAtomic
  Referenced from: /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx
  Reason: image not found

动态依赖项对二进制文件不可见。

$ otool -l HelloRx | grep -A 2 RPATH | grep path
         path @executable_path/../Frameworks (offset 12)
         path @loader_path/Frameworks (offset 12)
         path @executable_path/../Frameworks (offset 12)
         path @loader_path/Frameworks (offset 12)

XCode 假设二进制文件可以在与二进制文件相关的Frameworks目录中找到框架。 不幸的是,如果我查看构建目录,则没有Frameworks目录,因此出现错误。

$ ls
HelloRx         Pods_HelloRx.framework  RxCocoa
HelloRx.swiftmodule RxAtomic        RxSwift

$ ls ..
Debug

为了使它更加混乱,所有框架都被复制到自己的Rx*目录中,而不是一个全局Frameworks目录中。

我可以通过在“构建设置”>>“运行路径搜索路径”中添加更多路径来解决这个问题。

'@executable_path/RxAtomic'
'@executable_path/RxSwift'

我做了这个伎俩,但二进制文件仍然崩溃。

dyld: Library not loaded: @rpath/libswiftAppKit.dylib
  Referenced from: /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/RxSwift/RxSwift.framework/Versions/A/RxSwift
  Reason: image not found

现在是缺少libswiftAppKit.dylib

这可以通过添加另一个运行路径路径来“修复”。

'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx'

这终于停止崩溃,但我的应用程序抛出了很多警告:

objc[64025]: Class _TtCE6AppKitVSo17NSAnimationEffectP33_9E6F1C1DB126EBCC5B18B8BAC8A387CC26_CompletionHandlerDelegate is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftAppKit.dylib (0x101360b98) and /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx (0x10059a250). One of the two will be used. Which one is undefined.
objc[64025]: Class _TtC8Dispatch16DispatchWorkItem is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftDispatch.dylib (0x101a7c6d0) and /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx (0x10059bd28). One of the two will be used. Which one is undefined.
objc[64025]: Class _TtC10FoundationP33_45BFD3D387700B862E3A7353B97EF7ED20_CharacterSetStorage is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftFoundation.dylib (0x101c34f00) and /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx (0x10059d5e8). One of the two will be used. Which one is undefined.
objc[64025]: Class _TtC10Foundation12_DataStorage is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftFoundation.dylib (0x101c34fa8) and /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx (0x10059d690). One of the two will be used. Which one is undefined.
...

我可以忍受警告,但这显然不是正确的解决方案。 这让我思考,解决这个问题的正确方法是什么?

(我是 XCode 和 Swift 的新手,所以也许我在做一些疯狂的事情)

一种快速的方法是将所有 pod 框架都作为静态库。

  1. 在 Project Navigator 上选择 Pods 项目
  2. 在所有 pods 目标之上选择主 Pods 项目
  3. 转到 Build Settings 并将Mach-O Type更改为Static Library 这会将所有 pod 更改为Mach-O Type作为Static Library (每次运行pod install都会改回来,所以你可能需要再做一次)
  4. 干净的

这种方法的优点是您的输出将是单个可执行文件。

如果您想使用动态框架,请遵循本教程: https : //medium.com/livefront/how-to-add-a-dynamic-swift-framework-to-a-command-line-tool-bab6426d6c31 通过使用第二种方法,您的输出将不仅仅是单个可执行文件,而且您还必须提供所有动态框架。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM