post_migration_errors_fix_plan.md 15.6 KB

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:

  1. NetworkService.getAccessToken() and NetworkService.getRefreshToken() are async methods
  2. constructCampaignParams(campaign:isMap:) is a synchronous method
  3. 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:

  1. Zero Compilation Errors: Build succeeds without async/await errors
  2. Method Functionality: constructCampaignParams returns valid JSON with tokens
  3. API Compatibility: No breaking changes to method signature
  4. Token Integration: Tokens retrieved correctly from DatabaseManager
  5. Error Handling: Graceful behavior when tokens unavailable

✅ Quality Assurance:

  1. Code Review: Changes follow existing patterns in the file
  2. Testing: Method works with real token data
  3. Documentation: Comments updated to reflect DatabaseManager usage
  4. 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() to DatabaseManager.shared.getAccessToken()
  • Replace Line 2670: Change networkService.getRefreshToken() to DatabaseManager.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:

  1. ✅ Fixes all 4 compilation errors immediately
  2. ✅ Maintains API compatibility - no breaking changes
  3. ✅ Improves performance - direct database access vs async network calls
  4. ✅ Follows existing patterns - consistent with other parts of the file
  5. ✅ 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