Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.50.0] - 2026-05-29

This release introduces Wingify as the primary SDK branding and package namespace, while keeping existing VWO integrations fully supported.

Added

import Wingify_FME

let options = WingifyInitOptions(
    sdkKey: "32-alpha-numeric-sdk-key",
    accountId: 123456
)

WingifyFme.initialize(options: options) { result in
    switch result {
    case .success:
        let context = WingifyUserContext(id: "user-123")
        let flag = WingifyFme.getFlag(featureKey: "feature-key", context: context)
        _ = flag?.isEnabled()
    case .failure(let error):
        print(error.localizedDescription)
    }
}

Changed

Deprecated

The following VWO symbols are deprecated but continue to work without modification:

Deprecated (still supported) Use instead
VWOFme WingifyFme
VWOInitOptions WingifyInitOptions
VWOUserContext WingifyUserContext
VWOStorageConnector WingifyStorageConnector

Existing code does not need to change immediately. We recommend adopting the Wingify API for new projects and migrating when convenient:

// Still supported - no action required today
import VWO_FME

let options = VWOInitOptions(
    sdkKey: "32-alpha-numeric-sdk-key",
    accountId: 123456
)

VWOFme.initialize(options: options) { result in
    switch result {
    case .success:
        let context = VWOUserContext(id: "user-123")
        _ = VWOFme.getFlag(featureKey: "feature-key", context: context)
    case .failure(let error):
        print(error.localizedDescription)
    }
}

Migration tip: Replace VWOFme -> WingifyFme, VWOInitOptions -> WingifyInitOptions, and VWOUserContext -> WingifyUserContext, and update imports from VWO_FME to Wingify_FME. Method signatures and SDK behavior are unchanged.

[1.17.2] - 2026-05-18

Changed

Updated gateway user details request context handling to include ipAddress only when gateway configuration is present in VWOInitOptions.

[1.17.1] - 2026-05-115

Added

Fetch settings parallelly even when cache is not expired

[1.17.0] - 2026-04-28

Added

[1.16.0] - 2026-03-16

Fixed

[1.15.0] - 2026-03-12

Added

// Decisions expire after 60 seconds (60_000 ms); re-evaluation happens on the next getFlag call
 let options = VWOInitOptions(sdkKey: SDK_KEY, accountId: ACCOUNT_ID, cachedDecisionExpiryTime: 60000)

[1.14.1] - 2026-03-10

Fixed

[1.14.0] - 2026-02-03

Added

import VWO_FME

// Initialize first instance
let options1 = VWOInitOptions(
    sdkKey: "first_sdk_key",
    accountId: 123456,
    logLevel: .info,
    logPrefix: "Instance1",
    batchUploadTimeInterval: 60000  // 1 minute
)

VWOFme.initialize(options: options1) { result in
    switch result {
    case .success:
        print("First instance initialized")

        let userContext1 = VWOUserContext(id: "user_123")
        VWOFme.getFlag(featureKey: "feature_1", context: userContext1) { flag in
            // Use flag from first instance
        }
    case .failure(let error):
        print("First instance initialization failed: \(error)")
    }
}

// Initialize second instance with different configuration
let options2 = VWOInitOptions(
    sdkKey: "second_sdk_key",
    accountId: 789012,
    logLevel: .debug,
    logPrefix: "Instance2",
    batchUploadTimeInterval: 120000  // 2 minutes
)

VWOFme.initialize(options: options2) { result in
    switch result {
    case .success:
        print("Second instance initialized")

        let userContext2 = VWOUserContext(id: "user_456")
        VWOFme.getFlag(featureKey: "feature_2", context: userContext2) { flag in
            // Use flag from second instance
        }
    case .failure(let error):
        print("Second instance initialization failed: \(error)")
    }
}

Each SDK instance maintains its own:

This ensures complete isolation between instances, allowing you to safely use multiple VWO accounts or environments in the same application without any interference.

