# iOS Release Process
## Apple Developer Account Setup
### Prerequisites
1. **Apple Developer Account** ($99/year)
2. **Xcode** (latest version)
3. **Valid certificates and provisioning profiles**
### App Store Connect Setup
1. **Create App Record**
- App name: MyApp
- Bundle ID: com.myapp.app
- SKU: unique identifier
- Primary language: English
2. **App Information**
- Category: Social Networking / Lifestyle
- Content rights
- Age rating
- App Review Information
## Certificates & Provisioning
### Certificate Types
```bash
# 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
```bash
# 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:**
```ruby
git_url("https://github.com/your-org/certificates")
storage_mode("git")
type("development")
app_identifier(["com.myapp.app"])
username("your-apple-id@example.com")
team_id("YOUR_TEAM_ID")
```
### Manual Certificate Management
1. **Create Certificate Signing Request (CSR)**
- Open Keychain Access
- Certificate Assistant → Request Certificate from Certificate Authority
- Save CSR file
2. **Create Certificates in Developer Portal**
- iOS Development Certificate
- iOS Distribution Certificate
3. **Create App ID**
- Bundle ID: com.myapp.app
- Enable required capabilities (Push Notifications, etc.)
4. **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.myapp.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/MyApp/Info.plist:**
```xml
CFBundleDisplayName
MyApp
CFBundleIdentifier
com.myapp.app
CFBundleVersion
1
CFBundleShortVersionString
1.0.0
LSRequiresIPhoneOS
UIRequiredDeviceCapabilities
armv7
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIViewControllerBasedStatusBarAppearance
NSLocationWhenInUseUsageDescription
This app needs access to location to show nearby fundraising requests.
NSCameraUsageDescription
This app needs access to camera to take photos for fundraising requests.
NSPhotoLibraryUsageDescription
This app needs access to photo library to select images for fundraising requests.
NSContactsUsageDescription
This app needs access to contacts to help you share fundraising requests.
```
## Build Process
### Manual Build
```bash
# Clean build folder
cd ios
rm -rf build/
# Install dependencies
pod install
# Build for device
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-destination generic/platform=iOS \
-archivePath $PWD/build/MyApp.xcarchive \
archive
# Export IPA
xcodebuild -exportArchive \
-archivePath $PWD/build/MyApp.xcarchive \
-exportPath $PWD/build/ \
-exportOptionsPlist ExportOptions.plist
```
### Export Options
**ios/ExportOptions.plist:**
```xml
method
app-store
teamID
YOUR_TEAM_ID
uploadBitcode
uploadSymbols
compileBitcode
provisioningProfiles
com.myapp.app
match AppStore com.myapp.app
```
### Fastlane Build
**ios/fastlane/Fastfile:**
```ruby
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: "MyApp.xcodeproj"
)
# Build the app
build_app(
scheme: "MyApp",
export_method: "app-store",
export_options: {
provisioningProfiles: {
"com.myapp.app" => "match AppStore com.myapp.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: "MyApp",
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:**
```bash
#!/bin/bash
VERSION_TYPE=${1:-patch} # major, minor, patch
PLIST_PATH="ios/MyApp/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
```ruby
# Fastlane lane for internal testing
lane :internal do
build_app(scheme: "MyApp")
upload_to_testflight(
groups: ["Internal Testers"],
changelog: "Internal build for testing",
distribute_external: false
)
end
```
### External Testing
```ruby
# Fastlane lane for external testing
lane :external do
build_app(scheme: "MyApp")
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:**
```
MyApp is a revolutionary platform that connects users with meaningful services 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 MyApp today and start using services that matter to you.
```
### Screenshots
```bash
# Generate screenshots using Fastlane
fastlane snapshot
# Upload screenshots
fastlane deliver --skip_binary_upload
```
**Screenshotfile:**
```ruby
devices([
"iPhone 14 Pro Max",
"iPhone 14 Pro",
"iPhone SE (3rd generation)",
"iPad Pro (12.9-inch) (6th generation)"
])
languages([
"en-US"
])
scheme("MyApp")
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
```bash
# 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
```bash
# Verbose build output
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-destination generic/platform=iOS \
archive | xcpretty
# Check build settings
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-showBuildSettings
```