问题
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
回答1:
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)
}
}
回答2:
For your purpose you should use App Groups. It's a common scenario, you can read about this here in section "Sharing Data with Your Containing App". Then you can go deeper and read about How to Add an App to an App Group.
This allows you to share data between you extension and containing application. But this will not give you ability to observe data changes.
Hope it helps, feel free to ask a questions.
来源:https://stackoverflow.com/questions/55820193/how-to-set-response-data-into-todayextenstion-widget