12 KiB
12 KiB
iOS Release Process
Apple Developer Account Setup
Prerequisites
- Apple Developer Account ($99/year)
- Xcode (latest version)
- Valid certificates and provisioning profiles
App Store Connect Setup
-
Create App Record
- App name: Saayam
- Bundle ID: com.saayam.app
- SKU: unique identifier
- Primary language: English
-
App Information
- Category: Social Networking / Lifestyle
- Content rights
- Age rating
- App Review Information
Certificates & Provisioning
Certificate Types
# Development Certificate
# - Used for development and testing
# - Install on development devices
# Distribution Certificate
# - Used for App Store distribution
# - Required for production builds
Using Fastlane Match
# Initialize match
fastlane match init
# Generate development certificates
fastlane match development
# Generate App Store certificates
fastlane match appstore
# Generate Ad Hoc certificates (for testing)
fastlane match adhoc
Matchfile:
git_url("https://github.com/your-org/certificates")
storage_mode("git")
type("development")
app_identifier(["com.saayam.app"])
username("your-apple-id@example.com")
team_id("YOUR_TEAM_ID")
Manual Certificate Management
-
Create Certificate Signing Request (CSR)
- Open Keychain Access
- Certificate Assistant → Request Certificate from Certificate Authority
- Save CSR file
-
Create Certificates in Developer Portal
- iOS Development Certificate
- iOS Distribution Certificate
-
Create App ID
- Bundle ID: com.saayam.app
- Enable required capabilities (Push Notifications, etc.)
-
Create Provisioning Profiles
- Development Profile
- App Store Distribution Profile
Xcode Configuration
Project Settings
Build Settings:
# Code Signing
CODE_SIGN_IDENTITY = "iPhone Distribution"
DEVELOPMENT_TEAM = "YOUR_TEAM_ID"
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.saayam.app"
# Build Configuration
ENABLE_BITCODE = YES
SWIFT_OPTIMIZATION_LEVEL = "-O"
GCC_OPTIMIZATION_LEVEL = "s"
# Deployment
IPHONEOS_DEPLOYMENT_TARGET = "12.0"
TARGETED_DEVICE_FAMILY = "1,2" # iPhone and iPad
Info.plist Configuration
ios/SaayamApp/Info.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>Saayam</string>
<key>CFBundleIdentifier</key>
<string>com.saayam.app</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location to show nearby fundraising requests.</string>
<key>NSCameraUsageDescription</key>
<string>This app needs access to camera to take photos for fundraising requests.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to photo library to select images for fundraising requests.</string>
<key>NSContactsUsageDescription</key>
<string>This app needs access to contacts to help you share fundraising requests.</string>
</dict>
</plist>
Build Process
Manual Build
# Clean build folder
cd ios
rm -rf build/
# Install dependencies
pod install
# Build for device
xcodebuild -workspace SaayamApp.xcworkspace \
-scheme SaayamApp \
-configuration Release \
-destination generic/platform=iOS \
-archivePath $PWD/build/SaayamApp.xcarchive \
archive
# Export IPA
xcodebuild -exportArchive \
-archivePath $PWD/build/SaayamApp.xcarchive \
-exportPath $PWD/build/ \
-exportOptionsPlist ExportOptions.plist
Export Options
ios/ExportOptions.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>teamID</key>
<string>YOUR_TEAM_ID</string>
<key>uploadBitcode</key>
<true/>
<key>uploadSymbols</key>
<true/>
<key>compileBitcode</key>
<true/>
<key>provisioningProfiles</key>
<dict>
<key>com.saayam.app</key>
<string>match AppStore com.saayam.app</string>
</dict>
</dict>
</plist>
Fastlane Build
ios/fastlane/Fastfile:
default_platform(:ios)
platform :ios do
desc "Build and upload to TestFlight"
lane :beta do
setup_ci if ENV['CI']
# Sync certificates and provisioning profiles
match(
type: "appstore",
readonly: true
)
# Increment build number
increment_build_number(
xcodeproj: "SaayamApp.xcodeproj"
)
# Build the app
build_app(
scheme: "SaayamApp",
export_method: "app-store",
export_options: {
provisioningProfiles: {
"com.saayam.app" => "match AppStore com.saayam.app"
}
}
)
# Upload to TestFlight
upload_to_testflight(
skip_waiting_for_build_processing: true,
changelog: "Bug fixes and performance improvements"
)
end
desc "Deploy to App Store"
lane :release do
setup_ci if ENV['CI']
match(
type: "appstore",
readonly: true
)
build_app(
scheme: "SaayamApp",
export_method: "app-store"
)
upload_to_app_store(
force: true,
reject_if_possible: true,
skip_metadata: false,
skip_screenshots: false,
submit_for_review: true,
automatic_release: false,
submission_information: {
add_id_info_limits_tracking: true,
add_id_info_serves_ads: false,
add_id_info_tracks_action: true,
add_id_info_tracks_install: true,
add_id_info_uses_idfa: true,
content_rights_has_rights: true,
content_rights_contains_third_party_content: true,
export_compliance_platform: 'ios',
export_compliance_compliance_required: false,
export_compliance_encryption_updated: false,
export_compliance_uses_encryption: false,
export_compliance_is_exempt: false
}
)
end
end
Version Management
Automated Version Bumping
scripts/bump-ios-version.sh:
#!/bin/bash
VERSION_TYPE=${1:-patch} # major, minor, patch
PLIST_PATH="ios/SaayamApp/Info.plist"
# Get current version
CURRENT_VERSION=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$PLIST_PATH")
CURRENT_BUILD=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PLIST_PATH")
echo "Current version: $CURRENT_VERSION ($CURRENT_BUILD)"
# Calculate new version
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR=${VERSION_PARTS[0]}
MINOR=${VERSION_PARTS[1]}
PATCH=${VERSION_PARTS[2]}
case $VERSION_TYPE in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
esac
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
NEW_BUILD=$((CURRENT_BUILD + 1))
echo "New version: $NEW_VERSION ($NEW_BUILD)"
# Update Info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $NEW_VERSION" "$PLIST_PATH"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $NEW_BUILD" "$PLIST_PATH"
# Update Xcode project
xcrun agvtool new-marketing-version $NEW_VERSION
xcrun agvtool new-version -all $NEW_BUILD
echo "Version updated successfully!"
TestFlight Distribution
Internal Testing
# Fastlane lane for internal testing
lane :internal do
build_app(scheme: "SaayamApp")
upload_to_testflight(
groups: ["Internal Testers"],
changelog: "Internal build for testing",
distribute_external: false
)
end
External Testing
# Fastlane lane for external testing
lane :external do
build_app(scheme: "SaayamApp")
upload_to_testflight(
groups: ["Beta Testers"],
changelog: "Beta version with new features",
distribute_external: true,
notify_external_testers: true
)
end
App Store Submission
App Store Metadata
fastlane/metadata/en-US/:
name.txt # App name
subtitle.txt # App subtitle
description.txt # App description
keywords.txt # App Store keywords
marketing_url.txt # Marketing URL
support_url.txt # Support URL
privacy_url.txt # Privacy policy URL
description.txt:
Saayam is a revolutionary fundraising platform that connects donors with meaningful causes in their local community.
Key Features:
• Browse local fundraising requests
• Support NGOs and individual causes
• Track your donation impact
• Secure payment processing
• Real-time updates on funded projects
Join thousands of users making a difference in their communities. Download Saayam today and start supporting causes that matter to you.
Screenshots
# Generate screenshots using Fastlane
fastlane snapshot
# Upload screenshots
fastlane deliver --skip_binary_upload
Screenshotfile:
devices([
"iPhone 14 Pro Max",
"iPhone 14 Pro",
"iPhone SE (3rd generation)",
"iPad Pro (12.9-inch) (6th generation)"
])
languages([
"en-US"
])
scheme("SaayamApp")
clear_previous_screenshots(true)
Release Checklist
Pre-Submission Checklist
- Update version and build numbers
- Test on multiple devices and iOS versions
- Verify all app store metadata
- Check app icons and screenshots
- Test in-app purchases (if applicable)
- Verify privacy policy and terms of service
- Test deep linking
- Check push notifications
- Verify analytics integration
- Test crash reporting
App Store Review Guidelines
- App follows iOS Human Interface Guidelines
- No crashes or major bugs
- App provides value to users
- Respects user privacy
- Follows App Store Review Guidelines
- Proper use of Apple APIs
- Appropriate content rating
- Valid contact information
Post-Submission
- Monitor App Store Connect for review status
- Respond to reviewer feedback if needed
- Prepare for release day
- Monitor crash reports and user feedback
- Plan post-launch updates
Troubleshooting
Common Issues
# Certificate issues
# - Ensure certificates are valid and not expired
# - Check provisioning profile matches bundle ID
# - Verify team ID is correct
# Build issues
# - Clean build folder: rm -rf ios/build
# - Clean derived data: rm -rf ~/Library/Developer/Xcode/DerivedData
# - Reset CocoaPods: cd ios && pod deintegrate && pod install
# Archive issues
# - Check scheme is set to Release
# - Verify code signing settings
# - Ensure all dependencies are properly linked
Debugging Build Failures
# Verbose build output
xcodebuild -workspace SaayamApp.xcworkspace \
-scheme SaayamApp \
-configuration Release \
-destination generic/platform=iOS \
archive | xcpretty
# Check build settings
xcodebuild -workspace SaayamApp.xcworkspace \
-scheme SaayamApp \
-showBuildSettings