Are there comprehensive docs on consuming an xcfra...
# ios
p
Are there comprehensive docs on consuming an xcframework using cinterop? We have one working for an xcframework that was created using
xcodebuild -create-xcframework -framework
But using the same config for an xcframework created using
xcodebuild -create-xcframework -library
fails. Get an error that there are undefined symbols for the target arch
Undefined symbols for architecture arm64:
If I
lipo -thin arm64
the .a and then search for the symbols using
strings
the symbols are present
d
Hi @Paddy O'Brien, I've just set up XCFramework consumption in our project; it seems to be working as expected.
I don't think there's any comprehensive documentation - we're at the bleeding edge on this one.
p
is it wrapping .a files or .framework files? Are you able to share your config?
d
Sure let me dig out the relevant parts.
Amusingly - I did log on to ask a question about a problem with it 🙃
But it's more to do with refreshing the interop code generated without having to do a full clean, than generating it in the first place.
The high level process I've got is this - it's simple but effective so far: • A shell script that does the three XCFramework stages: ◦
xcodebuild
for Device â—¦ `xcodebuild`for Simulator â—¦ `xcodebuild`to combine those two
.frameworks
to an XCFramework
As you'll have seen, an XCFramework is really just a folder structure for Frameworks with a bit of plist metadata
p
It can also wrap static libraries using
xcodebuild -create-xcframework -library
unfortunately thats what we are being given by a third party
d
Then the script places the output XCFramework into a folder alongside a hand-made
.podspec
file
The podspec file uses the
vendored_frameworks
field to point to the XCFramework.
Hopefully this is familiar I'm listing it out in case anything is majorly different your side.
p
ahh, we also arent using the cocoapods plugin 😅
d
Ah right, I wouldn't know how else to do it TBH, now you've got me curious!
I thought using that would be the path of least resistence.
To put some lipstick on it and push it towards the Cocoapods plugin
😄
It does work.
p
I know how to do it, I just don’t wanna 😄 We consume multiple kmm frameworks from our iOS app with other modules shared between those. What we run into when we build with parallel targets, which is what cocoapods does, is classpath errors because one target starts downloading a dependency and the next just assumes its there
FWIW, I would not recommend multiple kmm frameworks, were in the process of moving to an umbrella module
Are you on Kotlin 1.7 by any chance?
l
One of the libraries we use in a project at work just switched to xcframeworks. If it helps, the best I’ve found is to keep the -framework flags in the def file, but start using linkerOpts.iosArm64, linkerOpts.iosX64, and linkerOpts.iosSimulatorArm64 to point to the individual frameworks inside (I’m sure there’s a much better way without pods, but I haven’t found it).
p
Is that separate .def files for each arch?
l
In a .def file, you can specify the arch/os
So my .def file could contain
Copy code
linkerOpts.linux = ...
linkerOpts.iosX64 = ...
linkerOpts.iosSimulatorArm64 = ...
linkerOpts.iosArm64 = ...
and it would look up the proper line based on the architecture/os at link time.
p
Hrm, that’s useful knowledge, I wish there were comprehensive docs or an EBNF grammar somewhere
l
I agree. I always forget the names, then I have to keep typing until IntelliJ doesn’t give red squiggles anymore. Except that it always marks iosSimulatorArm64 with red squiggles.
I only found out about this when I was reading a def file in the jetbrains samples.
p
I assume it works for other fields as well? not just linkerOpts?
l
Yes
As far as I can tell, it works for all of them. I believe you can even do something like
Copy code
compilerOpts.ios = ...
compilerOpts.iosX64 = <more specific args>
if you have some args that don’t depend on architecture, but I haven’t thoroughly tested that.