Ich versuche es so zu machen, dass das Programm den Navigationstitel überprüft und dann die Zellen entsprechend auffüllt. Dies wäre bei hartkodierten Arrays einfach, aber die Verwendung eines Core Data-Objekts macht die Sache schwierig.Zellen dynamisch befüllen, abhängig vom Seitentitel
Initializers - 3 Produkte für jedes Unternehmen und ein leeres Array sie nach der Überprüfung der Seitentitel zu setzen:
let defaultProductsApple = ["iPhone", "iPad", "Macbook"]
let defaultProductsGoogle = ["Search", "Firebase", "Magic Leap"]
let defaultProductsFacebook = ["Facebook", "Instagram", "WhatsApp"]
let defaultProductsTesla = ["Model S", "Model X", "PowerWall"]
let defaultProductsTwitter = ["Twitter", "Periscope", "Vine"]
var defaultProducts = [String]()
viewDidLoad - den Seitentitel überprüfen und das leere Array füllen, dann auf Kerndatensatz für Persistenz beim Löschen:
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(Cell.self, forCellReuseIdentifier: cellId)
// Navbar stuff
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(handleBackButton))
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", style: .plain, target: self, action: #selector(handleAdd))
let entity = NSEntityDescription.entity(forEntityName: "Product", in: managedContext)!
switch self.navigationItem.title! {
case "Apple":
defaultProducts = defaultProductsApple
case "Google":
defaultProducts = defaultProductsGoogle
case "Twitter":
defaultProducts = defaultProductsTwitter
case "Tesla":
defaultProducts = defaultProductsTesla
case "Facebook":
defaultProducts = defaultProductsFacebook
default:
defaultProducts = defaultProductsApple
}
for productName in defaultProducts {
let product = NSManagedObject(entity: entity,insertInto: managedContext)
product.setValue(productName, forKey: "name")
products.append(product)
}
do {
try managedContext.save()
tableView.reloadData()
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
und setzte schließlich die Etiketten in cellForRow:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! Cell
let product = products[indexPath.row]
cell.textLabel?.text = product.value(forKey: "name") as? String
return cell
}
Die Zellen füllen sich wie beim ersten Versuch - d. H., Wenn ich im vorherigen Bildschirm auf "Apple" tippe, zeigen die Zellen mir die 3 Produkte von Apple an. Aber wenn ich dann zurück gehe und auf "Google" tippe, zeigen die Zellen jetzt die 3 Produkte von Apple sowie die 3 Produkte von Google an und so weiter und so fort.
Wie kann ich es so machen, dass cell.textLabel?.text = product.value(forKey: "name") as? String
NUR die Produkte dieses Unternehmens lädt?
EDIT: viewWillAppear
und die save
Methoden:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//1
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
//2
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Product")
//3
do {
products = try managedContext.fetch(fetchRequest)
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
func save(name: String) {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
let entity =
NSEntityDescription.entity(forEntityName: "Product",
in: managedContext)!
let product = NSManagedObject(entity: entity,
insertInto: managedContext)
product.setValue(name, forKey: "name")
do {
try managedContext.save()
products.append(product)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
Finale Bearbeiten - Setzen Sie alle Standardeinstellungen in einem Rutsch
// Default 5 companies at launch - user can delete/add/edit
func setDefaults() {
let userDefaults = UserDefaults.standard
let defaultValues = ["firstRun" : true]
userDefaults.register(defaults: defaultValues)
if userDefaults.bool(forKey: "firstRun") {
let defaultProducts = ["Apple" : ["iPhone", "iPad", "Macbook"],
"Google" : ["Search", "Firebase", "Magic Leap"],
"Facebook" : ["Facebook", "Instagram", "WhatsApp"],
"Tesla" : ["Model S", "Model X", "PowerWall"],
"Twitter" : ["Twitter", "Periscope", "Vine"]]
let companyEntity = NSEntityDescription.entity(forEntityName: "Company", in: managedContext)!
let productEntity = NSEntityDescription.entity(forEntityName: "Product", in: managedContext)!
// Setting the default company data (name, logo, and stockPrice)
let url = URL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20symbol%2C%20Ask%2C%20YearHigh%2C%20YearLow%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22AAPL%22%2C%22GOOG%22%2C%22TWTR%22%2C%22TSLA%22%2C%20%22FB%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
} else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
let json = JSON(data: data!)
if let quotes = json["query"]["results"]["quote"].array {
for quote in quotes {
let symbol = quote["symbol"].stringValue
let name = NSLocalizedString(symbol, comment:"")
let ask = quote["Ask"].stringValue
let company = NSManagedObject(entity: companyEntity,insertInto: managedContext)
company.setValue(name, forKey: "name")
company.setValue(name, forKey: "logo")
company.setValue(ask, forKey: "stockPrice")
companies.append(company)
print(json)
}
// Setting the default products - should I be doing this here too?
let companyProducts = defaultProducts[companyName]
// iterate through all those products names...
for productName in companyProducts {
// create the corresponding Product:
let product = NSManagedObject(entity: productEntity,insertInto: managedContext)
// set its name attribute...
product.setValue(productName, forKey: "name")
// then set the relationship to the relevant Company...
product.setValue(company, forKey: "company")
}
DispatchQueue.main.async {
do {
try managedContext.save()
vc.tableView.reloadData()
userDefaults.set(false, forKey: "firstRun")
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
}
} else {
print("The data couldn't be loaded")
}
}
task.resume()
}
}
Haben Sie einen anderen Code haben, der die 'Produkte' Array aktualisiert, vielleicht durch eine Abrufanforderung ausführt, z. B. in 'ViewWillAppear' oder einer der anderen Lifecycle-Methoden? – pbasdf
@pbasdf Ja, ich habe meine Frage so bearbeitet, dass sie sowohl 'viewWillAppear' als auch' save' enthält. Jede Hilfe wird sehr geschätzt! – d0xi45
Danke - das erklärt, was Sie beobachten. Die Abrufanforderung (in viewWillAppear) ruft alles ab; Sie brauchen eine Möglichkeit, die Produkte von Apple von denen von Google (und allen anderen) zu unterscheiden. Sie können dies entweder tun, indem Sie der Entität Product ein Attribut 'Firma' hinzufügen oder indem Sie einer Entität 'Firma' eine Beziehung hinzufügen. Sie müssen auch Ihren Code ändern, um diese Standardwerte nur einmal zu laden. Ich werde später eine vollständige Antwort hinzufügen ... – pbasdf