Using static libraries in Swift with CocoaPods fails for Realm - swift

Since Xcode 9 it is possible to use static libraries by omitting the use_frameworks! flag in the Podfile. However, when used with the Pod RealmSwift this results in the following error:
[!] The following Swift pods cannot yet be integrated as static libraries:
The Swift pod `RealmSwift` depends upon `Realm`, which do not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set `use_modular_headers!` globally in your Podfile, or specify `:modular_headers => true` for particular dependencies.
Sadly, the proposed solution with use_modular_headers! does not work.
Other things I have tried include:
Using the latest Realm version (3.15.0)
Use the Objective C version and add Swift support, this won't build and give a module not found error in the RLMSupport.swift file .
Adding a bridging header for the Objective C version.
Endless clean, rebuild, Xcode relaunches and Derived Data folder cleaning.
It would not be preferable to circumvent CocoaPods and have this dependency be installed in a separate way, since that would make updating a more complex process. I hope there is a solution that works with CocoaPods, Realm and Swift.

I did the job doing following:
pod 'RealmSwift', '~> 3.17', :modular_headers => true
pod 'Realm', '~> 3.17', :modular_headers => true

As far as I can tell adding use_modular_headers! to top of Podfile works.
Adding s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } to .podspec doesn't work as far as I can tell. (Cocoapods 1.6.0-beta.2)
example:
target 'Opportunity' do
use_modular_headers!
end

I don't see why it wouldn't work. I got the same issue, and I added use_modular_headers! following way in the podfile and it worked.
target 'Pick Up Lines' do
use_modular_headers!
pod 'RealmSwift'
end
By the way, before doing any of it, make sure, you set the deployment target of the project as 11.0.

Related

XCFramework "Cannot load underlying module"

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!

XCode 12: 'SessionDelegate' has different definitions in different modules