Fixed

[1.13.0] - 2025-11-27

Added

[1.12.1] - 2025-11-12

Fixed

[1.12.0] - 2025-09-30

Added

[1.11.1] - 2025-09-21

Fixed

[1.11.0] - 2025-09-10

Added

[1.10.0] - 2025-09-01

Added

[1.9.1] - 2025-08-22

Added

[1.9.0] - 2025-08-06

Added

[1.8.2] - 2025-07-25

Added

[1.8.1] - 2025-07-24

Added

[1.8.0] - 2025-07-16

Added

   import VWO_FME

    let options = VWOInitOptions(sdkKey: SDK_KEY,
                             accountId: ACCOUNT_ID,
                             gatewayService: ["url": "REPLACE_WITH_GATEWAY_URL"],
                             cachedSettingsExpiryTime: 10 * 60 * 1000, // in milliseconds
                             pollInterval: nil,
                             storage: CustomStorage.shared)

    VWOFme.initialize(options: options) { result in
        switch result {
            case .success(let message):
                print("VWO init success")

            case .failure(let error):
                print("VWO init failed")
        }
    }

    class CustomStorage : VWOStorageConnector {

        static let shared = CustomStorage()
        private init() {}

        func set(_ value: Any?, forKey key: String) {
            // Use key and value to store
        }

        func getData(forKey key: String) -> Data? {
            // Use key to retrieve data
        }

    }

[1.7.1] - 2025-07-11

Added

   let userContext = VWOUserContext(customVariables: customVariables, shouldUseDeviceIdAsUserId: true)

[1.7.0] - 2025-06-12

Added

[1.6.1] - 2025-06-03

Added

[1.6.0] - 2025-05-09

Added

Changed

Fixed

[1.5.0] - 2025-03-11

Added

[1.4.1] - 2025-03-10

Added

[1.4.0] - 2025-02-14

Added

    let attributeName1 = "attribute-name-string"
    let attributeValue1 = "attribute-value-text"
    let attributeName2 = "attribute-name-float"
    let attributeValue2 = 7.0
    let attributeDict: [String: Any] = [attributeName1: attributeValue1,
                                        attributeName2: attributeValue2]
    VWOFme.setAttribute(attributes: [attributeDict], context: userContext)
    //The `VWOSessionCallback` protocol in Mobile Insights SDK includes a callback method to provide session information
     func vwoScreenCaptureSessionDidUpdate(data: [String : Any]) {
         FmeConfig.setSessionData(data)
     }

[1.3.1] - 2025-02-11

Fixed

[1.3.0] - 2025-01-10

Added

[1.2.0] - 2024-12-20

Added

[1.1.0] - 2024-11-08

Added

import VWO_FME

let options = VWOInitOptions(sdkKey: SDK_KEY,
                             accountId: ACCOUNT_ID,
                             gatewayService: ["url": "REPLACE_WITH_GATEWAY_URL"],
                             cachedSettingsExpiryTime: 10 * 60 * 1000) // in milliseconds

VWOFme.initialize(options: options) { result in
    switch result {
        case .success(let message):
            print("VWO init success")

        case .failure(let error):
            print("VWO init failed")
    }
}

[1.0.0] - 2024-10-15

Added

import VWO_FME

let options = VWOInitOptions(sdkKey: sdkKey, accountId: accountId, gatewayService: ["url": "REPLACE_WITH_GATEWAY_URL"])

VWOFme.initialize(options: options) { result in
    switch result {
        case .success(let message):
            print("VWO init success")

        case .failure(let error):
            print("VWO init failed")
    }
}

let userContext = VWOContext(
    id: USER_ID,
    ipAddress: "1.2.3.4", // pass actual IP Address
    userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148" // pass actual user agent
)

let featureFlagObj = VWOFme.getFlag(featureKey: FEATURE_KEY, context: userContext)

[0.1.0] - 2024-09-26

Added