A Gradle plugin for Kotlin Multiplatform projects that generate a XCFramework for Apple targets or a FatFramework for iOS targets, and manages the publishing process in a CocoaPod Repository.

Overview

KMP Framework Bundler

Maven Central License

KMP Framework Bundler is a Gradle plugin for Kotlin Multiplatform projects that generate a XCFramework for Apple targets or a FatFramework for iOS targets, and manages the publishing process in a CocoaPod Repository.

This plugin is a rewrite of the archived KMP FatFramework Cocoa. There is a migration guide below.

Setup

The library is uploaded on MavenCentral, so you can easily add the dependency on the plugins block:

plugins {
    id("com.prof18.kmp-framework-bundler") version "<latest-version>"
}

You can configure the plugin with the frameworkBundlerConfig block in your build.gradle[.kts].

The required fields are the following:

  • the name of the framework
  • the output path
  • the version name
  • the framework type:
    • XC_FRAMEWORK
    • XC_FRAMEWORK_LEGACY_BUILD
    • FAT_FRAMEWORK
frameworkBundlerConfig { 
  frameworkName.set("LibraryName")
  outputPath.set("$rootDir/../test-dest")
  versionName.set("1.0.0")
  frameworkType = FrameworkType.XC_FRAMEWORK
}

If the selected frameworkType is XC_FRAMEWORK, the official Gradle task provided by the Kotlin Team will be used to build the XCFramework. To use this official task, some setup is required:

import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework

plugins {
    kotlin("multiplatform")
}

kotlin {
    val xcf = XCFramework()

    ios {
        binaries.framework("LibraryName") {
            xcf.add(this)
        }
    }
    watchos {
        binaries.framework("LibraryName") {
            xcf.add(this)
        }
    }
    tvos {
        binaries.framework("LibraryName") {
            xcf.add(this)
        }
    }
    
    ...
}

Additional information is available in the official Kotlin doc.

If the selected frameworkType is XC_FRAMEWORK_LEGACY_BUILD, a custom task will be used to build the XCFramework. This is required before Kotlin 1.5.30.

If the selected frameworkType is FAT_FRAMEWORK, then a FatFramework will be built. When using a FatFramework, only iOS targets can be packed together. With XCFramework you can pack together all the Apple families: iOS, macOS, etc.

If you want to generate a CocoaPod repository, you have also to provide some parameters in the cocoaPodRepoInfo block:

  • a summary of the library
  • the homepage of the library
  • the license of the library
  • the authors of the library
  • the URL of the git repository that hosts the CocoaPod repo: this field is mandatory
frameworkBundlerConfig {
    frameworkName.set("LibraryName")
    outputPath.set("$rootDir/../test-dest")
    versionName.set("1.0.0")
    frameworkType = XC_FRAMEWORK

    cocoaPodRepoInfo {
        summary.set("This is a test KMP framework")
        homepage.set("https://github.com/prof18/cocoa-repo-xcframework-test")
        license.set("Apache")
        authors.set("\"Marco Gomiero\" => \"[email protected]\"")
        gitUrl.set("[email protected]:prof18/cocoa-repo-xcframework-test.git")
    }
}

Usage

The plugin adds five Gradle tasks to your project. The tasks relative to XCFramework or FatFramework will be added based on the selected frameworkType, e.g. if you choose an XCFramework, then only tasks related to XCFrameworks will appear.

  • buildDebugIosFatFramework that creates a FatFramework with the Debug target.

  • buildDebugXCFramework that creates a XCFramework with the Debug target.

  • buildReleaseIosFatFramework that creates a FatFramework with the Release target.

  • buildReleaseXCFramework that creates a XCFramework with the Release target.

  • generateCocoaPodRepo that generates a CocoaPod repository ready to host the Framework.

  • publishDebugIosFatFramework that publishes the Debug version of the FatFramework in the CocoaPod repository.

  • publishDebugXCFramework that publishes the Debug version of the XCFramework in the CocoaPod repository.

    The "publishDebug" task (for both the type of frameworks) takes care of everything:

    • changing the working branch of the CocoaPod repo from main/master to develop
    • building the debug framework
    • updating the version name inside the Podspec file
    • committing the changes
    • and publishing to remote

    In this way, in the iOS project, you can use the latest changes published on the develop branch:

    pod '<your-library-name>', :git => "[email protected]:<git-username>/<repo-name>.git", :branch => 'develop'

    To run this task, the outputPath provided in the frameworkBundlerConfig block must point to an existing local git repository (for example, the path "$rootDir/../test-dest" in the sample above, is a git repository), already initialized as a CocoaPod repo, with a .podspec file. If this is not the case, you can use the generateCocoaPodRepo task to generate one.

  • publishReleaseIosFatFramework that publishes the Release version of the FatFramework in the CocoaPod repository.

  • publishReleaseXCFramework that publishes the Release version of the XCFramework in the CocoaPod repository.

    The "publishRelease" task (for both the type of frameworks) takes care of everything:

    • changing the working branch of the CocoaPod repo from develop to main/master
    • building the release framework
    • updating the version name inside the Podspec file
    • committing the changes
    • tagging the commit
    • and publishing to remote

    In this way, in the iOS project, you have to specify a version:

    pod '<your-library-name>', :git => "[email protected]:<git-username>/<repo-name>.git", :tag => '<version-number>'

    To run this task, the outputPath provided in the frameworkBundlerConfig block must point to an existing local git repository (for example, the path "$rootDir/../test-dest" in the sample above, is a git repository), already initialized as a CocoaPod repo, with a .podspec file. If this is not the case, you can use the generateCocoaPodRepo task to generate one.

