#ios #swift #core-data
#iOS #swift #core-data
Вопрос:
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 чтобы дать подсчет, но это ноль
но когда я пытаюсь получить доступ из ViewController , создав переменную класса сущности core data , она возвращает nill
Комментарии:
1. Выведите ошибку в блоке catch и проверьте журнал ошибок.
print("error in saving", error)
2.
GenreListModel
как тип, так и экземпляр не имеют смысла. И вforEach
цикле вы собираетесь перезаписать данные в (только один раз) созданном экземпляре объекта.3. он печатает данные, поэтому я надеюсь, что проблем с сохранением нет. genreList.name при печати в разделе сохранить он печатает имя, но не сохраняет его в основной базе данных i guss.
4. @vadian, не могли бы вы кратко рассказать? часть завершения работает. GenreListModel — это просто имя для переноса данных после успешного завершения
5. Назовите переменные, функции, регистры перечислений с начальной строчной буквой и назовите типы, структуры, классы, перечисления с начальной прописной буквой, чтобы избежать путаницы.
Ответ №1:
Что не так?
Я буду основывать свой ответ на коде там. В вашей учетной записи 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
So tableView(_:numberOfRowsInSection:)
всегда будет возвращаться 0
.
Сделайте свой выбор. Либо genreList
или coreGenre
:
ApiManager.shared.getGenreKeys { genreList in
self.coreGenre = genreList.genres
}
amp;
var coreGenre: [GenreList] {
didSet { DispatchQueue.main.async { self.tableView.reloadData() } }
}
И удалите var genreList
Или удалите coreGenre
.
Это должно исправить UITableView
, и именно здесь ваш вопрос вводит в заблуждение: здесь нет CoreData. В completion
of getGenreKeys()
вы возвращаете значение. CoreData сохраняет значение в методе, но это все.
Это:
API -> Parse Value -> Save in CoreData
-> Completion -> Reload TableView to Display
Теперь в вашем стеке CoreData у вас есть метод saveGenreList(json:)
. Предполагая, что это работает, вы сохраняете его, но никогда не извлекаете.
NSFetchRequest
В вашем коде нет. Посмотрите, как выполнить выборку в CoreData.
Просто перестаньте думать CoreData
, чтобы понять проблему:
let retrieveValueFromAPI = "I got it"
let savedValue = retrieveValueFromAPI // (1)
return retrieveValueFromAPI
В (1) вы получите предупреждение о неиспользуемой переменной от Xcode. Это точно такая же проблема. Здесь это «значение ОЗУ» вместо значения диска, но это та же логика. Вы не используете то, что сохранили.
Вам нужно продолжить работу и отладку. И debug не только устраняет проблему. Есть несколько шагов:
- Воспроизвести проблему
- Найдите его источник / поймите, в чем может быть проблема
- Устраните проблему
Поиск его происхождения и причины — это шаги, которые вы пропустили, либо из-за неправильного понимания, либо из-за недостаточного пошагового исследования в вашем коде.