XCFramework "Cannot load underlying module" - swift

I've built an SDK as an XCFramework, which shares dependencies with the app that uses it. When I build, I'm getting:
...SDK.swiftmodule/arm64-apple-ios.swiftinterface:20:8: Cannot load underlying module for...
This occurs in the Compile Swift Sources action and the break is in the import MySharedDepedency statement in the swiftinterface file
As stated, the SDK in the project as an xcframework bundle. MySharedDependency is fulfilled with cocoapods. use_modular_headers is set in the Podfile, it's modulemap is included in the linker flags (by cocoapods).
Its DOES work if I use the use_frameworks! flag in the Podfile but only with dynamic linkage and for internal politics reasons, I need this to work with static linkage. If I add the :linkage => :static argument, I get the same error as with no use_frameworks! call
I've tried changing the order of the linked frameworks in Build Phases (so that the pods are linked before the SDK framework). I've tried adding recursive header/framework/module search paths everywhere I can find a MyDependency.modulemap...
Yes, I've cleaned caches, deintegrated, clean installed, erased deriveddata, restarted xcode, my machine, ...
Argh! Thanks for any help...

I had the same exactly the same scenario and the same problem
I solved using #_implementationOnly in every file from my xcframework's code like:
#_implementationOnly import Alamofire
After that just rebuild your XCFramework, clean and build your app's project.
It works like a charm without use_frameworks!

Related

Redefinition of module 'Firebase'

I'm trying to integrate Firebase into my app, but as soon as I'm building it after I thought I finished my install I get:
Redefinition of module 'Firebase'
as well as
Could not build Objective-C module 'SwiftOverlayShims'
which I have no idea what that means but I'm assuming its a result of the first.
My podfile looks like this:
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'app' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
pod 'Firebase/Auth'
# Pods for app
end
So I don't think theres anything conflicting there. I saw a solution that told me to go into my Header Search Path and see if my project had multiple Firebase directories, but I have no custom paths, so that wasn't it. Any insight?
EDIT: Here is the exact display from my errors
Uncommenting the platform line in my podfile and changing it to iOS 10.0 did get rid of the error saying "Could not build Objective-C module 'Firebase'" So we have made some progress.
Here is the path when selecting "previously defined here"
From what I can tell, it is only giving me one location. Selecting the redefinition error just gives me the relative path of module.modulemap , so I am assuming that is referring to the same thing. I am also getting multiple warnings like this
Skipping duplicate build file in Copy Files build phase: /Users/me/Library/Developer/Xcode/DerivedData/app-elgcucdextsnzqbtlznbqeulbfks/SourcePackages/artifacts/Firebase/FirebaseAnalytics.xcframework/ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework
as well as a couple other frameworks in the ios-arm64_i386_x86_64-simulator directory, so maybe that has something to do with it.

Swift Package Manager (SPM) and Cocoapod Dependency Conflict

Overview
I have two dependencies, one available as a Swift Package, and the other only available as a Cocoapod. The problem is that each has a dependency on a third package, which results in undefined behavior when multiple versions exist.
At a basic level, here is a graphic of my dependencies
APP imports:
B (SPM) imports:
C (SPM) imports:
D (SPM) <-
E (Pod) imports:
D (Pod) <-
I would like to remove the D (Pod) version and point to the D (SPM) version either via a Podfile script or build script.
More specific information:
I have a NetworkingService Swift Package that imports Firebase, and my main app imports the NetworkingService. My Podfile imports GoogleMLKit/PoseDetection. Firebase and PoseDetection share dependencies that result in undefined behavior (runtime crash) when a duplicate is present.
Note: This error should be reproducible by removing the intermediary NetworkingService package and importing Firebase to the main app as a Swift package.
Podfile
platform :ios, '15.0'
target 'MyApp' do
use_frameworks!
pod 'GoogleMLKit/PoseDetection', '2.5.0'
end
In Package.swift
.package(
name: "Firebase",
url: "https://github.com/firebase/firebase-ios-sdk.git",
.upToNextMajor(from: "8.10.0")
),
They duplicate a few dependencies, including GoogleUtilities and FBLPromises. Launching the app after pod install crashes with runtime exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FBLPromise HTTPBody]: unrecognized selector sent to instance 0x6000017685d0'
Searching that brought me to this GitHub issue where a contributor mentions:
The duplicate warnings are indicative of non-deterministic behavior. When there are multiple copies of a library, the right one may or may not be chosen.
I then attempted to refactor all Cocoapod dependencies with a modified version of this script I found linked on another StackOverflow post. The attempt was to make PoseDetection explicitly point to symbols from GoogleUtilitiesCopy and FBLPromisesCopy. But it seems that even the existence of these copies, despite pointing to the corresponding dependency, created undefined behavior.
Partial Workaround
If I run pod install followed by File > Packages > Update to latest package versions. The app will launch without an immediate runtime crash. However, I encounter other runtime crashes later within the app.***
Ideal Solution
I would like to remove the duplicate pod dependencies and point to the SPM versions either via the Podfile or a build phase script, but I'm not sure where to begin.
Firebase can be imported as a pod, but I do not want to do this because I have an existing SPM infrastructure that depends on Firebase. I'd prefer not to convert all of these packages into pods.
The main problem with SPM and Cocapods is that:
SPM is not aware of Cocapods and Cocapods not aware of SPM.
I had a similar situation where:
pod library depends on some Library networking
SPM library also depends on the same Library networking.
There are two solutions I think are worth trying.
1.) remove the pod and try to use the XCFramework version of it (should be available). that means you should manually add the library to your project and it should be selected as embed & sign and also as required.
2.) you can convert the pod library to SPM by using a simple binary target. Basically, you need to create a Package file that points to the XCFramework in its archived version (hence it should be a zip file). that way the SPM graph will handle it by itself.
I know it's not ideal, but these two approaches works for me.

