我正在尝试使我的 Viewcontroller 中的数组等于我的核心数据保存的对象。我正在使用核心数据并创建了一个名为 Pokemon 的实体,它具有 3 个属性 name、id 和 >一代。在应用程序委托(delegate)中,我使用以下函数从 API 获取 Pokemon .这就是我解析数据并保存上下文的方法:
typealias DownloadCompleted = () -> ()
var pokemonId: Int16 = 0
func fetchPokemon(url: String, completed: @escaping DownloadCompleted) {
let context = coreData.persistentContainer.viewContext
let url = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: url) { (data, repsonse, error) in
if error != nil {
print(error!)
}
do {
let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
let jsonArray = jsonResult.value(forKey: "results") as! [[String: Any]]
for pokemonData in jsonArray {
self.pokemonId += 1
if self.pokemonId > 721 {
self.coreData.saveContext()
return
}
guard let name = pokemonData["name"] as? String else {
return
}
let pokemon = Pokemon(context: context)
pokemon.name = name
pokemon.id = self.pokemonId
print("Name: \(pokemon.name) Id:\(self.pokemonId)")
if self.pokemonId <= 151 {
pokemon.generation = 1
} else if self.pokemonId <= 251 {
pokemon.generation = 2
} else if self.pokemonId <= 386 {
pokemon.generation = 3
} else if self.pokemonId <= 493 {
pokemon.generation = 4
} else if self.pokemonId <= 649 {
pokemon.generation = 5
} else if self.pokemonId <= 721 {
pokemon.generation = 6
}
}
guard let nextURL = jsonResult.value(forKey: "next") as? String else {
self.coreData.saveContext()
return
}
DispatchQueue.main.async {
self.fetchPokemon(url: nextURL, completed: {
self.coreData.saveContext()
})
completed()
}
} catch let err {
print(err.localizedDescription)
}
}
task.resume()
}
这就是我在 appDelegate 中的称呼。真的不知道在 fetchPokemon 中间要做什么或如何在另一个 View Controller 中调用它。所以我把它留空,不确定这是否与我遇到的问题有关。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let context = self.coreData.persistentContainer.viewContext
let pokemonListVC = self.window?.rootViewController as! PokemonListVC
pokemonListVC.context = context
fetchPokemon(url: pokemonAPI) {
}
return true
}
我正在使用应用商店中的这个 SQL-Light 只读应用。我检查了数据,所有 721 只宠物小 Sprite 都在保存。现在,我不知道如何使 View Controller 中的数组等于保存的所有 721 个 Pokemon。我将此代码添加到我的 viewController 中。
class PokemonListVC: UIViewController {
weak var context: NSManagedObjectContext! {
didSet {
return pokemon = Pokemon(context: context)
}
}
var pokemon: Pokemon? = nil
lazy var pokemons = [Pokemon]()
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
func loadData() {
pokemons = pokemon!.loadPokemon(generation: 1, context: context)
}
}
我创建了我的口袋妖怪实体的扩展,并添加了一个函数 loadPokemon,它按代过滤口袋妖怪。这是代码。
extension Pokemon {
func loadPokemon(generation: Int16 = 0, context: NSManagedObjectContext) -> [Pokemon] {
let request: NSFetchRequest<okemon> = Pokemon.fetchRequest()
request.predicate = NSPredicate(format: "generation = %@", generation)
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
do {
let pokemons = try context.fetch(request)
print("My Pokemon count: \(pokemons.count)")
return pokemons
} catch let err {
print(err.localizedDescription)
}
return []
}
}
当我在 ViewController 中调用 loadData 时,它会崩溃。数组计数为 0,英雄扩展中的数组计数也是 0。所以我不怎么让我的数组等于从 coreData 保存的 Pokemon。
非常感谢提供的任何帮助。
这是我的 deleteRecords 代码,它也在我的 appDelegate 中。这会在应用启动时删除所有记录。我在 fetchPokemons 之前的 didFinishLaunchingWithOption 函数的最开头调用了这个方法。
func deleteRecords() {
let context = coreData.persistentContainer.viewContext
let pokemonRequest: NSFetchRequest<okemon> = Pokemon.fetchRequest()
var deleteRequest: NSBatchDeleteRequest
var deleteResults: NSPersistentStoreResult
do {
deleteRequest = NSBatchDeleteRequest(fetchRequest: pokemonRequest as! NSFetchRequest<NSFetchRequestResult>)
deleteResults = try context.execute(deleteRequest)
} catch let err {
print(err.localizedDescription)
}
}
Best Answer-推荐答案 strong>
正如您所说,您确定所有 pockemon 记录都正确存储在您的 coredata 中,您可以通过提供 fetch 请求从您的 codedata 中简单地获取记录。我已经为联系人存储创建了演示,我可以通过此获取请求获取所有联系人,您可以在要获取所有记录的 ViewController 中尝试此代码。
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject> (entityName: "okemon")
do {
arrPockemon = try managedContext.fetch(fetchRequest)
}catch let error as NSError {
showAlert(string: error.localizedDescription)
}
首先尝试获取所有记录,如果获得所有记录,则继续过滤扩展名和所有记录。希望它会帮助你。你可以从这里学习https://code.tutsplus.com/tutorials/core-data-and-swift-core-data-stack--cms-25065
在 userDefault 上保存标志。
//check for first time when app is installed first time(first time flag is not present so)
let userDefault = UserDefaults.standard.dictionaryRepresentation()
if userDefault.keys.contains("isDataAvailable") {
//key is availebe so check it
if userDefault["isDataAvailable"] as! String == "1"{
//no need to call server for data
}else{
//fetch data from server
// once you get data from server make isDataAvailable flage as 1
UserDefaults.standard.setValue("1", forKey: "isDataAvailable")
UserDefaults.standard.synchronize()
}
}
else{
//flag is not avalable so call server for data
// once you get data from server make isDataAvailable flage as 1
UserDefaults.standard.setValue("1", forKey: "isDataAvailable")
UserDefaults.standard.synchronize()
}
关于ios - 将保存的上下文从 AppDelegate 加载到另一个 ViewController,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/43290506/
|