I'm building an iOS framework (both a .framework and an .xcframework) which contains some of my source code which uses RealmSwift.
I've found that I can sucessfully build the framework and use it in an app provided it uses a subset of the Realm API, but attempting to include some aspects of the API results in a symbol not found runtime error.
I can, for example, use the framework to open the db, add items, fetch items etc. etc. However if I attempt to reference a Results object then I get:
dyld[11749]: Symbol not found: _$s10RealmSwift7ResultsVyxGSlAASl5countSivgTW
Why might this be?
Here's a bit of code for reference(not complete, sufficient to illustrate), and build settings
public class ObjectA: Object, Codable {
@objc dynamic var category: String = ""
override public static func primaryKey() -> String? {
return "category"
}
}
public func addA(key:String) {
do {
let objectA = ObjectA()
objectA.category = key
let realm = try Realm(configuration: configuration!)
try? realm.write {
realm.add(objectA, update: Realm.UpdatePolicy.all)
}
} catch let error as NSError {
NSLog(TAG + "ERROR calling add() \(error.code) \(error.description)")
}
}
public func getAllAs() -> Results<ObjectA> {
let realm = try! Realm(configuration: configuration!)
let items = realm.objects(ObjectA.self)
return items
}
And some code calling it:
RealmDatabase.instance().addA(key: "something") //ok
let found = RealmDatabase.instance().findObjectA(key: "something") //ok
let allA = RealmDatabase.instance().getAllAs() // ok
let c = allA.count // not ok
If the above 4 lines are included in the framework, that will result in the error. If the last line is omitted, then the code runs successfully.
The pod file for the framework is:
target 'TheFramework' do
use_frameworks!
pod 'Realm', '10.49.1'
pod 'RealmSwift', '10.49.1'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
The pod file for the app using the framework is:
target 'ReferenceApp' do
project 'ReferenceApp.xcodeproj'
use_frameworks!
pod 'Realm', '10.49.1'
pod 'RealmSwift', '10.49.1'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
end
end
end
In the framework Xcode project, the Frameworks & Libraries section for the pods.framework is set to Do Not Embed. Build library for distribution is set to YES.
In the app using the Xcode project, the Frameworks & Libraries section for its pods.framework is similarly set to Do Not Embed, the framework is set to Embed & Sign.
Why can I reference and use 90% of the Realm API, but not 100%. Why does only a small part of the API result in a symbol not found error?
I'm building an iOS framework (both a .framework and an .xcframework) which contains some of my source code which uses RealmSwift.
I've found that I can sucessfully build the framework and use it in an app provided it uses a subset of the Realm API, but attempting to include some aspects of the API results in a symbol not found runtime error.
I can, for example, use the framework to open the db, add items, fetch items etc. etc. However if I attempt to reference a Results object then I get:
dyld[11749]: Symbol not found: _$s10RealmSwift7ResultsVyxGSlAASl5countSivgTW
Why might this be?
Here's a bit of code for reference(not complete, sufficient to illustrate), and build settings
public class ObjectA: Object, Codable {
@objc dynamic var category: String = ""
override public static func primaryKey() -> String? {
return "category"
}
}
public func addA(key:String) {
do {
let objectA = ObjectA()
objectA.category = key
let realm = try Realm(configuration: configuration!)
try? realm.write {
realm.add(objectA, update: Realm.UpdatePolicy.all)
}
} catch let error as NSError {
NSLog(TAG + "ERROR calling add() \(error.code) \(error.description)")
}
}
public func getAllAs() -> Results<ObjectA> {
let realm = try! Realm(configuration: configuration!)
let items = realm.objects(ObjectA.self)
return items
}
And some code calling it:
RealmDatabase.instance().addA(key: "something") //ok
let found = RealmDatabase.instance().findObjectA(key: "something") //ok
let allA = RealmDatabase.instance().getAllAs() // ok
let c = allA.count // not ok
If the above 4 lines are included in the framework, that will result in the error. If the last line is omitted, then the code runs successfully.
The pod file for the framework is:
target 'TheFramework' do
use_frameworks!
pod 'Realm', '10.49.1'
pod 'RealmSwift', '10.49.1'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
The pod file for the app using the framework is:
target 'ReferenceApp' do
project 'ReferenceApp.xcodeproj'
use_frameworks!
pod 'Realm', '10.49.1'
pod 'RealmSwift', '10.49.1'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
end
end
end
In the framework Xcode project, the Frameworks & Libraries section for the pods.framework is set to Do Not Embed. Build library for distribution is set to YES.
In the app using the Xcode project, the Frameworks & Libraries section for its pods.framework is similarly set to Do Not Embed, the framework is set to Embed & Sign.
Why can I reference and use 90% of the Realm API, but not 100%. Why does only a small part of the API result in a symbol not found error?
Share Improve this question asked Mar 16 at 15:54 PiepantsPiepants 37.3k46 gold badges198 silver badges397 bronze badges Recognized by Mobile Development Collective 3- Just as an aside .. this is cocoa pods ?! Would it be wise to just move on to SPM? – Fattie Commented Mar 19 at 12:00
- 1 @Fattie, I think the issue is a nested framework issue and is independent of the installation mechanism. But anyway, attempting to create a minimal reproducible variant using SPM has led to another issue: stackoverflow/questions/79520669/… – Piepants Commented Mar 19 at 15:46
- gotchya what a bummer – Fattie Commented Mar 19 at 16:23
2 Answers
Reset to default 0Using Realm with SPM rather than pods seems to eliminate the issue
Embed RealmSwift in the App
Open the App’s Xcode Project
Open the Xcode project for your ReferenceApp.Navigate to Frameworks Section
In the project navigator, select the ReferenceApp target, then go to the "General" tab and scroll to "Frameworks, Libraries, and Embedded Content."Add RealmSwift.framework
Click the "+" button, select RealmSwift.framework from the list it should appear since you’re using the RealmSwift pod, and add it.Set to Embed & Sign
Ensure RealmSwift.framework is set to "Embed & Sign" in the dropdown next to it not "Do Not Embed".Clean and Rebuild
Go to "Product" > "Clean Build Folder," then build and run the app again.The error happens because RealmSwift isn’t fully embedded, so symbols like Results count are missing at runtime. The solution embeds RealmSwift in the app, making it provide the symbols your framework needs.