kpgalligan
12/13/2024, 7:31 PMMario Loncar
12/16/2024, 3:41 PMkpgalligan
12/16/2024, 5:20 PMMario Loncar
12/16/2024, 6:50 PMskie {
analytics {
enabled.set(false)
}
features {
group {
FunctionInterop.FileScopeConversion.Enabled(false)
DefaultArgumentInterop.Enabled(false)
}
}
build {
produceDistributableFramework()
enableRelativeSourcePathsInDebugSymbols.set(true)
}
}
...
kotlin {
XCFramework(iosLibraryName).apply {
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { target ->
target.binaries.framework {
sharedData.forEach(::export)
baseName = iosLibraryName
binaryOption("bundleId", iosLibraryName)
isStatic = true
add(this)
}
}
}
sourceSets {
commonMain {
...
}
}
}
It is basically Android project with shared
module.
I build (debug) XCFramework using this command: :shared:assembleMultiplatformLibDebugXCFramework
which is then published to S3 bucket.
I saw in articles that you suggest using KMMBridge. Perhaps XCFramework export is done differently through it. 🤔kpgalligan
12/16/2024, 7:02 PMI saw in articles that you suggest using KMMBridgeIt's easier for most to set up publishing with KMMBridge, generally speaking, but it's not doing anything specific that would impact debugging (IIRC). Where do you host the
Package.swift
file? Is it the same Android repo, or do you "publish" SPM to another repo?kpgalligan
12/16/2024, 7:04 PMPackage.swift
file to a different repo without the rest of the source code, SPM/Xcode won't have it when the repo is cloned.Mario Loncar
12/17/2024, 8:34 AMkpgalligan
12/17/2024, 4:01 PMPackage.swift
to the "other" repo, you can just push the code as well. That'll let you debug. Pushing code around seems a little ugly, but doing it that way makes sure the code you're looking at is the correct version.kpgalligan
12/17/2024, 4:04 PMkpgalligan
12/17/2024, 4:04 PMkpgalligan
12/17/2024, 4:07 PM- uses: touchlab/ga-push-remote-swift-package@v1.1
id: push-remote-swift-package
with:
commitMessage: "KMP SPM package debug build for ${{ github.ref }}"
remoteRepo: touchlab/KMMBridgeAndroidDevFlowPublish
remoteBranch: ${{ github.ref }}
The dev/debug flow doesn't use tag versions. The idea is you can publish a feature change from Android to a branch, and point SPM to a branch rather than a version. "Why?" is a bit longer of an explanation.kpgalligan
12/17/2024, 4:09 PMMario Loncar
12/17/2024, 4:20 PMWhen you pushyeah I will go with this, but the thing that makes it a bit uglier in our case is the fact that repos are private and XCFramework itself is hosted on S3, rather than asset in SPM repository. 😄 The solution is logical and straightforward. Obstacles are quite specific to my use case unfortunately. Thanks for the effort. I appreciate it.to the "other" repo, you can just push the code as well. That'll let you debug. Pushing code around seems a little ugly, but doing it that way makes sure the code you're looking at is the correct version.Package.swift
kpgalligan
12/17/2024, 4:26 PMMario Loncar
12/17/2024, 4:53 PMkpgalligan
12/17/2024, 5:33 PMFor S3 we use asset authAny details on what that is and how it works? We haven't done much with S3 because Xcode/SPM need to be able to access resources using basic auth, which S3 doesn't (or didn't at some point) support.
I think I could just clone the KMP repo in SPM repo, take source code from it and commit.That's effectively what this is doing: https://github.com/touchlab/ga-push-remote-swift-package/blob/ad9b8b94b7e5790be230d7a569da871aac9700ae/src/main.ts#L48 It looks a little complicated, but it's standard git. From the source repo: • Fetch branch from target repo, or fetch default branch if the specific branch doesn't exist • Create a local branch from the fetch, and create a worktree for that branch • Copy everything from the source into the target (skipping
.git
and .github
, which would be bad)
• Push the branch or tag, depending on what you're trying to doMario Loncar
12/18/2024, 12:41 PMshared
module. When we want to publish XCFramework to iOS we use github action from Android repository. In the action, you can choose if you want to release stable or dev version. Stable version will just have semantic versioning number as filename, while dev version will contain lib name + part of checksum (since XCode won't see new file as different if they are named the same).
Action runs assembleMultiplatformLib[Debug|Release]XCFramework
, we configure AWS credentials using predefined Github Action:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.YOUR_ID }}
aws-secret-access-key: ${{ secrets.YOUR_KEY }}
aws-region: your-region
After that actions finds the XCFramework that needs to be uploaded and syncs it to S3 to its appropriate bucket. Bucket in our case if version of the XCFramework artifact:
aws s3 sync "$xcframework_dir" "$s3_bucket/$version/"
The key part after this is notifying iOS SPM repository (which contains path and checksum to XCFramework) via curl that state of library changed. For instance:
curl -X POST \
-H "Authorization: Bearer ${{ secrets.YOUR_TOKEN }}" \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Content-Type: application/json" \
<https://api.github.com/repos/$SWIFT_PACKAGE_REPO_OWNER/$SWIFT_PACKAGE_REPO/dispatches> \
--data "{\"event_type\": \"$event_type\", \"client_payload\": {\"release_version\": \"$version\", \"checksum\": \"$checksum\", \"checksum_short\": \"$checksum_short\", \"branch\": \"$GITHUB_REF_NAME\"}}"
This JSON, containing version of library and checksum is then parsed in iOS SPM repository which then modifies Package.swift with new path and checksum to the XCFramework and commits it, creates tag and release. And that is it. iOS devs can choose between main branch which contains stable versions or pick branch on SPM which is specific for some published dev version.
Package.swift looks like this in the end:
import PackageDescription
let frameworkName = "MultiplatformLib"
let packageUrl = "<https://our-resource-server/app-assets/multiplatform/5.20.0/MultiplatformLib.xcframework.zip>"
let fileChecksum = "generated-checksum-from-json"
let package = Package(
name: frameworkName,
products: [
.library(
name: frameworkName,
targets: [frameworkName]),
],
targets: [
.binaryTarget(
name: frameworkName,
url: packageUrl,
checksum: fileChecksum
)
]
)
So yeah, in order for debugging to work on published SPM XCFramework, I will just clone the source repo, take shared
and commit it so SPM repository. Basically, as you said, similar to what you suggested. Will let you know how that worked out!Mario Loncar
12/18/2024, 3:51 PMshared
directory in published SPM and debugging now works. Awesome news!kpgalligan
12/18/2024, 4:08 PM<https://our-resource-server/>
is some kind of S3 front end?kpgalligan
12/18/2024, 4:09 PMMario Loncar
12/18/2024, 4:35 PMMario Loncar
12/18/2024, 4:36 PM