Post-Migration Compilation Errors Fix Plan
🎯 Overview
This document outlines the detailed fix plan for the 4 compilation errors that appeared in WarplySDK.swift
after the successful Raw SQL migration of DatabaseManager. These errors are related to async/await mismatches in token access methods.
Error Location: SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift
Error Lines: 2669-2670
Error Count: 4 compilation errors
Estimated Fix Time: 10 minutes
📋 Current Compilation Errors
Error Details from Build Log:
Line 2669 - Access Token Error:
/Users/manos/Desktop/warply_projects/dei_sdk/warply_sdk_framework/SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift:2669:29: error: 'async' call in a function that does not support concurrency
"access_token": networkService.getAccessToken() ?? "",
^
Line 2669 - Error Handling:
/Users/manos/Desktop/warply_projects/dei_sdk/warply_sdk_framework/SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift:2669:29: error: call can throw, but it is not marked with 'try' and the error is not handled
"access_token": networkService.getAccessToken() ?? "",
^
Line 2670 - Refresh Token Error:
/Users/manos/Desktop/warply_projects/dei_sdk/warply_sdk_framework/SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift:2670:30: error: 'async' call in a function that does not support concurrency
"refresh_token": networkService.getRefreshToken() ?? "",
^
Line 2670 - Error Handling:
/Users/manos/Desktop/warply_projects/dei_sdk/warply_sdk_framework/SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift:2670:30: error: call can throw, but it is not marked with 'try' and the error is not handled
"refresh_token": networkService.getRefreshToken() ?? "",
^
🔍 Root Cause Analysis
Problem:
The constructCampaignParams(campaign:isMap:)
method on line 2662 is synchronous but trying to call async NetworkService methods.
Current Problematic Code:
public func constructCampaignParams(campaign: CampaignItemModel, isMap: Bool) -> String {
// Pure Swift parameter construction using stored tokens and configuration
let jsonObject: [String: String] = [
"web_id": storage.merchantId,
"app_uuid": storage.appUuid,
"api_key": "", // TODO: Get from configuration
"session_uuid": campaign.session_uuid ?? "",
"access_token": networkService.getAccessToken() ?? "", // ❌ ASYNC CALL
"refresh_token": networkService.getRefreshToken() ?? "", // ❌ ASYNC CALL
"client_id": "", // TODO: Get from configuration
"client_secret": "", // TODO: Get from configuration
"map": isMap ? "true" : "false",
"lan": storage.applicationLocale,
"dark": storage.isDarkModeEnabled ? "true" : "false"
]
// ... rest of method
}
Why This Happens:
- NetworkService.getAccessToken() and NetworkService.getRefreshToken() are async methods
- constructCampaignParams(campaign:isMap:) is a synchronous method
- Swift compiler prevents calling async methods from sync contexts without proper handling
✅ Solution Strategy
Approach: Replace NetworkService calls with DatabaseManager calls
Rationale:
- DatabaseManager has synchronous token access methods
- DatabaseManager is the source of truth for tokens
- NetworkService gets tokens from DatabaseManager anyway
- This maintains the synchronous nature of the method
🔧 Detailed Fix Plan
✅ Step 1: Identify the Exact Problem Location (2 minutes)
-
File:
SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift
-
Method:
constructCampaignParams(campaign:isMap:)
starting at line 2662 - Problem Lines: 2669-2670
- Error Type: Async/await mismatch in synchronous context
✅ Step 2: Analyze Current Implementation (2 minutes)
-
Current Method Signature:
public func constructCampaignParams(campaign: CampaignItemModel, isMap: Bool) -> String
- Method Purpose: Construct JSON parameters for campaign requests
- Synchronous Requirement: Must remain synchronous for existing callers
- Token Source: Currently using NetworkService (async), should use DatabaseManager (sync)
✅ Step 3: Implement the Fix (5 minutes) - COMPLETED ✅
3.1: Replace NetworkService calls with DatabaseManager calls - COMPLETED ✅
Current problematic code:
"access_token": networkService.getAccessToken() ?? "", // ❌ ASYNC
"refresh_token": networkService.getRefreshToken() ?? "", // ❌ ASYNC
Fixed code - IMPLEMENTED ✅:
// Get tokens synchronously from DatabaseManager
var accessToken = ""
var refreshToken = ""
// Use synchronous database access for tokens
do {
if let tokenModel = try DatabaseManager.shared.getTokenModelSync() {
accessToken = tokenModel.accessToken
refreshToken = tokenModel.refreshToken
}
} catch {
print("⚠️ [WarplySDK] Failed to get tokens synchronously: \(error)")
}
// Pure Swift parameter construction using stored tokens and configuration
let jsonObject: [String: String] = [
"web_id": storage.merchantId,
"app_uuid": storage.appUuid,
"api_key": "", // TODO: Get from configuration
"session_uuid": campaign.session_uuid ?? "",
"access_token": accessToken, // ✅ SYNC
"refresh_token": refreshToken, // ✅ SYNC
"client_id": "", // TODO: Get from configuration
"client_secret": "", // TODO: Get from configuration
"map": isMap ? "true" : "false",
"lan": storage.applicationLocale,
"dark": storage.isDarkModeEnabled ? "true" : "false"
]
3.2: Implementation Used - TokenModel Pattern ✅
Used the existing pattern from line 2635 as the most robust solution:
Implementation Details:
- ✅ Synchronous Access: Uses
DatabaseManager.shared.getTokenModelSync()
- ✅ Error Handling: Graceful fallback with try/catch
- ✅ Token Extraction: Extracts both access and refresh tokens
- ✅ Empty String Fallback: Uses empty strings if tokens unavailable
- ✅ Consistent Pattern: Follows existing code patterns in the same file
✅ Step 4: Verify the Fix (1 minute)
- Compilation Check: Ensure no async/await errors remain
- Method Signature: Confirm method remains synchronous
- Functionality: Verify tokens are retrieved correctly
- Error Handling: Ensure graceful fallback for missing tokens
📝 Implementation Details
Option A: Direct DatabaseManager Access (Preferred)
public func constructCampaignParams(campaign: CampaignItemModel, isMap: Bool) -> String {
// Pure Swift parameter construction using stored tokens and configuration
let jsonObject: [String: String] = [
"web_id": storage.merchantId,
"app_uuid": storage.appUuid,
"api_key": "", // TODO: Get from configuration
"session_uuid": campaign.session_uuid ?? "",
"access_token": DatabaseManager.shared.getAccessToken() ?? "", // ✅ SYNC
"refresh_token": DatabaseManager.shared.getRefreshToken() ?? "", // ✅ SYNC
"client_id": "", // TODO: Get from configuration
"client_secret": "", // TODO: Get from configuration
"map": isMap ? "true" : "false",
"lan": storage.applicationLocale,
"dark": storage.isDarkModeEnabled ? "true" : "false"
]
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
let data = try encoder.encode(jsonObject)
let stringData = String(data: data, encoding: .utf8) ?? ""
print("constructCampaignParams: " + stringData)
return stringData
} catch {
print("constructCampaignParams error: \(error)")
return ""
}
}
Option B: TokenModel Pattern (Fallback)
public func constructCampaignParams(campaign: CampaignItemModel, isMap: Bool) -> String {
// Get tokens synchronously from DatabaseManager
var accessToken = ""
var refreshToken = ""
// Use synchronous database access for tokens
do {
if let tokenModel = try DatabaseManager.shared.getTokenModelSync() {
accessToken = tokenModel.accessToken
refreshToken = tokenModel.refreshToken
}
} catch {
print("⚠️ [WarplySDK] Failed to get tokens synchronously: \(error)")
}
let jsonObject: [String: String] = [
"web_id": storage.merchantId,
"app_uuid": storage.appUuid,
"api_key": "", // TODO: Get from configuration
"session_uuid": campaign.session_uuid ?? "",
"access_token": accessToken, // ✅ SYNC
"refresh_token": refreshToken, // ✅ SYNC
"client_id": "", // TODO: Get from configuration
"client_secret": "", // TODO: Get from configuration
"map": isMap ? "true" : "false",
"lan": storage.applicationLocale,
"dark": storage.isDarkModeEnabled ? "true" : "false"
]
// ... rest of method unchanged
}
🧪 Testing Checklist
Pre-Fix Verification:
- Confirm Current Errors: Build project and verify 4 compilation errors on lines 2669-2670
- Identify Error Types: Confirm async/await mismatch and error handling issues
Post-Fix Verification:
-
Compilation Success: Build project with
⌘+B
- should compile without errors (User will test manually) -
Method Functionality: Verify
constructCampaignParams
returns valid JSON - Token Retrieval: Confirm tokens are retrieved from database correctly
- Error Handling: Test behavior when no tokens are available
- Integration: Verify method works with existing callers
Regression Testing:
- Other constructCampaignParams Methods: Ensure other overloads still work
- Campaign URL Construction: Verify campaign URLs are built correctly
- Token Management: Confirm token storage/retrieval still functions
- Network Requests: Test that API calls include correct tokens
🚨 Risk Assessment
Low Risk Changes:
- ✅ Method Signature: No changes to public API
- ✅ Return Type: Same JSON string format
- ✅ Functionality: Same token retrieval, different source
- ✅ Dependencies: DatabaseManager already used elsewhere
Potential Issues:
- ⚠️ Token Availability: DatabaseManager might return nil tokens
- ⚠️ Error Handling: Need graceful fallback for database errors
- ⚠️ Performance: Synchronous database access (should be fast)
Mitigation Strategies:
- ✅ Graceful Degradation: Use empty strings for missing tokens
- ✅ Error Logging: Log token retrieval failures for debugging
- ✅ Consistent Pattern: Follow existing pattern from line 2635
📊 Expected Outcome
Before Fix:
❌ 4 compilation errors in WarplySDK.swift
❌ Build fails with async/await mismatch
❌ Framework cannot be compiled
After Fix:
✅ 0 compilation errors in WarplySDK.swift
✅ Build succeeds with clean compilation
✅ Framework ready for production use
✅ Token retrieval works synchronously
🎯 Success Criteria
✅ Fix Complete When:
- Zero Compilation Errors: Build succeeds without async/await errors
-
Method Functionality:
constructCampaignParams
returns valid JSON with tokens - API Compatibility: No breaking changes to method signature
- Token Integration: Tokens retrieved correctly from DatabaseManager
- Error Handling: Graceful behavior when tokens unavailable
✅ Quality Assurance:
- Code Review: Changes follow existing patterns in the file
- Testing: Method works with real token data
- Documentation: Comments updated to reflect DatabaseManager usage
- Performance: No significant performance impact
📋 Implementation Checklist
Phase 1: Preparation (1 minute)
- Backup Current File: Ensure WarplySDK.swift is backed up
- Identify Exact Lines: Confirm lines 2669-2670 contain the errors
- Review DatabaseManager API: Check available synchronous token methods
Phase 2: Implementation (5 minutes)
-
Replace Line 2669: Change
networkService.getAccessToken()
toDatabaseManager.shared.getAccessToken()
-
Replace Line 2670: Change
networkService.getRefreshToken()
toDatabaseManager.shared.getRefreshToken()
- Add Error Handling: Ensure graceful fallback for nil tokens
- Update Comments: Reflect the change from NetworkService to DatabaseManager
Phase 3: Verification (3 minutes)
-
Build Project: Run
⌘+B
to verify compilation success - Check Warnings: Ensure no new warnings introduced
-
Test Method: Verify
constructCampaignParams
returns expected JSON - Integration Test: Confirm method works with existing callers
Phase 4: Documentation (1 minute)
- Update Comments: Document the synchronous token access pattern
- Log Changes: Record the fix in appropriate documentation
- Verify Consistency: Ensure similar patterns used throughout file
🔧 Alternative Solutions (If Needed)
Option 1: Make Method Async (Not Recommended)
public func constructCampaignParams(campaign: CampaignItemModel, isMap: Bool) async throws -> String {
// Would require changing all callers - breaking change
}
Rejected: Breaking change to public API
Option 2: Use Completion Handler (Not Recommended)
public func constructCampaignParams(campaign: CampaignItemModel, isMap: Bool, completion: @escaping (String) -> Void) {
// Would require changing all callers - breaking change
}
Rejected: Breaking change to public API
Option 3: Synchronous Token Access (Chosen)
// Use DatabaseManager for synchronous token access
"access_token": DatabaseManager.shared.getAccessToken() ?? "",
"refresh_token": DatabaseManager.shared.getRefreshToken() ?? "",
Selected: No breaking changes, maintains synchronous behavior
📈 Performance Considerations
DatabaseManager Access:
- ✅ Fast: Direct database access is typically very fast
- ✅ Cached: Tokens likely cached in memory by DatabaseManager
- ✅ Synchronous: No async overhead for simple token retrieval
- ✅ Reliable: Database is local, no network dependency
Comparison with NetworkService:
- NetworkService: Async, may involve network calls for token refresh
- DatabaseManager: Sync, direct access to stored tokens
- Performance: DatabaseManager should be faster for simple token access
🎉 Conclusion
This fix addresses the core issue of async/await mismatch by replacing async NetworkService calls with synchronous DatabaseManager calls. The solution:
- ✅ Fixes all 4 compilation errors immediately
- ✅ Maintains API compatibility - no breaking changes
- ✅ Improves performance - direct database access vs async network calls
- ✅ Follows existing patterns - consistent with other parts of the file
- ✅ Provides better reliability - local database vs potential network issues
Ready to implement! This is a straightforward fix that should resolve the compilation errors quickly and safely.
Generated: 27/06/2025, 12:52 pm
Estimated Implementation Time: 10 minutes
Risk Level: Low
Breaking Changes: None