Speaking of KMP, when you were designing your Grad...
# orbit-mvi
g
Speaking of KMP, when you were designing your Gradle plugin to generate .swift files, was using Mustache the best option available at that time? What other options did you consider? I’m asking because I want to create a KSP library POC that will also generate .swift files to be used by an iOS app. (the POC already exists for generating kotlin files to be used in shared modules, but I want also to generate swift for the iosApp)
m
cc @appmattus
j
Good question, I’d be curious to know the answer too. Right now, I’m just making the bridge code myself and abstracting away the boilerplate as much as possible with Swift protocols. I preferred how KMP-NativeCoroutines adapted `Flow`s to `Publisher`s, so I ended up doing a bit of a frankenstein job that actually isn’t too bad.
a
I had originally looked at how KSwift was implementing their code generation. Didn’t like it much and figured a templating library would suit the problem best for ease of understanding and maintenance. Been a while since I’ve looked at templating libraries in detail but I always liked the simplicity of Mustache’s API.
g
I think using KSP for generating the files could also work. My main challenge is to understand how those .swift files that we’re generating will end up inside the framework (klib) to be used and referenced on the iOS side. Any hint?
a
The way kswift was working along with the orbit plugin is to generate a separate XCFramework (it can’t go into klib). Two frameworks is clunky but seemed the only viable option at the time I created it. However, skie also generates swift code but manages to link this directly into the main XCFramework - now it’s open source we should be able to take a peek to see how it does this magic.
🙌 1
j
The difficulty I’m running into is that you can’t reference Obj-C lightweight generics at runtime, so the Swift interface is never quite Swift-y. Either that or you just need to generate a bunch of boilerplate, which Swift macros or code generation would help out with.
g
I’ll take a look at Skie. For my POC, I only want to create these files and place them inside the iOS app so they can be used. They won’t establish any bridge to the shared module; they’re merely ‘boilerplate’ replacements. The code that handles the bridging (headers, Objective-C) is automatically generated by the multiplatform framework, so I only need to reference those functions in the Swift files. I still need to use a XCFramework right?
a
You don’t have to use an XCFramework if you don’t want to. Generally I was considering it more of a convenience given that in the KMM stuff I was looking at you’d already have the main XCFramework generated from the Kotlin code so it seemed a natural fit You can simply copy the files into the project 🤣 could make the Xcode build copy the files across probably with not too much difficulty if you really wanted to. There are of course other ways to package the files up; for example swift package manager or cocoapods
😇 1
👍 1
j
I use SwiftPoet to generate the Swift. It has basically the same API as KotlinPoet. Then use rsync (with checksum checking, so that it doesn’t cause rebuilding to occur if nothing changed) to copy them across to the iOS project in the same run script build phase as the KMP framework is built.
a
Ah yeah SwiftPoet that’s what KSwift was using. There were a few bugs or at least some constructs missing when I came across in it at the time when I first wrote the Orbit plugin
g
Gonna explore that rsync approach 👌🏼
@Jon Bailey How did you address the issue where, when we copy files to an iOS project without using Xcode, they appear to be “unavailable”, but if we do it within Xcode, a “reference” is created? The script moves the files and creates directories, but when I open the iOS app, they aren’t visible or recognized by Xcode.
Maybe I shall adapt my copy script to copy the files into a local SPM package instead 🤔 seems cleaner the integration with the iOS project…
j
I created a group in the sidebar in Xcode, then point it to the folder the files are copied to. Then right click the group and click add files, and select the generated files
They have to be generated at least once to do this
Also you have to add the files to the scripts output files list
It’s all a bit manual. It would be really nice if SKIE let you include your own Swift files into the framework. Hopefully they add that
👍 1
g
yeah… very manual indeed, XCode is such a pain in the ass with this type of configurations when compared to AndroidStudio
It’s not very scalable if the files will continue to grow. I could manage with an initial setup for the folder reference containing those files, but having to repeat this every time a new file is created becomes tedious. 😞
j
Yeah, I only have one file per module created to avoid this
1
Well one file per module per KSP generator
g
I was testing the SPM approach, and it was going well (at least that’s how it seemed), but then one of those files I needed to copy imports another from my XCFramework, and things started to get messy.
yup that one file is a good approach too, just need to setup once and you’re good to go. Maybe will follow that
I don’t know if this was your original suggestion but: 1 - Create a group in the project’s root 2 - In copy bundle resources choose that folder 3 - Add the runscript with the script that does the copy This 1 time setup works. If I generate more files they get all copied auto 🙌
still gonna try to solve this just by scripting, but for now is a satisfactory solution.
could be a false positive because they are not getting attached to the desired target, therefore i can’t use them
j
I don’t think copy resources will work for source code, I can post my setup tomorrow if that helps
👀 1
Also I’d be wary of modifying the Xcode project while it’s open/building given how temperamental it can be
j
Yeah, if you were going to do project generation a la Cocoapods, then I would do it as a separate project that is building another framework. But at that point you might as well use SPM.
g
I came up with a script using xcodeproj and so far it’s working good. Just need to run more tests and see if the script should be run by gradle or xcode