dyld: lazy symbol binding failed: Symbol not found

最近針對安全性升級調整程式碼,並重新釋出自製的framework套件,結果安裝此套件的專案build得過,但遇到dyld: lazy symbol binding failed: Symbol not found錯誤無法run

最後參考此文章dyld: lazy symbol binding failed: Symbol not found - Swift Kingfisher

雖然不是因為使用Swift Kingfisher造成,但情況大同小異,最終在使用套件的專案之Podfile加上如下語法,並且主動執行一次pod install即可。這段語法用途在於把所有Pod專案的build setting中的Build Libraries for Distribution一次性的設定為YES。要手動設定也是可以。

post_install do |installer|

  installer.pods_project.targets.each do |target|

    target.build_configurations.each do |config|

      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'

    end

  end

end

如果對語法有興趣,可以參考此文瞭解一下CocoaPods Hooks

Alamofire request在dispatchPrecondition發生錯誤

 實際發生錯誤的程式碼斷在Alamofire的Session.swift如下片段

extension Session: SessionStateProvider {

    func request(for task: URLSessionTask) -> Request? {

        dispatchPrecondition(condition: .onQueue(rootQueue)) // -->錯在此行

        return requestTaskMap[task]

    }

// 略

}

會出現此錯誤是因為App本身用了AF.request之外,又導入另一framework套件,而該套件也有使用Alamofire,使用的方式是自行建立一個新的Session如下,該套件透過自建的Session將AF.request替換成myAF.request執行各項API操作。

public let myAF: Session = {

    let configuration = URLSessionConfiguration.default

    configuration.requestCachePolicy = .reloadIgnoringCacheData

    configuration.tlsMinimumSupportedProtocol = .dtlsProtocol12

    let delegate = Session.default.delegate

    let manager = Session.init(configuration: configuration,

                               delegate: delegate,

                               startRequestsImmediately: true,

                               cachedResponseHandler: nil)

    return manager

}()


如果App本身未使用AF.request,只使用本套件,是沒有問題。但是當App有使用AF.request又導入本套件,就會因為多個執行緒造成錯誤,主要原因是因為Session的設計如下。

open class Session {

    /// Shared singleton instance used by all `AF.request` APIs. Cannot be modified.

    public static let `default` = Session()

}


因此,如果想要自訂configuration,又不想發生錯誤,套件內的configuration設定需要改成如下寫法

AF.session.configuration.requestCachePolicy = .reloadIgnoringCacheData

AF.session.configuration.tlsMinimumSupportedProtocol = .dtlsProtocol12

改完後,維持使用AF.request即可。