Automated tool to generate Swift Package Manager packages from the Azure Communication UI Library for iOS
This automation tool successfully creates complete SPM packages from any tag of the Azure Communication UI Library repository, including both Calling and Chat functionality with full iOS device and simulator support.
# Generate SPM package from the latest stable tag
./generate-spm-package.sh --tag "AzureCommunicationUICalling_1.14.2"
# The generated package will be in ./output/ and ready to use!
- ✅ Checks local prebuild cache for existing packages
- ✅ Downloads from remote prebuild cache if available
- ✅ Validates package integrity with MD5 hash verification
- ✅ Skips build process if valid cache found (unless --force-build used)
- ✅ Clones the Azure Communication UI Library repository
- ✅ Checks out the specified git tag
- ✅ Validates repository structure
- ✅ Runs
pod install
to resolve dependencies - ✅ Prepares Xcode workspace for building
- ✅ Builds iOS device archives (arm64)
- ✅ Builds iOS simulator archives (arm64 + x86_64)
- ✅ Creates universal XCFrameworks for:
AzureCommunicationCalling
(Calling SDK)AzureCommunicationUICalling
(Calling UI Library with embedded FluentUI)AzureCommunicationUIChat
(Chat UI Library with embedded FluentUI)AzureCommunicationChat
(Chat SDK)Trouter
(Azure Communication Services Trouter - Required for Chat)AzureCommunicationCommon
(Common SDK)AzureCore
(Core SDK)
- ✅ Creates complete SPM package structure
- ✅ Copies all XCFrameworks with proper paths
- ✅ Includes source code for common components
- ✅ Creates minimal FluentUI module interface
- ✅ Generates Package.swift from template
- ✅ FluentUI hybrid integration: embedded in Azure frameworks + minimal module interface
- ✅ Creates local prebuild cache zip for future use
- ✅ Generates MD5 hash for integrity verification
- ✅ Tests package resolution with Swift Package Manager
- ✅ Validates XCFramework architectures
- ✅ Generates documentation and test files
- AzureCommunicationCalling - Azure Communication Services Calling SDK
- AzureCommunicationUICalling - Complete calling UI experience (includes embedded FluentUI)
- AzureCommunicationUIChat - Complete chat UI experience (includes embedded FluentUI and Trouter)
- AzureCommunicationUICommon - Common utilities and components
- iOS Device: arm64 (iPhone/iPad)
- iOS Simulator: arm64 + x86_64 (Apple Silicon + Intel Macs)
- iOS 16.0+
- Xcode 14.0+
- Swift 5.7+
- Git - For repository cloning and operations
- Xcode (with xcodebuild command line tools)
- CocoaPods (
gem install cocoapods
) - Swift Package Manager (included with Xcode)
Note: If a prebuild cache is available for your requested tag, the script will use it automatically and skip the build requirements above.
./generate-spm-package.sh --available-tags
./generate-spm-package.sh --latest
./generate-spm-package.sh --tag "AzureCommunicationUICalling_1.14.2"
./generate-spm-package.sh --latest --output-dir "/path/to/custom/output"
./generate-spm-package.sh --tag "AzureCommunicationUICalling_1.14.2" --force-build
./generate-spm-package.sh --help
Option | Description |
---|---|
-t, --tag <TAG> |
Git tag to checkout (required unless --latest is used) |
-l, --latest |
Use the latest available tag (alternative to --tag) |
-o, --output-dir <DIR> |
Output directory (default: ./output) |
--force-build |
Skip all cache checks and force a fresh build |
--available-tags |
Show available tags from the repository |
-h, --help |
Show help message |
- Default behavior: Checks local cache → remote cache → fresh build
- With
--force-build
: Skips all caches and builds fresh from source - Cache validation: Uses MD5 hashes to verify package integrity
Once generated, the SPM package can be used in any iOS project:
dependencies: [
.package(path: "path/to/generated/package")
],
targets: [
.target(
name: "YourTarget",
dependencies: [
.product(name: "AzureCommunicationCalling", package: "AzureCommunicationUI"),
.product(name: "AzureCommunicationUICalling", package: "AzureCommunicationUI"),
.product(name: "AzureCommunicationUIChat", package: "AzureCommunicationUI"),
.product(name: "AzureCommunicationUICommon", package: "AzureCommunicationUI")
]
)
]
import AzureCommunicationCalling // Calling SDK
import AzureCommunicationUICalling // Calling UI Library (includes embedded FluentUI)
import AzureCommunicationUIChat // Chat UI Library (includes embedded FluentUI)
import AzureCommunicationUICommon // Common utilities
The package uses a minimal module interface approach with FluentUI embedded within Azure Communication UI XCFrameworks and minimal Swift stubs for module resolution. This ensures:
- ✅ API Compatibility: FluentUI version matches exactly what Azure Communication SDK expects
- ✅ Runtime Stability: Only embedded FluentUI implementation runs - no conflicts
- ✅ Module Import Support: Minimal Swift stubs satisfy internal
import FluentUI
statements - ✅ Crash Prevention: Eliminates duplicate FluentUI implementations that caused DynamicColor crashes
- ✅ Clean Dependencies: Minimal interface without competing implementations or resources
The script creates minimal Swift stub files that provide just enough module interface to satisfy imports without competing implementations:
- Empty Swift classes satisfy
import FluentUI
statements in Azure frameworks - No actual implementation - all FluentUI functionality comes from embedded version
- No resource conflicts - only embedded FluentUI resources are used
- Runtime stability - single source of FluentUI implementation eliminates crashes
The script uses the cocoapods-spm
gem to properly integrate FluentUI during the build process:
- FluentUI is built from source and embedded into Azure frameworks
- Resources are correctly bundled and accessible at runtime
- Module imports work seamlessly within the Azure Communication SDK
All XCFrameworks support universal architectures:
- iOS Device: arm64 (iPhone/iPad)
- iOS Simulator: arm64 + x86_64 (Apple Silicon + Intel Macs)
When using both AzureCommunicationUICalling
and AzureCommunicationUIChat
frameworks in the same app, you may see console warnings about duplicate FluentUI classes:
objc[]: Class _TtC12FluentUI_ios14TabBarItemView is implemented in both [...]/AzureCommunicationUICalling.framework/AzureCommunicationUICalling and [...]/AzureCommunicationUIChat.framework/AzureCommunicationUIChat. One of the duplicates must be removed or renamed.
This is expected behavior and safe to ignore because:
- ✅ App functionality is not affected - Both calling and chat features work correctly
- ✅ Identical implementations - Both frameworks contain the same FluentUI version
- ✅ Runtime handles gracefully - Objective-C runtime picks one implementation consistently
- ✅ No crashes occur - These are warnings, not errors
Root Cause: FluentUI is embedded in both frameworks during the cocoapods-spm build process to ensure each framework is self-contained. When both frameworks are loaded, the Objective-C runtime detects the duplicate classes but continues to function normally.