I am trying to get my app to display the name of the selected cell on a different screen. I got it to display the word "Sample" but I want to show the name of the person selected. What can I do for it to show? It's just the one line of code I need to change in my prepareforSegue.
ViewController:
import UIKit
import CoreData
class ViewController: UIViewController,UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var ppl = [NSManagedObject]()
#IBAction func addName(sender: AnyObject) {
let alert = UIAlertController(title: "New Client",
message: "Add a new client",
preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Save",
style: .Default,
handler: { (action:UIAlertAction) -> Void in
let textField = alert.textFields!.first
self.saveName(textField!.text!)
self.tableView.reloadData()
})
let cancelAction = UIAlertAction(title: "Cancel",
style: .Default) { (action: UIAlertAction) -> Void in
}
alert.addTextFieldWithConfigurationHandler {
(textField: UITextField) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
presentViewController(alert,
animated: true,
completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Clients"
accessData()
tableView.registerClass(UITableViewCell.self,
forCellReuseIdentifier: "Cell")
tableView.reloadData()
}
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return ppl.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier("Cell")
let person = ppl[indexPath.row]
cell!.textLabel!.text =
person.valueForKey("name") as? String
return cell!
}
func tableView(tableView: UITableView,didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("SELECTED ITEM")
performSegueWithIdentifier("selectedView", sender: tableView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func saveName(name: String) {
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Person",
inManagedObjectContext:managedContext)
let person = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
person.setValue(name, forKey: "name")
do {
try managedContext.save()
ppl.append(person)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
func accessData() {
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Person")
do {
let results =
try managedContext.executeFetchRequest(fetchRequest)
ppl = results as! [NSManagedObject]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier=="selectedView") {
let dvc=segue.destinationViewController as! ViewController2
dvc.name="Sample"
//let selectedItem: NSManagedObject = ppl[self.tableView.indexPathForSelectedRow!.row] as NSManagedObject
//dvc.name = selectedItem.valueForKey("Cell") as! String
}
}
}
ViewController2:
import UIKit
class ViewController2:UIViewController{
#IBOutlet weak var userDisplay: UILabel!
var name = String()
override func viewDidLoad() {
super.viewDidLoad()
userDisplay.text = name
}
func printMe(){
print("I am a controller")
}
}
This can be done easily, instead of sending tableView as the sender when doing performSegueWithIdentifier("selectedView", sender: tableView) send the indexPath of the selected row, thus you have:
performSegueWithIdentifier("selectedView", sender: indexPath)
All you have to do then is change prepareForSegue method to be something like
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let indexPath = sender {
let cell = self.tableView.cellForRowAtIndexPath(indexPath as! NSIndexPath)
if let name = cell?.textLabel?.text {
let dvc = segue.destinationViewController as! SecondVC
dvc.name = name
}
}
}
Related
I want to make some blog or forum app.I made a home page to see other users's posts.I used tableview and prototype cell to do that.But when i run my app, i can not see all my items in my prototype cell.And they seem like default cells but they are not.I debugged it with changing cell's background color.I can see it but not completely true.
Here is my Home Page View Controller
import UIKit
import Parse
class FeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var postDizisi = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
verileriAl()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postDizisi.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "protCell", for: indexPath) as! FeedTableViewCell
cell.textView.text = postDizisi[indexPath.row].content
cell.usernameLabel.text = postDizisi[indexPath.row].username
return cell
}
#objc func verileriAl() {
print("done")
let query = PFQuery(className: "Post")
query.addDescendingOrder("createdAt")
query.findObjectsInBackground { (objects, error) in
if error != nil {
self.createAlert(title: "HATA", message: error?.localizedDescription ?? "HATA")
}else {
if objects!.count > 0 {
self.postDizisi.removeAll(keepingCapacity: false)
for object in objects! {
if let username = object.object(forKey: "username") as? String {
if let userContent = object.object(forKey: "content") as? String {
let post = Post(username: username, content: userContent)
self.postDizisi.append(post)
}
}else {
print("hata aldık")
}
}
self.tableView.reloadData()
}
}
}
}
func createAlert(title : String , message : String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let okBut
ton = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
alert.addAction(okButton)
present(alert, animated: true)
}
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(verileriAl), name: NSNotification.Name(rawValue: "veriGirildi"), object: nil)
}
}
Here is my upload View Controller
import UIKit
import Parse
class UploadViewController: UIViewController {
#IBOutlet weak var shareButton: UIButton!
#IBOutlet weak var usernameLabel: UILabel!
#IBOutlet weak var postTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
usernameLabel.text = PFUser.current()?.username
}
#IBAction func shareButtonClicked(_ sender: Any) {
let post = PFObject(className: "Post")
if PFUser.current() != nil {
post["username"] = PFUser.current()?.username
post["content"] = postTextView.text
post.saveInBackground { (success, error) in
if error != nil {
let alert = UIAlertController(title: "HAT", message: error?.localizedDescription ?? "HATA", preferredStyle: UIAlertController.Style.alert)
let okButton = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
alert.addAction(okButton)
self.present(alert, animated: true)
}else {
self.postTextView.text = ""
self.tabBarController?.selectedIndex = 0
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "veriGirildi"), object: nil)
}
}
}
}
}
I want to see like this
But when i runned my app it seems like this
Atil and ibrahimmbyrrm is just usernameLabel contents.Why it doesn't display other items on prototype cell
I want to see other users's posts on Home Page but my cell doesn't work successfully.I need help to fix it.I have this problem at all my projects.
I am trying to build a simple To Do app with Core Data.
In CoreData Model, I have created an Entity named "ToDoCoreData". It has one attribute "newToDoItem" type of String.
In CellForRowAt method I'm receiving the following error
Thread 1: EXC_BAD_ACCESS (code=1, address=0x6b49dedf6a0) - but everytime I rerun the app the newly added ToDo appeares in row.
The code is below. Would be glad if someone could help, please.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var toDoList:[ToDoCoreData] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
override func viewWillAppear(_ animated: Bool) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<ToDoCoreData> = ToDoCoreData.fetchRequest()
do {
toDoList = try context.fetch(fetchRequest)
} catch {
print(error.localizedDescription)
}
}
#IBAction func addNewToDo(_ sender: UIBarButtonItem) {
let ac = UIAlertController(title: "Add Task", message: "add New Task", preferredStyle: .alert)
let ok = UIAlertAction(title: "Add", style: .default) { (action) in
let textField = ac.textFields?[0]
// self.toDoList.insert((textField?.text)!, at: 0)
self.saveToDo(newToDoItem: (textField?.text)!)
self.tableView.reloadData()
}
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
ac.addTextField { textfield in
}
ac.addAction(ok)
ac.addAction(cancel)
present(ac, animated: true, completion: nil)
}
func saveToDo(newToDoItem: String) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "ToDoCoreData", in: context)
let taskObject = NSManagedObject(entity: entity!, insertInto: context) as! ToDoCoreData
taskObject.newToDoItem = newToDoItem
do {
try context.save()
toDoList.append(taskObject)
print("Success!")
} catch {
print(error.localizedDescription)
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
toDoList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
let toDo = toDoList[indexPath.row]
cell.rowLabel.text = toDo.newToDoItem
return cell
}
}
Here I Try MVVM pattern to achieve TableView but for showing alert I face problems , it compiles successfully but not showing alert.
[Result] on the tapped on profile pic which is in tableview cell, I want to show alert
TableViewCell
import Foundation
import UIKit
class ParentsImageCell : UITableViewCell {
weak var myVC : ProfileOfParentsDetailsViewController?
var parentProfileVC = ProfileOfParentsDetailsViewController()
#IBOutlet weak var imageProfile : UIImageView!
var items : ParentProfileViewModelItem? {
didSet {
guard let items = items as? ParentProfileViewModelProfileItem else {
return
}
imageProfile?.image = UIImage(named: items.profileImg)
}
}
static var nib:UINib {
return UINib(nibName: identifier, bundle: nil)
}
static var identifier: String {
return String(describing: self)
}
override func awakeFromNib() {
super.awakeFromNib()
imageProfile?.layer.cornerRadius = 62
imageProfile?.clipsToBounds = true
imageProfile?.contentMode = .scaleAspectFill
imageProfile?.backgroundColor = UIColor.lightGray
//Add Tapped Gesture
imageProfile.isUserInteractionEnabled = true
let gesture = UITapGestureRecognizer(
target: self,
action: #selector(didTappedChangeProfilePic))
gesture.numberOfTapsRequired = 1
gesture.numberOfTouchesRequired = 1
imageProfile.addGestureRecognizer(gesture)
}
#objc private func didTappedChangeProfilePic(){
print("tapped on imageView")
presentPhotoActionSheet()
}
override func prepareForReuse() {
super.prepareForReuse()
imageProfile?.image = nil
}
}
extension ParentsImageCell : UIImagePickerControllerDelegate ,UINavigationControllerDelegate {
func presentPhotoActionSheet(){
let actionSheet = UIAlertController(title: "Profile Picture", message: "How would you write to select a picture", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: nil))
actionSheet.addAction(UIAlertAction(title: "Take Photo", style: .default, handler: {[weak self] _ in
self?.presentCamera()
}))
actionSheet.addAction(UIAlertAction(title: "Choose Photo", style: .default, handler: { [weak self]_ in
self?.presentPhotoPicker()
}))
myVC?.present(actionSheet , animated: true)
}
func presentCamera(){
let vc = UIImagePickerController()
vc.sourceType = .camera
vc.delegate = self
vc.allowsEditing = true
myVC?.present(vc , animated: true)
}
func presentPhotoPicker(){
let vc = UIImagePickerController()
vc.sourceType = .photoLibrary
vc.delegate = self
vc.allowsEditing = true
myVC?.present(vc , animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info:
[UIImagePickerController.InfoKey : Any]) {
guard let selectedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage else {
return
}
self.imageProfile.image = selectedImage
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
ViewModel
class ParentProfileViewModel: NSObject {
var items = [ParentProfileViewModelItem]()
var reloadSections: ((_ section: Int) -> Void)?
override init() {
super.init()
guard let data = dataFromFile("ServerData"),
let profile = Profile(data: data) else {
return
}
// initialization code will go here
if let profile = profile.pictureUrl {
let profileItem = ParentProfileViewModelProfileItem(profileImg: profile)
items.append(profileItem)
}
if let name = profile.fullName {
let nameItem = ParentProfileViewModelNameItem(name: name)
items.append(nameItem)
}
if let email = profile.email {
let emailItem = ParentProfileViewModelEmailItem(email: email)
items.append(emailItem)
}
let coach = profile.coach
if !coach.isEmpty {
let coachItem = ParentProfileViewModelCoachItem(coach: coach)
items.append(coachItem)
}
let candidate = profile.candidate
if !candidate.isEmpty {
let candidateItem = ParentProfileViewModelCandidateItem(candidate: candidate)
items.append(candidateItem)
}
}
}
//MARK:- TableviewDatasource & Delegates
extension ParentProfileViewModel: UITableViewDataSource {
//Number of section
func numberOfSections(in tableView: UITableView) -> Int {
return items.count
}
//Number of RowInSection
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let item = items[section]
guard item.isCollapsible else {
return item.rowCount
}
if item.isCollapsed {
return 0
} else {
return item.rowCount
}
}
//Cell for row at indexpath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// we will configure the cells here
let item = items[indexPath.section]
switch item.type {
case .profileImg:
let vc = ProfileOfParentsDetailsViewController()
if let cell = tableView.dequeueReusableCell(withIdentifier: ParentsImageCell.identifier, for: indexPath) as? ParentsImageCell {
cell.items = item
cell.myVC = vc
return cell
}
case .fullName:
if let cell = tableView.dequeueReusableCell(withIdentifier: ParentsFulNameCell.identifier, for: indexPath) as? ParentsFulNameCell {
cell.items = item
return cell
}
case .email:
if let cell = tableView.dequeueReusableCell(withIdentifier: ParentsEmailCell.identifier, for: indexPath) as? ParentsEmailCell {
cell.items = item
return cell
}
case .candidate:
if let item = item as? ParentProfileViewModelCandidateItem, let cell = tableView.dequeueReusableCell(withIdentifier: CandidatCell.identifier, for: indexPath) as? CandidatCell {
let candidate = item.candidate[indexPath.row]
cell.item = candidate
return cell
}
case .coach:
if let item = item as? ParentProfileViewModelCoachItem, let cell = tableView.dequeueReusableCell(withIdentifier: ParentCoachCell.identifier, for: indexPath) as? ParentCoachCell {
cell.item = item.coach[indexPath.row]
return cell
}
}
return UITableViewCell()
}
}
ViewController
import Foundation
import UIKit
class ProfileOfParentsDetailsViewController: UIViewController {
let viewModel = ParentProfileViewModel()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
viewModel.reloadSections = { [weak self] (section: Int) in
self?.tableView?.beginUpdates()
self?.tableView?.reloadSections([section], with: .fade)
self?.tableView?.endUpdates()
}
tableView?.dataSource = viewModel
tableView.delegate = viewModel
tableView?.estimatedRowHeight = 250
tableView?.rowHeight = UITableView.automaticDimension
tableView?.register(ParentsImageCell.nib, forCellReuseIdentifier: ParentsImageCell.identifier)
tableView?.register(ParentsEmailCell.nib, forCellReuseIdentifier: ParentsEmailCell.identifier)
tableView?.register(ParentsFulNameCell.nib, forCellReuseIdentifier: ParentsFulNameCell.identifier)
tableView?.register(CandidatCell.nib, forCellReuseIdentifier: CandidatCell.identifier)
tableView?.register(ParentCoachCell.nib, forCellReuseIdentifier: ParentCoachCell.identifier)
tableView?.register(ParentsHeaderView.nib, forHeaderFooterViewReuseIdentifier: ParentsHeaderView.identifier)
}
I try to get called alert Sheet , but I Failed and also comment about my approach towards MVVM
I try to called the tableview data source and delegate in VM
I try to get called alert Sheet , but I Failed and also comment about my approach towards MVVM
I try to called the tableview data source and delegate in VM
I'm new to Swift and need your help.
I have two View Controllers with a tableview and two Entities called Groups and Singlegroups with an one to many relationship.The Entity Singlegroups has an attribute from type Date.
In View Controller 1 (MasterViewController) I show all Groups in my TableView and in the second View Controller (DetailViewController) I show all Singlegroups related to the Group of the selected row.
Now I want to load the SingleGroups on second View Controller only from current month but I can't get it to work, because I have no FetchRequest in the second View Controller. I transfer the Single Groups for the selected row in the prepareForSegue method.
I tried to call a fetchRequest manually in thousands different ways but nothing happend.
Hope you understand my problem and can help me.
MasterViewController ViewWillAppear:
import UIKit
import CoreData
class MasterViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var groups: [Groups] = []
#IBOutlet weak var groupsTableView: UITableView!
var groupsTextField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
groupsTableView.delegate = self
groupsTableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewWillAppear(_ animated: Bool) {
// Core date initialization
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<Groups> = Groups.fetchRequest()
do {
groups = try managedContext.fetch(fetchRequest)
groupsTableView.reloadData()
} catch {
// TODO: error handling
print("Could not fetch groups")
}
}
PrepareForSegue in MasterViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetailViewController" {
guard let destination = segue.destination as? DetailViewController,
let selectedRow = self.groupsTableView.indexPathForSelectedRow?.row else {
return
}
destination.group = groups[selectedRow]
destination.title = groups[selectedRow].groupTitle
}
DetailViewController ViewWillAppear:
import UIKit
import CoreData
class DetailViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate {
var singleGroupDate: UILabel!
var singleGroupName: UILabel!
var singleGroupAmount: UILabel!
#IBOutlet weak var dateLabelTextField: UITextField!
#IBOutlet weak var singleGroupSum: UILabel!
#IBOutlet weak var singleGroupTableView: UITableView!
var groups: [Groups] = []
var group: Groups?
override func viewDidLoad() {
super.viewDidLoad()
singleGroupTableView.delegate = self
singleGroupTableView.dataSource = self
}
override func viewWillAppear(_ animated: Bool) {
// Core date initialization
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
// create alert
let alert = UIAlertController(
title: "Could not get app delegate",
message: "Could not get app delegate, unexpected error occured. Try again later.",
preferredStyle: .alert)
// add OK action
alert.addAction(UIAlertAction(title: "OK", style: .default))
// show alert
self.present(alert, animated: true)
return
}
let managedContext = appDelegate.persistentContainer.viewContext
singleGroupTableView.reloadData()
DetailViewController TableView:
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return group?.singleGroups?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = singleGroupTableView.dequeueReusableCell(withIdentifier: "SingleGroupsTableViewCell", for: indexPath) as! SingleGroupsTableViewCell
let currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = Locale.current
currencyFormatter.positivePrefix = currencyFormatter.plusSign
currencyFormatter.negativePrefix = currencyFormatter.minusSign
if let singleGroup = group?.singleGroups?[indexPath.row] {
cell.singleGroupNameLabel?.text = singleGroup.singleGroupName
cell.singleGroupAmountLabel?.text = currencyFormatter.string(from: singleGroup.singleGroupAmount as NSNumber)
cell.singleGroupAmountLabel.textColor = UIColor.red
cell.singleGroupDateLabel?.text = DateHelper.convertDate(date: singleGroup.singleGroupTimeStamp)
}
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
deleteSingleGroup(at: indexPath)
}
}
UPDATE:
I solved it myself by writing a new fetch request for the SingleGroups Entity and changing the numbersOfRowsInSection method of my tableview.
func orderFetchRequest() -> NSFetchRequest<NSFetchRequestResult> {
let startDateFetch = Date().startOfMonth()
let endDateFetch = Date().endOfMonth()
self.startDate = startDateFetch!
self.endDate = endDateFetch!
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "SingleGroups")
let sortDescriptor = NSSortDescriptor(key: "singleGroupTimeStamp", ascending: false)
let predicate1 = NSPredicate(format: "group == %#", group!)
let predicate2 = NSPredicate(format: "singleGroupTimeStamp >= %# AND singleGroupTimeStamp <= %#", startDate as CVarArg, endDate as CVarArg)
let compound = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1, predicate2])
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.predicate = compound
return fetchRequest
}
func fetchData() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = orderFetchRequest()
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath:nil, cacheName: nil)
do {
try fetchedResultsController.performFetch()
singleGroupTableView.reloadData()
}
catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fetchedResultsController.fetchedObjects?.count ?? 0
First off, I'm pretty new to XCode. I'm a highschool student taking a coding class.
Here is the tutorial: https://www.raywenderlich.com/115695/getting-started-with-core-data-tutorial
Can you please help me update my code to fit the new Swift update?
Error: "Value of type AppDelegate has no member managedObjectContext"
Line giving me errors:
let appDelegate =
UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
However, when I remove this, and replace it with
let delegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = delegate.persistentContainer.viewContext
lots more errors pop up.
My full code:
import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDataSource
{
#IBOutlet weak var tableView: UITableView!
#IBAction func addName(_ sender: Any)
{
let alert = UIAlertController(title: "New Name", message: "Add a new name", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save", style: .default, handler:
{
(action:UIAlertAction) -> Void in
let textField = alert.textFields!.first
self.saveName(name: textField!.text!)
self.tableView.reloadData()
})
let cancelAction = UIAlertAction(title: "Cancel", style: .default) {
(action: UIAlertAction) -> Void in
}
alert.addTextField
{
(textField: UITextField) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
present(alert, animated: true, completion: nil)
}
func saveName(name: String)
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Person", inManagedObjectContext:managedContext)
let person = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
person.setValue(name, forKey: "name")
do
{
try managedContext.save()
people.append(person)
}
catch let error as NSError
{
print("Could not save \(error), \(error.userInfo)")
}
}
var people = [NSManagedObject]()
override func viewDidLoad()
{
super.viewDidLoad()
title = "\"The List\""
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//1
let appDelegate =
UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
//2
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
//3
do {
let results =
try managedContext.executeFetchRequest(fetchRequest)
people = results as! [NSManagedObject]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return people.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let person = people[indexPath.row]
cell!.textLabel!.text = person.value(forKey: "name") as? String
return cell!
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You can use a simple library (written by me) for latest Swift syntax AACoreData.
Simply assign your data model after installing the library,
AACoreData.sharedInstance().dataModel = "YourEntity"
For more guide and documentation visit the official repository AACoreData.
you should use the updated Core Data Model Tutorials for Swift 3 - that is more easy then going the hard way to convert old code.
https://www.raywenderlich.com/145692/core-data-by-tutorials-updated-for-swift-3-and-ios-10
https://www.raywenderlich.com/145809/getting-started-core-data-tutorial