Partner Build Guide¶
Complete technical guide for partners to build and configure their custom ECall iOS application.
Overview¶
This guide describes how partners can build their own branded iOS application on top of the ECall base code.
At a high level, partners: - Configure Xcode with a new bundle ID and app name (their own Apple Developer account) - Provide a small, fixed set of partner-specific configuration values - Reuse all shared infrastructure endpoints and defaults from the ECall system (partners do not point to their own backend) - Configure signing, certificates, and distribution
All configuration that controls backend URLs and low-level infrastructure is managed by the ECall core system and must remain unchanged for partner builds.
Prerequisites¶
Required Software¶
- Xcode: Latest stable version (14.0+ recommended)
- macOS: macOS 12.0 or later
- CocoaPods: For dependency management
- Git: For cloning repository
Required Accounts¶
- Apple Developer Account: Active membership ($99/year)
- Partner API Credentials: APP_API_ID and APP_API_HASH from partner program
- GitHub Access: Access to ECall source code repository
Required Knowledge¶
- Basic iOS development knowledge
- Familiarity with Xcode
- Understanding of bundle IDs and provisioning profiles
- Knowledge of iOS deployment process
Project Setup¶
Step 1: Clone Repository¶
git clone https://github.com/your-org/ecall-ios.git
cd ecall-ios
Step 2: Install Dependencies¶
# Install CocoaPods if not already installed
sudo gem install cocoapods
# Install dependencies
pod install
Note: Always open ecall.xcworkspace, not ecall.xcodeproj after running pod install.
Step 3: Open Workspace¶
open ecall.xcworkspace
Configuration¶
Bundle Identifier Setup¶
Method 1: Xcode Project Settings¶
- Select project in Project Navigator
- Select target
ecall - Go to General tab
- Update Bundle Identifier:
com.yourcompany.ecall - Update Display Name:
YourAppName
Method 2: Build Settings¶
- Select project in Project Navigator
- Select target
ecall - Go to Build Settings tab
- Search for
PRODUCT_BUNDLE_IDENTIFIER - Update value to your bundle ID
Recommended Format: com.[company].[appname] - Example: com.acmecorp.securecall - Example: com.example.businesscall
Configuration Responsibility Matrix¶
The table below summarizes which values a partner must provide and which are fixed by the ECall system.
Partner-provided (per cloned app)¶
- Apple account & bundle identifiers
PRODUCT_BUNDLE_IDENTIFIER(e.g.,com.partner.brandcall)- App display name
- Partner API credentials
APP_API_IDAPP_API_HASH- URL schemes and client IDs
BUNDLE_URL_SCHEME(recommended: derived from bundle ID, must be unique)GOOGLE_CLIENT_ID(from partner Google Cloud Console project)GOOGLE_URL_SCHEME(generated fromGOOGLE_CLIENT_ID, used for URL Types)- Partner-visible URLs
SHARE_URL(public share URL, e.g., landing page or invite page)BASE_DOMAIN(primary domain shown to users, e.g.,example.com)
Fixed by ECall system (do not modify)¶
- Backend / infrastructure endpoints:
API_BASE_URLSOCKET_BASE_URLJANUS_SOCKET_URL- Environment selection:
ENVIRONMENT_NAME(Dev / Staging / Production)- Low-level engine options:
MTL_ENABLE_DEBUG_INFOMTL_FAST_MATH
Partners must not change any of the fixed values. They are set by the core ECall team to ensure that all partner apps connect to the correct infrastructure.
API Credentials Configuration¶
Method 1: Build Settings (Recommended)¶
- Select project in Project Navigator
- Select target
ecall - Go to Build Settings tab
- Click + → Add User-Defined Setting
- Add the following variables:
APP_API_ID = 12345678
APP_API_HASH = a1b2c3d4e5f6g7h8
These values will be automatically injected into Info.plist at build time.
Security Note: Never commit actual credentials to version control. Use separate configs for different environments.
Method 2: Configuration Files¶
- Create
Config.plist(add to.gitignore) - Add configuration structure (see
Config.example.plist) - Load in code:
if let path = Bundle.main.path(forResource: "Config", ofType: "plist"),
let config = NSDictionary(contentsOfFile: path) {
let apiId = config["APP_API_ID"] as? String
let apiHash = config["APP_API_HASH"] as? String
}
Note: This method requires manual loading. Build Settings (Method 1) is recommended as values are automatically available via Bundle.main.object(forInfoDictionaryKey:).
Additional Configuration Variables¶
For partner builds, configuration is intentionally minimal.
- Partners set:
APP_API_IDAPP_API_HASHBUNDLE_URL_SCHEMEGOOGLE_CLIENT_IDGOOGLE_URL_SCHEMESHARE_URLBASE_DOMAIN- All other configuration values are pre-configured by the ECall core team and must remain unchanged.
For internal/core ECall development, see Configuration Variables Guide for the full list of variables and their meanings. That guide is not intended for partner editing of backend URLs.
Environment Configuration¶
Configure Build Configurations¶
- Select project in Project Navigator
- Go to Info tab
- Under Configurations, you can:
- Create new configurations (Development, Staging, Production)
- Assign different settings per configuration
Environment-Specific API Endpoints¶
For partner builds, environment endpoints are controlled by the ECall system.
- Partners do not change:
API_BASE_URLSOCKET_BASE_URLJANUS_SOCKET_URLENVIRONMENT_NAME- These values are provided either by the base project settings or by the ECall team when preparing a clone.
You can still verify the effective environment at runtime (read-only):
let environment = AppEnvironment.current
environment.printInfo() // Logs environment name, URLs, and identifiers
Branding Configuration¶
App Icon¶
- Prepare app icon assets (1024x1024px for App Store, plus iOS sizes)
- Open
Assets.xcassetsin Xcode - Select
AppIcon - Drag and drop icon images into corresponding slots
- Required sizes:
- 20x20, 29x29, 40x40, 60x60, 76x76, 83.5x83.5
- 1024x1024 (App Store)
Launch Screen¶
- Open
LaunchScreen.storyboard - Customize with your branding:
- Add logo image
- Update colors
- Modify layout
Or create programmatic launch screen:
// In AppDelegate or SceneDelegate
window?.rootViewController = LaunchViewController()
App Name and Display Name¶
- Update Display Name in project settings (General tab)
- Update
CFBundleDisplayNamein Info.plist:<key>CFBundleDisplayName</key> <string>YourAppName</string> - Update
CFBundleName(optional):<key>CFBundleName</key> <string>YourAppName</string>
Color Scheme¶
Update colors in your SwiftUI views or create a theme:
// Create AppTheme.swift
extension Color {
static let brandPrimary = Color(hex: "#007AFF")
static let brandSecondary = Color(hex: "#5856D6")
// ... your brand colors
}
Localization¶
- Open
Localizable.xcstrings - Update strings for your brand:
- App name references
- Error messages
- UI labels
- Add new languages if needed
Certificates and Provisioning¶
Development Certificate¶
- Open Xcode Preferences → Accounts
- Add your Apple ID
- Select your team
- Click Manage Certificates
- Click + → Apple Development
- Xcode will automatically create and manage certificate
Provisioning Profiles¶
Automatic Signing (Recommended)¶
- Select project in Project Navigator
- Select target
ecall - Go to Signing & Capabilities tab
- Enable Automatically manage signing
- Select your Team
- Xcode will automatically create provisioning profile
Manual Signing¶
- Disable Automatically manage signing
- Select Provisioning Profile
- Download from Apple Developer Portal if needed
- Select certificate and profile
Push Notification Certificates¶
APNs Certificate (Standard Push)¶
- Go to Apple Developer Portal → Certificates, Identifiers & Profiles
- Select Identifiers → Your App ID
- Enable Push Notifications
- Download and install APNs certificate
- Upload to your backend server for push notification service
VoIP Certificate (VoIP Push)¶
- Same process as APNs certificate
- Enable VoIP Services capability
- Download VoIP certificate
- Upload to backend for VoIP push notifications
Note: VoIP push is required for incoming call notifications via CallKit.
Build Configurations¶
Debug Configuration¶
For development and testing:
- Select scheme ecall → Edit Scheme
- Go to Run → Info
- Set Build Configuration to Debug
- Use development API endpoints
- Enable debug logging
Release Configuration¶
For App Store distribution:
- Select scheme ecall → Edit Scheme
- Go to Archive → Info
- Set Build Configuration to Release
- Use production API endpoints
- Disable debug logging
- Enable code optimization
Build Settings¶
Key settings to verify:
- Code Signing Identity: Automatic or specific certificate
- Development Team: Your Apple Developer team
- Bundle Identifier: Your custom bundle ID
- Version: Current version number
- Build: Build number (auto-increment)
- Deployment Target: iOS 16.6+ (minimum supported)
Capabilities¶
Required Capabilities¶
Enable in Signing & Capabilities tab:
- Push Notifications: For incoming call notifications
- Background Modes:
- Voice over IP
- Background fetch
- Remote notifications
- CallKit: For native call UI integration
- Audio, AirPlay, and Picture in Picture: For audio/video calls
- Camera: For video calls
- Microphone: For audio calls
Optional Capabilities¶
- Keychain Sharing: If sharing keychain between apps
- App Groups: For widget or extension sharing
- Associated Domains: For universal links
Building the App¶
Development Build¶
- Select ecall scheme
- Select target device or simulator
- Press ⌘ + R or click Run
- App will build and launch on device/simulator
Archive Build (for Distribution)¶
- Select Any iOS Device or Generic iOS Device as target
- Go to Product → Archive
- Wait for archive to complete
- Organizer window will open
- Select archive and click Distribute App
- Choose distribution method:
- App Store Connect
- Ad Hoc
- Enterprise
- Development
Build from Command Line¶
# Development build
xcodebuild -workspace ecall.xcworkspace \
-scheme ecall \
-configuration Debug \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
build
# Archive build
xcodebuild -workspace ecall.xcworkspace \
-scheme ecall \
-configuration Release \
archive \
-archivePath build/ecall.xcarchive
Testing¶
Unit Tests¶
xcodebuild test -workspace ecall.xcworkspace \
-scheme ecall \
-destination 'platform=iOS Simulator,name=iPhone 15 Pro'
Manual Testing Checklist¶
- [ ] App launches successfully
- [ ] Registration/login works with API credentials
- [ ] Can make audio calls
- [ ] Can make video calls
- [ ] Incoming calls work (VoIP push)
- [ ] CallKit integration works
- [ ] Push notifications work
- [ ] App icons display correctly
- [ ] Launch screen shows branding
- [ ] All UI strings are correct
- [ ] Bundle ID matches App Store Connect
Troubleshooting¶
Common Issues¶
Issue: "No such module 'WebRTC'"¶
Solution: Run pod install and open .xcworkspace file, not .xcodeproj
Issue: "Signing for 'ecall' requires a development team"¶
Solution: Add your Apple Developer team in Signing & Capabilities tab
Issue: "Bundle identifier is already in use"¶
Solution: Use a unique bundle identifier for your app
Issue: API credentials not working¶
Solution: - Verify credentials are correct - Check Info.plist or build settings - Ensure production credentials for production builds
Issue: Push notifications not working¶
Solution: - Verify APNs/VoIP certificates are installed - Check capabilities are enabled - Verify backend is configured with correct certificates - Test with device (not simulator)
Issue: Build fails with code signing errors¶
Solution: - Clean build folder (⌘ + Shift + K) - Check certificates are valid in Keychain - Verify provisioning profile matches bundle ID - Try automatic signing
Debug Logging¶
Enable debug logging in development:
// In AppConfig.swift or similar
#if DEBUG
let enableDebugLogging = true
#else
let enableDebugLogging = false
#endif
Security Best Practices¶
Credential Storage¶
- Never commit credentials to Git
-
Add to
.gitignore:Config.plist *.credentials -
Use build configurations
- Separate dev/staging/prod credentials
-
Use environment variables or secure storage
-
Code obfuscation (optional)
- For additional security in production builds
- Use tools like SwiftShield or similar
Certificate Pinning¶
For production, enable certificate pinning:
// In APIClient.swift
func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// Implement certificate pinning
#if !DEBUG
// Certificate pinning logic
#endif
}
Deployment¶
App Store Connect¶
- Create app in App Store Connect
- Set bundle ID to match your configured bundle ID
- Complete app information:
- App name
- Description
- Screenshots
- Privacy policy URL
- Archive and upload build
- Submit for review
Version Management¶
Update version in project settings: - Version: Semantic versioning (e.g., 1.0.0) - Build: Incremental build number
Or use scripts to auto-increment:
# In build phase script
agvtool next-version -all
agvtool new-version -all $VERSION_NUMBER
Maintenance¶
Updating Dependencies¶
# Update CocoaPods
pod update
# Update specific pod
pod update WebRTC
Updating Source Code¶
# Pull latest changes
git pull origin main
# Reinstall pods if Podfile changed
pod install
Keeping API Credentials Updated¶
- Rotate credentials periodically
- Update in build settings or configuration files
- Test thoroughly after credential updates
Additional Resources¶
Documentation¶
Support¶
- GitHub Issues: For bug reports and feature requests
- Partner Portal: For API credential management
- Technical Support: partners-support@ecall.example.com
Summary Checklist¶
Before submitting to App Store:
- [ ] Bundle identifier configured
- [ ] App name and display name set
- [ ] API credentials configured (APP_API_ID, APP_API_HASH)
- [ ] App icon and launch screen customized
- [ ] Certificates and provisioning profiles set up
- [ ] All capabilities enabled
- [ ] Push notification certificates configured
- [ ] Build configurations set (Debug/Release)
- [ ] Tested on physical device
- [ ] All features tested (calls, notifications, etc.)
- [ ] Version and build number updated
- [ ] App Store Connect app created
- [ ] Privacy policy URL provided
- [ ] App description and screenshots ready