Bas Pay SDK — Native iOS / Swift Integration Guide#
This document explains how to integrate the bas_pay.xcframework into a native iOS (Swift) project — without Flutter.
Table of Contents#
Overview#
Bas Pay iOS SDK is distributed as an XCFramework (bas_pay.xcframework). It contains:| Component | Description |
|---|
BasMainIosKt.BasMainIosController(...) | Factory method that creates a UIViewController containing the full payment UI (built with Compose Multiplatform) |
BankyLiteNotificationManager | Notification manager that must be registered before presenting the payment screen |
onReturnDataToIOS callback | Closure that receives the payment result as a JSON string when the payment flow completes |
The XCFramework is automatically downloaded from:https://github.com/BasPlatform/BasPayment-IOS/releases/latest/download/bas_pay.xcframework.zip
Current latest version: 1.0.1
Architecture#
┌──────────────────────────────────────────────┐
│ Your Swift App │
│ │
│ 1. BankyLiteNotificationManager.register() │
│ 2. BasMainIosKt.BasMainIosController(...) │
│ 3. present(viewController) │
│ 4. onReturnDataToIOS callback ← result JSON │
└──────────────────┬───────────────────────────-┘
│
▼
┌──────────────────────────────────────────────┐
│ bas_pay.xcframework │
│ ┌────────────────────────────────────────┐ │
│ │ BasMainIosKt │ │
│ │ • BasMainIosController() → UIVC │ │
│ ├────────────────────────────────────────┤ │
│ │ BankyLiteNotificationManager │ │
│ │ • .shared.register() │ │
│ └────────────────────────────────────────┘ │
│ │
│ (Compose Multiplatform UI inside) │
└──────────────────────────────────────────────-┘
Requirements#
| Requirement | Minimum Version |
|---|
| iOS Deployment Target | 13.0 |
| Swift | 5.0 |
| Xcode | 15.0+ |
| CocoaPods (if using) | 1.16.0+ |
Installation#
Method 1: Manual Download (Recommended)#
Step 1: Download the XCFramework from the latest release:Step 2: Your project structure should look like:YourProject/
├── YourProject.xcodeproj
├── YourProject/
│ ├── AppDelegate.swift
│ ├── SceneDelegate.swift
│ ├── ViewController.swift
│ └── ...
└── Frameworks/
└── bas_pay.xcframework/
├── ios-arm64/
│ └── bas_pay.framework
└── ios-arm64_x86_64-simulator/
└── bas_pay.framework
1.
Open your .xcodeproj in Xcode
2.
Select your project target → General tab
3.
Scroll to Frameworks, Libraries, and Embedded Content
4.
Click + → Add Other... → Add Files...
5.
Select bas_pay.xcframework from the Frameworks/ directory
6.
Set Embed to "Embed & Sign"
Method 2: CocoaPods#
Create or edit your Podfile:Note: The podspec has a prepare_command that automatically downloads bas_pay.xcframework from GitHub Releases during pod install.
Step: Xcode Project Configuration#
After adding the framework, configure your build settings:1.
Target → Build Settings → Search Paths:Add the Frameworks/ directory to Framework Search Paths:$(PROJECT_DIR)/Frameworks
2.
Target → Build Settings → Other Linker Flags:If you encounter linking issues, add: 3.
Target → Build Settings → Excluded Architectures:For simulator builds, you may need:EXCLUDED_ARCHS[sdk=iphonesimulator*] = i386
Usage#
Step 1: Import the SDK#
Step 2: Register BankyLite Notifications#
This must be called before presenting the payment screen. It registers internal notification handlers needed by the SDK.Step 3: Create the Payment ViewController#
Step 4: Present the Payment Screen#
Important: The payment ViewController must be wrapped in a UINavigationController before presenting.
Parameters Reference#
| Parameter | Type | Required | Default | Description |
|---|
trxToken | String | ✅ Yes | — | The transaction token obtained from your backend API. Unique per payment session. |
userIdentifier | String? | ❌ No | nil | User identifier (e.g., phone number "733733733") |
fullName | String? | ❌ No | nil | Full name of the paying user |
language | String? | ❌ No | "ar" | UI language: "ar" (Arabic) or "en" (English) |
product | String? | ❌ No | nil | Product name or identifier |
onReturnDataToIOS | ((String?) -> Void)? | ✅ Yes | — | Callback closure that receives the payment result JSON string |
environment | String? | ❌ No | "prod" | Environment: "prod" for production, "dev" for development/testing |
Note: Unlike Android, there is no platform parameter in iOS — the SDK detects it automatically.
Response Handling#
Response JSON Structure#
The onReturnDataToIOS callback receives a JSON string with this structure:{
"status": true,
"message": "Payment completed successfully",
"result": { ... },
"code": 200
}
Response Fields#
| Field | Type | Description |
|---|
status | Bool | true = payment succeeded, false = payment failed |
message | String | Human-readable status message |
result | Any? | Additional payment result data (structure may vary) |
code | Int | Status code. 699 = unknown/default error code |
Parsing the Response#
Create a helper model to parse the result:Alternative — Quick parsing with JSONSerialization (simpler):
Environment Configuration#
| Environment | Value | Use Case |
|---|
| Production | "prod" | Live payments with real transactions |
| Development | "dev" | Testing and development — no real charges |
Complete Example — UIKit#
Complete Example — SwiftUI#
Usage in your app entry point:
Error Handling#
| Scenario | How to Detect | Recommended Action |
|---|
| User cancelled payment | onReturnDataToIOS receives nil | Show "Payment cancelled" message |
| Payment failed | status == false in response JSON | Show error from message field |
| Invalid token | status == false, check code | Request a new token from backend |
rootViewController not found | Cannot present payment screen | Ensure app has a key window with a root VC |
| XCFramework not found | Build error: No such module 'bas_pay' | Verify framework is embedded & signed |
| Simulator architecture error | Build fails on simulator | Add EXCLUDED_ARCHS[sdk=iphonesimulator*] = i386 |
Privacy & App Store#
The SDK includes a PrivacyInfo.xcprivacy file that declares:| Privacy Key | Value |
|---|
NSPrivacyTracking | false |
NSPrivacyTrackingDomains | Empty (none) |
NSPrivacyAccessedAPITypes | Empty (none) |
NSPrivacyCollectedDataTypes | Empty (none) |
✅ The SDK does not track users and does not collect personal data beyond what is explicitly passed via parameters.
Troubleshooting#
| Problem | Solution |
|---|
No such module 'bas_pay' | Ensure bas_pay.xcframework is added to Frameworks, Libraries, and Embedded Content with Embed & Sign |
| Build error on Simulator (i386) | Add to Build Settings: EXCLUDED_ARCHS[sdk=iphonesimulator*] = i386 |
BankyLiteNotificationManager crash | Make sure BankyLiteNotificationManager.shared.register() is called before creating the payment VC |
| Payment screen doesn't appear | Ensure you wrap the VC in UINavigationController before presenting |
rootViewController is nil | Make sure the app has a visible key window. In SwiftUI, access via UIApplication.shared.connectedScenes |
| Callback not firing | Check that onReturnDataToIOS closure is not nil. Use [weak self] to prevent retain cycles |
CocoaPods prepare_command fails | Ensure curl and unzip are available. Check internet connection. Run pod install --verbose for details |
| Linker errors | Add -ObjC to Other Linker Flags in Build Settings |
use_frameworks! error | The SDK requires use_frameworks! in your Podfile |
Files Checklist#
Before handing off to the iOS developer, ensure they have:
API Quick Reference#
Key Differences from Android#
| Aspect | Android (Kotlin) | iOS (Swift) |
|---|
| SDK Format | .aar files | .xcframework |
| Entry Point | BasPay.start() | BasMainIosKt.BasMainIosController() |
| Result Mechanism | onActivityResult | onReturnDataToIOS callback closure |
| Pre-registration | Not needed | BankyLiteNotificationManager.shared.register() required |
| Presentation | Starts an Activity | Present a UINavigationController |
platform parameter | Accepted | Not used (auto-detected) |
| Package Manager | Gradle / flatDir | CocoaPods / Manual XCFramework |
Modified at 2026-05-12 20:55:15