Sample Project

To see the plugin in action, I've published a little sample project. This project will publish a FatFramework to: https://github.com/prof18/fat-framework-cocoa-repo-test and an XCFramework to https://github.com/prof18/xcframework-cocoa-repo-test/tree/main. The framework are imported in the FrameworkTest iOS project.

Migration from KMP FatFramework Cocoa

If you were a user of the KMP FatFramework Cocoa plugin, you can easily migrate to the KMP Framework Bundler. Here are the required changes:

  1. The plugin id changed from com.prof18.kmp.fatframework.cocoa to com.prof18.kmp-framework-bundler
  2. The name of the configuration DSL changed from fatFrameworkCocoaConfig to frameworkBundlerConfig
  3. The useXCFramework flag is deprecated in favour of the frameworkType selection

For reference, the following old configuration

fatFrameworkCocoaConfig {
    frameworkName = "LibraryName"
    outputPath = "$rootDir/../test-dest"
    versionName = "1.0"
    useXCFramework = true

    cocoaPodRepoInfo {
        summary = "This is a test KMP framework"
        homepage = "https://github.com/prof18/ccoca-repo-test"
        license = "Apache"
        authors = "\"Marco Gomiero\" => \"[email protected]\""
        gitUrl = "[email protected]:prof18/ccoca-repo-test.git"
    }
}

become:

frameworkBundlerConfig {
    frameworkName.set("LibraryName")
    outputPath.set("$rootDir/../test-dest")
    versionName.set("1.0.0")
    frameworkType = XC_FRAMEWORK

    cocoaPodRepoInfo {
        summary.set("This is a test KMP framework")
        homepage.set("https://github.com/prof18/cocoa-repo-xcframework-test")
        license.set("Apache")
        authors.set("\"Marco Gomiero\" => \"[email protected]\"")
        gitUrl.set("[email protected]:prof18/cocoa-repo-xcframework-test.git")
    }
}

Further Readings

This plugin is born from a set of unbundled Gradle tasks that I was copying between every Kotlin Multiplatform project. I've written about these tasks in a couple of articles:

For more info about CocoaPod, I suggest reading the following resources:

License

   Copyright 2022 Marco Gomiero

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
You might also like...
A Bluetooth kotlin multiplatform "Cross-Platform" library for iOS and Android

Blue-Falcon A Bluetooth "Cross Platform" Kotlin Multiplatform library for iOS, Android, MacOS, Raspberry Pi and Javascript. Bluetooth in general has t

Dependency Injection library for Kotlin Multiplatform, support iOS and Android

Multiplatform-DI library for Kotlin Multiplatform Lightweight dependency injection framework for Kotlin Multiplatform application Dependency injection

Simple Kotlin Multiplatform PrayerTimes App for iOS and Android

Kotlin Multiplatform ___ _______ ___ / _ \_______ ___ _____ ___/_ __(_)_ _ ___ ___ / _ | __

Location Service Manager for Kotlin Multiplatform Mobile iOS and android
Location Service Manager for Kotlin Multiplatform Mobile iOS and android

Location Service Manager for Kotlin Multiplatform Mobile iOS and android Features Provides simple permission settings Dramatically reduce the amount o

Kotlin Multiplatform Mobile demo for Android and iOS - app for viewing Cat pictures
Kotlin Multiplatform Mobile demo for Android and iOS - app for viewing Cat pictures

CatViewerDemo Android demo iOS demo Kotlin Multiplatform Mobile demo for Android and iOS. App for viewing Cat pictures from Cats API. This sample show

A local storage management library for Kotlin Multiplatform Mobile iOS and android
A local storage management library for Kotlin Multiplatform Mobile iOS and android

A local storage management library for Kotlin Multiplatform Mobile iOS and android Features iOS and Android local storage in one interface Provides ge

A Kotlin Multiplatform Project using TMDB Api. Currently supports Android,iOS,Desktop and web platforms
A Kotlin Multiplatform Project using TMDB Api. Currently supports Android,iOS,Desktop and web platforms

