Skip to content

Instantly share code, notes, and snippets.

@chrisjenx
Created November 30, 2025 00:06
Show Gist options
  • Select an option

  • Save chrisjenx/79fe87fc45a3821afe2715832e3770be to your computer and use it in GitHub Desktop.

Select an option

Save chrisjenx/79fe87fc45a3821afe2715832e3770be to your computer and use it in GitHub Desktop.
Work around Stripes SPM Package Issues
#!/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