{"id":13994770,"url":"https://github.com/bielikb/xcframeworks","last_synced_at":"2025-04-05T07:05:22.699Z","repository":{"id":51799158,"uuid":"193686460","full_name":"bielikb/xcframeworks","owner":"bielikb","description":"Demonstration of creating and integrating xcframeworks and their co-op with static libraries and Swift packages","archived":false,"fork":false,"pushed_at":"2022-11-04T18:05:16.000Z","size":6025,"stargazers_count":543,"open_issues_count":7,"forks_count":47,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-03-29T06:06:07.331Z","etag":null,"topics":["binary","catalyst","create","fastlane-plugin","macos","module","package","stability","swift","swift-interface","swift-packages","xcframework","xcode"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bielikb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-25T10:26:59.000Z","updated_at":"2025-03-27T14:46:33.000Z","dependencies_parsed_at":"2023-01-21T20:02:53.421Z","dependency_job_id":null,"html_url":"https://github.com/bielikb/xcframeworks","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bielikb%2Fxcframeworks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bielikb%2Fxcframeworks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bielikb%2Fxcframeworks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bielikb%2Fxcframeworks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bielikb","download_url":"https://codeload.github.com/bielikb/xcframeworks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247299832,"owners_count":20916190,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary","catalyst","create","fastlane-plugin","macos","module","package","stability","swift","swift-interface","swift-packages","xcframework","xcode"],"created_at":"2024-08-09T14:03:05.803Z","updated_at":"2025-04-05T07:05:22.674Z","avatar_url":"https://github.com/bielikb.png","language":"Shell","readme":"# xcframeworks repo\nThis is a demonstration of creating and integrating the xcframeworks and their co-op with static libraries and Swift packages within the same Xcode project.\n\n## Table of contents\n* [Changelog](#Changelog)\n* [Introduction: New .xcframework format](#Introduction:-New-.xcframework-format)\n* [How to create .xcframework that contain iOS + iOS Simulator platforms](#How-to-create-.xcframework-that-contains-iOS-+-iOS-Simulator-platforms)\n* [Create xcframework using fastlane plugin](#Create-xcframework-using-fastlane-plugin)\n* [Testing \u0026 Troubleshooting](#Testing-\u0026-Troubleshooting)\n* [Distribution of xcframeworks](#Distribution-of-xcframeworks)\n* [How to integrate .xcframework in your project](#How-to-integrate-.xcframework-in-your-project)\n* [What's in XCFrameworks workspace](#What's-in-XCFrameworks-workspace)\n* [Materials](#Materials)\n\n## Pre-requisities\n- Xcode 11 and above\n- Swift 5.1 and above\n- Github/Gitlab/Bitbucket account set in Xcode's account preferences\n\n# Changelog\n\n| What's new | Xcode version | Swift version | Description |\n|---|---|---|---|\n| Module stable binaries | Xcode 11 | Swift 5.1 | Library evolution allows the library authors to distribute module stable Swift binaries |\n| New version of .swiftinterface interface | Xcode 11.4 | Swift 5.2 | New annotations added to Swift `@_inheritsConvenienceInitializers`, `@_hasMissingDesignatedInitializers`. ⚠️ Module interfaces aren't backwards compatible, clients using Swift 5.1.3 and below won't be able to compile Swift binaries compiled with Swift 5.2. More info [here](https://forums.swift.org/t/cant-use-framework-compiled-with-swift-5-2-in-swift-5-1-3-project/35248/6) |\n| Support for binary dependencies in SwiftPM | Xcode 12.0 | Swift 5.3 | Swift Package Manager now supports declaring binary targets in `Package.swift` |\n| Debug symbols | Xcode 12.0 | Swift 5.3 | Debug symbols (dSYMs, BCSymbolMaps) can be included within the xcframework through new `-debug-symbols \u003cabsolute path\u003e` flag |\n\n# Introduction: New .xcframework format\n\n## Requirements\n- Xcode11\n- Swift 5.1 and above\n\n## Motivation \u0026 consequences\n- introduce standard format to gain module stability for your Swift frameworks \u0026 libraries. Library author \u0026 client of a library are no longer required to use the same version of compiler. Please note, that the module stable interfaces are only forward-compatible\n- provide seamless experience when creating \u0026 integrating the module stable frameworks\n- support all Apple platforms and architectures\n\n- **STOP** creating \u0026 using `fat dynamic frameworks`. (library author)\n- **STOP** slicing frameworks by stripping the architectures in your projects' targets' custom `build-phase`. (integrator)\n\n## Contents of xcframework\n\nThis format bundles module-stable frameworks (.swiftinterface) for the platforms of interest.\n\nThe [Info.plist](./Products/xcframeworks/DynamicFramework.xcframework) contains all available frameworks in a bundle specified by library identifiers. This information is used by Xcode during the linking time =\u003e xcodebuild picks the right framework for the platform we're building against.\nSince Xcode 12.0 the xcframework can contain also debug symbols (dSYMs, BCSymbolMaps).\n\nThe structure of xcframework looks as shown below\n\n![xcframework](./res/xcframework.png)\n\n## Size of xcframework\nDuring my tests I realized, the size of an `xcframework` was smaller than the size of an corresponding `fat framework`. I tested swift only \u0026 mixed frameworks.\nGenerally the `lipo` commandline tool adds a bit of overhead for all contained architectures.\n\n## Platforms\nxcframework supports all Apple platforms \u0026 their variants - `iOS`, `maccatalyst`, `macOS`, `tvOS`, `watchOS`, `iPadOS`, `carPlayOS`.\n\n## List of destinations\n| Platform  |  Destination |\n|---|---|\n| iOS  | generic/platform=iOS  |\n| iOS Simulator  | generic/platform=iOS Simulator |\n| maccatalyst | generic/platform=macOS,variant=Mac Catalyst |\n| iPadOS  | generic/platform=iPadOS |\n| iPadOS Simulator  | generic/platform=iPadOS Simulator|\n| macOS  | generic/platform=macOS  |\n| tvOS  | generic/platform=tvOS  |\n| watchOS | generic/platform=watchOS |\n| watchOS Simulator | generic/platform=watchOS Simulator |\n| carPlayOS | generic/platform=carPlayOS\n| carPlayOS Simulator | generic/platform=carPlayOS Simulator\n\n---\n\n# How to create .xcframework that contain iOS + iOS Simulator platforms\n\nThis section describes the process of creating the xcframework by archiving \u0026 creating the final xcframeworks from 2 archives built for `iOS` \u0026 `iOS Simulator`.\n\nHowever, if you're not interested in the details of the process of `how` the xcframework is created, head directly to section: [Create xcframework using fastlane plugin](#Create-xcframework-using-fastlane-plugin).\n\n## 1. Archive your scheme for desired platforms (destinations)\n1.1 Pass `SKIP_INSTALL=NO` \u0026\u0026 `BUILD_LIBRARY_FOR_DISTRIBUTION=YES` to archive your scheme\n\n```swift\nxcodebuild archive \\\n-workspace MyWorkspace.xcworkspace \\\n-scheme MyScheme \\\n-destination \"generic/platform=iOS\" \\\n-archivePath \"archives/MyScheme-iOS\" \\\nSKIP_INSTALL=NO \\\nBUILD_LIBRARY_FOR_DISTRIBUTION=YES\n```\n\n1.2 **iOS Simulator** - archive your scheme for iOS Simulator platform by specifying correct destination `destination=\"generic/platform=iOS Simulator\"` \u0026 point archivePath to architecture specific path, e.g. `archives/MyScheme-iOS-Simulator`.\n\n```swift\nxcodebuild archive \\\n..\n-destination \"generic/platform=iOS Simulator\" \\\n-archivePath \"archives/MyScheme-iOS-Simulator\" \\\n..\n```\n\n1.3 **iOS** - archive your scheme for iOS by specifying `destination=\"generic/platform=iOS\"` \u0026 point archivePath to device specific path. The architecture specific path will ensure the archive from step 2. wont be overwritten, e.g. `MyScheme-iOS`\n\n```\nxcodebuild archive \\\n..\n-destination \"generic/platform=iOS\" \\\n-archivePath \"archives/MyScheme-iOS\" \\\n..\n```\n\n### Locations\nBinaries in `.xcarchive` are located under:\n\n* `Products/Library/Frameworks` folder for dynamic frameworks\n* `Products/usr/local/lib` folder for static libraries\n\n## 2. Create .xcframework from built archives\n\n`xcodebuild` allows you to create xcframework by specifying frameworks, libraries or even can add headers to the libraries.\n![-create-xcframework](./res/xcodebuild_create_xc_framework.png)\n\n\n###### 1. Specify all frameworks or libraries that you want to add into .xcframework\n\n###### 2. Specify the outpath path using `-output` argument. Don't forget to add `.xcframework` extension to your output path.\n\n```\nxcodebuild -create-xcframework \\\n           -framework My-iOS.framework \\\n           -debug-symbols \u003cabsolute path to dSYM or BCSymbolMaps folder in the xcarchive\u003e # available from XCode 12.0+\n           -framework My-iOS_Simulator.framework \\\n           -debug-symbols \u003cabsolute path to dSYM or BCSymbolMaps folder in the xcarchive\u003e # available from XCode 12.0+\n           -output My.xcframework\n```\n\nModule stability is gained with Xcode 11 + Swift 5.1, once your module declares `.swiftinterface` file, that describes the public interface of your framework along with linker flags, used toolchain and other info. Swift interface can be found under your framework's `swiftmodule` folder.\n`.swiftinterface` file is autogenerated when xcframework is created.\n\n![swift-interface](./res/swiftinterface.png)\n\n## Create xcframework using fastlane plugin\n\n[This plugin](https://github.com/bielikb/fastlane-plugin-create_xcframework) allows you to generate the `xcframework` (including all dSYMs \u0026 BCSymbolMaps) by specifying the desired destinations.\nE.g. destination `[iOS]` will generate xcframework that contains slices for both `iOS` \u0026 `iOS Simulator`.\n⚠️ Currently the plugin doesn't support static libraries.\n\n1. Add plugin to your project\n```\nfastlane add_plugin create_xcframework\n```\n\n2. Add lane to your `Fastfile`\n```\ndesc \"Export xcframework\"\nlane :export_xcframework do\n  create_xcframework(\n    workspace: 'path/to/your.xcworkspace',\n    scheme: 'name of your scheme',\n    destinations: ['iOS', 'maccatalyst'],\n    xcframework_output_directory: 'Products/xcframeworks'\n  )\nend\n```\n\n_NOTE:_\n\n[Version 1.1.0](https://github.com/bielikb/fastlane-plugin-create_xcframework/releases/tag/v1.1.0) of the fastlane plugin includes support for `debug symbols`.\n\nYou can try out the plugin in this project by calling following command:\n```\nbundle exec fastlane export_xcframework\n```\n\n---\n\n# Testing \u0026 Troubleshooting\n\nMake sure to always build \u0026 run your generated xcframework before distributing it to your clients.\nFew of the **problems will unveil just at the compile or run time**, so **don't** rely solely on the success of the xcframework creation.\n\nHere's the list of compiler errors I got across when integrating built xcframework into Xcode project.\n\n| Problem  | Severity |  Description | Solution |\n|---|---|---|---|\n| Redundant conformance of `x` to `NSObjectProtocol` | error - thrown at dynamic linking time | Your class is already subclassed from `NSObject`, which conforms to `NSObjectProtocol`  | Check protocol conformances of your classes and remove redundant conformance to `NSObjectProtocol` |\n| Use of unimplemented initializer 'init()' for class | error - thrown at dynamic linking time | Objective-C ABI public classes need to provide `public` init | Provide `public` init override for your public class:  `override public init()` |\n| @objc' class method in extension of subclass of `Class X` requires iOS 13.0.0 | error | Rules for interoperability with Objective-C has changed since iOS 13.0.0. and currently doesn't support `@objc` interoperability in class extensions. There's open question on [Swift forums](https://forums.swift.org/t/xcframework-requires-to-target-ios-13-for-inter-framework-dependencies-with-objective-c-compatibility-tested-with-xcode-11-beta-7/28539) | Move/Remove `@objc` declaration from your Swift class extension |\n| scoped imports are not yet supported in module interfaces | warning | Read more about Swift import declarations here: https://nshipster.com/import/ | Import the module instead of specific declaration. For example: change `import class MyModule.MyClass` to `import MyModule` |\n| [Can’t use framework compiled with Swift 5.2 in Swift 5.1.3 project](https://forums.swift.org/t/cant-use-framework-compiled-with-swift-5-2-in-swift-5-1-3-project/35248) | error - thrown at linking time | The xcframework was generated using the Swift 5.2 and above. Module stable interfaces are not backwards-compatible. | Update your Xcode to Xcode 11.4 and above or generate module stable binary using Xcode 11.3 and below |\n| Incompatible module | error - thrown at linking time | The module built for iOS Simulator shares the same arch slice as the new M1. | Exclude arm64 slice when building your xcframework by specifying following build setting: EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64 |\n\n---\n\n# Distribution of xcframeworks\n\n* **manually**\n\nDistribution of xcframeworks using the native dependency manager `Swift Package Manager` or the 3rd party dependency managers does come with several reported integration issues. Manual integration seems sofar to be the safest/bullet-proof integration option.\n\n* **Swift Package Manager**\n\n    - [binary targets are supported since Xcode 12.0](https://developer.apple.com/wwdc20/10147)\n    - define binary target in your Swift Package manifest.\n    - zipped xcframework filename should contain the version number\n    - compute the binary checksum by calling `swift package compute-checksum \u003cxcframework filename`.\n    - use the computed binary checksum in your Swift Package manifest, when referencing the xcframework remotely.\n\n\n* **CocoaPods**\n\n    - supported since v1.9.1, several important bug-fixes came with the version [1.10.0](https://github.com/CocoaPods/CocoaPods/releases/tag/1.10.0)\n    - As a vendor, you might consider limiting the cocoapods pods audience to avoid any unnecessary issues by specifying the minimum cocoapods version required: eg `spec.cocoapods_version = '\u003e= 1.10.0'``\n    - use `vendored_frameworks` to specify you xcframework(s) in your podspec. e.g. `spec.vendored_frameworks = 'DynamicFramework.xcframework'`\n    - specify paths to your dSYMs and xcframework in `spec.preserve_paths = [...]`, since Xcode 12 the xcframeworks can contain symbol files, so there's no need to distribute the symbol files explicitly\n\n* **Carthage**  \n\n    - Since version [0.37.0](https://github.com/Carthage/Carthage/releases/tag/0.37.0) Carthage produces xcframeworks for open-sourced depdendencies when `--use-xcframeworks` flag is passed. It doesn't support fetching already existing xcframeworks.\n\n---\n\n# How to integrate .xcframework in your project\n\n1. Drag \u0026 drop .xcframework manually into your project's target\n\n![Drag \u0026 drop xcframework](./res/xcframework_drag_n_drop.gif)\n\n2. Embed \u0026 sign .xcframework in your project's target\n\n![Embed \u0026 sign .xcframework](./res/xcframework_embed_sign.png)\n\n---\n\n# What's in XCFrameworks workspace\n\n`XCFrameworks` workspace consists of:\n- `StaticLibrary` project - represents static library project\n- `DynamicFramework` project - represents project that builds dylib\n- `Swift Package` - Swift Package for internal development (within Sample project)\n- `TextAttributes` - external Swift Package\n\n- `Sample` - Sample project that includes all of the dependencies mentioned above.\n\n![swift-interface](./res/project.png)\n\n---\n\n# Materials\n\n## Binary Frameworks in Swift\nhttps://developer.apple.com/videos/play/wwdc2019/416/\n\n## Distribute binary frameworks as Swift packages\nhttps://developer.apple.com/wwdc20/10147\nhttps://developer.apple.com/documentation/swift_packages/distributing_binary_frameworks_as_swift_packages\n\n## ABI Stability \u0026 Module Stability - swift.org\nhttps://swift.org/blog/abi-stability-and-more/\n\n## Library evolution in Swift - swift.org\nhttps://swift.org/blog/library-evolution/\n\n## Library evolution for stable ABIs\nhttps://github.com/apple/swift-evolution/blob/master/proposals/0260-library-evolution.md\n\n## Library evolution - Docs\nhttps://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst\n\n## Swift Unwrapped - Swift 5.1 with Doug Gregor (Library evolution, ...)\nhttps://spec.fm/podcasts/swift-unwrapped/308610\n\n## Alexis Beingessner - How Swift Achieved Dynamic Linking Where Rust Couldn't\nhttps://gankra.github.io/blah/swift-abi/\n\n## Alex Grebenyuk - XCFrameworks (case-study about Distribution of xcframeworks as Swift Packages for specific case)\nhttps://kean.blog/post/xcframeworks-caveats\n","funding_links":[],"categories":["Shell"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbielikb%2Fxcframeworks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbielikb%2Fxcframeworks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbielikb%2Fxcframeworks/lists"}