簡體   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