Edit:
This problem occurs after XCode 12 Beta5. Xcode doesn't allow different modules to define same names (Probably for public classes & protocols). Alamofire and Kingfisher appears to define SessionDelegate at the same time. I'm still trying to find a solution..
I'm implementing iOS 14 Widgets in our application. I have started working with XCode 12 Beta 2 and everthing was compiling fine. When I have updated XCode to XCode 12 Beta 6, I faced with following error:
'SessionDelegate' has different definitions in different modules;
first difference is definition in module 'Kingfisher.Swift' found end
of class
I'm also attaching the screenshot of the file with error.
Is there any way to edit header files to have different names for SessionDelegate for Alamofire or Kingfisher? Is there any workaround to overcome this issue?
Here are things I have tried so far:
I have updated both Alamofire and Kingfisher to latest version
I have cleaned Podfile.lock and all pods as well as Derived Data
I tried to compile with Legacy Build System
You can try SWIFT_INSTALL_OBJC_HEADER = NO, it works for me
At this moment (Xcode 12.0 or Xcode 12.2b2), the only possible solution is to rename the Objective-C interface and avoid conflicts. This could be done by one of:
Rename conflicting class entirely, update all places where it's used (e.g. replace SessionDelegate by KingfisherSessionDelegate)
Add #objc(...) attribute to a Swift class, which will update the Obj-C interface in a generated ...-Swift.h file and avoid the names conflict.
// SessionDelegate.swift
#objc(KFSessionDelegate)
class SessionDelegate: NSObject { ... }
// Kingfisher-Swift.h
#interface KFSessionDelegate : NSObject
...
#end
This solution is already included in the Kingfisher 5.15.4 release and could be applied to any other libraries and your own frameworks.
Also, the thread on Apple forums: https://developer.apple.com/forums/thread/658012
The error is saying that you have multiple classes with the same name SessionDelegate in different modules. This error is related to Xcode 12.
For now, a quick solution is to install the module with CocoaPods (if you're using Carthage) and if needed, rename the SessionDelegate interface.
If you guys need a temporary solution, here is how for Cocoapods users:
Clone the Kingfisher library to the same folder level with your project. You can get it from Github
Open Kingfisher.xcworkspace in XCode and rename SessionDelegate.swift file under Sources/Netowking to KingFisherSessionDelegate and change the class name as well accordingly.
Rename the usages of SessionDelegate to KingfisherSessionDelegate which is only available in Sources/Networking/ImageDownloader.swift as of Kingfisher version 5.15.0
Add local path in your Podfile
pod 'Kingfisher', :path => '../Kingfisher'
I too had the same issue, sam's solution worked for me but with one change. There are 2 pods with the same definition so i changed the value of SWIFT_INSTALL_OBJC_HEADER to NO for both the pods. After doing it i was getting import error in one of the pod. So then i changed SWIFT_INSTALL_OBJC_HEADER to YES for that particular pod which was having the import error and kept the other pods SWIFT_INSTALL_OBJC_HEADER to NO. This worked for me.
for me worked when I update the 'SWIFT_INSTALL_OBJC_HEADER' key in podfile
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
if target.name == 'Alamofire'
target.build_configurations.each do |config|
config.build_settings['SWIFT_INSTALL_OBJC_HEADER'] = 'No'
end
end
end
end
end

How to integrate FBSDKCoreKit into a Swift custom Framework?

Did anyone managed to integrate FBSDKCoreKit to a custom swift framework with cocoapods (or alternate method)?
When I do this (experiment 1):
target 'MyFramework' do
project 'MyFrameWork/MyFramework.xcodeproject'
pod 'FacebookSDK', :modular_headers => true
end
target 'MyApp' do
workspace 'MyWorkspace.xcworkspace'
project 'MyApp/MyApp.xcodeproj'
inherit! :complete
target :MyAppTests
target :MyAppUITests
end
I get No such module 'FBSDKCoreKit' when compiling the framework (same applies when setting modular_headers => false.
I have also tested use_frameworks! as follows: (experiment 2):
target 'MyFramework' do
project 'MyFrameWork/MyFramework.xcodeproject'
use_frameworks!
pod 'FacebookSDK'
end
target 'MyApp' do
workspace 'MyWorkspace.xcworkspace'
project 'MyApp/MyApp.xcodeproj'
inherit! :complete
target :MyAppTests
target :MyAppUITests
end
But then I get this error:
dyld: Library not loaded: #rpath/Bolts.framework/Bolts
Referenced from: /private/var/containers/Bundle/Application/***/MyApp.app/Frameworks/MyFramework.framework/MyFramework
Reason: image not found`.
Note: When I add the FacebookSDK to MyApp (with use_frameworks!) it works, but then, I can't make use of it from within MyFramework (hence useless to me).
I finally found another way to do that, so I dropped Cocoapods.
I stumbled upon the fact that Facebook publishes a Swift package (https://swiftpackageregistry.com/facebook/facebook-ios-sdk).
So I proceeded as follows:
removed pod 'FacebookSDK' from my pod file;
added the above mentioned package for my framework.
And voila!

No such module RealmSwift

This is not a duplicate question.
I have been using realm for a long time. Recently I am getting the error of "No such module RealmSwift". But this is happening only in release target scheme not in build target scheme. Is there any particular reason as to why it is not working only in release? I have seen this question at a lot of places but none of those solutions worked for me.
My podfile looks similar to this:
# Uncomment the next line to define a global platform for your project
platform :ios, '12.0'
#use_modular_headers!
inhibit_all_warnings!
def shared_pods
pod 'RealmSwift'
end
target ‘************’ do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for ************
shared_pods
target '************Tests' do
inherit! :search_paths
# Pods for testing
end
end
target '************UITests' do
inherit! :search_paths
# Pods for testing
# shared_pods
end
This is more of a troubleshooting step than a direct answer since I duplicated your issue.
You've been using Realm a while so you know this but for future readers, ensure that any file where you're using RealmSwift includes
import RealmSwift
I just tried your podfile on a new project and am getting weird behavior as well. I replaced your podfile with the following 5 lines and it works correctly.
project 'Realm Test.xcodeproj'
target 'Realm Test' do
use_frameworks!
platform :osx, '10.13'
pod 'RealmSwift'
end
That was a macOS project but it worked equally well with an iOS project. On that project I uncommented #platform :ios, '12.0'
I think this is the issue
inherit! :search_paths
That lets the target know about the search paths but does not link them in. I would suggest changing that to
inherit! :complete
Which appears to be working in my project.
Oh - for completness, I ran into this once as well and the solution was
add the parent path of RealmSwift.framework (i.e., the containing
directory) to your framework search paths.
This is a common Realm bug which occurs in Xcode after pod install. Clean and Build the project once, the bug should go away!

Library not found for -lFirebase after installing XLForm

I have a project in Swift where I use some libraries. When I run on the simulators or on the physical device, it runs perfectly. But by the time I try to archive the project to send it to the store, I receive the following error message:
ld: library not found for -lFirebase
The problem is when I use the XLForm library, which was the last modification I have done to my Podfile.
I am using the .xcworkspace since I started using the CocoaPods, and I have never had any problem before.
My Podfile:
# Uncomment this line to define a global platform for your project
# platform :ios, '8.0'
# Uncomment this line if you're using Swift
# use_frameworks!
pod 'Firebase', '= 2.5.0'
pod 'Google/CloudMessaging'
pod 'Google'
pod 'Google/Analytics'
pod 'XLForm', '~> 3.0'
target 'Dimmi' do
end
target 'DimmiTests' do
end
target 'DimmiUITests' do
end
The XLForm library does not depends on any other library or framework. Also, I tried to install it manually with no success.
You need to create a bridging header file and import the Objective-C framework through it.
Create a new header file and name it in the following pattern:
ProjectName-Bridging-Header.h
Then add your framework header to it
#import Framework.h
Then add the bridging header to your build settings under Objective-C Bridging Header.