A Kotlin Multiplatform Project using TMDB Api(https://www.themoviedb.org/). Currently this project is implemented in following platforms Andr

Kotlin Multiplatform is an SDK for cross-platform mobile development, which enables teams to use the same business logic in both Android and iOS client applications.
Kotlin Multiplatform is an SDK for cross-platform mobile development, which enables teams to use the same business logic in both Android and iOS client applications.

Kotlin Multiplatform is an SDK for cross-platform mobile development, which enables teams to use the same business logic in both Android and iOS client applications.

BlurHash support for iOS, Android and JVM via Kotlin Multiplatform
BlurHash support for iOS, Android and JVM via Kotlin Multiplatform

blurhash A Kotlin Multiplatform library to use blurhash in your Android App, iOS / Mac App & JVM Backend. Android iOS JVM Why? If you've tried using b

Comments
  • A problem occurred configuring root project 'projectName'. > You must provide the property `frameworkName`

    A problem occurred configuring root project 'projectName'. > You must provide the property `frameworkName`

    Hi~

    I added this line in my Gradle plugins DSL id("com.prof18.kmp-framework-bundler") version "0.0.1"

    Then click Gradle sync now. finally, gradle will throw this exception

    FAILURE: Build failed with an exception.
    
    * What went wrong:
    A problem occurred configuring root project 'projectName'.
    > You must provide the property `frameworkName`
    
    * Try:
    > Run with --stacktrace option to get the stack trace.
    > Run with --info or --debug option to get more log output.
    > Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 151ms
    

    I also tried this in an empty project, but it still

    opened by darkokoa 2
  • podspec file does not exists!

    podspec file does not exists!

    I'm getting this error after running publishReleaseXCFramework:

    > podspec file does not exists!

    Does the repo being pointed to in gitUrl.set() need to already be a cocoapod repo and already have a podspec file before running the above task?

    Also, I'm confused about this line in the readme:

    To run this task, the outputPath provided in the frameworkBundlerConfig block must be a git repository.

    Does this mean the outputPath should look something like this: outputPath.set("[email protected]:example/example.git") ? Because in the example project it is set like so:

    outputPath.set("$rootDir/../test-dest-xc")

    opened by paulkangaroo 5
Releases(0.0.2)
Owner
Marco Gomiero
Senior Android Engineer @ TIER • Kotlin Google Developer Expert • Android & Kotlin Lover, fan of Kotlin Multiplatform
Marco Gomiero
💫 A Gradle Plugin to generate your networking code from Swagger

Swagger Gradle Codegen A Gradle plugin to generate networking code from a Swagger spec file. This plugin wraps swagger-codegen, and exposes a configur

Yelp.com 399 Nov 28, 2022
kinstall is an easy way to install gradle-based command-line kotlin projects that use the application plugin.

kinstall kinstall is an easy way to install gradle-based command-line kotlin projects that use the application plugin. use First, install kinstall its

david kilmer 0 Apr 24, 2022
An app to demonstrate Apple's new feature dynamic island in Android with Jetpack Compose

Jet Island Dynamic Island in Android with Jetpack Compose An app to demonstrate Apple's new feature dynamic island in Android with Jetpack Compose. Th

Cengiz TORU 101 Nov 29, 2022
This is a Kotlin multiplatform template project used to generate and deploy a natively compiled AWS lambda function using the custom runtime.

Overview This is a Kotlin multiplatform template project used to generate and deploy a natively compiled AWS Lambda function using a custom runtime. U

Greg Steckman 5 Jun 25, 2022
Gradle plugin for simplify Kotlin Multiplatform mobile configurations

Mobile Multiplatform gradle plugin This is a Gradle plugin for simple setup of Kotlin Multiplatform mobile Gradle modules. Setup buildSrc/build.gradle

IceRock Development 78 Sep 27, 2022
A set of highly-opinionated, batteries-included gradle plugins to get you started building delicious multi-module Kotlin projects

Sourdough Gradle What is Sourdough Gradle? Sourdough is a set of highly opinionated gradle plugins that aim to act as the starter for your Kotlin proj

Backbone 0 Oct 3, 2022
A modular object storage framework for Kotlin multiplatform projects.

ObjectStore A modular object storage framework for Kotlin multiplatform projects. Usage ObjectStore provides a simple key/value storage interface whic

Drew Carlson 4 Nov 10, 2022
Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in Kotlin with Jetpack Compose and a backed in Kotlin hosted on AppEngine.

Conferences4Hall Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in K

Gérard Paligot 98 Dec 15, 2022
Skip the process of setting up a new android project!

Android-Project-Template Skip the process of setting up an android app by using this template. Prerequisites Have an idea about: Clean Architecture De

Kibet 7 Aug 1, 2022
An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile.

An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile. 项目架构主要分为原生系统层、Android/iOS业务SDK层、KMM SDK层、KMM业务逻辑SDK层、iOS sdkfra

libill 4 Nov 20, 2022