Why I cant import the library that in swift file after installing the the dependency in Cocoapods?

I already install this library, XLPagerTabStrip via Cocoapod. My pod file is look like this,and already hit pod install in terminal.
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'MyProject' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for MyProject
pod 'XLPagerTabStrip', '~> 8.0'
end
So everything is completed install,but when I want to import the library in Swift file,it giving an error ->> No such module 'XLPagerTabSript'.
I read a lot of question about this,which mention add the file path of the library to
Build Setting -> Search Paths -> User Header Search Paths. I also already did,but still giving the same error.
What I add in User Header Search Path is something like this:
${SRCROOT}/Users/Myname/Desktop/MyProject/Pods/XLPagerTabStrip
After adding the file path,I clean the project,build the project again,the tried to add in import XLPagerTabStrip to one of my swift file,the error still the same.
Can somebody let me know what is problem actually? Cause I beginner in Ios development,I totally no idea what I doing wrong.
I end up solve it by update my Xcode vesion and insert the file path of the library in inside
Build Setting -> Search Paths -> Framework Search Paths -> (Add the
file path of the library here)
By this I can import the library in swift file without any warning

How to link CocoaImageHashing pod with Swift project (dyld: Library not loaded)

I'm trying to use the CocoaImageHashing pod from a Swift project so that I can do some perceptual hashing for image duplicate detection.
I setup the workspace following the CocoaPods instructions and attempted to run the default Hello World swift file.
dyld: Library not loaded: #rpath/CocoaImageHashing.framework/Versions/A/CocoaImageHashing
Referenced from: /Users/sarge/Library/Developer/Xcode/DerivedData/PHashTest-cdongczzcrynrfclysczwalanrlq/Build/Products/Debug/PHashTest
Reason: image not found
(lldb)
My Podfile is:
platform :osx, '10.12'
target 'PHashTest' do
use_frameworks!
pod 'CocoaImageHashing', :git => 'https://github.com/ameingast/cocoaimagehashing.git'```
end
I tried commenting out the use_frameworks! line in case this was some kind of dynamic library problem. I then get a build error.
Framework not found CocoaImageHashing
My General > Linked Frameworks and Libraries does include the CocoaImageHashing framework. I see Xcode building files from it during a build.
Is there something I have to do to get the CocoaImageHashing pod to build the dynamic library that Swift expects? Or do I need to not use Swift because CocoaImageHashing has to be included dynamically.
(I'm very unfamiliar with Swift so I don't know what to look for)
You should include the framework at General -> Embedded Binaries as well.

MacOS Swift Framework testing fail

I have a framework written in obj-c and swift.
Now i try to run a related unit test target, but I get this error:
2014-07-10 07:45:54.064 xctest[4908:303] The test bundle at /Users/steve/Temporary/Build/Products/Debug/SOGraphDB-Mac Tests.xctest could not be loaded because an unanticipated error occurred: Error Domain=NSCocoaErrorDomain Code=3587 "The bundle “SOGraphDB-Mac Tests” couldn’t be loaded because it is damaged or missing necessary resources." (dlopen_preflight(/Users/steve/Temporary/Build/Products/Debug/SOGraphDB-Mac Tests.xctest/Contents/MacOS/SOGraphDB-Mac Tests): Library not loaded: #rpath/libswiftAppKit.dylib
Referenced from: /Users/steve/Temporary/Build/Products/Debug/SOGraphDB.framework/Versions/A/SOGraphDB
Reason: image not found) UserInfo=0x10011c640 {NSLocalizedFailureReason=The bundle is damaged or missing necessary resources., NSLocalizedRecoverySuggestion=Try reinstalling the bundle., NSFilePath=/Users/steve/Temporary/Build/Products/Debug/SOGraphDB-Mac Tests.xctest/Contents/MacOS/SOGraphDB-Mac Tests, NSDebugDescription=dlopen_preflight(/Users/steve/Temporary/Build/Products/Debug/SOGraphDB-Mac Tests.xctest/Contents/MacOS/SOGraphDB-Mac Tests): Library not loaded: #rpath/libswiftAppKit.dylib
Referenced from: /Users/steve/Temporary/Build/Products/Debug/SOGraphDB.framework/Versions/A/SOGraphDB
Reason: image not found, NSBundlePath=/Users/steve/Temporary/Build/Products/Debug/SOGraphDB-Mac Tests.xctest, NSLocalizedDescription=The bundle “SOGraphDB-Mac Tests” couldn’t be loaded because it is damaged or missing necessary resources.}
Any idea what the root cause can be?
The error seems realated to "Library not loaded: #rpath/libswiftAppKit.dylib"
Both (framework and test bundle) compile without any error or warning (in Beta2)
I had a similar problem, though mine was an iOS test target, linking to a Swift framework, that failed to run on Xcode 6 GM. The test target had run successfully on an early beta of Xcode 6, but the final version reported the runtime error: Library not loaded: #rpath/libswiftCore.dylib
I noticed that a newer project did not have the failure, so I compared the build settings and test code. I was able to resolve the problem with three steps:
The test target needs the "Embedded Target Contains Swift Code" setting to be YES. This tells the linker to add the Swift runtime libraries to the executable.
The test target needs an explicit value for the "Runpath Search Paths" build setting. This tells the loader where to find the Swift runtime libaries. I copied the following setting from a fresh new test target:
LD_RUNPATH_SEARCH_PATHS = $(inherited) #executable_path/../Frameworks #loader_path/../Frameworks
The test cases need to explicitly import any modules that are used by the linked framework. In my project, the framework used UIKit but the test cases only used my framework. When I added an explicit import UIKit to the test cases, the link problem went away.
Since I keep running into this issue whenever I mess with build settings, here's the cleanest answer I can provide as of Xcode 8b5:
If unit tests don't run on iOS, make sure you have:
Runpath Search Paths: #loader_path/Frameworks
If unit tests don't run on macOS, make sure you have:
Runpath Search Paths: #loader_path/../Frameworks
This will show up as LD_RUNPATH_SEARCH_PATHS in your pbxproj file. You can also add $(inherited) to make sure project-wide paths are added as well, but those are probably empty.
Lastly, I didn't need the executable_path/... settings, doesn't make a difference for me whether they're there or not for unit tests.
I had the same problem.
Ended up copying libswiftAppKit.dylib out of the Xcode application directory (I am using beta 3), into a directory that I could reference (not part of an application bundle), then adding the library to the "Link binary with libraries" setting for the test bundle. My tests then started working.
FYI, the path for the dylib was at '/Applications/Xcode6-Beta3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftAppKit.dylib'
Probably not a good final solution, but it works for the interim.
My solution was to add a single file to my test target, AppKitTests.swift (or AppKitSpec.swift in my case), and all the file contains is:
// While I don't know why, The.framework is built linked to libswiftAppKit.
// Frameworks do not embed the Swift libraries themselves, it's up to the host
// app to include the necessary libraries. So here we are, including AppKit on
// behalf of The.framework so that the tests can run.
import AppKit
Oh, I also added AppKit to the test target's set of frameworks.
I had this occur to me in Beta 4 and it turned out that I had done it to myself without realizing it.
I had a Framework project called Fnord. My FnordTests target contained a couple of unit test classes that had import Fnord at the top of each file. For some reason Xcode was complaining about those imports and so I commented them out. This is when I started getting the same symptoms while trying to run my unit tests.
I noticed that the settings for my FnordTests target were such that the target would be linked with Fnord.framework, and I realized that it might not be able to do that with the aforementioned import Fnord statements diked-out.
So I put them back in, and everything went back to normal. Curiously, Xcode no longer showed those import statements as being problematic, but this is beta so I can forgive that.
I hope this helps someone.
I ran into the same issue, adding
import AppKit
in the Swift file fixed it