保存 API 对 coreData 的响应,访问时仍然显示 nil
saving API response to coreData, still shows nil when accessing
func getGenreKeys(complition: @escaping (_ genre : GenreListModel?) -> ())
{
let genreUrl = URL(string: "\(baseUrl)\(genreListUrl)\(apiKey)")!
urlSessionManager(url: genreUrl,toUseDataType: GenreListModel.self) { json in
//json will contain genreList Object , which can be used to get keys
switch json
{
case .success(let genreListData) :
complition(genreListData)
CoreData.shared.saveGenreList(json: genreListData)
case .failure(let error) :
print(error)
}
}
}
以上是api完成码
func saveGenreList(json: GenreListModel){
let context = persistentContainer.viewContext
let genreList = GenreList(context: context)
json.genres?.forEach({ Genres in
genreList.name = Genres.name
do{
try context.save()
}
catch{
print("error in saving")
}
})
}
这是我在完成 api 提取后保存数据所做的。
var coreGenre : GenreList?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return coreGenre?.name?.count ?? 0
上面的代码是 VC 的一部分,它需要获取 coreGenre.name 来给出计数,但它是 nill
但是当我尝试通过创建核心数据实体 class 的变量从 viewController 访问时,它 returns nill
怎么了?
我的回答基于代码 there。在您分享该代码的 GitHub 帐户中。
第一期:
你有:
var genrelist : GenreListModel? {
didSet{
//after getting data a table needs to reload and ui elements needs to be used in main thread only
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
var coreGenre : [GenreList]?
override func viewWillAppear(_ animated: Bool) {
...
ApiManager.shared.getGenreKeys { genre in
self.genrelist = genre
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return coreGenre?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
genrelist?.genres?[indexPath.row].id
...
cell.genreLabel.text = genrelist?.genres?[indexPath.row].name
...
}
第一期:
coreGenre
从未设置! genreList
已设置,但未设置 coreGenre
。所以不要指望它会是 nil
!
的其他东西
你没有写 coreGenre = something
所以 tableView(_:numberOfRowsInSection:)
总是 return 0
.
做出你的选择。 genreList
或 coreGenre
:
ApiManager.shared.getGenreKeys { genreList in
self.coreGenre = genreList.genres
}
&
var coreGenre: [GenreList] {
didSet { DispatchQueue.main.async { self.tableView.reloadData() } }
}
并删除 var genreList
或者,删除 coreGenre
.
这应该可以解决 UITableView
,这就是您的问题具有误导性的地方:这里没有 CoreData。在 completion
的 getGenreKeys()
中,你 return 的值。 CoreData在方法中保存值,仅此而已。
是:
API -> Parse Value -> Save in CoreData
-> Completion -> Reload TableView to Display
现在在您的 CoreData 堆栈中,您有一个方法 saveGenreList(json:)
。假设它有效,您保存它但永远不会检索它。
您的代码中没有 NSFetchRequest
。看看如何在CoreData中执行fetch。
别再想CoreData
,想明白问题了:
let retrieveValueFromAPI = "I got it"
let savedValue = retrieveValueFromAPI // (1)
return retrieveValueFromAPI
在 (1) 中,您将收到来自 Xcode 的未使用变量警告。这是完全相同的问题。这里它是一个“RAM 值”而不是磁盘值,但这是相同的逻辑。你没有使用你保存的东西。
您需要继续工作和调试。调试不仅可以解决问题。有几个步骤:
- 重现问题
- 找到它的 origin/understand 可能是什么问题
- 解决问题
寻找它的起源,以及为什么,是你错过的步骤,要么是由于误解,要么是你的代码中没有足够的逐步研究。
func getGenreKeys(complition: @escaping (_ genre : GenreListModel?) -> ())
{
let genreUrl = URL(string: "\(baseUrl)\(genreListUrl)\(apiKey)")!
urlSessionManager(url: genreUrl,toUseDataType: GenreListModel.self) { json in
//json will contain genreList Object , which can be used to get keys
switch json
{
case .success(let genreListData) :
complition(genreListData)
CoreData.shared.saveGenreList(json: genreListData)
case .failure(let error) :
print(error)
}
}
}
以上是api完成码
func saveGenreList(json: GenreListModel){
let context = persistentContainer.viewContext
let genreList = GenreList(context: context)
json.genres?.forEach({ Genres in
genreList.name = Genres.name
do{
try context.save()
}
catch{
print("error in saving")
}
})
}
这是我在完成 api 提取后保存数据所做的。
var coreGenre : GenreList?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return coreGenre?.name?.count ?? 0
上面的代码是 VC 的一部分,它需要获取 coreGenre.name 来给出计数,但它是 nill
但是当我尝试通过创建核心数据实体 class 的变量从 viewController 访问时,它 returns nill
怎么了?
我的回答基于代码 there。在您分享该代码的 GitHub 帐户中。
第一期:
你有:
var genrelist : GenreListModel? {
didSet{
//after getting data a table needs to reload and ui elements needs to be used in main thread only
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
var coreGenre : [GenreList]?
override func viewWillAppear(_ animated: Bool) {
...
ApiManager.shared.getGenreKeys { genre in
self.genrelist = genre
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return coreGenre?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
genrelist?.genres?[indexPath.row].id
...
cell.genreLabel.text = genrelist?.genres?[indexPath.row].name
...
}
第一期:
coreGenre
从未设置! genreList
已设置,但未设置 coreGenre
。所以不要指望它会是 nil
!
的其他东西
你没有写 coreGenre = something
所以 tableView(_:numberOfRowsInSection:)
总是 return 0
.
做出你的选择。 genreList
或 coreGenre
:
ApiManager.shared.getGenreKeys { genreList in
self.coreGenre = genreList.genres
}
&
var coreGenre: [GenreList] {
didSet { DispatchQueue.main.async { self.tableView.reloadData() } }
}
并删除 var genreList
或者,删除 coreGenre
.
这应该可以解决 UITableView
,这就是您的问题具有误导性的地方:这里没有 CoreData。在 completion
的 getGenreKeys()
中,你 return 的值。 CoreData在方法中保存值,仅此而已。
是:
API -> Parse Value -> Save in CoreData
-> Completion -> Reload TableView to Display
现在在您的 CoreData 堆栈中,您有一个方法 saveGenreList(json:)
。假设它有效,您保存它但永远不会检索它。
您的代码中没有 NSFetchRequest
。看看如何在CoreData中执行fetch。
别再想CoreData
,想明白问题了:
let retrieveValueFromAPI = "I got it"
let savedValue = retrieveValueFromAPI // (1)
return retrieveValueFromAPI
在 (1) 中,您将收到来自 Xcode 的未使用变量警告。这是完全相同的问题。这里它是一个“RAM 值”而不是磁盘值,但这是相同的逻辑。你没有使用你保存的东西。
您需要继续工作和调试。调试不仅可以解决问题。有几个步骤:
- 重现问题
- 找到它的 origin/understand 可能是什么问题
- 解决问题
寻找它的起源,以及为什么,是你错过的步骤,要么是由于误解,要么是你的代码中没有足够的逐步研究。