iosswiftwidgetnsuserdefaultstoday-extension

How to set response data into TodayExtenstion widget


Trying to access response data from service to show into TodayExtenstion Widget

import Foundation

struct MarketIndex:Codable {

    let indicesName: String
    let indicesValue: String
    let dateValue : String
    let indicesChangeValue : String
    let changePercentage : String
    let indexVolume: String?
}

struct MarketIndexCache {
    static let key = "MARKET_INDEX_KEY"
    static func save(_ value: [MarketIndex]!) {
        UserDefaults.standard.set(try? PropertyListEncoder().encode(value), forKey: key)
    }
    static func get() -> [MarketIndex]! {
        var marketIndex: [MarketIndex]!
        if let data = UserDefaults.standard.value(forKey: key) as? Data {
            marketIndex = try? PropertyListDecoder().decode([MarketIndex].self, from: data)
            return marketIndex!
        } else {
            return marketIndex
        }
    }
    static func remove() {
        UserDefaults.standard.removeObject(forKey: key)
    }
}

MarketIndexClient Service Call class code snippet

marketIndexClient.fetchMarketIndex(symbol: "AAPL,MSFT"){ marketIndex in
    self.stockIndex = marketIndex
    completion()
    MarketIndexCache.save(self.stockIndex)
    self.dispatchGroupCalls.leave()

}

When Trying to access another viewcontroller able to get saved data.

override func viewDidLoad() {
    super.viewDidLoad()
    marketIndex = MarketIndexCache.get()
}

When trying to access its from TodayWidgetViewController its returns nil.

import UIKit
import NotificationCenter
class TodayWidgetViewController

    override func viewDidLoad() {
        super.viewDidLoad()

        marketIndex = MarketIndexCache.get()
        print(marketIndex as Any)

    }

Is UserDefaults for two targets will not share the data with each other?

When I select target projectName do I need to configure the TodayExtenstion so both need to sync with each other when my project run on device.

I unable to debug TodayExtenstionWidget when running application project.

This are my observation found while working with TodayExtenstion.

I am unable to figure it out why its returns nil! Your inputs will really guide me to achieve it.

ERROR MESSAGE:

Unexpectedly found nil while unwrapping an Optional value Fatal error: Unexpectedly found nil while unwrapping an Optional value


Solution

  • Hey as @LowKostKustomz explained, you need to activate app groups in both main app and extension. Then while saving from main app as well as extension, try something like

    struct MarketIndexCache {
        static let key = "MARKET_INDEX_KEY"
        static let groupBundleID = <#you group identifier#>
        static func save(_ value: [MarketIndex]!) {
            let defaults = UserDefaults.init(suiteName: groupBundleID)
            defaults?.set(try? PropertyListEncoder().encode(value), forKey: key)
        }
        static func get() -> [MarketIndex]! {
            var marketIndex: [MarketIndex]!
            if let data = defaults?.value(forKey: key) as? Data {
                let defaults = UserDefaults.init(suiteName: groupBundleID)
                marketIndex = try? PropertyListDecoder().decode([MarketIndex].self, from: data)
                return marketIndex!
            } else {
                return marketIndex
            }
        }
        static func remove() {
            let defaults = UserDefaults.init(suiteName: groupBundleID)
            defaults?.removeObject(forKey: key)
        }
    }