iOS SDK (Swift)
Native iOS SDK built with Swift for optimal performance and native iOS integration.
Status
🔄 Coming Q3 2025 - Currently in development
Join the waitlist to be notified when available.
Planned Features
Core Features
- ✅ Wallet-to-wallet calls (audio/video)
- ✅ Native CallKit integration
- ✅ Push notifications (APNs)
- ✅ Messaging
- ✅ Voicemail
- ✅ Call history
iOS-Specific
- ✅ CallKit integration
- ✅ Siri shortcuts
- ✅ Widgets
- ✅ Live Activities
- ✅ CarPlay integration
- ✅ Picture-in-Picture
- ✅ SharePlay integration
Requirements
- iOS 15.0+
- Xcode 15.0+
- Swift 5.9+
Planned Installation
Swift Package Manager
dependencies: [
.package(url: "https://github.com/Dial-WTF/Dial-iOS-SDK.git", from: "1.0.0")
]CocoaPods
pod 'DialSDK', '~> 1.0'Planned API
Setup
import DialSDK
let dial = DialClient(
apiKey: "your-api-key",
walletAddress: "0x..."
)Authentication
// Sign message with wallet
let signature = await wallet.sign(message: "Authenticate with Dial")
try await dial.authenticate(
walletAddress: "0x...",
signature: signature
)Making Calls
let call = try await dial.calls.start(
to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
type: .video
)CallKit Integration
import CallKit
import DialSDK
class CallManager: NSObject, DialCallDelegate {
let callKitProvider = CXProvider(configuration: createConfiguration())
func dialDidReceiveIncomingCall(_ call: DialCall) {
// Automatically displayed in native iOS call UI
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .generic, value: call.from)
update.hasVideo = call.type == .video
callKitProvider.reportNewIncomingCall(
with: call.uuid,
update: update
) { error in
if let error = error {
print("Error reporting call: \(error)")
}
}
}
}SwiftUI Integration
import SwiftUI
import DialSDK
struct CallView: View {
@StateObject var callManager = CallManager()
var body: some View {
VStack {
if let call = callManager.currentCall {
if call.status == .ringing {
IncomingCallView(call: call)
} else {
ActiveCallView(call: call)
}
} else {
Button("Make Call") {
Task {
await callManager.startCall(to: "0x...")
}
}
}
}
}
}
struct IncomingCallView: View {
let call: DialCall
var body: some View {
VStack(spacing: 20) {
Text("Incoming call from")
Text(call.from)
.font(.headline)
HStack(spacing: 40) {
Button(action: { call.decline() }) {
Image(systemName: "phone.down.fill")
.foregroundColor(.red)
}
Button(action: { call.answer() }) {
Image(systemName: "phone.fill")
.foregroundColor(.green)
}
}
.font(.system(size: 30))
}
}
}UIKit Integration
import UIKit
import DialSDK
class CallViewController: UIViewController {
let dial = DialClient.shared
var currentCall: DialCall?
override func viewDidLoad() {
super.viewDidLoad()
dial.delegate = self
}
@IBAction func makeCall(_ sender: UIButton) {
Task {
currentCall = try await dial.calls.start(
to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
type: .video
)
}
}
}
extension CallViewController: DialClientDelegate {
func dialDidReceiveIncomingCall(_ call: DialCall) {
currentCall = call
presentCallViewController(for: call)
}
}Messaging
// Send message
try await dial.messages.send(
to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
content: "Hello!",
type: .text
)
// Listen for messages
dial.messages.onReceived { message in
print("New message from \(message.from): \(message.content)")
}Push Notifications
import UserNotifications
import DialSDK
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Register for push notifications
UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .sound, .badge]
) { granted, error in
if granted {
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
return true
}
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
DialClient.shared.registerForPushNotifications(deviceToken: deviceToken)
}
}Async/Await Support
Full support for Swift’s modern concurrency:
// All API calls support async/await
let call = try await dial.calls.start(to: "0x...", type: .audio)
let messages = try await dial.messages.getHistory(with: "0x...")
let voicemails = try await dial.voicemail.getAll()Combine Support
Integration with Combine framework:
import Combine
import DialSDK
class CallViewModel: ObservableObject {
@Published var currentCall: DialCall?
@Published var messages: [DialMessage] = []
private var cancellables = Set<AnyCancellable>()
init() {
DialClient.shared.callPublisher
.sink { [weak self] call in
self?.currentCall = call
}
.store(in: &cancellables)
}
}Siri Shortcuts
import Intents
import DialSDK
class CallIntentHandler: NSObject, CallIntentHandling {
func handle(intent: CallIntent, completion: @escaping (CallIntentResponse) -> Void) {
Task {
let call = try await DialClient.shared.calls.start(
to: intent.recipient,
type: .audio
)
completion(CallIntentResponse.success(call: call))
}
}
}Widgets
import WidgetKit
import SwiftUI
import DialSDK
struct CallHistoryWidget: Widget {
let kind: String = "CallHistoryWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
CallHistoryWidgetView(entry: entry)
}
.configurationDisplayName("Call History")
.description("View your recent Dial calls")
}
}CarPlay Integration
import CarPlay
import DialSDK
class CarPlaySceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate {
func templateApplicationScene(
_ templateApplicationScene: CPTemplateApplicationScene,
didConnect interfaceController: CPInterfaceController
) {
// Add Dial calling to CarPlay
let callTemplate = CPListTemplate(
title: "Dial",
sections: createCallingSections()
)
interfaceController.setRootTemplate(callTemplate, animated: true)
}
}Privacy & Security
Required Permissions
Add to Info.plist:
<key>NSCameraUsageDescription</key>
<string>We need camera access for video calls</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need microphone access for calls</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need photo library access to share images</string>Keychain Integration
Secure storage of credentials:
// Automatically stores auth tokens in Keychain
try await dial.authenticate(
walletAddress: "0x...",
signature: signature
)
// Token securely stored in iOS KeychainPerformance
- Native Swift implementation
- Hardware-accelerated video encoding/decoding
- Optimized for battery life
- Background audio support
- Low memory footprint
Roadmap
Q3 2025 - Alpha Release
- Core calling features
- CallKit integration
- Push notifications
- Messaging
Q4 2025 - Beta Release
- Video conferencing
- Siri shortcuts
- Widgets
- CarPlay support
Q1 2026 - Stable Release
- Full feature parity
- SharePlay integration
- Live Activities
- Production-ready
Example App
A complete example app will be available:
- GitHub Repository
- Demonstrates all features
- Best practices
- UI/UX patterns
Get Notified
Want early access?
Next Steps
- React Native SDK - Coming Q2 2025
- Android SDK - Coming Q3 2025
- TypeScript SDK - Available now
Last updated on