Created
November 30, 2025 00:06
-
-
Save chrisjenx/79fe87fc45a3821afe2715832e3770be to your computer and use it in GitHub Desktop.
Work around Stripes SPM Package Issues
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # | |
| # update-stripe-frameworks.sh | |
| # | |
| # A generic script to download and update Stripe xcframeworks for iOS projects. | |
| # This script is useful when Swift Package Manager fails to pull Stripe assets reliably. | |
| # | |
| # Usage: | |
| # ./update-stripe-frameworks.sh [version] | |
| # | |
| # Arguments: | |
| # version - (optional) Stripe iOS SDK version to download (e.g., "25.1.1") | |
| # If not provided, downloads the latest release. | |
| # | |
| # Configuration: | |
| # 1. Set IOS_PROJECT_DIR to your iOS project directory (containing .xcodeproj) | |
| # 2. Set FRAMEWORKS_DIR to where you want frameworks stored | |
| # 3. Optionally customize REQUIRED_FRAMEWORKS based on your needs | |
| # | |
| # The script will: | |
| # 1. Download Stripe.xcframework.zip from official GitHub releases | |
| # 2. Unzip the frameworks | |
| # 3. Copy the required xcframeworks to your specified Frameworks directory | |
| # 4. Clean up temporary files | |
| # | |
| # After running this script, you may need to (first time only): | |
| # - Open your Xcode project | |
| # - Remove any existing Stripe SPM package references | |
| # - Drag the xcframeworks from the Frameworks folder to "Frameworks, Libraries, and Embedded Content" | |
| # - Set each framework to "Embed & Sign" | |
| # | |
| # Requirements: | |
| # - curl (for downloading) | |
| # - unzip (for extracting) | |
| # - Internet connection to access github.com | |
| # | |
| set -e | |
| # ============================================================================ | |
| # CONFIGURATION - Customize these for your project | |
| # ============================================================================ | |
| # Directory containing your .xcodeproj file | |
| # Examples: | |
| # IOS_PROJECT_DIR="./ios" | |
| # IOS_PROJECT_DIR="./MyApp" | |
| # IOS_PROJECT_DIR="${HOME}/Projects/MyApp/ios" | |
| IOS_PROJECT_DIR="." | |
| # Directory where frameworks will be stored (relative to IOS_PROJECT_DIR or absolute) | |
| FRAMEWORKS_DIR="${IOS_PROJECT_DIR}/Frameworks" | |
| # Your Xcode project file name (for integration checking) | |
| XCODE_PROJECT_NAME="*.xcodeproj" # Will auto-detect, or set explicitly like "MyApp.xcodeproj" | |
| # Required frameworks for StripePaymentSheet functionality | |
| # Customize this list based on which Stripe features you use: | |
| # - Minimal (StripePaymentSheet only): StripeCore, StripeUICore, StripeApplePay, | |
| # StripePayments, StripePaymentsUI, StripePaymentSheet | |
| # - Full (all features): Use the complete list below | |
| REQUIRED_FRAMEWORKS=( | |
| "Stripe.xcframework" | |
| "Stripe3DS2.xcframework" | |
| "StripeApplePay.xcframework" | |
| "StripeCameraCore.xcframework" | |
| "StripeCardScan.xcframework" | |
| "StripeConnect.xcframework" | |
| "StripeCore.xcframework" | |
| "StripeFinancialConnections.xcframework" | |
| "StripeIdentity.xcframework" | |
| "StripeIssuing.xcframework" | |
| "StripePayments.xcframework" | |
| "StripePaymentSheet.xcframework" | |
| "StripePaymentsUI.xcframework" | |
| "StripeUICore.xcframework" | |
| ) | |
| # ============================================================================ | |
| # END CONFIGURATION | |
| # ============================================================================ | |
| # Stripe GitHub releases base URL (official public URLs) | |
| STRIPE_RELEASES_URL="https://github.com/stripe/stripe-ios/releases" | |
| STRIPE_API_URL="https://api.github.com/repos/stripe/stripe-ios/releases" | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| # Functions | |
| print_info() { | |
| echo -e "${BLUE}ℹ️ $1${NC}" >&2 | |
| } | |
| print_success() { | |
| echo -e "${GREEN}✅ $1${NC}" >&2 | |
| } | |
| print_warning() { | |
| echo -e "${YELLOW}⚠️ $1${NC}" >&2 | |
| } | |
| print_error() { | |
| echo -e "${RED}❌ $1${NC}" >&2 | |
| } | |
| get_latest_version() { | |
| print_info "Fetching latest Stripe iOS SDK version..." | |
| local version | |
| version=$(curl -s "${STRIPE_API_URL}/latest" | grep -o '"tag_name"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') | |
| if [ -z "$version" ]; then | |
| print_error "Failed to fetch latest version from GitHub API" | |
| exit 1 | |
| fi | |
| echo "$version" | |
| } | |
| download_frameworks() { | |
| local version=$1 | |
| local download_url="${STRIPE_RELEASES_URL}/download/${version}/Stripe.xcframework.zip" | |
| local temp_dir=$(mktemp -d) | |
| local zip_file="${temp_dir}/Stripe.xcframework.zip" | |
| print_info "Downloading Stripe xcframeworks version ${version}..." | |
| print_info "URL: ${download_url}" | |
| if ! curl -L -f -o "${zip_file}" "${download_url}"; then | |
| print_error "Failed to download Stripe.xcframework.zip" | |
| print_error "Please check if version ${version} exists at ${STRIPE_RELEASES_URL}" | |
| rm -rf "${temp_dir}" | |
| exit 1 | |
| fi | |
| print_success "Download complete" | |
| print_info "Extracting frameworks..." | |
| if ! unzip -q "${zip_file}" -d "${temp_dir}"; then | |
| print_error "Failed to extract Stripe.xcframework.zip" | |
| rm -rf "${temp_dir}" | |
| exit 1 | |
| fi | |
| print_success "Extraction complete" | |
| # Return the temp directory path | |
| echo "${temp_dir}" | |
| } | |
| setup_frameworks() { | |
| local temp_dir=$1 | |
| # Resolve FRAMEWORKS_DIR to absolute path | |
| local frameworks_path | |
| if [[ "${FRAMEWORKS_DIR}" = /* ]]; then | |
| frameworks_path="${FRAMEWORKS_DIR}" | |
| else | |
| frameworks_path="$(pwd)/${FRAMEWORKS_DIR}" | |
| fi | |
| # Create Frameworks directory if it doesn't exist | |
| if [ ! -d "${frameworks_path}" ]; then | |
| print_info "Creating Frameworks directory at ${frameworks_path}..." | |
| mkdir -p "${frameworks_path}" | |
| fi | |
| # Remove existing frameworks | |
| print_info "Removing existing Stripe frameworks..." | |
| for framework in "${REQUIRED_FRAMEWORKS[@]}"; do | |
| if [ -d "${frameworks_path}/${framework}" ]; then | |
| rm -rf "${frameworks_path}/${framework}" | |
| print_info " Removed ${framework}" | |
| fi | |
| done | |
| # Copy new frameworks | |
| print_info "Copying new frameworks..." | |
| for framework in "${REQUIRED_FRAMEWORKS[@]}"; do | |
| if [ -d "${temp_dir}/${framework}" ]; then | |
| cp -R "${temp_dir}/${framework}" "${frameworks_path}/" | |
| print_success " Copied ${framework}" | |
| else | |
| print_warning " ${framework} not found in downloaded archive (may not be needed)" | |
| fi | |
| done | |
| # Store resolved path for later use | |
| RESOLVED_FRAMEWORKS_DIR="${frameworks_path}" | |
| } | |
| cleanup() { | |
| local temp_dir=$1 | |
| print_info "Cleaning up temporary files..." | |
| rm -rf "${temp_dir}" | |
| print_success "Cleanup complete" | |
| } | |
| # Find the Xcode project file | |
| find_xcode_project() { | |
| local project_dir="${IOS_PROJECT_DIR}" | |
| if [[ "${XCODE_PROJECT_NAME}" == "*.xcodeproj" ]]; then | |
| # Auto-detect | |
| local found=$(find "${project_dir}" -maxdepth 1 -name "*.xcodeproj" -type d | head -1) | |
| if [ -n "$found" ]; then | |
| echo "$found" | |
| return 0 | |
| fi | |
| else | |
| # Use explicit name | |
| if [ -d "${project_dir}/${XCODE_PROJECT_NAME}" ]; then | |
| echo "${project_dir}/${XCODE_PROJECT_NAME}" | |
| return 0 | |
| fi | |
| fi | |
| return 1 | |
| } | |
| # Check if xcframeworks are already integrated in the Xcode project | |
| # Returns 0 if frameworks are integrated from Frameworks/ directory, 1 otherwise | |
| check_xcode_integration() { | |
| local xcode_project | |
| xcode_project=$(find_xcode_project) | |
| if [ -z "$xcode_project" ]; then | |
| return 1 | |
| fi | |
| local pbxproj="${xcode_project}/project.pbxproj" | |
| if [ ! -f "${pbxproj}" ]; then | |
| print_warning "Could not find project.pbxproj to check integration status" | |
| return 1 | |
| fi | |
| # Check if frameworks are referenced from the Frameworks/ directory | |
| if grep -q "path = Frameworks/Stripe.*\.xcframework" "${pbxproj}" 2>/dev/null; then | |
| return 0 | |
| fi | |
| # Also check for direct framework references | |
| if grep -q "Stripe.*\.xcframework" "${pbxproj}" 2>/dev/null; then | |
| return 0 | |
| fi | |
| return 1 | |
| } | |
| # Check if SPM packages for Stripe still exist in the project | |
| # Returns 0 if SPM packages exist (need removal), 1 otherwise | |
| check_spm_packages() { | |
| local xcode_project | |
| xcode_project=$(find_xcode_project) | |
| if [ -z "$xcode_project" ]; then | |
| return 1 | |
| fi | |
| local pbxproj="${xcode_project}/project.pbxproj" | |
| if [ ! -f "${pbxproj}" ]; then | |
| return 1 | |
| fi | |
| # Check for Stripe SPM package references | |
| if grep -qi "stripe-ios-spm\|stripe.*XCRemoteSwiftPackageReference" "${pbxproj}" 2>/dev/null; then | |
| return 0 | |
| fi | |
| return 1 | |
| } | |
| print_next_steps() { | |
| local version=$1 | |
| local needs_xcode_update=false | |
| local has_spm_packages=false | |
| # Check current integration status | |
| if ! check_xcode_integration; then | |
| needs_xcode_update=true | |
| fi | |
| if check_spm_packages; then | |
| has_spm_packages=true | |
| fi | |
| echo "" | |
| echo -e "${GREEN}========================================${NC}" | |
| echo -e "${GREEN} Stripe frameworks updated to ${version}${NC}" | |
| echo -e "${GREEN}========================================${NC}" | |
| echo "" | |
| # If Xcode project is already configured and no SPM packages to remove, we're done | |
| if [ "$needs_xcode_update" = false ] && [ "$has_spm_packages" = false ]; then | |
| echo -e "${GREEN}✅ Xcode project is already configured with manual xcframeworks.${NC}" | |
| echo -e "${GREEN} No additional steps required - just build and run!${NC}" | |
| echo "" | |
| echo -e "${BLUE}Frameworks location: ${RESOLVED_FRAMEWORKS_DIR:-${FRAMEWORKS_DIR}}${NC}" | |
| echo "" | |
| return | |
| fi | |
| # Print next steps only if needed | |
| echo -e "${YELLOW}Next steps to complete the integration:${NC}" | |
| echo "" | |
| local step=1 | |
| local xcode_project | |
| xcode_project=$(find_xcode_project) || xcode_project="${IOS_PROJECT_DIR}/<YourProject>.xcodeproj" | |
| echo "${step}. Open the Xcode project:" | |
| echo " ${xcode_project}" | |
| echo "" | |
| ((step++)) | |
| if [ "$has_spm_packages" = true ]; then | |
| echo "${step}. Remove existing Stripe SPM package:" | |
| echo " - Go to Project Settings > Package Dependencies" | |
| echo " - Remove 'stripe-ios-spm' package" | |
| echo "" | |
| ((step++)) | |
| fi | |
| if [ "$needs_xcode_update" = true ]; then | |
| echo "${step}. Add the xcframeworks to your project:" | |
| echo " - Select your target in Xcode" | |
| echo " - Go to 'General' > 'Frameworks, Libraries, and Embedded Content'" | |
| echo " - Click '+' and then 'Add Other...' > 'Add Files...'" | |
| echo " - Navigate to: ${RESOLVED_FRAMEWORKS_DIR:-${FRAMEWORKS_DIR}}" | |
| echo " - Select all .xcframework folders and click 'Open'" | |
| echo " - Set each framework to 'Embed & Sign'" | |
| echo "" | |
| ((step++)) | |
| fi | |
| echo "${step}. Build and run to verify the integration" | |
| echo "" | |
| echo -e "${BLUE}Frameworks location: ${RESOLVED_FRAMEWORKS_DIR:-${FRAMEWORKS_DIR}}${NC}" | |
| echo "" | |
| } | |
| print_usage() { | |
| echo "Usage: $0 [OPTIONS] [version]" | |
| echo "" | |
| echo "Download and update Stripe xcframeworks for iOS projects." | |
| echo "" | |
| echo "Arguments:" | |
| echo " version Stripe iOS SDK version to download (e.g., '25.1.1')" | |
| echo " If not provided, downloads the latest release." | |
| echo "" | |
| echo "Options:" | |
| echo " -h, --help Show this help message" | |
| echo " -d, --dir DIR Set the iOS project directory (default: current directory)" | |
| echo " -f, --frameworks DIR Set the frameworks output directory" | |
| echo "" | |
| echo "Examples:" | |
| echo " $0 # Download latest version to ./Frameworks" | |
| echo " $0 25.1.1 # Download specific version" | |
| echo " $0 -d ./ios # Specify iOS project directory" | |
| echo " $0 -f ./MyFrameworks # Specify custom frameworks directory" | |
| echo "" | |
| } | |
| # Main execution | |
| main() { | |
| # Parse arguments | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -h|--help) | |
| print_usage | |
| exit 0 | |
| ;; | |
| -d|--dir) | |
| IOS_PROJECT_DIR="$2" | |
| FRAMEWORKS_DIR="${IOS_PROJECT_DIR}/Frameworks" | |
| shift 2 | |
| ;; | |
| -f|--frameworks) | |
| FRAMEWORKS_DIR="$2" | |
| shift 2 | |
| ;; | |
| -*) | |
| print_error "Unknown option: $1" | |
| print_usage | |
| exit 1 | |
| ;; | |
| *) | |
| VERSION="$1" | |
| shift | |
| ;; | |
| esac | |
| done | |
| local version="${VERSION:-}" | |
| echo "" | |
| echo -e "${BLUE}========================================${NC}" | |
| echo -e "${BLUE} Stripe XCFramework Updater${NC}" | |
| echo -e "${BLUE}========================================${NC}" | |
| echo "" | |
| # Get version to download | |
| if [ -z "$version" ]; then | |
| version=$(get_latest_version) | |
| fi | |
| print_info "Target version: ${version}" | |
| print_info "iOS Project directory: ${IOS_PROJECT_DIR}" | |
| print_info "Frameworks directory: ${FRAMEWORKS_DIR}" | |
| # Download and extract frameworks | |
| temp_dir=$(download_frameworks "$version") | |
| # Setup frameworks in the project | |
| setup_frameworks "$temp_dir" | |
| # Cleanup | |
| cleanup "$temp_dir" | |
| # Print next steps | |
| print_next_steps "$version" | |
| } | |
| # Run main function with all arguments | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment